diff -uNr click-1.5.0-dist/bsdmodule/Makefile.in click-1.5.0/bsdmodule/Makefile.in --- click-1.5.0-dist/bsdmodule/Makefile.in Wed Mar 22 19:52:08 2006 +++ click-1.5.0/bsdmodule/Makefile.in Thu Feb 1 14:02:03 2007 @@ -27,6 +27,20 @@ INSTALL_DATA = @INSTALL@ -m 644 mkinstalldirs = @top_srcdir@/mkinstalldirs +ifeq ($(V),1) +ccompile = $(COMPILE) $(1) +cxxcompile = $(CXXCOMPILE) $(1) +else +ccompile = @/bin/echo ' ' $(2) $< && $(COMPILE) $(1) +cxxcompile = @/bin/echo ' ' $(2) $< && $(CXXCOMPILE) $(1) +endif + +quiet_cmd_cxxcompile = CXX $(quiet_modtag) $(subst $(obj)/,,$@) +cmd_cxxcompile = $(CXXCOMPILE) -c -o $@ $< + +quiet_cmd_ccompile = CC $(quiet_modtag) $(subst $(obj)/,,$@) +cmd_ccompile = $(COMPILE) -c -o $@ $< + .SUFFIXES: .SUFFIXES: .S .c .cc .o .s .ii @@ -60,12 +74,12 @@ driver.o \ $(EXTRA_DRIVER_OBJS) -BSDMODULE_OBJS = config.o sched.o module.o \ +BSDMODULE_OBJS = config.o sched.o module.o module_c.o \ clickfs.o clickfs_vnops.o clickfs_tree.o clickfs_element.o EXTRA_DRIVER_OBJS = @EXTRA_DRIVER_OBJS@ -OBJS = setdef0.o $(GENERIC_OBJS) $(ELEMENT_OBJS) $(BSDMODULE_OBJS) elements.o setdef1.o +OBJS = $(GENERIC_OBJS) $(ELEMENT_OBJS) $(BSDMODULE_OBJS) elements.o CPPFLAGS = @CPPFLAGS@ -DCLICK_BSDMODULE -DBSD_NETISRSCHED CFLAGS = @CFLAGS_NDEBUG@ -g @@ -90,7 +104,7 @@ -include elements.mk endif -click.ko: Makefile vnode_if.h $(OBJS) +click.ko: Makefile vnode_if.h vnode_if_newproto.h vnode_if_typedef.h $(OBJS) $(LD) -Bshareable -o click.ko $(OBJS) Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -108,11 +122,13 @@ $(top_builddir)/click-buildtool elem2export < elements.conf > elements.cc @rm -f elements.d -setdef0.c setdef1.c: module.o - gensetdefs module.o -vnode_if.h: $(freebsd_srcdir)/kern/vnode_if.pl $(freebsd_srcdir)/kern/vnode_if.src $(srcdir)/massage-vnode_if.pl - $(PERL) $(freebsd_srcdir)/kern/vnode_if.pl -h $(freebsd_srcdir)/kern/vnode_if.src - $(PERL) $(srcdir)/massage-vnode_if.pl vnode_if.h +vnode_if.h: $(freebsd_srcdir)/kern/vnode_if.src + /usr/bin/awk -f $(freebsd_srcdir)/tools/vnode_if.awk $(freebsd_srcdir)/kern/vnode_if.src -h +vnode_if_newproto.h: $(freebsd_srcdir)/kern/vnode_if.src + /usr/bin/awk -f $(freebsd_srcdir)/tools/vnode_if.awk $(freebsd_srcdir)/kern/vnode_if.src -p +vnode_if_typedef.h: $(freebsd_srcdir)/kern/vnode_if.src + /usr/bin/awk -f $(freebsd_srcdir)/tools/vnode_if.awk $(freebsd_srcdir)/kern/vnode_if.src -q + DEPFILES := $(wildcard *.d) ifneq ($(DEPFILES),) @@ -129,7 +145,7 @@ clean: -rm -f *.d *.o click.ko elements.mk elements.cc elements.conf \ - vnode_if.h vnode_if.h~ setdef0.c setdef1.c setdefs.h + vnode_if.h vnode_if_newproto.h vnode_if_typedef.h distclean: clean -rm -f Makefile diff -uNr click-1.5.0-dist/bsdmodule/clickfs.cc click-1.5.0/bsdmodule/clickfs.cc --- click-1.5.0-dist/bsdmodule/clickfs.cc Fri Sep 16 15:33:26 2005 +++ click-1.5.0/bsdmodule/clickfs.cc Thu Feb 1 14:02:04 2007 @@ -29,16 +29,13 @@ #include -extern vop_t **clickfs_root_vnops; -extern struct vnodeopv_desc clickfs_vnodeop_opv_desc; - struct clickfs_mount { struct vnode *click_root; }; static int clickfs_mount(struct mount *mp, char *user_path, caddr_t data, - struct nameidata *ndp, struct proc *p) + struct nameidata *ndp, struct thread *td) { char path[MAXPATHLEN]; size_t count; @@ -82,13 +79,7 @@ } static int -clickfs_start(struct mount *mp, int flags, struct proc *p) -{ - return 0; -} - -static int -clickfs_unmount(struct mount *mp, int mntflags, struct proc *p) +clickfs_unmount(struct mount *mp, int mntflags, struct thread *td) { struct clickfs_mount *cmp = (struct clickfs_mount *)mp->mnt_data; int error; @@ -97,7 +88,7 @@ if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - error = vflush(mp, 1, flags); // there is 1 extra vnode ref. + error = vflush(mp, 1, flags, td); // there is 1 extra vnode ref. if (error) return error; @@ -114,13 +105,13 @@ *vpp = cmp->click_root; VREF(*vpp); - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); + vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread); return 0; } static int -clickfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) +clickfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) { memcpy(sbp, &mp->mnt_stat, sizeof(*sbp)); return 0; @@ -128,7 +119,7 @@ static int clickfs_sync(struct mount *mp, int waitfor, struct ucred *cred, - struct proc *p) + struct thread *td) { return 0; } @@ -145,19 +136,20 @@ return 0; } -struct vfsops clickfs_vfsops = { - clickfs_mount, - clickfs_start, - clickfs_unmount, - clickfs_root, - vfs_stdquotactl, - clickfs_statfs, - clickfs_sync, - vfs_stdvget, - vfs_stdfhtovp, - vfs_stdcheckexp, - vfs_stdvptofh, - clickfs_init, - clickfs_uninit, - vfs_stdextattrctl +extern "C" struct vfsops clickfs_vfsops = { + clickfs_mount, + NULL, + clickfs_unmount, + clickfs_root, + NULL, + clickfs_statfs, + clickfs_sync, + NULL, + NULL, + NULL, + NULL, + clickfs_init, + clickfs_uninit, + NULL, + NULL }; diff -uNr click-1.5.0-dist/bsdmodule/clickfs_vnops.cc click-1.5.0/bsdmodule/clickfs_vnops.cc --- click-1.5.0-dist/bsdmodule/clickfs_vnops.cc Mon Jan 9 18:19:32 2006 +++ click-1.5.0/bsdmodule/clickfs_vnops.cc Thu Feb 1 14:02:04 2007 @@ -29,6 +29,7 @@ #include #include #include +#include CLICK_CXX_UNPROTECT #include @@ -37,7 +38,7 @@ #define UIO_MX 32 -vop_t **clickfs_vnops; +extern struct vop_vector clickfs_vnodeops; /* forward declaration */ static enum vtype clickfs_vtype[] = { VDIR, /* CLICKFS_DIRENT_DIR */ @@ -54,7 +55,7 @@ struct clickfs_dirent *de; int error; - error = getnewvnode(VT_NON, mp, clickfs_vnops, vpp); + error = getnewvnode("click", mp, &clickfs_vnodeops, vpp); if (error) return error; de = clickfs_tree_root; @@ -62,7 +63,7 @@ vp = *vpp; vp->v_data = de; vp->v_type = clickfs_vtype[de->type]; - vp->v_flag = VROOT; + vp->v_vflag = VV_ROOT; return 0; } @@ -74,7 +75,7 @@ struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; int plen = cnp->cn_namelen; - struct proc *p = cnp->cn_proc; + struct thread *td = cnp->cn_thread; struct clickfs_dirent *cde= VTOCDE(dvp); int error = 0; @@ -84,7 +85,7 @@ return ENOTDIR; if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) return EROFS; - VOP_UNLOCK(dvp, 0, p); + VOP_UNLOCK(dvp, 0, td); if (plen == 1 && *pname == '.') { *vpp = dvp; @@ -105,19 +106,19 @@ goto done; } - error = getnewvnode(VT_NON, dvp->v_mount, clickfs_vnops, vpp); + error = getnewvnode("click", dvp->v_mount, &clickfs_vnodeops, vpp); if (error) goto done; (*vpp)->v_data = cde; (*vpp)->v_type = clickfs_vtype[cde->type]; if (cde == clickfs_tree_root) - (*vpp)->v_flag = VROOT; - vn_lock(*vpp, LK_SHARED | LK_RETRY, p); + (*vpp)->v_vflag = VV_ROOT; + vn_lock(*vpp, LK_SHARED | LK_RETRY, td); return 0; done: - vn_lock(dvp, LK_SHARED | LK_RETRY, p); + vn_lock(dvp, LK_SHARED | LK_RETRY, td); return error; } @@ -179,7 +180,7 @@ cde->data.handle.r_offset = cde->data.handle.w_offset = 0; vp->v_data = NULL; vp->v_type = VNON; - VOP_UNLOCK(vp, 0, ap->a_p); + VOP_UNLOCK(vp, 0, ap->a_td); return 0; } @@ -461,30 +462,38 @@ return(clickfs_fsync_body(cde)); } -int -clickfs_default(struct vop_generic_args *ap) -{ - return(vop_defaultop(ap)); -} - -static struct vnodeopv_entry_desc clickfs_root_vnop_entries[] = -{ - { &vop_default_desc, (vop_t *) clickfs_default }, - { &vop_lookup_desc, (vop_t *) clickfs_lookup }, - { &vop_getattr_desc, (vop_t *) clickfs_getattr }, - { &vop_setattr_desc, (vop_t *) clickfs_setattr }, - { &vop_reclaim_desc, (vop_t *) clickfs_reclaim }, - { &vop_inactive_desc, (vop_t *) clickfs_inactive }, - { &vop_access_desc, (vop_t *) clickfs_access }, - { &vop_readdir_desc, (vop_t *) clickfs_readdir }, - { &vop_open_desc, (vop_t *) clickfs_open }, - { &vop_read_desc, (vop_t *) clickfs_read }, - { &vop_write_desc, (vop_t *) clickfs_write }, - { &vop_close_desc, (vop_t *) clickfs_close }, - { &vop_fsync_desc, (vop_t *) clickfs_fsync }, - { &vop_readlink_desc, (vop_t *) clickfs_readlink }, - { (struct vnodeop_desc *) NULL, (int (*) (void *)) NULL } +/* XXX: Blatant kludge as c++ does not like c99 initializers. */ +static struct vop_vector clickfs_vnodeops = { + &default_vnodeops, + NULL, + NULL, + clickfs_lookup, + NULL, + NULL, + NULL, + clickfs_open, + clickfs_close, + clickfs_access, + clickfs_getattr, + clickfs_setattr, + clickfs_read, + clickfs_write, + NULL, + NULL, + NULL, + NULL, + NULL, + clickfs_fsync, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + clickfs_readdir, + clickfs_readlink, + clickfs_inactive, + clickfs_reclaim, + NULL, /* .. 5 at current revision */ }; - -struct vnodeopv_desc clickfs_vnodeop_opv_desc = -{ &clickfs_vnops, clickfs_root_vnop_entries }; diff -uNr click-1.5.0-dist/bsdmodule/module.cc click-1.5.0/bsdmodule/module.cc --- click-1.5.0-dist/bsdmodule/module.cc Thu Jan 5 18:04:27 2006 +++ click-1.5.0/bsdmodule/module.cc Thu Feb 1 14:02:04 2007 @@ -315,68 +315,3 @@ click_dmalloc_cleanup(); } } - -static int -click_load(struct module *mod, int cmd, void *arg) -{ - int ret = ENOTSUP; - - /* Load and unload the VFS part first */ - ret = vfs_modevent(mod, cmd, arg); - if (ret) - return ret; - - switch (cmd) { - case MOD_LOAD: - printf("Click module loading\n"); - if (init_module()) { - ret = EINVAL; - break; - } - - ret = 0; - break; - - case MOD_UNLOAD: - printf("Click module unloading\n"); - cleanup_module(); - ret = 0; - break; - - case MOD_SHUTDOWN: - /* - * MOD_SHUTDOWN is usually called when the machine is - * about to shut down and the module is loaded at the - * moment. Perhaps we should call cleanup_module() at - * this point, but since we're shutting down anyway, - * it doesn't really matter.. - */ - printf("Click module shutdown\n"); - ret = 0; - break; - - default: - printf("Click: unknown module command %d\n", cmd); - ret = EINVAL; - break; - } - - return ret; -} - -static struct vfsconf click_vfsconf = { - &clickfs_vfsops, - "click", - -1, - 0, - VFCF_SYNTHETIC -}; - -static moduledata_t mod_data = { - "click", - click_load, - &click_vfsconf -}; - -DECLARE_MODULE(click, mod_data, SI_SUB_VFS, SI_ORDER_MIDDLE); -VNODEOP_SET(clickfs_vnodeop_opv_desc); diff -uNr click-1.5.0-dist/bsdmodule/module_c.c click-1.5.0/bsdmodule/module_c.c --- click-1.5.0-dist/bsdmodule/module_c.c Thu Jan 1 01:00:00 1970 +++ click-1.5.0/bsdmodule/module_c.c Thu Feb 1 14:02:03 2007 @@ -0,0 +1,90 @@ +/* + * module_c.c -- FreeBSD kernel module glue + * + * Copyright (c) 2006 Bruce M. Simpson. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int init_module(void); +extern void cleanup_module(void); + +extern struct vfsops clickfs_vfsops; + +static int +click_modevent(module_t mod, int type, void *data) +{ + int ret; + + /* Load and unload the VFS part first */ + ret = vfs_modevent(mod, type, data); + if (ret != 0) { + return ret; + } + + switch (type) { + case MOD_LOAD: + printf("Click module loading\n"); + if (init_module()) { + ret = EINVAL; + break; + } + ret = 0; + break; + case MOD_UNLOAD: + printf("Click module unloading\n"); + cleanup_module(); + ret = 0; + break; + case MOD_SHUTDOWN: + printf("Click module shutdown\n"); + ret = 0; + break; + default: + printf("Click: unknown module command %d\n", type); + ret = EOPNOTSUPP; + break; + } + + return ret; +} + +/* + * We have to break the rules of VFS_SET() here somewhat. + */ +static struct vfsconf click_vfsconf = { + VFS_VERSION, + "click", + &clickfs_vfsops, + -1, + 0, + VFCF_SYNTHETIC, + NULL, + NULL +}; + +static moduledata_t click_mod = { + "click", + click_modevent, + &click_vfsconf +}; + +DECLARE_MODULE(click, click_mod, SI_SUB_VFS, SI_ORDER_MIDDLE); diff -uNr click-1.5.0-dist/bsdmodule/sched.cc click-1.5.0/bsdmodule/sched.cc --- click-1.5.0-dist/bsdmodule/sched.cc Thu Jan 5 18:04:33 2006 +++ click-1.5.0/bsdmodule/sched.cc Thu Feb 1 14:02:04 2007 @@ -317,11 +317,8 @@ void click_netisr(void) { - int s = splimp(); RouterThread *rt = click_master->thread(0); - rt->driver(); - splx(s); } #endif //BSD_NETISRSCHED @@ -344,10 +341,10 @@ #endif #ifdef BSD_NETISRSCHED - register_netisr(NETISR_CLICK, click_netisr); + netisr_register(NETISR_CLICK, click_netisr, NULL, 0); schednetisr(NETISR_CLICK); click_timer_h = timeout(click_timer, NULL, 1); - click_dummyifnet.if_flags |= IFF_UP|IFF_RUNNING; + click_dummyifnet.if_flags |= IFF_UP|IFF_DRV_RUNNING; #endif placeholder_router = new Router("", click_master); @@ -403,7 +400,7 @@ { #ifdef BSD_NETISRSCHED untimeout(click_timer, NULL, click_timer_h); - unregister_netisr(NETISR_CLICK); + netisr_unregister(NETISR_CLICK); ether_poll_deregister(&click_dummyifnet); delete placeholder_router; #else diff -uNr click-1.5.0-dist/configure click-1.5.0/configure --- click-1.5.0-dist/configure Fri May 19 21:50:14 2006 +++ click-1.5.0/configure Thu Feb 1 14:02:03 2007 @@ -4449,14 +4449,15 @@ =========================================" >&2;} { (exit 1); exit 1; }; } -elif test -r $freebsd_includedir/net/if_var.h -a -r $freebsd_srcdir/kern/vnode_if.pl; then +elif test -r $freebsd_includedir/net/if_var.h -a -r $freebsd_srcdir/kern/vnode_if.src; then ac_have_bsd_kernel=y + KERNEL_CXX="$KERNEL_CXX -fpermissive" else { { echo "$as_me:$LINENO: error: ========================================= Can't find $freebsd_includedir/net/if_var.h and/or -$freebsd_srcdir/kern/vnode_if.pl. Are you sure $freebsd_srcdir +$freebsd_srcdir/kern/vnode_if.src. Are you sure $freebsd_srcdir and $freebsd_includedir contain FreeBSD kernel source? =========================================" >&5 @@ -4464,7 +4465,7 @@ ========================================= Can't find $freebsd_includedir/net/if_var.h and/or -$freebsd_srcdir/kern/vnode_if.pl. Are you sure $freebsd_srcdir +$freebsd_srcdir/kern/vnode_if.src. Are you sure $freebsd_srcdir and $freebsd_includedir contain FreeBSD kernel source? =========================================" >&2;} @@ -12279,7 +12280,7 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include -#if __FreeBSD_version < 440002 || __FreeBSD_version >= 500000 +#if __FreeBSD_version < 500000 #include #endif _ACEOF @@ -12330,13 +12331,13 @@ { echo "$as_me:$LINENO: WARNING: ========================================= -Your version of FreeBSD is old. Click works with FreeBSD 4.5 and later. +Your version of FreeBSD is old. Click works with FreeBSD 5.x and later. =========================================" >&5 echo "$as_me: WARNING: ========================================= -Your version of FreeBSD is old. Click works with FreeBSD 4.5 and later. +Your version of FreeBSD is old. Click works with FreeBSD 5.x and later. =========================================" >&2;} fi diff -uNr click-1.5.0-dist/configure.in click-1.5.0/configure.in --- click-1.5.0-dist/configure.in Fri May 19 21:48:10 2006 +++ click-1.5.0/configure.in Thu Feb 1 14:02:03 2007 @@ -208,14 +208,14 @@ are relative. You must supply absolute paths starting with /. =========================================]) -elif test -r $freebsd_includedir/net/if_var.h -a -r $freebsd_srcdir/kern/vnode_if.pl; then +elif test -r $freebsd_includedir/net/if_var.h -a -r $freebsd_srcdir/kern/vnode_if.src; then ac_have_bsd_kernel=y else AC_MSG_ERROR([ ========================================= Can't find $freebsd_includedir/net/if_var.h and/or -$freebsd_srcdir/kern/vnode_if.pl. Are you sure $freebsd_srcdir +$freebsd_srcdir/kern/vnode_if.src. Are you sure $freebsd_srcdir and $freebsd_includedir contain FreeBSD kernel source? =========================================]) @@ -545,11 +545,12 @@ dnl if test $ac_have_bsd_kernel = y; then + KERNEL_CXX="$KERNEL_CXX -fpermissive" AC_CACHE_CHECK(FreeBSD version, ac_cv_freebsd_version, [ save_flags="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$freebsd_includedir" AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include -#if __FreeBSD_version < 440002 || __FreeBSD_version >= 500000 +#if __FreeBSD_version < 500000 #include #endif]])], ac_cv_freebsd_version=yes, ac_cv_freebsd_version=no) CPPFLAGS="$save_flags"]) @@ -560,7 +561,7 @@ AC_MSG_WARN([ ========================================= -Your version of FreeBSD is old. Click works with FreeBSD 4.5 and later. +Your version of FreeBSD is old. Click works with FreeBSD 5.x and later. =========================================]) fi diff -uNr click-1.5.0-dist/drivers/e1000-2.x/Makefile.orig click-1.5.0/drivers/e1000-2.x/Makefile.orig --- click-1.5.0-dist/drivers/e1000-2.x/Makefile.orig Wed Feb 14 04:34:17 2001 +++ click-1.5.0/drivers/e1000-2.x/Makefile.orig Thu Jan 1 01:00:00 1970 @@ -1,67 +0,0 @@ -# -# Makefile for Intel(R) PRO/1000 LAN Adapter driver for Linux -# Copyright (C) 1999 - 2000 Intel -# - -CC = gcc - -# Required Flags -CFLAGS = -DLINUX -D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -O2 -pipe -I. \ --I/usr/src/linux/include -# Check for SMP -CFLAGS += $(subst SMP, -D__SMP__, $(findstring SMP, $(shell uname -v))) -# Check for Module Versioning -CFLAGS += $(shell [ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS) - -TARGET = e1000.o -CFILES = e1000_main.c e1000_fxhw.c e1000_phy.c e1000_proc.c - -# ANS, ia32 2.2.x only -ARCH = $(shell uname -m | sed -e s/i.86/i386/) -KVER = $(shell uname -r | sed -e s/2\.2.*/2.2/) -ifeq ($(ARCH), i386) -ifeq ($(KVER), 2.2) -CFILES += ans.c ans_hw.c ans_os.c ans_driver.c -CFLAGS += -DIANS -DIANS_BASE_ADAPTER_TEAMING -IANS = y -endif -endif - -INSTDIR = /lib/modules/$(shell uname -r)/net - -.SILENT: all -all: $(TARGET) - echo; echo; \ - echo "**************************************************"; \ - echo "** $(TARGET) built for for $(shell uname -s -r)"; \ - if uname -v | grep SMP > /dev/null; then \ - echo "** SMP Enabled"; \ - else \ - echo "** SMP Disabled"; \ - fi; \ - if [ -f /usr/include/linux/modversions.h ]; then \ - echo "** Module Versioning Enabled"; \ - else \ - echo "** Module Versioning Disabled"; \ - fi; \ - if echo $(IANS) | grep y > /dev/null; then \ - echo "** iANS hooks enabled"; \ - fi; - echo "**************************************************"; - -$(TARGET): $(CFILES:.c=.o) - $(LD) -r $^ -o $@ - -install: $(TARGET) - mkdir -p $(INSTDIR) - install -m 644 $(TARGET) $(INSTDIR) - depmod -a - -uninstall: - if [ -f $(INSTDIR)/$(TARGET) ]; then \ - rm $(INSTDIR)/$(TARGET); \ - fi - -clean: - rm -f *.o *~ core - diff -uNr click-1.5.0-dist/drivers/e1000-2.x/e1000.h.orig click-1.5.0/drivers/e1000-2.x/e1000.h.orig --- click-1.5.0-dist/drivers/e1000-2.x/e1000.h.orig Wed Feb 14 04:34:23 2001 +++ click-1.5.0/drivers/e1000-2.x/e1000.h.orig Thu Jan 1 01:00:00 1970 @@ -1,1131 +0,0 @@ -/***************************************************************************** - ***************************************************************************** -Copyright (c) 1999 - 2000, Intel Corporation - -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. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 CONTRIBUTORS 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. - - ***************************************************************************** - ****************************************************************************/ - -#ifndef _E1000_H_ -#define _E1000_H_ - - -/* - * - * e1000.h - * - */ - -#include "e1000_kcompat.h" -#include "e1000_fxhw.h" -#include "e1000_phy.h" - -#ifdef IANS -#include "ans_driver.h" -#include "base_comm.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) ) -#include -#else -#include -#endif - -#include -#include -#include - - -#define MDI - -/* Unix Typedefs */ -typedef unsigned char uchar_t; -typedef unsigned int uint_t; -typedef unsigned short ushort_t; -typedef unsigned long ulong_t; -typedef unsigned long paddr_t; -typedef ulong_t major_t; -typedef unsigned char boolean_t; -typedef unsigned long uintptr_t; - -#define B_TRUE 1 -#define B_FALSE 0 -#define TRUE 1 -#define FALSE 0 - -typedef struct net_device device_t; -typedef struct pci_dev pci_dev_t; -typedef struct sk_buff sk_buff_t; -typedef struct net_device_stats net_device_stats_t; - - -/* - * e1000_defines.h - * - */ - -/* Supported RX Buffer Sizes */ -#define E1000_RXBUFFER_2048 2048 -#define E1000_RXBUFFER_4096 4096 -#define E1000_RXBUFFER_8192 8192 -#define E1000_RXBUFFER_16384 16384 - -/* Max and Min Number of Supported TX and RX Descriptors */ -#define E1000_MAX_TXD 256 -#define E1000_MIN_TXD 80 -#define E1000_MAX_RXD 256 -#define E1000_MIN_RXD 80 - -#define ETH_LENGTH_OF_ADDRESS 6 - -/* The number of entries in the CAM. The CAM (Content Addressable -* Memory) holds the directed and multicast addresses that we -* monitor. We reserve one of these spots for our directed address, -* allowing us E1000_CAM_ENTRIES - 1 multicast addresses. -*/ - - -#define RET_STATUS_SUCCESS 0 -#define RET_STATUS_FAILURE 1 - -/* E1000 specific hardware defines */ -#define e1000regs E1000_REGISTERS -#define PE1000_ADAPTER bdd_t* - -#ifdef MDI -#define DL_MAC_ADDR_LEN 6 - -/***************************************************************************** - * Structure for the Ethernet address ( 48 bits ) or 6 bytes - *****************************************************************************/ -typedef union { - uchar_t bytes[DL_MAC_ADDR_LEN]; - ushort_t words[DL_MAC_ADDR_LEN / 2]; -} DL_eaddr_t; - -#define DL_ID (ENETM_ID) -#define ETHERNET_HEADER_SIZE 14 - -#if defined(DL_STRLOG) && !defined(lint) -#define DL_LOG(x) DLstrlog ? x : 0 -#else -#define DL_LOG(x) -#endif - - -#endif /* MDI */ - -/* - * e1000_sw.h - * - * This file has all the defines for all the software defined structures - * that are necessary for the hardware as well as the DLPI interface - */ -#define E1000_PCI - -/* The size in bytes of a standard ethernet header */ -#define ENET_HEADER_SIZE 14 -#define MAX_INTS 256 -#define CRC_LENGTH 4 - -#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 - -#define MAX_NUM_MULTICAST_ADDRESSES 128 -#define MAX_NUM_PHYS_FRAGS_PER_PACKET 16 -#define E1000_NUM_MTA_REGISTERS 128 -#define RCV_PKT_MUL 5 - -/* - * This structure is used to define the characterstics of the message that is - * sent by the upper layers for transmission. It contains the physical/virtual - * address mapping for the physical fragments of the packet and also the length - * of the fragment. - */ -typedef struct _PHYS_ADDRESS_UNIT { - caddr_t FragPhysAddr; - caddr_t FragVirtAddr; - UINT Length; -} PHYS_ADDRESS_UNIT, *PPHYS_ADDRESS_UNIT; - - -/*----------------------------------------------------------------------------- - A structure that points to the next entry in the queue. - ------------------------------------------------------------------------------*/ -typedef struct _SINGLE_LIST_LINK { - struct _SINGLE_LIST_LINK *Flink; -} SINGLE_LIST_LINK, *PSINGLE_LIST_LINK; - -/* This structure stores the additional information that - * is associated with every packet to be transmitted. It stores - * the message block pointer and the TBD addresses associated with - * the m_blk and also the link to the next tcb in the chain - */ -typedef struct _TX_SW_PACKET_ { - /* Link to the next TX_SW_PACKET in the list */ - SINGLE_LIST_LINK Link; - - sk_buff_t *Packet; /* Pointer to message to be transmitted */ - - ulong_t TxDescriptorBufferAddr; - /* First buffer descriptor address */ - - PE1000_TRANSMIT_DESCRIPTOR FirstDescriptor; - PE1000_TRANSMIT_DESCRIPTOR LastDescriptor; - UINT TxSwPacketNumber; -} TX_SW_PACKET, *PTX_SW_PACKET; - - - -/* ----------------------------------------------------------------------------- -* A "ListHead" structure that points to the head and tail of a queue -* --------------------------------------------------------------------------- */ -typedef struct _LIST_DESCRIBER { - struct _SINGLE_LIST_LINK *volatile Flink; - struct _SINGLE_LIST_LINK *volatile Blink; -} LIST_DESCRIBER, *PLIST_DESCRIBER; - - -/* This structure is similar to the RX_SW_PACKET structure used for Ndis. -* This structure stores information about the 2k aligned receive buffer -* into which the E1000 DMA's frames. This structure is maintained as a -* linked list of many receiver buffer pointers. -*/ -typedef struct _RX_SW_PACKET { - /* Link to the next RX_SW_PACKET in the list */ - SINGLE_LIST_LINK Link; - - struct sk_buff *skb; /* Pointer to the received packet */ - - /* A virtual pointer to the actual aligned buffer. */ - PVOID VirtualAddress; - - /* Debug only fields */ -#if DBG - PE1000_RECEIVE_DESCRIPTOR DescriptorVirtualAddress; - UINT RxSwPacketNumber; -#endif - -} RX_SW_PACKET, *PRX_SW_PACKET; - -/* MultiCast Command Block (MULTICAST_CB) -* The multicast structure contains an array of multicast addresses and -* also a count of the total number of addresses. -*/ -typedef struct _multicast_cb_t { - ushort mc_count; /* Number of multicast addresses */ - uchar_t MulticastBuffer[(ETH_LENGTH_OF_ADDRESS * - MAX_NUM_MULTICAST_ADDRESSES)]; -} mltcst_cb_t, *pmltcst_cb_t; - - -/* ----------------------------------------------------------------------------- QUEUE_INIT_LIST -- Macro which will initialize a queue to NULL. ----------------------------------------------------------------------------*/ -#define QUEUE_INIT_LIST(_LH) \ - (_LH)->Flink = (_LH)->Blink = (PSINGLE_LIST_LINK)0 - -/*----------------------------------------------------------------------------- -* IS_QUEUE_EMPTY -- Macro which checks to see if a queue is empty. -*--------------------------------------------------------------------------- */ -#define IS_QUEUE_EMPTY(_LH) \ - ((_LH)->Flink == (PSINGLE_LIST_LINK)0) - - -/* ------------------------------------------------------------------------- -* QUEUE_GET_HEAD -- Macro which returns the head of the queue, but does not -* remove the head from the queue. -*------------------------------------------------------------------------- */ -#define QUEUE_GET_HEAD(_LH) ((PSINGLE_LIST_LINK) ((_LH)->Flink)) - -/*----------------------------------------------------------------------------- -* QUEUE_REMOVE_HEAD -- Macro which removes the head of the head of a queue. -*-------------------------------------------------------------------------- */ -#define QUEUE_REMOVE_HEAD(_LH) \ - { \ - PSINGLE_LIST_LINK ListElem; \ - if (ListElem = (_LH)->Flink) \ - { \ - if(!((_LH)->Flink = ListElem->Flink)) \ - (_LH)->Blink = (PSINGLE_LIST_LINK) 0; \ - } \ - } - - -/*----------------------------------------------------------------------------- -* QUEUE_POP_HEAD -- Macro which will pop the head off of a queue (list), and -* return it (this differs from QUEUE_REMOVE_HEAD only in -* the 1st line). -*-----------------------------------------------------------------------------*/ -#define QUEUE_POP_HEAD(_LH) \ - (PSINGLE_LIST_LINK) (_LH)->Flink; \ - { \ - PSINGLE_LIST_LINK ListElem; \ - if ((ListElem = (_LH)->Flink)) \ - { \ - if(!((_LH)->Flink = ListElem->Flink)) \ - (_LH)->Blink = (PSINGLE_LIST_LINK) 0; \ - } \ - } - - -/*----------------------------------------------------------------------------- -* QUEUE_GET_TAIL -- Macro which returns the tail of the queue, but does not -* remove the tail from the queue. -*-------------------------------------------------------------------------- */ -#define QUEUE_GET_TAIL(_LH) ((PSINGLE_LIST_LINK)((_LH)->Blink)) - - -/*----------------------------------------------------------------------------- -* QUEUE_PUSH_TAIL -- Macro which puts an element at the tail (end) of the queue -* -*--------------------------------------------------------------------------- */ -#define QUEUE_PUSH_TAIL(_LH,_E) \ - if ((_LH)->Blink) \ - { \ - ((PSINGLE_LIST_LINK)(_LH)->Blink)->Flink = (PSINGLE_LIST_LINK)(_E); \ - (_LH)->Blink = (PSINGLE_LIST_LINK)(_E); \ - } else \ - { \ - (_LH)->Flink = \ - (_LH)->Blink = (PSINGLE_LIST_LINK)(_E); \ - } \ - (_E)->Flink = (PSINGLE_LIST_LINK)0; - - - -/*----------------------------------------------------------------------------- -* QUEUE_PUSH_HEAD -- Macro which puts an element at the head of the queue. -*--------------------------------------------------------------------------- */ -#define QUEUE_PUSH_HEAD(_LH,_E) \ - if (!((_E)->Flink = (_LH)->Flink)) \ - { \ - (_LH)->Blink = (PSINGLE_LIST_LINK)(_E); \ - } \ - (_LH)->Flink = (PSINGLE_LIST_LINK)(_E); - - -/* Ethernet Frame Structure */ -/*- Ethernet 6-byte Address */ -typedef struct _eth_address_t { - uchar_t eth_node_addr[ETH_LENGTH_OF_ADDRESS]; -} eth_address_t, *peth_address_t; - -typedef enum { - ANE_ENABLED = 0, - ANE_DISABLED, - ANE_SUSPEND -} ANE_state_t; - -/* This is the hardware dependant part of the board config structure called - bdd_t structure, it is very similar to the Adapter structure in the - driver. The bd_config structure defined by the DLPI interface has - pointer to this structure -*/ -#define TX_LOCKUP 0x01 -typedef struct _ADAPTER_STRUCT { - /* Hardware defines for the E1000 */ - PE1000_REGISTERS HardwareVirtualAddress; /* e1000 registers */ - - /* Node Ethernet address */ - uchar_t perm_node_address[ETH_LENGTH_OF_ADDRESS]; - UCHAR CurrentNetAddress[ETH_LENGTH_OF_ADDRESS]; - - /* command line options */ - UCHAR AutoNeg; - UCHAR ForcedSpeedDuplex; - USHORT AutoNegAdvertised; - UCHAR WaitAutoNegComplete; - - BOOLEAN GetLinkStatus; - - UCHAR MacType; - UCHAR MediaType; - UINT32 PhyId; - UINT32 PhyAddress; - - /* PCI device info */ - UINT16 VendorId; - UINT16 DeviceId; - UINT16 SubSystemId; - UINT16 SubVendorId; - - UCHAR DmaFairness; - - BOOLEAN LinkStatusChanged; - - - /* Flags for various hardware-software defines */ - u_int e1000_flags; /* misc. flags */ - UINT32 AdapterStopped; /* Adapter has been reset */ - UINT32 FullDuplex; /* current duplex mode */ - UINT32 FlowControl; /* Enable/Disable flow control */ - UINT32 OriginalFlowControl; - UINT RxPciPriority; /* Receive data priority */ - uint_t flags; /* Misc board flags */ - - BOOLEAN LongPacket; /* Long Packet Enable Status */ - UINT RxBufferLen; - - UINT32 tag_mode; /* iANS tag mode (none, IEEE, ISL) */ - - #ifdef IANS - IANS_BD_LINK_STATUS ans_link; - UINT32 ans_speed; - UINT32 ans_duplex; - #endif - - /* PCI configuration parameters */ - UINT PciCommandWord; /* Stores boot-up PCI command word */ - UINT DeviceNum; /* The bus+dev value for the card */ - UINT PciConfigMethod; /* CONFIG1 or 2 for scan */ - UINT RevID; /* Revision ID for the board */ - UINT32 LinkIsActive; /* Link status */ - UINT DoRxResetFlag; - UINT AutoNegFailed; /* Auto-negotiation status flag */ - UINT TxcwRegValue; /* Original Transmit control word */ - UINT TxIntDelay; /* Transmit Interrupt delay */ - UINT RxIntDelay; /* Receive Interrupt delay */ - UINT MaxDpcCount; /* Interrupt optimization count */ - - UCHAR ExternalSerDes; - - /* PCI information for the adapter */ - ulong_t io_base; /* IO base address */ - ulong_t mem_base; /* Memory base address */ - uchar_t irq; /* IRQ level */ - int irq_level; - - int bd_number; /* Board Number */ - - /* Transmit descriptor definitions */ - PE1000_TRANSMIT_DESCRIPTOR FirstTxDescriptor; - /* transmit descriptor ring start */ - PE1000_TRANSMIT_DESCRIPTOR LastTxDescriptor; - /* transmit descriptor ring end */ - PE1000_TRANSMIT_DESCRIPTOR NextAvailTxDescriptor; - /* next free tmd */ - PE1000_TRANSMIT_DESCRIPTOR OldestUsedTxDescriptor; - /* next tmd to reclaim (used) */ - UINT NumTxDescriptorsAvail; - UINT NumTxDescriptors; - PE1000_TRANSMIT_DESCRIPTOR e1000_tbd_data; - /* pointer to buffer descriptor area */ - - /* Transmit software structure definitions */ - PTX_SW_PACKET e1000_TxSwPacketPtrArea; - /* pointer to TxSwPacket Area */ - - /* Define SwTxPacket structures */ - LIST_DESCRIBER FreeSwTxPacketList; - /* Points to the head and tail of the "Free" packet list */ - - LIST_DESCRIBER UsedSwTxPacketList; - /* Points to the head and tail of the "Used" packet list */ - - /* Receive definitions */ - - UINT NumRxDescriptors; - UINT MulticastFilterType; - - /* Receive descriptor definitions */ - PE1000_RECEIVE_DESCRIPTOR FirstRxDescriptor; - /* receive descriptor ring 1 start */ - - PE1000_RECEIVE_DESCRIPTOR LastRxDescriptor; - /* receive descriptor ring 1 end */ - - PE1000_RECEIVE_DESCRIPTOR NextRxDescriptorToCheck; - /* next chip rmd ring 1 */ - - PE1000_RECEIVE_DESCRIPTOR e1000_rlast1p; - /* last free rmd ring 1 */ - - - /* Receive software defintions */ - PRX_SW_PACKET RxSwPacketPointerArea; - /* Pointer to memory space allocated for RX_SW_PACKET structures */ - - PE1000_RECEIVE_DESCRIPTOR e1000_rbd_data; - /* pointer to rx buffer descriptor area */ - - /* Points to the head and tail of the "RxSwPacketList" */ - LIST_DESCRIBER RxSwPacketList; - - pmltcst_cb_t pmc_buff; - /* pointer to multi cast addrs */ - UINT NumberOfMcAddresses; - UINT MaxNumReceivePackets; - UINT MaxRcvPktMinThresh; - UINT MaxRcvPktMaxThresh; - - /* Lock defintions for the driver */ - spinlock_t bd_intr_lock; /* Interrupt lock */ - spinlock_t bd_tx_lock; /* Transmit lock */ - - UINT32 cur_line_speed; /* current line speed */ - uchar_t brdcst_dsbl; /* if set, disables broadcast */ - uchar_t TransmitTimeout; /* detects transmit lockup */ - - uchar_t ReportTxEarly; /* 1 => RS bit, 0 => RPS bit */ - - pci_dev_t *pci_dev; /* pci device struct pointer */ - /************************************************************************* - * Hardware Statistics from the E1000 registers - *************************************************************************/ - UINT RcvCrcErrors; - /* Receive packets with CRC errors */ - - UINT RcvSymbolErrors; - /* Receive packets with symbol errors */ - - UINT RcvMissedPacketsErrors; - /* Packets missed due to receive FIFO full */ - - UINT DeferCount; - /* Packet not transmitted due to either of the - * reasons- transmitter busy - * IPG timer not expired - * Xoff frame received - * link not up - */ - - UINT RcvSequenceErrors; - /* Receive sequence errors on the wire */ - - UINT RcvLengthErrors; - /* Counts undersized and oversized packets */ - - UINT RcvXonFrame; - /* Receive XON frame */ - - UINT TxXonFrame; - /* Transmit XON frame */ - - UINT RcvXoffFrame; - /* Receive XOFF frame */ - - UINT TxXoffFrame; - /* Transmit XOFF frame */ - - UINT Rcv64; - /* Received packets of size 64 */ - - UINT Rcv65; - /* Received packets of size 65-127 */ - - UINT Rcv128; - /* Received packets of size 128-255 */ - - UINT Rcv256; - /* Received packets of size 256-511 */ - - UINT Rcv512; - /* Received packets of size 512-1023 */ - - UINT Rcv1024; - /* Received packets of size 1024-1522 */ - - UINT GoodReceives; - /* Non-error legal length packets */ - - UINT RcvBroadcastPkts; - /* Received broadcast packets */ - - UINT RcvMulticastPkts; - /* Received multicast packets */ - - UINT GoodTransmits; - /* Good packets transmitted */ - - UINT Rnbc; - /* No Receive buffers available ( Receive queue full) */ - - UINT RcvUndersizeCnt; - /* Received packet is less than 64 bytes */ - - UINT RcvOversizeCnt; - /* Received packet greater than max ethernet packet */ - - UINT RcvJabberCnt; - /* Received packet > max size + bad CRC */ - - UINT TotPktRcv; - /* Total packets received */ - - UINT TotPktTransmit; - /* Total packets transmitted */ - - UINT TrsPkt64; - /* 64 byte packet transmitted */ - - UINT TrsPkt65; - /* Transmitted pkt 65-127 bytes */ - - UINT TrsPkt128; - /* Transmitted pkt 128-255 bytes */ - - UINT TrsPkt256; - /* Transmitted pkt 256-511 */ - - UINT TrsPkt512; - /* Transmitted pkt 512-1023 */ - - UINT TrsPkt1024; - /* Transmitted Pkt 1024-1522 */ - - UINT TrsMulticastPkt; - /* Transmitted Multicast Packet */ - - UINT TrsBroadcastPkt; - /* Transmitted broadcast packet */ - - UINT TxAbortExcessCollisions; - /* Excessive Coillision count */ - - UINT TxLateCollisions; - /* Late collision count */ - - UINT TotalCollisions; - /* Total collision count */ - - UINT SingleCollisions; - UINT MultiCollisions; - UINT FCUnsupported; - UINT RcvGoodOct; - UINT TrsGoodOct; - UINT RcvFragment; - UINT RcvTotalOct; - UINT TrsTotalOct; - - /* Livengood Statistics */ - UINT AlignmentErrors; - UINT TotalRcvErrors; - UINT TrsUnderRun; - UINT TrsNoCRS; - UINT CarrierExtErrors; - UINT RcvDMATooEarly; - -} ADAPTER_STRUCT, *PADAPTER_STRUCT; - -/*- Ethernet 14-byte Header */ -typedef struct _eth_header_t { - uchar_t eth_dest[ETH_LENGTH_OF_ADDRESS]; - uchar_t eth_src[ETH_LENGTH_OF_ADDRESS]; - ushort eth_typelen; -} eth_header_t, *peth_header_t; - - - - - - -/* - * e1000_dlpi.h - * - * This file supports all the defines that are specific to the Streams - * sturcture and the DLPI interface - */ - -/* - * STREAMS structures - */ -/* - * All the DLPI functions that are global and have been pre-fixed with DL should - * be given the prefix e1000 - */ -#define DL_NAME "e1000" -#define DLdevflag e1000devflag -#define DLinfo e1000info -#define DLrminfo e1000rminfo -#define DLwminfo e1000wminfo -#define DLrinit e1000rinit -#define DLwinit e1000winit -#define DLstrlog e1000strlog -#define DLifstats e1000ifstats -#define DLboards e1000boards -#define DLconfig e1000config -#define DLid_string e1000id_string -#define MBLK_LEN( X ) (X->b_wptr - X->b_rptr) -#define PHYS_ADDR( X ) vtop((caddr_t)( X ), NULL ) -#define MBLK_NEXT( X ) ( X->b_cont ) - -/* - * Flow control definnitions for STREAMS - */ -#define DL_MIN_PACKET 0 -#define DL_MAX_PACKET 1500 -#define DL_MAX_PACKET_LLC (DL_MAX_PACKET - 3) -#define DL_MAX_PACKET_SNAP (DL_MAX_PACKET_LLC - 5) -#define DL_HIWATER (64 * 1024) -#define DL_LOWATER (20 * 1024) /* set to 20k */ -#define USER_MAX_SIZE DL_MAX_PACKET -#define USER_MIN_SIZE 46 - -#ifdef MDI -/* - * Flag definitions used for various states - */ -#define DRV_LOADED 0x800 -#define BOARD_PRESENT 0x01 -#define BOARD_DISABLED 0x02 -#define PROMISCUOUS 0x100 -#define ALL_MULTI 0x200 -#define BOARD_OPEN 0x010 -/* - * Board structure definition only necessary for a MDI driver. This structure - * defines all the NOS related fields that would be associated with each board. - * This definition is a part of the dlpi_ether header file for - * the UW212 driver, so it is not defined for the UW212 driver - */ -typedef struct bdconfig { - #ifdef IANS - void *iANSReserved; - piANSsupport_t iANSdata; - #endif - struct bdconfig *bd_next; /* pointer to next bd in chain */ - struct bdconfig *bd_prev; /* pointer to prev bd in chain */ - uint unit; /* from mdi_get_unit */ - major_t major; /* major number for device */ - ulong_t io_start; /* start of I/O base address */ - ulong_t io_end; /* end of I/O base address */ - paddr_t mem_start; /* start of base mem address */ - paddr_t mem_end; /* start of base mem address */ - int irq_level; /* interrupt request level */ - int open_cnt; - int bd_number; /* board number in multi-board setup */ - int flags; /* board management flags */ - int tx_flags; /* tx management flags */ - int rx_flags; /* rx management flags */ - int OutQlen; /* number of transmit pkts queued */ - struct timer_list timer_id; /* watchdog timer ID */ - int timer_val; /* watchdog timer value */ - int multicast_cnt; /* count of multicast address sets */ - DL_eaddr_t eaddr; /* Ethernet address storage */ - - ADAPTER_STRUCT *bddp; /* board struct */ - mltcst_cb_t *mc_data; /* pointer to the mc addr for the bd */ - - uint_t tx_count; - - /* these are linux only */ - struct sk_buff *last_mp_fail; - device_t *device; - uchar_t pci_bus; - uchar_t pci_dev_fun; - ushort_t vendor; - int tx_out_res; - void *base_tx_tbds; - void *base_rx_rbds; - struct net_device_stats net_stats; - -} bd_config_t; - -#endif /* MDI */ - -/************************************************************************* -* * -* Module Name: * -* e1000_pci.h * -* Abstract: * -* This header file contains PCI related constants and bit definitions. * -* * -* This driver runs on the following hardware: * -* - E10001000 based PCI gigabit ethernet adapters (aka Kodiak) * -* * -* Environment: * -* Kernel Mode - * -* * -* Source History: * -* The contents of this file is based somewhat on code developed for * -* Intel Pro/100 family (Speedo1 and Speedo3). * -* * -* March 7, 1997 * -* 1st created - Ported from E100B pci.h file * -* * -*************************************************************************/ - -/* typedefs for each NOS */ -#if defined LINUX - -/* PCI Device ID - for internal use */ -#define PCI_DEV_NO 0x00FF -#define PCI_BUS_NO 0xFF00 - -/* max number of pci buses */ -#define MAX_PCI_BUSES 0xFF - -/* number of PCI config bytes to access */ -#define PCI_BYTE 1 -#define PCI_WORD 2 -#define PCI_DWORD 4 - -/* PCI access methods */ -#define P_CONF_T1 1 -#define P_CONF_T2 2 -#define P_TEST_PATN 0xCDEF - -#define PO_DEV_NO 11 -#define PO_BUS_NO 16 -#define P_CSPACE 0x80000000 -#endif - - -/*----------------------------------------------------------------------*/ - -#ifndef _PCI_H -#define _PCI_H - - -/* Maximum number of PCI devices */ -#define PCI_MAX_DEVICES 32 - -/*-------------------------------------------------------------------------*/ -/* PCI configuration hardware ports */ -/*-------------------------------------------------------------------------*/ -#define CF1_CONFIG_ADDR_REGISTER 0x0CF8 -#define CF1_CONFIG_DATA_REGISTER 0x0CFC -#define CF2_SPACE_ENABLE_REGISTER 0x0CF8 -#define CF2_FORWARD_REGISTER 0x0CFA -#define CF2_BASE_ADDRESS 0xC000 - - -/*-------------------------------------------------------------------------*/ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -typedef struct _PCI_CONFIG_STRUC { - USHORT PciVendorId; /* PCI Vendor ID */ - USHORT PciDeviceId; /* PCI Device ID */ - USHORT PciCommand; - USHORT PciStatus; - UCHAR PciRevisionId; - UCHAR PciClassCode[3]; - UCHAR PciCacheLineSize; - UCHAR PciLatencyTimer; - UCHAR PciHeaderType; - UCHAR PciBIST; - ULONG PciBaseReg0; - ULONG PciBaseReg1; - ULONG PciBaseReg2; - ULONG PciBaseReg3; - ULONG PciBaseReg4; - ULONG PciBaseReg5; - ULONG PciCardbusCISPtr; - USHORT PciSubSysVendorId; - USHORT PciSubSysDeviceId; - ULONG PciExpROMAddress; - ULONG PciReserved2; - ULONG PciReserved3; - UCHAR PciInterruptLine; - UCHAR PciInterruptPin; - UCHAR PciMinGnt; - UCHAR PciMaxLat; -} PCI_CONFIG_STRUC, *PPCI_CONFIG_STRUC; - -/*-------------------------------------------------------------------------*/ -/* PCI Configuration Space Register Offsets */ -/* Refer To The PCI Specification For Detailed Explanations */ -/*-------------------------------------------------------------------------*/ -#define PCI_VENDOR_ID_REGISTER 0x00 /* PCI Vendor ID Register */ -#define PCI_DEVICE_ID_REGISTER 0x02 /* PCI Device ID Register */ -#define PCI_CONFIG_ID_REGISTER 0x00 /* PCI Configuration ID Register */ -#define PCI_COMMAND_REGISTER 0x04 /* PCI Command Register */ -#define PCI_STATUS_REGISTER 0x06 /* PCI Status Register */ -#define PCI_REV_ID_REGISTER 0x08 /* PCI Revision ID Register */ -#define PCI_CLASS_CODE_REGISTER 0x09 /* PCI Class Code Register */ -#define PCI_CACHE_LINE_REGISTER 0x0C /* PCI Cache Line Register */ - -#define PCI_BIST_REGISTER 0x0F /* PCI Built-In SelfTest Register */ -#define PCI_BAR_0_REGISTER 0x10 /* PCI Base Address Register 0 */ -#define PCI_BAR_1_REGISTER 0x14 /* PCI Base Address Register 1 */ -#define PCI_BAR_2_REGISTER 0x18 /* PCI Base Address Register 2 */ -#define PCI_BAR_3_REGISTER 0x1C /* PCI Base Address Register 3 */ -#define PCI_BAR_4_REGISTER 0x20 /* PCI Base Address Register 4 */ -#define PCI_BAR_5_REGISTER 0x24 /* PCI Base Address Register 5 */ -#define PCI_SUBVENDOR_ID_REGISTER 0x2C /* PCI SubVendor ID Register */ -#define PCI_SUBDEVICE_ID_REGISTER 0x2E /* PCI SubDevice ID Register */ -#define PCI_EXPANSION_ROM 0x30 /* PCI Expansion ROM Base Register */ -#define PCI_MIN_GNT_REGISTER 0x3E /* PCI Min-Gnt Register */ -#define PCI_MAX_LAT_REGISTER 0x3F /* PCI Max_Lat Register */ -#define PCI_TRDY_TIMEOUT_REGISTER 0x40 /* PCI TRDY Timeout Register */ -#define PCI_RETRY_TIMEOUT_REGISTER 0x41 /* PCI Retry Timeout Register */ - - - -/*-------------------------------------------------------------------------*/ -/* PCI Class Code Definitions */ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -#define PCI_BASE_CLASS 0x02 /* Base Class - Network Controller */ -#define PCI_SUB_CLASS 0x00 /* Sub Class - Ethernet Controller */ -#define PCI_PROG_INTERFACE 0x00 /* Prog I/F - Ethernet COntroller */ - -/*-------------------------------------------------------------------------*/ -/* PCI Command Register Bit Definitions */ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -#define CMD_IO_SPACE 0x0001 /* BIT_0 */ -#define CMD_MEMORY_SPACE 0x0002 /* BIT_1 */ -#define CMD_BUS_MASTER 0x0004 /* BIT_2 */ -#define CMD_SPECIAL_CYCLES 0x0008 /* BIT_3 */ -#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ -#define CMD_VGA_PALLETTE_SNOOP 0x0020 /* BIT_5 */ -#define CMD_PARITY_RESPONSE 0x0040 /* BIT_6 */ -#define CMD_WAIT_CYCLE_CONTROL 0x0080 /* BIT_7 */ -#define CMD_SERR_ENABLE 0x0100 /* BIT_8 */ -#define CMD_BACK_TO_BACK 0x0200 /* BIT_9 */ - -/*-------------------------------------------------------------------------*/ -/* PCI Status Register Bit Definitions */ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -#define STAT_BACK_TO_BACK 0x0080 /* BIT_7 */ -#define STAT_DATA_PARITY 0x0100 /* BIT_8 */ -#define STAT_DEVSEL_TIMING 0x0600 /* BIT_9_10 */ -#define STAT_SIGNAL_TARGET_ABORT 0x0800 /* BIT_11 */ -#define STAT_RCV_TARGET_ABORT 0x1000 /* BIT_12 */ -#define STAT_RCV_MASTER_ABORT 0x2000 /* BIT_13 */ -#define STAT_SIGNAL_MASTER_ABORT 0x4000 /* BIT_14 */ -#define STAT_DETECT_PARITY_ERROR 0x8000 /* BIT_15 */ - -/*-------------------------------------------------------------------------*/ -/* PCI Base Address Register For Memory (BARM) Bit Definitions */ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -#define BARM_LOCATE_BELOW_1_MEG 0x0002 /* BIT_1 */ -#define BARM_LOCATE_IN_64_SPACE 0x0004 /* BIT_2 */ -#define BARM_PREFETCHABLE 0x0008 /* BIT_3 */ - -/*-------------------------------------------------------------------------*/ -/* PCI Base Address Register For I/O (BARIO) Bit Definitions */ -/* Configuration Space Header */ -/*-------------------------------------------------------------------------*/ -#define BARIO_SPACE_INDICATOR 0x0001 /* BIT_0 */ - -/*-------------------------------------------------------------------------*/ -/* PCI BIOS Definitions */ -/* Refer To The PCI BIOS Specification */ -/*-------------------------------------------------------------------------*/ -/*- Function Code List */ -#define PCI_FUNCTION_ID 0xB1 /* AH Register */ -#define PCI_BIOS_PRESENT 0x01 /* AL Register */ -#define FIND_PCI_DEVICE 0x02 /* AL Register */ -#define FIND_PCI_CLASS_CODE 0x03 /* AL Register */ -#define GENERATE_SPECIAL_CYCLE 0x06 /* AL Register */ -#define READ_CONFIG_BYTE 0x08 /* AL Register */ -#define READ_CONFIG_WORD 0x09 /* AL Register */ -#define READ_CONFIG_DWORD 0x0A /* AL Register */ -#define WRITE_CONFIG_BYTE 0x0B /* AL Register */ -#define WRITE_CONFIG_WORD 0x0C /* AL Register */ -#define WRITE_CONFIG_DWORD 0x0D /* AL Register */ - -/*- Function Return Code List */ -#define SUCCESSFUL 0x00 -#define FUNC_NOT_SUPPORTED 0x81 -#define BAD_VENDOR_ID 0x83 -#define DEVICE_NOT_FOUND 0x86 -#define BAD_REGISTER_NUMBER 0x87 - -/*- PCI BIOS Calls */ -#define PCI_BIOS_INTERRUPT 0x1A /* PCI BIOS Int 1Ah Function Call */ -#define PCI_PRESENT_CODE 0x20494350 /* Hex Equivalent Of 'PCI ' */ - -#define PCI_SERVICE_IDENTIFIER 0x49435024 /* ASCII Codes for 'ICP$' */ - -/*-------------------------------------------------------------------------*/ -/* Device and Vendor IDs */ -/*-------------------------------------------------------------------------*/ -#define E1000_DEVICE_ID 0x1000 -#define WISEMAN_DEVICE_ID 0x1000 -#define LIVENGOOD_FIBER_DEVICE_ID 0x1001 -#define LIVENGOOD_COPPER_DEVICE_ID 0x1004 -#define E1000_VENDOR_ID 0x8086 - -#define SPLASH_DEVICE_ID 0x1226 -#define SPLASH_VENDOR_ID 0x8086 -#define SPEEDO_DEVICE_ID 0x1227 -#define SPEEDO_VENDOR_ID 0x8086 -#define D100_DEVICE_ID 0x1229 -#define D100_VENDOR_ID 0x8086 -#define NITRO3_DEVICE_ID 0x5201 -#define NITRO3_VENDOR_ID 0x8086 -#define XXPS_BRIDGE_DEVICE_ID 0x1225 -#define XXPS_BRIDGE_VENDOR_ID 0x8086 -#define OPB0_BRIDGE_DEVICE_ID 0x84C4 -#define OPB0_BRIDGE_VENDOR_ID 0x8086 - - -#endif /* PCI_H */ - - - - -/* - * e1000_externs.h - * - * This file has all the defines for the functions in various header files - */ -#ifdef E1000_MAIN_STATIC -static void e1000_print_brd_conf(bd_config_t *); -static int e1000_init(bd_config_t *); -static int e1000_runtime_init(bd_config_t *); - -static boolean_t e1000_sw_init(bd_config_t *); -static void *malloc_contig(int); -static void free_contig(void *); -static void e1000_dealloc_space(bd_config_t *); -static bd_config_t *e1000_alloc_space(void); - -static boolean_t e1000_find_pci_device(pci_dev_t *, PADAPTER_STRUCT); - -static void e1000_watchdog(device_t *); -static void e1000_intr(int, void *, struct pt_regs *); - -static void SetupTransmitStructures(PADAPTER_STRUCT, boolean_t); -static int SetupReceiveStructures(bd_config_t *, boolean_t, boolean_t); -static int ReadNodeAddress(PADAPTER_STRUCT, PUCHAR); -static int e1000_set_promisc(bd_config_t *, int flag); -static void e1000DisableInterrupt(PADAPTER_STRUCT); -static void e1000EnableInterrupt(PADAPTER_STRUCT); -static void e1000DisableInterrupt(PADAPTER_STRUCT); -static void ProcessTransmitInterrupts(bd_config_t *); -static void ProcessReceiveInterrupts(bd_config_t *); -static void UpdateStatsCounters(bd_config_t *); -static uint_t SendBuffer(PTX_SW_PACKET, bd_config_t *); - -int e1000_probe(void); -static int e1000_open(device_t *); -static int e1000_close(device_t *); -static int e1000_xmit_frame(struct sk_buff *, device_t *); -static struct net_device_stats *e1000_get_stats(device_t *); -static int e1000_change_mtu(device_t *, int); -static int e1000_set_mac(device_t *, void *); -static void e1000_set_multi(device_t *); -static void e1000_check_options(int board); -static boolean_t DetectKnownChipset(PADAPTER_STRUCT); -static int e1000_GetBrandingMesg(uint16_t dev, uint16_t sub_ven, uint16_t sub_dev); -#endif -extern void AdapterStop(PADAPTER_STRUCT); -extern ushort_t ReadEepromWord(PADAPTER_STRUCT, ushort_t); -extern boolean_t ValidateEepromChecksum(PADAPTER_STRUCT); -extern void CheckForLink(PADAPTER_STRUCT); -extern BOOLEAN InitializeHardware(PADAPTER_STRUCT Adapter); -extern BOOLEAN SetupFlowControlAndLink(PADAPTER_STRUCT Adapter); -extern VOID GetSpeedAndDuplex(PADAPTER_STRUCT Adapter, PUINT16 Speed, PUINT16 Duplex); -extern VOID ConfigFlowControlAfterLinkUp(PADAPTER_STRUCT Adapter); -extern VOID ClearHwStatsCounters(PADAPTER_STRUCT Adapter); - -/************************************************************************* -* * -* Module Name: * -* pci.h * -* Abstract: * -* This header file contains PCI related constants and bit definitions. * -* * -* This driver runs on the following hardware: * -* - E10001000 based PCI gigabit ethernet adapters (aka Kodiak) * -* * -* Environment: * -* Kernel Mode - * -* * -* Source History: * -* The contents of this file is based somewhat on code developed for * -* Intel Pro/100 family (Speedo1 and Speedo3). * -* * -* March 7, 1997 * -* 1st created - Ported from E100B pci.h file * -* * -*************************************************************************/ -#ifndef _E1K_PCI_H -#define _E1K_PCI_H - -/*-------------------------------------------------------------------------*/ -/* Device and Vendor IDs */ -/*-------------------------------------------------------------------------*/ -#define E1000_DEVICE_ID 0x1000 -#define E1000_VENDOR_ID 0x8086 - -#define SPLASH_DEVICE_ID 0x1226 -#define SPLASH_VENDOR_ID 0x8086 -#define SPEEDO_DEVICE_ID 0x1227 -#define SPEEDO_VENDOR_ID 0x8086 -#define D100_DEVICE_ID 0x1229 -#define D100_VENDOR_ID 0x8086 -#define NITRO3_DEVICE_ID 0x5201 -#define NITRO3_VENDOR_ID 0x8086 -#define XXPS_BRIDGE_DEVICE_ID 0x1225 -#define XXPS_BRIDGE_VENDOR_ID 0x8086 -#define OPB0_BRIDGE_DEVICE_ID 0x84C4 -#define OPB0_BRIDGE_VENDOR_ID 0x8086 - -#define INTEL_440BX_AGP 0x7192 -#define INTEL_440BX 0x7190 -#define INTEL_440GX 0x71A0 -#define INTEL_440LX_EX 0x7180 -#define INTEL_440FX 0x1237 -#define INTEL_430TX 0x7100 -#define INTEL_450NX_PXB 0x84CB -#define INTEL_450KX_GX_PB 0x84C4 - - -/********************************************************************** -** Other component's device number in PCI config space -**********************************************************************/ - -#define PXB_0A_DEVNO 0x12 -#define PXB_0B_DEVNO 0x13 -#define PXB_1A_DEVNO 0x14 -#define PXB_1B_DEVNO 0x15 - -#define PB0_DEVNO 0x19 -#define PB1_DEVNO 0x1A - -#define PXB_C0_REV_ID 0x4 - - -#endif /* PCI_H */ -#endif /* _E1000_H_ */ diff -uNr click-1.5.0-dist/drivers/e1000-2.x/e1000_main.c.orig click-1.5.0/drivers/e1000-2.x/e1000_main.c.orig --- click-1.5.0-dist/drivers/e1000-2.x/e1000_main.c.orig Wed Feb 14 04:34:27 2001 +++ click-1.5.0/drivers/e1000-2.x/e1000_main.c.orig Thu Jan 1 01:00:00 1970 @@ -1,4075 +0,0 @@ -/***************************************************************************** - ***************************************************************************** -Copyright (c) 1999 - 2000, Intel Corporation - -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. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 CONTRIBUTORS 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. - - ***************************************************************************** - ****************************************************************************/ - -/********************************************************************** -* * -* INTEL CORPORATION * -* * -* This software is supplied under the terms of the license included * -* above. All use of this driver must be in accordance with the terms * -* of that license. * -* * -* Module Name: e1000.c * -* * -* Abstract: Functions for the driver entry points like load, * -* unload, open and close. All board specific calls made * -* by the network interface section of the driver. * -* * -* Environment: This file is intended to be specific to the Linux * -* operating system. * -* * -**********************************************************************/ - - -/* This first section contains the setable parametes for configuring the - * driver into the kernel. - */ - -#define E1000_DEBUG_DEFAULT 0 -static int e1000_debug_level = E1000_DEBUG_DEFAULT; - -/* global defines */ -#define MAX_TCB 80 /* number of transmit descriptors */ -#define MAX_RFD 80 /* number of receive descriptors */ - -/* includes */ -#ifdef MODULE -#ifdef MODVERSIONS -#include -#endif -#include -#endif -#define E1000_MAIN_STATIC -#ifdef IANS -#define _IANS_MAIN_MODULE_C_ -#endif -#include "e1000.h" -#include "e1000_vendor_info.h" -#include "e1000_proc.h" - -/* Global Data structures and variables */ -static const char *version = -"Intel(R) PRO/1000 Gigabit Ethernet Adapter - Loadable driver, ver. 2.5.11\n"; -static char e1000_copyright[] = " Copyright (c) 1999-2000 Intel Corporation\n"; -static char e1000id_string[128] = "Intel(R) PRO/1000 Gigabit Server Adapter"; -static char e1000_driver[] = "e1000"; -static char e1000_version[] = "2.5.11"; - -static bd_config_t *e1000first = NULL; -static int e1000boards = 0; -static int e1000_rxfree_cnt = 0; - -/* Driver performance tuning variables */ -static uint_t e1000_pcimlt_override = 0; -static uint_t e1000_pcimwi_enable = 1; -static uint_t e1000_txint_delay = 128; -static uint_t e1000_rxint_delay = 0; - -static int e1000_flow_ctrl = 3; -static int e1000_rxpci_priority = 0; -static uint_t e1000_maxdpc_count = 5; - -static int TxDescriptors[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int RxDescriptors[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - -/* Feature enable/disable */ -static int Jumbo[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int WaitForLink[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int SBP[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* Speed and Duplex Settings */ -static int AutoNeg[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int Speed[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int ForceDuplex[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - -/* This parameter determines whether the driver sets the RS bit or the - * RPS bit in a transmit packet. These are the possible values for this - * parameter: - * e1000_ReportTxEarly = 0 ==> set the RPS bit - * = 1 ==> set the RS bit - * = 2 ==> (default) let the driver auto-detect - * - * If the RS bit is set in a packet, an interrupts is generated as soon - * as the packet is DMAed from host memory to the FIFO. If the RPS bit - * is set, an interrupt is generated after the packet has been transmitted - * on the wire. - */ -static uchar_t e1000_ReportTxEarly = 2; /* let the driver auto-detect */ - - -/* these next ones are for Linux specific things */ -static int probed = 0; - -/* The system interface routines */ - -/**************************************************************************** -* Name: e1000_probe -* -* Description: This routine is called when the dynamic driver module -* "e1000" is loaded using the command "insmod". -* -* This is a Linux required routine. -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* NONE -* -* Returns: -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -int -e1000_probe() -{ - device_t *dev; - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - pci_dev_t *pcid = NULL; - int num_boards = 0; - int first_time = 0, loop_cnt = 0; - - if (e1000_debug_level >= 1) - printk("e1000_probe()\n"); - - /* Has the probe routine been called before? The driver can be probed only - * once. - */ - if (probed) - return (0); - else - probed++; - - /* does the system support pci? */ - if ((!CONFIG_PCI) || (!pci_present())) - return (0); - -#ifdef CONFIG_PROC_FS - { - int len; - - /* first check if e1000_proc_dir already exists */ - len = strlen(ADAPTERS_PROC_DIR); - for (e1000_proc_dir=proc_net->subdir;e1000_proc_dir; - e1000_proc_dir=e1000_proc_dir->next) { - if ((e1000_proc_dir->namelen == len) && - (!memcmp(e1000_proc_dir->name, ADAPTERS_PROC_DIR, len))) - break; - } - if (!e1000_proc_dir) - e1000_proc_dir = - create_proc_entry(ADAPTERS_PROC_DIR, S_IFDIR, proc_net); - if (!e1000_proc_dir) return -ENODEV; - } -#endif - - /* loop through all of the ethernet PCI devices looking for ours */ - while ((pcid = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pcid))) { - dev = NULL; - - if (e1000_debug_level >= 2) - printk("e1000_probe: vendor = 0x%x, device = 0x%x \n", - pcid->vendor, pcid->device); - - - /* is the device ours? */ - if ((pcid->vendor != E1000_VENDOR_ID) || - !((pcid->device == WISEMAN_DEVICE_ID) || - (pcid->device == LIVENGOOD_FIBER_DEVICE_ID) || - (pcid->device == LIVENGOOD_COPPER_DEVICE_ID))) continue; /* No, continue */ - - if (!first_time) { - /* only display the version message one time */ - first_time = 1; - - /* print out the version */ - printk("%s", version); - printk("%s\n", e1000_copyright); - } - - /* register the net device, but don't allocate a private structure yet */ - dev = init_etherdev(dev, 0); - - if (dev == NULL) { - printk(KERN_ERR "Not able to alloc etherdev struct\n"); - break; - } - - /* Allocate all the memory that the driver will need */ - if (!(bdp = e1000_alloc_space())) { - printk("%s - Failed to allocate memory\n", e1000_driver); - e1000_dealloc_space(bdp); - return 0; - } - bdp->device = dev; - -#ifdef CONFIG_PROC_FS - if (e1000_create_proc_dev(bdp) < 0) { - e1000_remove_proc_dev(dev); - e1000_dealloc_space(bdp); - continue; /*return e100nics;*/ - } -#endif - - /* init the timer */ - bdp->timer_val = -1; - - /* point the Adapter to the bddp */ - Adapter = (PADAPTER_STRUCT) bdp->bddp; - -#ifdef IANS - bdp->iANSdata = kmalloc(sizeof(iANSsupport_t), GFP_KERNEL); - memset((PVOID) bdp->iANSdata, 0, sizeof(iANSsupport_t)); - bd_ans_drv_InitANS(bdp, bdp->iANSdata); -#endif - - /* - * Obtain the PCI specific information about the driver. - */ - if (e1000_find_pci_device(pcid, Adapter) == 0) { - printk("%s - Failed to find PCI device\n", e1000_driver); - return (0); - } - - /* range check the command line parameters for this board */ - if(!e1000_GetBrandingMesg(Adapter->DeviceId, Adapter->SubVendorId, Adapter->SubSystemId)) { - continue; - } - printk("%s\n", e1000id_string); - e1000_check_options(loop_cnt); - - switch (Speed[loop_cnt]) { - case SPEED_10: - switch(ForceDuplex[loop_cnt]) { - case HALF_DUPLEX: - Adapter->AutoNeg = 0; - Adapter->ForcedSpeedDuplex = HALF_10; - break; - case FULL_DUPLEX: - Adapter->AutoNeg = 0; - Adapter->ForcedSpeedDuplex = FULL_10; - break; - default: - Adapter->AutoNeg = 1; - Adapter->AutoNegAdvertised = - ADVERTISE_10_HALF | ADVERTISE_10_FULL; - } - break; - case SPEED_100: - switch(ForceDuplex[loop_cnt]) { - case HALF_DUPLEX: - Adapter->AutoNeg = 0; - Adapter->ForcedSpeedDuplex = HALF_100; - break; - case FULL_DUPLEX: - Adapter->AutoNeg = 0; - Adapter->ForcedSpeedDuplex = FULL_100; - break; - default: - Adapter->AutoNeg = 1; - Adapter->AutoNegAdvertised = - ADVERTISE_100_HALF | ADVERTISE_100_FULL; - } - break; - case SPEED_1000: - Adapter->AutoNeg = 1; - Adapter->AutoNegAdvertised = ADVERTISE_1000_FULL; - break; - default: - Adapter->AutoNeg = 1; - switch(ForceDuplex[loop_cnt]) { - case HALF_DUPLEX: - Adapter->AutoNegAdvertised = - ADVERTISE_10_HALF | ADVERTISE_100_HALF; - break; - case FULL_DUPLEX: - Adapter->AutoNegAdvertised = - ADVERTISE_10_FULL | ADVERTISE_100_FULL | ADVERTISE_1000_FULL; - break; - default: - Adapter->AutoNegAdvertised = AutoNeg[loop_cnt]; - } - } - - - Adapter->WaitAutoNegComplete = WaitForLink[loop_cnt]; - - - /* Set Adapter->MacType */ - switch (pcid->device) { - case WISEMAN_DEVICE_ID: - if (Adapter->RevID == WISEMAN_2_0_REV_ID) - Adapter->MacType = MAC_WISEMAN_2_0; - else { - if (Adapter->RevID == WISEMAN_2_1_REV_ID) - Adapter->MacType = MAC_WISEMAN_2_1; - else { - Adapter->MacType = MAC_WISEMAN_2_0; - printk(KERN_ERR - "Could not identify hardware revision\n"); - } - } - break; - case LIVENGOOD_FIBER_DEVICE_ID: - case LIVENGOOD_COPPER_DEVICE_ID: - Adapter->MacType = MAC_LIVENGOOD; - break; - default: - Adapter->MacType = MAC_WISEMAN_2_0; - printk(KERN_ERR "Could not identify hardware revision\n"); - break; - } - - /* save off the needed information */ - bdp->device = dev; - dev->priv = bdp; - Adapter = bdp->bddp; - - /* save off the pci device structure pointer */ - Adapter->pci_dev = pcid; - bdp->vendor = pcid->vendor; - - /* set the irq into the dev and bdp structures */ - dev->irq = pcid->irq; - bdp->irq_level = pcid->irq; - - - /* point to all of our entry point to let the system know where we are */ - dev->open = &e1000_open; - dev->hard_start_xmit = &e1000_xmit_frame; - dev->stop = &e1000_close; - dev->get_stats = &e1000_get_stats; - dev->set_multicast_list = &e1000_set_multi; - dev->set_mac_address = &e1000_set_mac; - dev->change_mtu = &e1000_change_mtu; -#ifdef IANS - dev->do_ioctl = &bd_ans_os_Ioctl; -#endif - /* set memory base addr */ - dev->base_addr = pci_resource_start(pcid, 0); - - /* now map the phys addr into system space... */ - /* - * Map the PCI memory base address to a virtual address that can be used - * for access by the driver. The amount of memory to be mapped will be - * the E1000 register area. - */ - - Adapter->HardwareVirtualAddress = - (PE1000_REGISTERS) ioremap(pci_resource_start(pcid, 0), - sizeof(E1000_REGISTERS)); - - if (Adapter->HardwareVirtualAddress == NULL) { - /* - * If the hardware register space can not be allocated, the driver - * must fail to load. - */ - printk("e1000_probe ioremap failed\n"); - - /* this is a problem, if the first one inits OK but a secondary one - * fails, what should you return? Now it will say the load was OK - * but one or more boards may have failed to come up - */ - - break; - } - - bdp->mem_start = pci_resource_start(pcid, 0); - - if (e1000_debug_level >= 2) - printk("memstart = 0x%p, virt_addr = 0x%p\n", - (void *) bdp->mem_start, - (void *) Adapter->HardwareVirtualAddress); - - e1000_init(bdp); - - /* Printout the board configuration */ - e1000_print_brd_conf(bdp); - - /* init the basic stats stuff */ - ClearHwStatsCounters(Adapter); - /* Update the statistics needed by the upper */ - UpdateStatsCounters(bdp); - - /* up the loop count( it's also the number of our boards found) */ - loop_cnt++; - - if (e1000_debug_level >= 2) { - printk("dev = 0x%p ", dev); - printk(" priv = 0x%p\n", dev->priv); - printk(" irq = 0x%x ", dev->irq); - printk(" next = 0x%p ", dev->next); - printk(" flags = 0x%x\n", dev->flags); - printk(" bdp = 0x%p\n", bdp); - printk(" irq_level = 0x%x\n", bdp->irq_level); - } - } /* end of pci_find_class while loop */ - - e1000boards = num_boards = loop_cnt; - - if (num_boards) - return (0); - else - return (-ENODEV); -} - -/* register e1000_probe as our initilization routine */ -module_init(e1000_probe); - -/* set some of the modules specific things here */ -#ifdef MODULE -MODULE_AUTHOR("Intel Corporation, "); -MODULE_DESCRIPTION("Intel(R) PRO/1000 Gigabit Ethernet driver"); -MODULE_PARM(TxDescriptors, "1-8i"); -MODULE_PARM(RxDescriptors, "1-8i"); -MODULE_PARM(Jumbo, "1-8i"); -MODULE_PARM(WaitForLink, "1-8i"); -MODULE_PARM(AutoNeg, "1-8i"); -MODULE_PARM(Speed, "1-8i"); -MODULE_PARM(ForceDuplex, "1-8i"); -MODULE_PARM(SBP, "1-8i"); -#endif - -/**************************************************************************** -* Name: cleanup_module -* -* Description: This routine is an entry point into the driver. -* -* This is a Linux required routine. -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* NONE -* -* Returns: -* It returns 0 and can not fail -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -int -cleanup_module(void) -{ - bd_config_t *bdp, *next_bdp; - PADAPTER_STRUCT Adapter; - device_t *dev, *next_dev; - - /* start looking at the first device */ - if (e1000first) - dev = e1000first->device; - else - return 0; - if (e1000_debug_level >= 1) - printk("cleanup_module: SOR, dev = 0x%p \n\n\n", dev); - - while (dev) { -#ifdef CONFIG_PROC_FS - e1000_remove_proc_dev(dev); -#endif - bdp = (bd_config_t *) dev->priv; - next_bdp = bdp->bd_next; - - if (next_bdp) - next_dev = next_bdp->device; - else - next_dev = NULL; - Adapter = bdp->bddp; - - /* unregister this instance of the module */ - if (e1000_debug_level >= 2) - printk("--Cleanup, unreg_netdev\n"); - unregister_netdev(dev); - - /* - * Free the memory mapped area that is allocated to the E1000 hardware - * registers - */ - if (e1000_debug_level >= 2) - printk("--Cleanup, iounmap\n"); - iounmap(Adapter->HardwareVirtualAddress); - /* free the irq back to the system */ - -#ifdef IANS - kfree(bdp->iANSdata); -#endif - /* free up any memory here */ - if (e1000_debug_level >= 2) - printk("--Cleanup, e1000_dealloc_space\n"); - e1000_dealloc_space(bdp); - - dev = next_dev; - } - -#ifdef CONFIG_PROC_FS - { - struct proc_dir_entry *de; - - /* check if the subdir list is empty before removing e1000_proc_dir */ - for (de = e1000_proc_dir->subdir; de; de = de->next) { - /* ignore . and .. */ - if (*(de->name) == '.') continue; - break; - } - if (de) return 0; - remove_proc_entry(ADAPTERS_PROC_DIR, proc_net); - } -#endif - - return (0); -} - - -/**************************************************************************** -* Name: e1000_check_options -* -* Description: This routine does range checking on command line options. -* -* Author: IntelCorporation -* -* Born on Date: 03/28/2000 -* -* Arguments: -* int board - board number to check values for -* -* Returns: -* None -* -****************************************************************************/ -static void -e1000_check_options(int board) -{ - - /* Transmit Descriptor Count */ - if (TxDescriptors[board] == -1) { - TxDescriptors[board] = MAX_TCB; - } else if ((TxDescriptors[board] > E1000_MAX_TXD) || - (TxDescriptors[board] < E1000_MIN_TXD)) { - printk("Invalid TxDescriptor count specified (%i)," - " using default of %i\n", TxDescriptors[board], MAX_TCB); - TxDescriptors[board] = MAX_TCB; - } else { - printk("Using specified value of %i TxDescriptors\n", - TxDescriptors[board]); - } - - /* Receive Descriptor Count */ - if (RxDescriptors[board] == -1) { - RxDescriptors[board] = MAX_RFD; - } else if ((RxDescriptors[board] > E1000_MAX_RXD) || - (RxDescriptors[board] < E1000_MIN_RXD)) { - printk("Invalid RxDescriptor count specified (%i)," - " using default of %i\n", RxDescriptors[board], MAX_RFD); - RxDescriptors[board] = MAX_RFD; - } else { - printk("Using specified value of %i RxDescriptors\n", - RxDescriptors[board]); - } - - /* Jumbo Frame Enable */ - if (Jumbo[board] == -1) { - Jumbo[board] = 1; - } else if ((Jumbo[board] > 1) || (Jumbo[board] < 0)) { - printk("Invalid Jumbo specified (%i), using default of %i\n", - Jumbo[board], 1); - Jumbo[board] = 1; - } else { - printk("Jumbo Frames %s\n", - Jumbo[board] == 1 ? "Enabled" : "Disabled"); - } - - /* Wait for link at driver load */ - if (WaitForLink[board] == -1) { - WaitForLink[board] = 1; - } else if ((WaitForLink[board] > 1) || (WaitForLink[board] < 0)) { - printk("Invalid WaitForLink specified (%i), using default of %i\n", - WaitForLink[board], 1); - WaitForLink[board] = 1; - } else { - printk("WaitForLink %s\n", - WaitForLink[board] == 1 ? "Enabled" : "Disabled"); - } - - /* Forced Speed and Duplex */ - switch (Speed[board]) { - case -1: - Speed[board] = 0; - switch (ForceDuplex[board]) { - case -1: - ForceDuplex[board] = 0; - break; - case 0: - printk("Speed and Duplex Autonegotiation Enabled\n"); - break; - case 1: - printk("Warning: Half Duplex specified without Speed\n"); - printk("Using Autonegotiation at Half Duplex only\n"); - break; - case 2: - printk("Warning: Full Duplex specified without Speed\n"); - printk("Using Autonegotiation at Full Duplex only\n"); - break; - default: - printk("Invalid Duplex Specified (%i), Parameter Ignored\n", - ForceDuplex[board]); - ForceDuplex[board] = 0; - printk("Speed and Duplex Autonegotiation Enabled\n"); - } - break; - case 0: - switch (ForceDuplex[board]) { - case -1: - case 0: - printk("Speed and Duplex Autonegotiation Enabled\n"); - ForceDuplex[board] = 0; - break; - case 1: - printk("Warning: Half Duplex specified without Speed\n"); - printk("Using Autonegotiation at Half Duplex only\n"); - break; - case 2: - printk("Warning: Full Duplex specified without Speed\n"); - printk("Using Autonegotiation at Full Duplex only\n"); - break; - default: - printk("Invalid Duplex Specified (%i), Parameter Ignored\n", - ForceDuplex[board]); - ForceDuplex[board] = 0; - printk("Speed and Duplex Autonegotiation Enabled\n"); - } - break; - case 10: - case 100: - switch (ForceDuplex[board]) { - case -1: - case 0: - printk("Warning: %i Mbps Speed specified without Duplex\n", - Speed[board]); - printk("Using Autonegotiation at %i Mbps only\n", Speed[board]); - ForceDuplex[board] = 0; - break; - case 1: - printk("Forcing to %i Mbps Half Duplex\n", Speed[board]); - break; - case 2: - printk("Forcing to %i Mbps Full Duplex\n", Speed[board]); - break; - default: - printk("Invalid Duplex Specified (%i), Parameter Ignored\n", - ForceDuplex[board]); - ForceDuplex[board] = 0; - printk("Warning: %i Mbps Speed specified without Duplex\n", - Speed[board]); - printk("Using Autonegotiation at %i Mbps only\n", Speed[board]); - } - break; - case 1000: - switch (ForceDuplex[board]) { - case -1: - case 0: - printk("Warning: 1000 Mbps Speed specified without Duplex\n"); - printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - ForceDuplex[board] = 0; - break; - case 1: - printk("Warning: Half Duplex is not supported at 1000 Mbps\n"); - printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - break; - case 2: - printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - break; - default: - printk("Invalid Duplex Specified (%i), Parameter Ignored\n", - ForceDuplex[board]); - ForceDuplex[board] = 0; - printk("Warning: 1000 Mbps Speed specified without Duplex\n"); - printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - } - break; - default: - printk("Invalid Speed Specified (%i), Parameter Ignored\n", - Speed[board]); - Speed[board] = 0; - switch (ForceDuplex[board]) { - case -1: - case 0: - printk("Speed and Duplex Autonegotiation Enabled\n"); - ForceDuplex[board] = 0; - break; - case 1: - printk("Warning: Half Duplex specified without Speed\n"); - printk("Using Autonegotiation at Half Duplex only\n"); - break; - case 2: - printk("Warning: Full Duplex specified without Speed\n"); - printk("Using Autonegotiation at Full Duplex only\n"); - break; - default: - printk("Invalid Duplex Specified (%i), Parameter Ignored\n", - ForceDuplex[board]); - ForceDuplex[board] = 0; - printk("Speed and Duplex Autonegotiation Enabled\n"); - } - } - - if (AutoNeg[board] == -1) { - AutoNeg[board] = 0x2F; - } else { - if (AutoNeg[board] & ~0x2F) { - printk("Invalid AutoNeg Specified (0x%X)\n", AutoNeg[board]); - AutoNeg[board] = 0x2F; - } - printk("AutoNeg Advertising "); - if(AutoNeg[board] & 0x20) { - printk("1000/FD"); - if(AutoNeg[board] & 0x0F) - printk(", "); - } - if(AutoNeg[board] & 0x08) { - printk("100/FD"); - if(AutoNeg[board] & 0x07) - printk(", "); - } - if(AutoNeg[board] & 0x04) { - printk("100/HD"); - if(AutoNeg[board] & 0x03) - printk(", "); - } - if(AutoNeg[board] & 0x02) { - printk("10/FD"); - if(AutoNeg[board] & 0x01) - printk(", "); - } - if(AutoNeg[board] & 0x01) - printk("10/HD"); - printk("\n"); - } -} - -/**************************************************************************** -* Name: e1000_open -* -* Description: This routine is the open call for the interface. -* -* This is a Linux required routine. -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* NONE -* -* Returns: -* It returns 0 on success -* -EAGAIN on failure -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_open(device_t * dev) -{ - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - int ret_val; - - bdp = dev->priv; - Adapter = bdp->bddp; - - if (e1000_debug_level >= 1) - printk("open: SOR, bdp = 0x%p\n", bdp); - - /* make sure we have not already opened this interface */ - if(bdp->flags & BOARD_OPEN) - return -EBUSY; - - if (e1000_init(bdp)) { - return -ENOMEM; - } - if (e1000_runtime_init(bdp)) { - return -ENOMEM; - } - Adapter->AdapterStopped = FALSE; - -#ifdef IANS_BASE_VLAN_TAGGING - /* on a close a global reset is issued to the hardware, - * so VLAN settings are lost and need to be re-set on open */ - if((IANS_BD_TAGGING_MODE)ANS_PRIVATE_DATA_FIELD(bdp)->tag_mode != IANS_BD_TAGGING_NONE) - bd_ans_hw_EnableVLAN(bdp); -#endif - - if (request_irq(dev->irq, &e1000_intr, SA_SHIRQ, "e1000", dev)) { - if (e1000_debug_level >= 1) - printk("open: request_irq failed"); - - return (-EAGAIN); - } - - /* Check to see if promiscuous mode needs to be turned on */ - if (dev->flags & IFF_PROMISC) { - /* turn promisc mode on */ - ret_val = e1000_set_promisc(bdp, B_TRUE); - bdp->flags |= PROMISCUOUS; - } else { - /* turn promisc mode off */ - ret_val = e1000_set_promisc(bdp, B_FALSE); - bdp->flags &= ~PROMISCUOUS; - } - -#ifdef MODULE - /* up the mod use count used by the system */ - MOD_INC_USE_COUNT; -#endif - - /* setup and start the watchdog timer */ - init_timer(&bdp->timer_id); - - /* set the timer value for 2 sec( i.e. 200 10msec tics ) - * jiffies are mesured in tics and is equiv. to LBOLTS in Unix - */ - bdp->timer_id.expires = bdp->timer_val = jiffies + 200; - bdp->timer_id.data = (ulong_t) dev; - bdp->timer_id.function = (void *) &e1000_watchdog; - - /* start the timer */ - add_timer(&bdp->timer_id); - - /* set the device flags */ - netif_start_queue(dev); - - /* enable interrupts */ - e1000EnableInterrupt(Adapter); - - /* init the basic stats stuff */ - ClearHwStatsCounters(Adapter); - - bdp->flags |= BOARD_OPEN; - return (0); -} - -/**************************************************************************** -* Name: e1000_close -* -* Description: This routine is an entry point into the driver. -* -* This is a Linux required routine. -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* device_t pointer -* -* Returns: -* It returns 0 and can not fail. -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_close(device_t * dev) -{ - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - PRX_SW_PACKET RxSwPacket; - ushort_t status; - int j; - - bdp = dev->priv; - Adapter = bdp->bddp; - - /* set the device to not started */ - - netif_stop_queue(dev); - /* stop the hardware */ - - /* Disable all possible interrupts */ - E1000_WRITE_REG(Imc, (0xffffffff)); - status = E1000_READ_REG(Icr); - - /* Reset the chip */ - AdapterStop(Adapter); - - /* kill the timer */ - del_timer(&bdp->timer_id); - - /* free the irq back to the system */ - if (e1000_debug_level >= 1) - printk("E1000: close: free_irq\n"); - free_irq(dev->irq, dev); - - /* - * Free up the transmit descriptor area - */ - if (e1000_debug_level >= 2) - printk("--Cleanup, free tx descriptor area\n"); - free_contig(Adapter->e1000_TxSwPacketPtrArea); - Adapter->e1000_TxSwPacketPtrArea = NULL; - free_contig(bdp->base_tx_tbds); - bdp->base_tx_tbds = NULL; - - /* - * Free up the RX_SW_PACKET area also free any allocated - * receive buffers - */ - if (e1000_debug_level >= 2) - printk("--Cleanup, free rx packet area + skbuffs\n"); - if (Adapter->RxSwPacketPointerArea != NULL) { - for (j = 0, RxSwPacket = Adapter->RxSwPacketPointerArea; - j < Adapter->NumRxDescriptors; j++, RxSwPacket++) { - if (RxSwPacket != NULL && RxSwPacket->skb != NULL) { - if (e1000_debug_level >= 2) - printk(" -- kfree_skb\n"); - dev_kfree_skb(RxSwPacket->skb); - RxSwPacket->skb = NULL; - } - } - } - - /* - * Free the receive descriptor area - */ - if (e1000_debug_level >= 2) - printk("--Cleanup, free rx descriptor area\n"); - /* free_contig( Adapter->e1000_rbd_data ); */ - free_contig(bdp->base_rx_rbds); - bdp->base_rx_rbds = NULL; - free_contig(Adapter->RxSwPacketPointerArea); - Adapter->RxSwPacketPointerArea = NULL; - - bdp->flags &= ~BOARD_OPEN; - -#ifdef MODULE - /* adjust the mod use count */ - MOD_DEC_USE_COUNT; -#endif - - return (0); -} - -/**************************************************************************** -* Name: e1000_xmit_frame -* -* Description: This routine is called to transmit a frame. -* -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* sb_buff pointer -* device_t pointer -* -* Returns: -* It returns B_FALSE on success -* B_TRUE on failure -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_xmit_frame(struct sk_buff *skb, device_t * dev) -{ - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - PTX_SW_PACKET TxSwPacket; - int lock_flag; - - bdp = dev->priv; - Adapter = (PADAPTER_STRUCT) bdp->bddp; - - /* get the tx lock */ - spin_lock_irqsave(&Adapter->bd_tx_lock, lock_flag); - - if (e1000_debug_level >= 3) - printk("e1000_tx_frame\n"); - - /******************************************************************* - * Check if any TxDescriptors are available, if not, back out of - * this function. - *******************************************************************/ - if ((Adapter->NumTxDescriptorsAvail) <= 1) { - /* TxSwPacket->Packet = NULL; */ - - if (e1000_debug_level >= 3) - printk - ("e1000_tx_frame No Tx descriptors available %d\n", - Adapter->NumTxDescriptorsAvail); - - bdp->tx_out_res = 1; - -#ifdef IANS - if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - ans_notify(dev, IANS_IND_XMIT_QUEUE_FULL); - } -#endif - netif_stop_queue(dev); - bdp->net_stats.tx_dropped += 1; - - /* release the tx_lock */ - spin_unlock_irqrestore(&Adapter->bd_tx_lock, lock_flag); - - /* fail the call */ - return (B_TRUE); - } - - /* Get a "TxSwPacket" to hold miscellaneous information about the resources - * that will be used to send this packet. - */ - - TxSwPacket = - (PTX_SW_PACKET) QUEUE_GET_HEAD(&Adapter->FreeSwTxPacketList); - - if (!TxSwPacket) { - if (e1000_debug_level >= 3) { - printk("TxSwPacket 0x%p is NOT VALID!!!!!\n\n", TxSwPacket); - } - - printk("!e1000_tx_frame no TxSwPackets left\n"); - - bdp->tx_out_res = 1; - -#ifdef IANS - if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - ans_notify(dev, IANS_IND_XMIT_QUEUE_FULL); - } -#endif - netif_stop_queue(dev); - bdp->net_stats.tx_dropped += 1; - - /* release the tx_lock */ - spin_unlock_irqrestore(&Adapter->bd_tx_lock, lock_flag); - - return (B_TRUE); - } - - /* Initialize TxSwPacket structure. We'll have to reference this - * structure when we do our transmit cleanup processing for this packet. - */ - TxSwPacket->Packet = skb; - - - if (e1000_debug_level >= 3) - printk("tx_frame: calling SendBuffer, TxSwPacket = 0x%p\n", - TxSwPacket); - - /* call the transmit routine */ - SendBuffer(TxSwPacket, bdp); - - /* set the xmit start time, it's only in tics so the res in not good */ - dev->trans_start = jiffies; - - /* - * e1000_tx_frame could be called from the context of - * e1000_tx_queued_frames. In that case, if the packet gets transmitted - * successfully, the write queue length needs to be decremented. - */ - - if (bdp->OutQlen) - bdp->OutQlen--; - - /* release the tx_lock */ - spin_unlock_irqrestore(&Adapter->bd_tx_lock, lock_flag); - - return (B_FALSE); -} - -/**************************************************************************** -* Name: SendBuffer -* -* Description: This routine physically sends the packet to the nic controller. -* -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* TX_SW_PACKET pointer -* bd_config_t pointer -* -* Returns: -* It returns B_TRUE always and can not fail. -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static UINT -SendBuffer(PTX_SW_PACKET TxSwPacket, bd_config_t * bdp) -{ - PADAPTER_STRUCT Adapter; - PE1000_TRANSMIT_DESCRIPTOR CurrentTxDescriptor; - sk_buff_t *skb; - net_device_stats_t *stats; - - Adapter = bdp->bddp; - skb = TxSwPacket->Packet; - stats = &bdp->net_stats; - - CurrentTxDescriptor = Adapter->NextAvailTxDescriptor; - - CurrentTxDescriptor->BufferAddress = 0; - CurrentTxDescriptor->BufferAddress += virt_to_bus(skb->data); - - CurrentTxDescriptor->Lower.DwordData = skb->len; - - /* zero out the status field in the descriptor. */ - CurrentTxDescriptor->Upper.DwordData = 0; - -#ifdef IANS - if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - if(bd_ans_os_Transmit(bdp, CurrentTxDescriptor, &skb)==BD_ANS_FAILURE) { - dev_kfree_skb(skb); - return B_FALSE; - } - } -#endif - - /* Check the wrap-around case */ - if (CurrentTxDescriptor == Adapter->LastTxDescriptor) - Adapter->NextAvailTxDescriptor = Adapter->FirstTxDescriptor; - else - Adapter->NextAvailTxDescriptor++; - - Adapter->NumTxDescriptorsAvail--; - - TxSwPacket = - (PTX_SW_PACKET) QUEUE_POP_HEAD(&Adapter->FreeSwTxPacketList); - - /* Last Descriptor of Packet needs End Of Packet (EOP), - * Report Status (RS) and append Ethernet CRC (IFCS) bits set. - */ - TxSwPacket->TxDescriptorBufferAddr = - CurrentTxDescriptor->BufferAddress; - - /* Put this TxSwPacket at the end in the "in use" list */ - QUEUE_PUSH_TAIL(&Adapter->UsedSwTxPacketList, &TxSwPacket->Link); - - /* - * If there is a valid value for the transmit interrupt delay, set up the - * delay in the descriptor field - */ - if (Adapter->TxIntDelay) { - CurrentTxDescriptor->Lower.DwordData |= - (E1000_TXD_CMD_EOP | E1000_TXD_CMD_IDE | E1000_TXD_CMD_IFCS); - } else { - CurrentTxDescriptor->Lower.DwordData |= - (E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS); - } - - /* Set the RS or the RPS bit by looking at the ReportTxEarly setting */ - if (Adapter->ReportTxEarly == 1) - CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RS; - else - CurrentTxDescriptor->Lower.DwordData |= E1000_TXD_CMD_RPS; - - /* Advance the Transmit Descriptor Tail (Tdt), this tells the - * E1000 that this frame is available to transmit. - */ - - E1000_WRITE_REG(Tdt, (((unsigned long) Adapter->NextAvailTxDescriptor - - (unsigned long) Adapter->FirstTxDescriptor) >> 4)); - - return (B_TRUE); -} - -/**************************************************************************** -* Name: e1000_get_stats -* -* Description: This routine is called when the OS wants the nic stats returned -* -* Author: IntelCorporation -* -* Born on Date: 7/12/99 -* -* Arguments: -* device_t dev - the device stucture to return stats on -* -* Returns: -* the address of the net_device_stats stucture for the device -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static struct net_device_stats * -e1000_get_stats(device_t * dev) -{ - bd_config_t *bdp = dev->priv; - - /* Statistics are updated from the watchdog - so just return them now */ - return (&bdp->net_stats); -} - - -/* this routine is to change the MTU size for jumbo frames */ -/**************************************************************************** -* Name: e1000_change_mtu -* -* Description: This routine is called when the OS would like the driver to -* change the MTU size. This is used for jumbo frame support. -* -* Author: IntelCorporation -* -* Born on Date: 7/12/98 -* -* Arguments: -* device_t pointer - pointer to the device -* int - the new MTU size -* -* Returns: -* ???? -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_change_mtu(device_t * dev, int new_mtu) -{ - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - - bdp = (bd_config_t *) dev->priv; - Adapter = bdp->bddp; - - if ((new_mtu < MINIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE) || - (new_mtu > MAX_JUMBO_FRAME_SIZE - ENET_HEADER_SIZE)) - return -EINVAL; - - if (new_mtu <= MAXIMUM_ETHERNET_PACKET_SIZE - ENET_HEADER_SIZE) { - /* 802.x legal frame sizes */ - Adapter->LongPacket = FALSE; - if (Adapter->RxBufferLen != E1000_RXBUFFER_2048) { - Adapter->RxBufferLen = E1000_RXBUFFER_2048; - if (dev->flags & IFF_UP) { - e1000_close(dev); - e1000_open(dev); - } - } - } else if (Adapter->MacType < MAC_LIVENGOOD) { - /* Jumbo frames not supported on 82542 hardware */ - printk("e1000: Jumbo frames not supported on 82542\n"); - return -EINVAL; - } else if (Jumbo[Adapter->bd_number] != 1) { - printk("e1000: Jumbo frames disabled\n"); - return -EINVAL; - } else if (new_mtu <= (4096 - 256) - ENET_HEADER_SIZE) { - /* 4k buffers */ - Adapter->LongPacket = TRUE; - if (Adapter->RxBufferLen != E1000_RXBUFFER_4096) { - Adapter->RxBufferLen = E1000_RXBUFFER_4096; - if (dev->flags & IFF_UP) { - e1000_close(dev); - e1000_open(dev); - - } - } - } else if (new_mtu <= (8192 - 256) - ENET_HEADER_SIZE) { - /* 8k buffers */ - Adapter->LongPacket = TRUE; - if (Adapter->RxBufferLen != E1000_RXBUFFER_8192) { - Adapter->RxBufferLen = E1000_RXBUFFER_8192; - if (dev->flags & IFF_UP) { - e1000_close(dev); - e1000_open(dev); - } - } - } else { - /* 16k buffers */ - Adapter->LongPacket = TRUE; - if (Adapter->RxBufferLen != E1000_RXBUFFER_16384) { - Adapter->RxBufferLen = E1000_RXBUFFER_16384; - if (dev->flags & IFF_UP) { - e1000_close(dev); - e1000_open(dev); - } - } - } - dev->mtu = new_mtu; - return 0; -} - -/**************************************************************************** -* Name: e1000_init -* -* Description: This routine is called when this driver is loaded. This is -* the initialization routine which allocates memory, starts the -* watchdog, & configures the adapter, determines the system -* resources. -* -* Author: IntelCorporation -* -* Born on Date: 1/18/98 -* -* Arguments: -* NONE -* -* Returns: -* NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_init(bd_config_t * bdp) -{ - PADAPTER_STRUCT Adapter; - device_t *dev; - uint16_t LineSpeed, FullDuplex; - - if (e1000_debug_level >= 1) - printk("e1000_init()\n"); - - dev = bdp->device; - Adapter = (PADAPTER_STRUCT) bdp->bddp; - - /* - * Disable interrupts on the E1000 card - */ - e1000DisableInterrupt(Adapter); - - /**** Reset and Initialize the E1000 *******/ - AdapterStop(Adapter); - Adapter->AdapterStopped = FALSE; - - /* Validate the EEPROM */ - if (!ValidateEepromChecksum(Adapter)) { - printk("e1000: The EEPROM checksum is not valid \n"); - return (1); - } - - /* read the ethernet address from the eprom */ - ReadNodeAddress(Adapter, &Adapter->perm_node_address[0]); - - if (e1000_debug_level >= 2) { - printk("Node addr is: "); - printk("%x:", Adapter->perm_node_address[0]); - printk("%x:", Adapter->perm_node_address[1]); - printk("%x:", Adapter->perm_node_address[2]); - printk("%x:", Adapter->perm_node_address[3]); - printk("%x:", Adapter->perm_node_address[4]); - printk("%x\n ", Adapter->perm_node_address[5]); - } - - /* save off the perm node addr in the bdp */ - memcpy(bdp->eaddr.bytes, &Adapter->perm_node_address[0], - DL_MAC_ADDR_LEN); - - /* tell the system what the address is... */ - memcpy(&dev->dev_addr[0], &Adapter->perm_node_address[0], - DL_MAC_ADDR_LEN); - - /* Scan the chipset and determine whether to set the RS bit or - * the RPS bit during transmits. On some systems with a fast chipset - * (450NX), setting the RS bit may cause data corruption. Check the - * space.c paratemer to see if the user has forced this setting or - * has let the software do the detection. - */ - - if ((e1000_ReportTxEarly == 0) || (e1000_ReportTxEarly == 1)) - Adapter->ReportTxEarly = e1000_ReportTxEarly; /* User setting */ - else { /* let the software setect the chipset */ - if(Adapter->MacType < MAC_LIVENGOOD) { - if (DetectKnownChipset(Adapter) == B_TRUE) - Adapter->ReportTxEarly = 1; /* Set the RS bit */ - else - Adapter->ReportTxEarly = 0; /* Set the RPS bit */ - } else - Adapter->ReportTxEarly = 1; - } - - - Adapter->FlowControl = e1000_flow_ctrl; - Adapter->RxPciPriority = e1000_rxpci_priority; - - /* Do the adapter initialization */ - if (!InitializeHardware(Adapter)) { - printk("InitializeHardware Failed\n"); - return (1); - } - - /* all initialization done, mark board as present */ - bdp->flags = BOARD_PRESENT; - - CheckForLink(Adapter); - if(E1000_READ_REG(Status) & E1000_STATUS_LU) { - Adapter->LinkIsActive = TRUE; - GetSpeedAndDuplex(Adapter, &LineSpeed, &FullDuplex); - Adapter->cur_line_speed = (uint32_t) LineSpeed; - Adapter->FullDuplex = (uint32_t) FullDuplex; -#ifdef IANS - Adapter->ans_link = IANS_STATUS_LINK_OK; - Adapter->ans_speed = (uint32_t) LineSpeed; - Adapter->ans_duplex = FullDuplex == FULL_DUPLEX ? - BD_ANS_DUPLEX_FULL : BD_ANS_DUPLEX_HALF; -#endif - } else { - Adapter->LinkIsActive = FALSE; - Adapter->cur_line_speed = 0; - Adapter->FullDuplex = 0; -#ifdef IANS - Adapter->ans_link = IANS_STATUS_LINK_FAIL; - Adapter->ans_speed = 0; - Adapter->ans_duplex = 0; -#endif - } - - if (e1000_debug_level >= 1) - printk("e1000_init: end\n"); - - return (0); -} - -static int -e1000_runtime_init(bd_config_t * bdp) -{ - PADAPTER_STRUCT Adapter; - device_t *dev; - - if (e1000_debug_level >= 1) - printk("e1000_init()\n"); - - dev = bdp->device; - - Adapter = (PADAPTER_STRUCT) bdp->bddp; /* Setup Shared Memory Structures */ - - /* Make sure RxBufferLen is set to something */ - if (Adapter->RxBufferLen == 0) { - Adapter->RxBufferLen = E1000_RXBUFFER_2048; - Adapter->LongPacket = FALSE; - } - - if (!e1000_sw_init(bdp)) { - /* Board is disabled because all memory structures - * could not be allocated - */ - printk - ("%s - Could not allocate the software mem structures\n", - e1000_driver); - bdp->flags = BOARD_DISABLED; - return (1); - } - - /* Setup and initialize the transmit structures. */ - SetupTransmitStructures(Adapter, B_TRUE); - - /* Setup and initialize the receive structures -- we can receive packets - * off of the wire - */ - SetupReceiveStructures(bdp, TRUE, TRUE); - - return 0; -} - -/**************************************************************************** -* Name: e1000_set_mac -* -* Description: This routine sets the ethernet address of the board -* -* Author: IntelCorporation -* -* Born on Date: 07/11/99 -* -* Arguments: -* bdp - Ptr to this card's bd_config_t structure -* eaddrp - Ptr to the new ethernet address -* -* Returns: -* 1 - If successful -* 0 - If not successful -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static int -e1000_set_mac(device_t * dev, void *p) -{ - - bd_config_t *bdp; - uint32_t HwLowAddress = 0; - uint32_t HwHighAddress = 0; - uint32_t RctlRegValue; - uint16_t PciCommandWord; - PADAPTER_STRUCT Adapter; - uint32_t IntMask; - - struct sockaddr *addr = p; - - if (e1000_debug_level >= 1) - printk("set_eaddr()\n"); - - bdp = dev->priv; - Adapter = bdp->bddp; - - RctlRegValue = E1000_READ_REG(Rctl); - - /* - * setup the MAC address by writing to RAR0 - */ - - if (Adapter->MacType == MAC_WISEMAN_2_0) { - - /* if MWI was enabled then dis able it before issueing the receive - * reset to the hardware. - */ - if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { - PciCommandWord = - Adapter->PciCommandWord & ~CMD_MEM_WRT_INVALIDATE; - - WritePciConfigWord(PCI_COMMAND_REGISTER, &PciCommandWord); - } - - /* reset receiver */ - E1000_WRITE_REG(Rctl, E1000_RCTL_RST); - - DelayInMilliseconds(5); /* Allow receiver time to go in to reset */ - } - - memcpy(Adapter->CurrentNetAddress, addr->sa_data, DL_MAC_ADDR_LEN); - - /****************************************************************** - ** Setup the receive address (individual/node/network address). - ******************************************************************/ - - if (e1000_debug_level >= 2) - printk("Programming IA into RAR[0]\n"); - - HwLowAddress = (Adapter->CurrentNetAddress[0] | - (Adapter->CurrentNetAddress[1] << 8) | - (Adapter->CurrentNetAddress[2] << 16) | - (Adapter->CurrentNetAddress[3] << 24)); - - HwHighAddress = (Adapter->CurrentNetAddress[4] | - (Adapter->CurrentNetAddress[5] << 8) | E1000_RAH_AV); - - E1000_WRITE_REG(Rar[0].Low, HwLowAddress); - E1000_WRITE_REG(Rar[0].High, HwHighAddress); - - memcpy(bdp->eaddr.bytes, addr->sa_data, DL_MAC_ADDR_LEN); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - - if (Adapter->MacType == MAC_WISEMAN_2_0) { - - /****************************************************************** - ** Take the receiver out of reset. - ******************************************************************/ - - E1000_WRITE_REG(Rctl, 0); - - DelayInMilliseconds(1); - - /* if MWI was enabled then reenable it after issueing the global - * or receive reset to the hardware. - */ - - if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { - WritePciConfigWord(PCI_COMMAND_REGISTER, - &Adapter->PciCommandWord); - } - - IntMask = E1000_READ_REG(Ims); - e1000DisableInterrupt(Adapter); - - /* Enable receiver */ - SetupReceiveStructures(bdp, FALSE, FALSE); - - E1000_WRITE_REG(Ims, IntMask); - /* e1000EnableInterrupt( Adapter ); */ - } - - return (0); -} - - -/**************************************************************************** -* Name: e1000_print_brd_conf -* -* Description: This routine printd the board configuration. -* -* Author: IntelCorporation -* -* Born on Date: 7/24/97 -* -* Arguments: -* bdp - Ptr to this card's DL_bdconfig structure -* -* Returns: -* NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static void -e1000_print_brd_conf(bd_config_t * bdp) -{ - - PADAPTER_STRUCT Adapter = (PADAPTER_STRUCT) bdp->bddp; - - if(Adapter->LinkIsActive == TRUE) - printk("%s: Mem:0x%p IRQ:%d Speed:%ld Mbps Dx:%s\n\n", - bdp->device->name, (void *) bdp->mem_start, - bdp->irq_level, Adapter->cur_line_speed, - Adapter->FullDuplex == FULL_DUPLEX ? "Full" : "Half"); - else - printk("%s: Mem:0x%p IRQ:%d Speed:N/A Dx:N/A\n\n", - bdp->device->name, (void *) bdp->mem_start, bdp->irq_level); -} - -/***************************************************************************** -* Name: SetupTransmitStructures -* -* Description: This routine initializes all of the transmit related -* structures. This includes the Transmit descriptors -* and the TX_SW_PACKETs structures. -* -* NOTE -- The device must have been reset before this routine -* is called. -* -* Author: IntelCorporation -* -* Born on Date: 6/14/97 -* -* Arguments: -* Adapter - A pointer to our context sensitive "Adapter" structure. -* DebugPrint - print debug or not. ( not used in this driver ) -* -* -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ - -static void -SetupTransmitStructures(PADAPTER_STRUCT Adapter, boolean_t DebugPrint) -{ - - PTX_SW_PACKET TxSwPacketPtr; - UINT i; - - if (e1000_debug_level >= 1) - printk("SetupTransmitStructures\n"); - - /* - * Initialize the Free TX_SW_PACKET list, the used TX_SW_PACKET list. - * Initialization involves mainly setting the - * head and tail pointers of these lists to NULL - */ - QUEUE_INIT_LIST(&Adapter->FreeSwTxPacketList); - QUEUE_INIT_LIST(&Adapter->UsedSwTxPacketList); - - /********************************************************************** - * Setup TxSwPackets - **********************************************************************/ - - /* - * The transmit algorithm parameters like the append size - * and copy size which are used for the transmit algorithm and - * are configurable. - */ - Adapter->TxIntDelay = e1000_txint_delay; - - /* Setup the initial pointers to the TxSwPacket data space */ - TxSwPacketPtr = Adapter->e1000_TxSwPacketPtrArea; - - /* - * Setup the linked list of the TX_SW_PACKETS - */ - for (i = 0; i < Adapter->NumTxDescriptors; i++, TxSwPacketPtr++) { - - /* Initialize this TX_SW_PACKET area to zeros */ - memset((PVOID) TxSwPacketPtr, 0, sizeof(TX_SW_PACKET)); - - /* Add this TX_SW_PACKET to the free list */ - QUEUE_PUSH_TAIL(&Adapter->FreeSwTxPacketList, - &TxSwPacketPtr->Link); - } - - /************************************************** - * Setup TX Descriptors - ***************************************************/ - - /* Initialize all of the Tx descriptors to zeros */ - memset((PVOID) Adapter->FirstTxDescriptor, 0, - (sizeof(E1000_TRANSMIT_DESCRIPTOR)) * - Adapter->NumTxDescriptors); - - /* Setup TX descriptor pointers */ - Adapter->NextAvailTxDescriptor = Adapter->FirstTxDescriptor; - Adapter->OldestUsedTxDescriptor = Adapter->FirstTxDescriptor; - - /* Reset the number of descriptors that are available */ - Adapter->NumTxDescriptorsAvail = Adapter->NumTxDescriptors; - - /* Setup the Transmit Control Register (TCTL). */ - if (Adapter->FullDuplex) { - E1000_WRITE_REG(Tctl, (E1000_TCTL_PSP | E1000_TCTL_EN | - (E1000_COLLISION_THRESHOLD << - E1000_CT_SHIFT) | - (E1000_FDX_COLLISION_DISTANCE << - E1000_COLD_SHIFT))); - } else { - E1000_WRITE_REG(Tctl, (E1000_TCTL_PSP | E1000_TCTL_EN | - (E1000_COLLISION_THRESHOLD << - E1000_CT_SHIFT) | - (E1000_HDX_COLLISION_DISTANCE << - E1000_COLD_SHIFT))); - } - - /*********************************************************** - * Setup Hardware TX Registers - ************************************************************/ - - /* Setup HW Base and Length of Tx descriptor area */ - E1000_WRITE_REG(Tdbal, - virt_to_bus((void *) Adapter->FirstTxDescriptor)); - E1000_WRITE_REG(Tdbah, 0); - - E1000_WRITE_REG(Tdl, (Adapter->NumTxDescriptors * - sizeof(E1000_TRANSMIT_DESCRIPTOR))); - - /* Setup our HW Tx Head & Tail descriptor pointers */ - E1000_WRITE_REG(Tdh, 0); - E1000_WRITE_REG(Tdt, 0); - - - /* Zero out the Tx Queue State registers -- we don't use this mechanism. */ - if (Adapter->MacType < MAC_LIVENGOOD) { - E1000_WRITE_REG(Tqsal, 0); - E1000_WRITE_REG(Tqsah, 0); - } - /* Set the Transmit IPG register with default values. - * Three values are used to determine when we transmit a packet on the - * wire: IPGT, IPGR1, & IPGR2. IPGR1 & IPGR2 have no meaning in full - * duplex. Due to the state machine implimentation all values are - * effectivly 2 higher i.e. a setting of 10 causes the hardware to - * behave is if it were set to 1 - * 2. These settigs are in "byte times". For example, an IPGT setting - * of 10 plus the state machine delay of 2 is 12 byte time = 96 bit - * times. - */ - - /* Set the Transmit IPG register with default values. */ - switch (Adapter->MacType) { - case MAC_LIVENGOOD: - if(Adapter->MediaType == MEDIA_TYPE_FIBER) { - E1000_WRITE_REG(Tipg, DEFAULT_LVGD_TIPG_IPGT_FIBER | - (DEFAULT_LVGD_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT) | - (DEFAULT_LVGD_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT)); - } else { - E1000_WRITE_REG(Tipg, DEFAULT_LVGD_TIPG_IPGT_COPPER | - (DEFAULT_LVGD_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT) | - (DEFAULT_LVGD_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT)); - } - break; - case MAC_WISEMAN_2_0: - case MAC_WISEMAN_2_1: - default: - E1000_WRITE_REG(Tipg, DEFAULT_WSMN_TIPG_IPGT | - (DEFAULT_WSMN_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT) | - (DEFAULT_WSMN_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT)); - break; - } - /* - * Set the Transmit Interrupt Delay register with the vaule for the - * transmit interrupt delay - */ - E1000_WRITE_REG(Tidv, Adapter->TxIntDelay); -} - -/***************************************************************************** -* Name: SetupReceiveStructures -* -* Description: This routine initializes all of the receive related -* structures. This includes the receive descriptors, the -* actual receive buffers, and the RX_SW_PACKET software structures. -* -* NOTE -- The device must have been reset before this routine -* is called. -* -* Author: IntelCorporation -* -* Born on Date: 6/27/97 -* -* Arguments: -* Adapter - A pointer to our context sensitive "Adapter" structure. -* -* DebugPrint - A variable that indicates whether a "debug" version of -* the driver should print debug strings to the terminal. -* -* flag - indicates if the driver should indicate link -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ -static int -SetupReceiveStructures(bd_config_t *bdp, boolean_t DebugPrint, - boolean_t flag) -{ - PRX_SW_PACKET RxSwPacket; - PE1000_RECEIVE_DESCRIPTOR RxDescriptorPtr; - UINT i; - PADAPTER_STRUCT Adapter = bdp->bddp; - uint32_t RegRctl = 0; - - if (e1000_debug_level >= 1) - printk("SetupReceiveStructures\n"); - - /* Init the list of "Receive Buffer Pointers" */ - QUEUE_INIT_LIST(&Adapter->RxSwPacketList); - - /* - * Set the value of the maximum number of packets that will be processed - * in the interrupt context from the file space.c - */ - Adapter->MaxNumReceivePackets = RxDescriptors[Adapter->bd_number];; - - /* - * Set the Receive interrupt delay and also the maximum number of times - * the transmit and receive interrupt are going to be processed from the - * space.c file - */ - Adapter->RxIntDelay = e1000_rxint_delay; - Adapter->MaxDpcCount = e1000_maxdpc_count; - - /* Setup the initial pointer to the first "RX_SW_PACKET" */ - RxSwPacket = (PRX_SW_PACKET) Adapter->RxSwPacketPointerArea; - - /* Initialize all of the Rx descriptors to zeros */ - memset((PVOID) Adapter->FirstRxDescriptor, 0, - (sizeof(E1000_RECEIVE_DESCRIPTOR)) * Adapter->NumRxDescriptors); - - /* Go through and set up each RX_SW_PACKET. Since each RX_SW_PACKET already - * has it virtual and physical address fields filled in (this was done - * in e1000_sw_init), all we really need to do, is build our - * "RxSwPacketList". Also, we need to go through and initialize/setup - * each Receive Descriptor. - */ - - for (i = 0, RxDescriptorPtr = Adapter->FirstRxDescriptor; - i < Adapter->NumRxDescriptors; - i++, RxSwPacket++, RxDescriptorPtr++) { - - if (RxSwPacket->skb == NULL) - printk - ("SetupReceiveStructures rcv buffer memory not allocated"); - else { - RxDescriptorPtr->BufferAddress = 0; - RxDescriptorPtr->BufferAddress += - virt_to_bus(RxSwPacket->VirtualAddress); - /* Add this RX_SW_PACKET to the list of RX_SW_PACKETs */ - QUEUE_PUSH_TAIL(&Adapter->RxSwPacketList, &RxSwPacket->Link); - } - } - - - /* Setup our descriptor pointers */ - Adapter->NextRxDescriptorToCheck = Adapter->FirstRxDescriptor; - - /* - * Set up all the RCTL fields - */ - E1000_WRITE_REG(Rctl, 0); - - E1000_WRITE_REG(Rdtr0, (Adapter->RxIntDelay | E1000_RDT0_FPDB)); - - /* Setup HW Base and Length of Rx descriptor area */ - E1000_WRITE_REG(Rdbal0, - virt_to_bus((void *) Adapter->FirstRxDescriptor)); - E1000_WRITE_REG(Rdbah0, 0); - - E1000_WRITE_REG(Rdlen0, (Adapter->NumRxDescriptors * - sizeof(E1000_RECEIVE_DESCRIPTOR))); - - /* Setup our HW Rx Head & Tail descriptor pointers */ - E1000_WRITE_REG(Rdh0, 0); - E1000_WRITE_REG(Rdt0, - (((unsigned long) Adapter->LastRxDescriptor - - (unsigned long) Adapter->FirstRxDescriptor) >> 4)); - - /* Zero out the registers associated with the second receive descriptor - * ring, because we don't use that ring. - */ - if (Adapter->MacType < MAC_LIVENGOOD) { - E1000_WRITE_REG(Rdbal1, 0); - E1000_WRITE_REG(Rdbah1, 0); - E1000_WRITE_REG(Rdlen1, 0); - E1000_WRITE_REG(Rdh1, 0); - E1000_WRITE_REG(Rdt1, 0); - } - /* Setup the Receive Control Register (RCTL), and ENABLE the receiver. - * The initial configuration is to: Enable the receiver, accept - * broadcasts, discard bad packets (and long packets), disable VLAN filter - * checking, set the receive descriptor minimum threshold size to 1/2, - * and the receive buffer size to 2k. */ - - RegRctl = E1000_RCTL_EN | /* Enable Receive Unit */ - E1000_RCTL_BAM | /* Accept Broadcast Packets */ - (Adapter->MulticastFilterType << E1000_RCTL_MO_SHIFT) | - E1000_RCTL_RDMTS0_HALF | - E1000_RCTL_LBM_NO; /* Loopback Mode = none */ - - switch (Adapter->RxBufferLen) { - case E1000_RXBUFFER_2048: - default: - RegRctl |= E1000_RCTL_SZ_2048; - break; - case E1000_RXBUFFER_4096: - RegRctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case E1000_RXBUFFER_8192: - RegRctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case E1000_RXBUFFER_16384: - RegRctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - } - - if(SBP[Adapter->bd_number] > 0) { - RegRctl |= E1000_RCTL_SBP; - } - E1000_WRITE_REG(Rctl, RegRctl); - - /* - * Check and report the status of the link - */ - if (!(E1000_READ_REG(Status) & E1000_STATUS_LU) && (flag == TRUE)) - printk("e1000: %s Link is Down\n", bdp->device->name); - - Adapter->DoRxResetFlag = B_FALSE; - - return (0); -} - -/***************************************************************************** -* Name: UpdateStatsCounters -* -* Description: This routine will dump and reset the E10001000's internal -* Statistics counters. The current stats dump values will be -* added to the "Adapter's" overall statistics. -* -* Author: IntelCorporation -* -* Born on Date: 6/13/97 -* -* Arguments: -* Adapter - A pointer to our context sensitive "Adapter" structure. -* -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ - -static VOID -UpdateStatsCounters(bd_config_t * bdp) -{ - - PADAPTER_STRUCT Adapter; - net_device_stats_t *stats; - - Adapter = bdp->bddp; - stats = &bdp->net_stats; - - /* Add the values from the chip's statistics registers to the total values - * that we keep in software. These registers clear on read. - */ - Adapter->RcvCrcErrors += E1000_READ_REG(Crcerrs); - Adapter->RcvSymbolErrors += E1000_READ_REG(Symerrs); - Adapter->RcvMissedPacketsErrors += E1000_READ_REG(Mpc); - Adapter->DeferCount += E1000_READ_REG(Dc); - Adapter->RcvSequenceErrors += E1000_READ_REG(Sec); - Adapter->RcvLengthErrors += E1000_READ_REG(Rlec); - Adapter->RcvXonFrame += E1000_READ_REG(Xonrxc); - Adapter->TxXonFrame += E1000_READ_REG(Xontxc); - Adapter->RcvXoffFrame += E1000_READ_REG(Xoffrxc); - Adapter->TxXoffFrame += E1000_READ_REG(Xofftxc); - Adapter->Rcv64 += E1000_READ_REG(Prc64); - Adapter->Rcv65 += E1000_READ_REG(Prc127); - Adapter->Rcv128 += E1000_READ_REG(Prc255); - Adapter->Rcv256 += E1000_READ_REG(Prc511); - Adapter->Rcv512 += E1000_READ_REG(Prc1023); - Adapter->Rcv1024 += E1000_READ_REG(Prc1522); - Adapter->GoodReceives += E1000_READ_REG(Gprc); - Adapter->RcvBroadcastPkts += E1000_READ_REG(Bprc); - Adapter->RcvMulticastPkts += E1000_READ_REG(Mprc); - Adapter->GoodTransmits += E1000_READ_REG(Gptc); - Adapter->Rnbc += E1000_READ_REG(Rnbc); - Adapter->RcvUndersizeCnt += E1000_READ_REG(Ruc); - Adapter->RcvFragment += E1000_READ_REG(Rfc); - Adapter->RcvOversizeCnt += E1000_READ_REG(Roc); - Adapter->RcvJabberCnt += E1000_READ_REG(Rjc); - Adapter->TotPktRcv += E1000_READ_REG(Tpr); - Adapter->TotPktTransmit += E1000_READ_REG(Tpt); - Adapter->TrsPkt64 += E1000_READ_REG(Ptc64); - Adapter->TrsPkt65 += E1000_READ_REG(Ptc127); - Adapter->TrsPkt128 += E1000_READ_REG(Ptc255); - Adapter->TrsPkt256 += E1000_READ_REG(Ptc511); - Adapter->TrsPkt512 += E1000_READ_REG(Ptc1023); - Adapter->TrsPkt1024 += E1000_READ_REG(Ptc1522); - Adapter->TrsMulticastPkt += E1000_READ_REG(Mptc); - Adapter->TrsBroadcastPkt += E1000_READ_REG(Bptc); - Adapter->TxAbortExcessCollisions += E1000_READ_REG(Ecol); - Adapter->TxLateCollisions += E1000_READ_REG(Latecol); - Adapter->TotalCollisions += E1000_READ_REG(Colc); - Adapter->SingleCollisions += E1000_READ_REG(Scc); - Adapter->MultiCollisions += E1000_READ_REG(Mcc); - Adapter->FCUnsupported += E1000_READ_REG(Fcruc); - - /* The byte count registers are 64-bits, to reduce the chance of overflow - * The entire 64-bit register clears when the high 32-bits are read, so the - * lower half must be read first - */ - Adapter->RcvGoodOct += E1000_READ_REG(Gorl); - Adapter->RcvGoodOct += ((uint64_t) E1000_READ_REG(Gorh) << 32); - Adapter->TrsGoodOct += E1000_READ_REG(Gotl); - Adapter->TrsGoodOct += ((uint64_t) E1000_READ_REG(Goth) << 32); - Adapter->RcvTotalOct += E1000_READ_REG(Torl); - Adapter->RcvTotalOct += ((uint64_t) E1000_READ_REG(Torh) << 32); - Adapter->TrsTotalOct += E1000_READ_REG(Totl); - Adapter->TrsTotalOct += ((uint64_t) E1000_READ_REG(Toth) << 32); - - /* New statistics registers in the 82543 */ - if (Adapter->MacType >= MAC_LIVENGOOD) { - Adapter->AlignmentErrors += E1000_READ_REG(Algnerrc); - Adapter->TotalRcvErrors += E1000_READ_REG(Rxerrc); - Adapter->TrsUnderRun += E1000_READ_REG(Tuc); - Adapter->TrsNoCRS += E1000_READ_REG(Tncrs); - Adapter->CarrierExtErrors += E1000_READ_REG(Cexterr); - Adapter->RcvDMATooEarly += E1000_READ_REG(Rutec); - } - - /* Fill out the OS statistics structure */ - stats->rx_packets = Adapter->GoodReceives; /* total pkts received */ - stats->tx_packets = Adapter->GoodTransmits; /* total pkts transmitted */ - stats->rx_bytes = Adapter->RcvGoodOct; /* total bytes reveived */ - stats->tx_bytes = Adapter->TrsGoodOct; /* total bytes transmitted */ - stats->multicast = Adapter->RcvMulticastPkts; /* multicast pkts received */ - stats->collisions = Adapter->TotalCollisions; /* total collision count */ - /* Rx Errors */ - stats->rx_errors = Adapter->TotalRcvErrors + Adapter->RcvCrcErrors + - Adapter->AlignmentErrors + - Adapter->RcvLengthErrors + - Adapter->Rnbc + Adapter->RcvMissedPacketsErrors + - Adapter->CarrierExtErrors; - stats->rx_dropped = Adapter->Rnbc; - stats->rx_length_errors = Adapter->RcvLengthErrors; - stats->rx_crc_errors = Adapter->RcvCrcErrors; - stats->rx_frame_errors = Adapter->AlignmentErrors; - stats->rx_fifo_errors = Adapter->RcvMissedPacketsErrors; - stats->rx_missed_errors = Adapter->RcvMissedPacketsErrors; - /* Tx Errors */ - stats->tx_errors = Adapter->TxAbortExcessCollisions + - Adapter->TrsUnderRun + - Adapter->TxLateCollisions; - stats->tx_aborted_errors = Adapter->TxAbortExcessCollisions; - stats->tx_fifo_errors = Adapter->TrsUnderRun; - stats->tx_window_errors = Adapter->TxLateCollisions; - /* Tx Dropped needs to be maintained elsewhere */ -} - -/**************************************************************************** -* -* Name: ReadNodeAddress -* -* Description: Gets the node/Ethernet/Individual Address for this NIC -* from the EEPROM. -* -* Example EEPROM map: -* Word 0 = AA00 -* Word 1 = 1100 -* Word 2 = 3322 -* -* Author: IntelCorporation -* -* Born on Date: 3/30/98 -* -* Arguments: -* Adapter Ptr to this card's adapter data structure -* -* Returns: -* Status RET_STATUS_SUCCESS = read valid address -* RET_STATUS_FAILURE = unable to read address -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -***************************************************************************/ -static int -ReadNodeAddress(IN PADAPTER_STRUCT Adapter, OUT PUCHAR NodeAddress) -{ - UINT i; - USHORT EepromWordValue; - - DL_LOG(strlog(DL_ID, 0, 3, SL_TRACE, "ReadNodeAddress")); - - /* Read our node address from the EEPROM. */ - for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { - /* Get word i from EEPROM */ - EepromWordValue = ReadEepromWord(IN Adapter, IN(USHORT) - - (EEPROM_NODE_ADDRESS_BYTE_0 - + (i / 2))); - - /* Save byte i */ - NodeAddress[i] = (UCHAR) EepromWordValue; - - /* Save byte i+1 */ - NodeAddress[i + 1] = (UCHAR) (EepromWordValue >> 8); - } - - - /* Our IA should not have the Multicast bit set */ - if (NodeAddress[0] & 0x1) { - return (RET_STATUS_FAILURE); - } - - memcpy(&Adapter->CurrentNetAddress[0], - &Adapter->perm_node_address[0], DL_MAC_ADDR_LEN); - return (RET_STATUS_SUCCESS); - -} - -/***************************************************************************** -* Name: e1000_set_promisc -* -* Description: This routine sets the promiscous mode for receiving packets -* that it is passed. -* -* Author: IntelCorporation -* -* Born on Date: 7/7/97 -* -* Arguments: -* bd_config_t - board struct -* flag - turn it on( B_TRUE ) or off ( B_FALSE ) -* -* Returns: -* B_FALSE - if successful -* B_TRUE - if not -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ -static int -e1000_set_promisc(bd_config_t * bdp, int flag) -{ - uint32_t RctlRegValue; - uint32_t TempRctlReg; - uint32_t NewRctlReg; - PADAPTER_STRUCT Adapter; - - Adapter = (PADAPTER_STRUCT) bdp->bddp; - - /* - * Save the original value in the RCTL register - */ - RctlRegValue = E1000_READ_REG(Rctl); - TempRctlReg = RctlRegValue; - - - if (e1000_debug_level >= 1) - printk("e1000_set_promiscuous, SOR"); - - /* Check to see if we should set/clear the "Unicast Promiscuous" bit. */ - if (flag == B_TRUE) { - /* - * Since the promiscuous flag is set to TRUE, set both the unicast as - * well as the multicast promiscuous mode on the RCTL - */ - TempRctlReg |= (E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM); - E1000_WRITE_REG(Rctl, TempRctlReg); - if (e1000_debug_level >= 1) - printk("Promiscuous mode ON"); - } else { - /* - * Turn off both the unicast as well as the multicast promiscuous mode - */ - TempRctlReg &= (~E1000_RCTL_UPE); - TempRctlReg &= (~E1000_RCTL_MPE); - E1000_WRITE_REG(Rctl, TempRctlReg); - if (e1000_debug_level >= 1) - printk("Promiscuous mode OFF"); - } - - - /* Write the new filter back to the adapter, if it has changed */ - if (TempRctlReg != RctlRegValue) { - E1000_WRITE_REG(Rctl, TempRctlReg); - } - - NewRctlReg = E1000_READ_REG(Rctl); - - if (NewRctlReg != TempRctlReg) - return (B_FALSE); - else - return (B_TRUE); -} - -/***************************************************************************** -* Name: e1000DisableInterrupt -* -* Description: This routine disables (masks) all interrupts on our adapter. -* -* Author: IntelCorporation -* -* Born on Date: 8/25/97 -* -* Arguments: -* pointer to our "Adapter" structure. -* -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ - -static void -e1000DisableInterrupt(PADAPTER_STRUCT Adapter) -{ - if (e1000_debug_level >= 1) - printk("DisableInterrupts: SOR\n"); - - /* - * Mask all adapter interrupts. - */ - E1000_WRITE_REG(Imc, (0xffffffff & ~E1000_IMC_RXSEQ)); - -} - - -/***************************************************************************** -* Name: e1000EnableInterrupt -* -* Description: This routine enables (un-masks) all interrupts on our adapter. -* -* Author: IntelCorporation -* -* Born on Date: 8/25/97 -* -* Arguments: -* pointer to our "Adapter" structure. -* -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ - -static void -e1000EnableInterrupt(PADAPTER_STRUCT Adapter) -{ - if (e1000_debug_level >= 1) - printk("EnableInterrupts: SOR\n"); - - /* Enable interrupts (SBL -- may want to enable different int bits..) */ - E1000_WRITE_REG(Ims, IMS_ENABLE_MASK); -} - -/***************************************************************************** -* Name: e1000_intr -* -* Description: This routine is the ISR for the e1000 board. It services -* the RX & TX queues & starts the RU if it has stopped due -* to no resources. -* -* Author: IntelCorporation -* -* Born on Date: 8/25/97 -* -* Arguments: -* ivec - The interrupt vector for this board. -* -* Returns: -* (none) -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ - -static void -e1000_intr(int irq, void *dev_inst, struct pt_regs *regs) -{ - /* note - regs is not used but required by the system */ - uint32_t IcrContents; - PADAPTER_STRUCT Adapter; - uint32_t CtrlRegValue, TxcwRegValue, RxcwRegValue; - UINT DpcCount; - device_t *dev; - bd_config_t *bdp; - - dev = (device_t *) dev_inst; - bdp = dev->priv; - Adapter = (PADAPTER_STRUCT) bdp->bddp; - - if (e1000_debug_level >= 1) - printk("e1000_intr: bdp = 0x%p\n ", bdp); - - if (!Adapter) - return; - - /* - * The board is present but not yet initialized. Since the board is not - * initialized we do not process the interrupt - */ - if (!bdp->flags || (bdp->flags & BOARD_DISABLED)) { - return; - } - - - /* get board status */ - if ((IcrContents = E1000_READ_REG(Icr))) { - - /* This card actually has interrupts to process */ - - /* Disable Interrupts from this card */ - e1000DisableInterrupt(Adapter); - - /* - * The Receive Sequence errors RXSEQ and the link status change LSC - * are checked to detect that the cable has been pulled out. For - * the 82542 silicon, the receive sequence errors interrupt - * are an indication that cable is not connected. If there are - * sequence errors or if link status has changed, proceed to the - * cable disconnect workaround - */ - - if (IcrContents & (E1000_ICR_RXSEQ|E1000_ICR_LSC|E1000_ICR_GPI_EN1)) { - Adapter->GetLinkStatus = - Adapter->LinkStatusChanged = TRUE; - /* run the watchdog ASAP */ - mod_timer(&bdp->timer_id, jiffies); - } - if(IcrContents & E1000_ICR_GPI_EN1) { - ReadPhyRegister(Adapter, PXN_INT_STATUS_REG, Adapter->PhyAddress); - } - if(Adapter->LinkStatusChanged && - Adapter->MediaType == MEDIA_TYPE_FIBER) { - CtrlRegValue = E1000_READ_REG(Ctrl); - TxcwRegValue = E1000_READ_REG(Txcw); - RxcwRegValue = E1000_READ_REG(Rxcw); - if((CtrlRegValue & E1000_CTRL_SWDPIN1) || - ((RxcwRegValue & E1000_RXCW_C) && - (TxcwRegValue & E1000_TXCW_ANE))) { - - E1000_WRITE_REG(Txcw, Adapter->TxcwRegValue); - E1000_WRITE_REG(Ctrl, CtrlRegValue & ~E1000_CTRL_SLU); - Adapter->AutoNegFailed = 0; - } - Adapter->LinkStatusChanged = FALSE; - } - if(Adapter->LinkStatusChanged && - Adapter->MediaType == MEDIA_TYPE_COPPER) { - CheckForLink(Adapter); - } - - DpcCount = Adapter->MaxDpcCount; - - /* - * Since we are already in the interrupt context, we want to clean up - * as many transmit and receive packets that have been processed by - * E1000 since taking interrupts is expensive. We keep a count called - * the DpcCount which is the maximum number of times that we will try - * to clean up interrupts from within this interrupt context. If the - * count is too high, it can lead to interrupt starvation - */ - while (DpcCount) { - /* Process the receive interrupts to clean receive descriptors */ - if (e1000_debug_level >= 3) - printk("intr: DpcCount = 0x%x\n ", DpcCount); - - ProcessReceiveInterrupts(bdp); - - /* - * Process and clean up transmit interrupts - */ - ProcessTransmitInterrupts(bdp); - - DpcCount--; - - if (DpcCount) { - if (!(E1000_READ_REG(Icr))) { - break; - } - } - } - - /* Enable Interrupts */ - e1000EnableInterrupt(Adapter); - - - /* - * If there are any frames that have been queued, they are also - * Processed from this context. ??? We need to verify if there is - * any benefit of doing this - */ - } - return; -} - -/**************************************************************************** -* Name: ProcessTransmitInterrupts -* -* Description: This routine services the TX queues. It reclaims the -* TCB's & TBD's & other resources used during the transmit -* of this buffer. It is called from the ISR. -* -* Author: IntelCorporation -* -* Born on Date: 8/7/97 -* -* Arguments: -* bdp - Ptr to this card's DL_bdconfig structure -* -* Returns: -* NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ - -static void -ProcessTransmitInterrupts(bd_config_t * bdp) -{ - PTX_SW_PACKET TxSwPacket; - PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; - - PADAPTER_STRUCT Adapter; - UINT NumTxSwPacketsCleaned = 0; - device_t *dev; - int lock_flag_tx; - - - if (e1000_debug_level >= 3) - printk("ProcessTransmitInterrupts, SOR\n"); - - Adapter = (PADAPTER_STRUCT) bdp->bddp; - dev = bdp->device; - - spin_lock_irqsave(&Adapter->bd_tx_lock, lock_flag_tx); - - /* This function will examine each TxSwPacket in the 'used' queue - * if the E1000 is done with it then the associated resources - * (Tx Descriptors and Map Registers) - * will be "freed" and the TxSwPacket will be returned to the 'free' - * queue. - */ - - - for (TxSwPacket = - (PTX_SW_PACKET) QUEUE_GET_HEAD(&Adapter->UsedSwTxPacketList); - /* While there are still TxSwPackets in the used queue check them */ - TxSwPacket; - /* Look at the next TxSwPacket in the USED queue */ - TxSwPacket = - (PTX_SW_PACKET) QUEUE_GET_HEAD(&Adapter->UsedSwTxPacketList)) { - - if (e1000_debug_level >= 3) - printk("Examining TxSwPacket 0x%p\n", TxSwPacket); - - /* Get hold of the next descriptor that the E1000 will report status - * back to (this will be the last descriptor of a given TxSwPacket). - * We only want to free the TxSwPacket (and it resources) if the E1000 - * is done with ALL of the descriptors. If the E1000 is done with the - * last one then it is done with all of them. - */ - TransmitDescriptor = Adapter->OldestUsedTxDescriptor; - - /* Check for wrap case */ - if (TransmitDescriptor > Adapter->LastTxDescriptor) - TransmitDescriptor -= Adapter->NumTxDescriptors; - - if (e1000_debug_level >= 3) { - printk("First descriptor 0x%p \n", - TxSwPacket->FirstDescriptor); - printk("Last descriptor 0x%p \n", TxSwPacket->LastDescriptor); - } - - /* If the descriptor done bit is set free TxSwPacket and associated - * resources - */ - - if (TransmitDescriptor->Upper.Fields. - TransmitStatus & E1000_TXD_STAT_DD) { - /* Free descriptors used by this TxSwPacket. */ - if (TransmitDescriptor == Adapter->LastTxDescriptor) - Adapter->OldestUsedTxDescriptor = - Adapter->FirstTxDescriptor; - else - Adapter->OldestUsedTxDescriptor = (TransmitDescriptor + 1); - - - /* Make available the descriptors that were previously used */ - Adapter->NumTxDescriptorsAvail += 1; - - if (TxSwPacket->Packet) { - dev_kfree_skb_irq(TxSwPacket->Packet); - TxSwPacket->Packet = NULL; - NumTxSwPacketsCleaned++; - } - - /* Remove the TxSwPacket that we just cleaned-up from the "Used" - * list - */ - QUEUE_POP_HEAD(&Adapter->UsedSwTxPacketList); - - /* Return this "Software packet" back to the "free" list */ - QUEUE_PUSH_TAIL(&Adapter->FreeSwTxPacketList, - &TxSwPacket->Link); - - /* clear the out of resource condition */ - if (bdp->tx_out_res && netif_queue_stopped(dev)) { - bdp->tx_out_res = 0; -#ifdef IANS - if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - ans_notify(dev, IANS_IND_XMIT_QUEUE_READY); - } -#endif - netif_wake_queue(dev); - } - - } else { - - if (e1000_debug_level >= 3) - printk - ("Last descriptor 0x%p NOT complete\n", - TransmitDescriptor); - - /* Found a TxSwPacket that the E1000 is not done with - * then there is no reason to check the rest of the queue. - */ - break; - } - - } /* end for each TxSwPacket */ - - spin_unlock_irqrestore(&Adapter->bd_tx_lock, lock_flag_tx); - - if (e1000_debug_level >= 3) - printk("Freed %d TxSwPackets\n", NumTxSwPacketsCleaned); - - if (!NumTxSwPacketsCleaned && e1000_debug_level >= 3) - printk("TxSwPacket = 0x%p\n", TxSwPacket); - - return; -} - -/**************************************************************************** -* Name: e1000_set_multicast -* -* Description: This routine sets a list of multicast addresses -* as requested by the DLPI module in the 128 * 32 MTA -* vector table. It also calculates the appropriate hash -* value and sets the bit in the vector table -* -* Author: IntelCorporation -* -* Born on Date: 1/12/98 -* -* Arguments: -* dev - Ptr to this card's dev structure -* -* Returns: -* NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static void -e1000_set_multi(device_t * dev) -{ - - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - uint32_t TempRctlReg = 0; - uint32_t HwLowAddress; - uint32_t HwHighAddress; - USHORT i, j; - UINT HashValue = 0, HashReg, HashBit; - UINT TempUint; - int ret_val; - PUCHAR MulticastBuffer; - uint16_t PciCommandWord; - uint32_t IntMask; - struct dev_mc_list *mc_list; - uchar_t *mc_buff; - - - /* The data must be a multiple of the Ethernet address size. */ - - if (e1000_debug_level >= 1) - printk("e1000_set_multicast\n"); - - bdp = dev->priv; - Adapter = (PADAPTER_STRUCT) bdp->bddp; - MulticastBuffer = Adapter->pmc_buff->MulticastBuffer; - - /* check to see if promiscuous mode should be enabled */ - if ((dev->flags & IFF_PROMISC) && !(bdp->flags & PROMISCUOUS)) { - /* turn promisc mode on */ - ret_val = e1000_set_promisc(bdp, B_TRUE); - bdp->flags |= PROMISCUOUS; - } else { - /* turn promisc mode off */ - ret_val = e1000_set_promisc(bdp, B_FALSE); - bdp->flags &= ~PROMISCUOUS; - } - -#if 0 /* we should try to enable this feature... */ - /* this is how you turn on receiving ALL multicast addrs */ - if ((dev->flags & IFF_ALLMULTI) && !(bdp->flags & ALL_MULTI)) { - /* turn on recv all multi addrs */ - TempRctlReg |= E1000_RCTL_MPE; - E1000_WRITE_REG(Rctl, TempRctlReg); - bdp->flags |= ALL_MULTI; - } else { - /* turn off recv all multi addrs */ - TempRctlReg &= ~E1000_RCTL_MPE; -/* this next line with hang the load, so be careful... */ - E1000_WRITE_REG(Rctl, TempRctlReg); - bdp->flags &= ~ALL_MULTI; - } -#endif - - mc_buff = Adapter->pmc_buff->MulticastBuffer; - /* Fill in the multicast addresses. */ - for (i = 0, mc_list = dev->mc_list; i < dev->mc_count; - i++, mc_list = mc_list->next) { - memcpy(mc_buff, (u8 *) & mc_list->dmi_addr, DL_MAC_ADDR_LEN); - mc_buff += DL_MAC_ADDR_LEN; - } - /* reset the MulticastBuffer pointer */ - - /* set the count in the Adapter struct */ - Adapter->NumberOfMcAddresses = dev->mc_count; - - - /* adjust the count on addrs to bytes */ - Adapter->pmc_buff->mc_count = dev->mc_count * DL_MAC_ADDR_LEN; - - /* The E1000 has the ability to do perfect filtering of 16 addresses. - * The driver uses one of the E1000's 16 receive address registers - * for its node/network/mac/individual address. So, we have room - * for up to 15 multicast addresses in the CAM, additional MC - * addresses are handled by the MTA (Multicast Table Array) - */ - - /* this just needs to be the count of how many addrs - * there are in the table - */ - TempUint = dev->mc_count; - - - /* If we were using the MTA then it must be cleared */ - if (Adapter->NumberOfMcAddresses > E1000_RAR_ENTRIES - 1) { - for (i = 0; i < E1000_NUM_MTA_REGISTERS; i++) { - E1000_WRITE_REG(Mta[i], 0); - } - } - - /* If we are given more MC addresses than we can handle, then we'll - * notify the OS that we can't accept any more MC addresses - */ - - if (TempUint > MAX_NUM_MULTICAST_ADDRESSES) { - Adapter->NumberOfMcAddresses = MAX_NUM_MULTICAST_ADDRESSES; - } else { - /* Set the number of MC addresses that we are being requested to use */ - Adapter->NumberOfMcAddresses = TempUint; - } - - /* Store the Rctl values to use for restoring */ - TempRctlReg = E1000_READ_REG(Rctl); - - if (Adapter->MacType == MAC_WISEMAN_2_0) { - - /* if MWI was enabled then disable it before issueing the global - * reset to the hardware. - */ - if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { - PciCommandWord = - Adapter->PciCommandWord & ~CMD_MEM_WRT_INVALIDATE; - - WritePciConfigWord(PCI_COMMAND_REGISTER, &PciCommandWord); - } - - /* The E1000 must be in reset before changing any RA registers. - * Reset receive unit. The chip will remain in the reset state - * until software explicitly restarts it. - */ - E1000_WRITE_REG(Rctl, E1000_RCTL_RST); - - DelayInMilliseconds(5); /* Allow receiver time to go in to reset */ - } - - /********************************************************************** - * Copy up to 15 MC addresses into the E1000's receive address - * registers pairs (Ral Rah). The first pair (Ral0 Rah0) is used - * for our MAC/Node/Network address/IA. If there are more than 15 - * multicast addresses then the additional addresses will be hashed - * and the Multicast Table Array (MTA) will be used. - **********************************************************************/ - for (i = 0, j = 1; - (i < Adapter->NumberOfMcAddresses && j < E1000_RAR_ENTRIES); - i++, j++) { - - /* HW expcets these in big endian so we reverse the byte order */ - HwLowAddress = - (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS] | - (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS + 1] << 8) - | (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS + 2] << - 16) | - (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS + 3] << 24)); - - /* HW expcets these in big endian so we reverse the byte order */ - HwHighAddress = - (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS + 4] | - (MulticastBuffer[i * ETH_LENGTH_OF_ADDRESS + - 5] << 8) | E1000_RAH_AV); - - E1000_WRITE_REG(Rar[j].Low, HwLowAddress); - E1000_WRITE_REG(Rar[j].High, HwHighAddress); - - } - - /* if the Receive Addresses Registers are not full then - * Clear the E1000_RAH_AV bit in other Receive Address Registers - * NOTE: 'j' must be unchanged from the RAL/RAH loop - */ - - while (j < E1000_RAR_ENTRIES) { - E1000_WRITE_REG(Rar[j].Low, 0); - E1000_WRITE_REG(Rar[j].High, 0); - j++; - } - - /* hash each remaining (if any) MC address into the E1000's receive - * multicast hash table. NOTE: 'i' must be unchanged from the RAL/RAH loop - */ - - while (i < Adapter->NumberOfMcAddresses) { - - /* The portion of the address that is used for the hash table is - * determined by the MulticastFilterType setting. - */ - - switch (Adapter->MulticastFilterType) { - /* [0] [1] [2] [3] [4] [5] - * 01 AA 00 12 34 56 - * LSB MSB - According to H/W docs - */ - - case 0: /* [47:36] i.e. 0x563 for above example address */ - HashValue = - ((MulticastBuffer - [i * ETH_LENGTH_OF_ADDRESS + - 4] >> 4) | (((USHORT) MulticastBuffer[i * - ETH_LENGTH_OF_ADDRESS - + 5]) << 4)); - break; - - case 1: /* [46:35] i.e. 0xAC6 for above example address */ - HashValue = - ((MulticastBuffer - [i * ETH_LENGTH_OF_ADDRESS + - 4] >> 3) | (((USHORT) MulticastBuffer[i * - ETH_LENGTH_OF_ADDRESS - + 5]) << 5)); - break; - - case 2: /* [45:34] i.e. 0x5D8 for above example address */ - HashValue = - ((MulticastBuffer - [i * ETH_LENGTH_OF_ADDRESS + - 4] >> 2) | (((USHORT) MulticastBuffer[i * - ETH_LENGTH_OF_ADDRESS - + 5]) << 6)); - break; - - case 3: /* [43:32] i.e. 0x634 for above example address */ - HashValue = - ((MulticastBuffer - [i * ETH_LENGTH_OF_ADDRESS + 4]) | (((USHORT) - MulticastBuffer - [i * - ETH_LENGTH_OF_ADDRESS - + 5]) << 8)); - break; - - } - - /********************************************************** - * Set the corresponding bit in the Multicast Table Array. - * Mta is treated like a bit vector of 4096 bit split in - * to 128 registers of 32 bits each. The Register to set - * is in bits 11:5 of HashValue and the Bit within the - * register to set is bits 4:0. - ************************************************************/ - - /* Bit number to set is in lower 5 bits */ - HashBit = HashValue & 0x1F; - - /* MTA register number is bits 11:5 */ - HashReg = (HashValue >> 5) & 0x7F; - - /* Read MTA entry */ - TempUint = E1000_READ_REG(Mta[(HashReg)]); - - /* Set hashed bit */ - TempUint |= (1 << HashBit); - - /* Write new value */ - E1000_WRITE_REG(Mta[HashReg], TempUint); - - i++; - } - - if (Adapter->MacType == MAC_WISEMAN_2_0) { - - /* if WMI was enabled then reenable it after issueing the global - * or receive reset to the hardware. - */ - if (Adapter->PciCommandWord && CMD_MEM_WRT_INVALIDATE) { - WritePciConfigWord(PCI_COMMAND_REGISTER, - &Adapter->PciCommandWord); - } - - DelayInMilliseconds(5); - - /* Take receiver out of reset */ - E1000_WRITE_REG(Rctl, 0); - /* clear E1000_RCTL_RST bit (and all others) */ - IntMask = E1000_READ_REG(Ims); - e1000DisableInterrupt(Adapter); - - /* Enable receiver */ - SetupReceiveStructures(bdp, FALSE, FALSE); - - /* e1000EnableInterrupt( Adapter ); */ - E1000_WRITE_REG(Ims, IntMask); - - /* Restore Receive Control to state it was in prior to MC add request */ - E1000_WRITE_REG(Rctl, TempRctlReg); - } - - - return; -} - - - -/**************************************************************************** -* Name: ProcessReceiveInterrupts -* -* Description: This routine processes the RX interrupt & services the -* RX queues. For each successful RFD, it allocates a -* msg block & sends the msg upstream. The freed RFD is then -* put at the end of the free list of RFD's. -* -* Author: IntelCorporation -* -* Born on Date: 7/19/97 -* -* Arguments: -* bdp - Ptr to this card's DL_bdconfig structure -* -* Returns: -* NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ - -static void -ProcessReceiveInterrupts(bd_config_t * bdp) -{ - PADAPTER_STRUCT Adapter; - device_t *dev; - int bytes_srvcd; /* # of bytes serviced */ - sk_buff_t *skb, *new_skb; - /* Pointer to the receive descriptor being examined. */ - PE1000_RECEIVE_DESCRIPTOR CurrentDescriptor; - PE1000_RECEIVE_DESCRIPTOR LastDescriptorProcessed; - PRX_SW_PACKET RxSwPacket; - /* The amount of data received in the RBA (will be PacketSize + - * 4 for the CRC). - */ - USHORT Length; - UINT Count = 0; - BOOLEAN Status = FALSE; - net_device_stats_t *stats; - - if (e1000_debug_level >= 3) - printk("ProcessReceiveInterrupts, SOR\n"); - - Adapter = (PADAPTER_STRUCT) bdp->bddp; - dev = bdp->device; - stats = &bdp->net_stats; - - bytes_srvcd = 0; - - CurrentDescriptor = Adapter->NextRxDescriptorToCheck; - - if (!((CurrentDescriptor->ReceiveStatus) & E1000_RXD_STAT_DD)) { - if (e1000_debug_level >= 3) - printk("Proc_rx_ints: Nothing to do!\n"); - /* don't send anything up. just clear the RFD */ - return; - } - - /* Loop through the receive descriptors starting at the last known - * descriptor owned by the hardware that begins a packet. - */ - while ((CurrentDescriptor->ReceiveStatus & E1000_RXD_STAT_DD) && - (Count < Adapter->MaxNumReceivePackets)) { - - /* Get a pointer to the actual receive buffer */ - RxSwPacket = - (PRX_SW_PACKET) QUEUE_GET_HEAD(&Adapter->RxSwPacketList); - - /* Make sure this is also the last descriptor in the packet. */ - if (!(CurrentDescriptor->ReceiveStatus & E1000_RXD_STAT_EOP)) { - /* - * If the received packet has spanned multiple descriptors, ignore - * and discard all the packets that do not have EOP set and proceed - * to the next packet. - */ - printk("Receive packet consumed mult buffers\n"); - - new_skb = RxSwPacket->skb; - - } else { /* packet has EOP set - begin */ - /* - * Store the packet length. Take the CRC lenght out of the length - * calculation. - */ - Length = CurrentDescriptor->Length - CRC_LENGTH; - - /* - * Only the packets that are valid ethernet packets are processed and - * sent up the stack.Normally, hardware will discard bad packets . - */ -#ifdef IANS_BASE_VLAN_TAGGING - if ((Length <= (Adapter->LongPacket == TRUE ? MAX_JUMBO_FRAME_SIZE : - MAXIMUM_ETHERNET_PACKET_SIZE)) - && (Length >= - (bdp->iANSdata->tag_mode == IANS_BD_TAGGING_802_3AC ? - MINIMUM_ETHERNET_PACKET_SIZE - QTAG_SIZE : - MINIMUM_ETHERNET_PACKET_SIZE)) - && ((CurrentDescriptor->Errors == 0) || - (SBP[Adapter->bd_number] > 0 && - CurrentDescriptor->Errors == E1000_RXD_ERR_CE))) { -#else - if ((Length <= (Adapter->LongPacket == TRUE ? MAX_JUMBO_FRAME_SIZE : - MAXIMUM_ETHERNET_PACKET_SIZE)) - && (Length >= MINIMUM_ETHERNET_PACKET_SIZE) - && ((CurrentDescriptor->Errors == 0) || - (SBP[Adapter->bd_number] > 0 && - CurrentDescriptor->Errors == E1000_RXD_ERR_CE))) { -#endif - Status = TRUE; - - /* allocate a mesg buff to copy the msg in */ - skb = RxSwPacket->skb; - if (skb == NULL) { - printk("ProcessReceiveInterrupts found a NULL skb\n"); - - break; - } - - - if (e1000_debug_level >= 3) - printk - ("ProcRecInts: skb = 0x%p, skb_data = 0x%p, len = 0x%x\n", - skb, skb->data, skb->len); - /* - * Allocate a new receive buffer to replace the receive buffer that - * is being sent up the stack. - */ -#ifdef IANS - new_skb = alloc_skb(Adapter->RxBufferLen + BD_ANS_INFO_SIZE, - GFP_ATOMIC); -#else - new_skb = alloc_skb(Adapter->RxBufferLen + 2, GFP_ATOMIC); -#endif - if (new_skb == NULL) { - - /* - * If the allob_physreq fails, we then try to copy the received - * packet into a message block that is allocated using the call - * allocb. - */ - printk("!Proc_Rec_Ints cannot alloc_skb memory\n"); - - return; - } - -#ifdef IANS - skb_reserve(new_skb, BD_ANS_INFO_SIZE); -#else - skb_reserve(new_skb, 2); -#endif - /* - * Adjust the skb and send the received packet up the stack - */ - - /* adjust the skb internal pointers */ - /* Modifies skb->tail and skb->len */ - skb_put(skb, Length); - - /* CHECKSUM */ - /* set the checksum info */ - skb->ip_summed = CHECKSUM_NONE; - -#ifdef IANS - if(bdp->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - if(bd_ans_os_Receive(bdp, CurrentDescriptor, skb) == - BD_ANS_FAILURE) { - dev_kfree_skb_irq(skb); - } else { - /* pass the packet up the stack */ - netif_rx(skb); - } - } else { - /* set the protocol */ - skb->protocol = eth_type_trans(skb, dev); - /* pass the packet up the stack */ - netif_rx(skb); - } -#else - /* set the protocol */ - skb->protocol = eth_type_trans(skb, dev); - /* pass the packet up the stack */ - netif_rx(skb); - - if (e1000_debug_level >= 3) - printk - ("ProcRecInts: After skb_put, new_skb = 0x%p\n", - new_skb); - -#endif - } else { - printk("e1000: Bad Packet Length\n"); - skb = RxSwPacket->skb; - new_skb = skb; /* Reuse the same old skb */ - - if (e1000_debug_level >= 3) - printk("e1000: re-using same skb\n"); - - } /* packet len is good/bad if */ - } /* packet has EOP set - end */ - - /* Zero out the receive descriptors status */ - CurrentDescriptor->ReceiveStatus = 0; - - CurrentDescriptor->BufferAddress = 0; - RxSwPacket->skb = NULL; - - /* set who this is from */ - new_skb->dev = dev; - - RxSwPacket->skb = new_skb; - - if (RxSwPacket->skb == NULL) { - RxSwPacket->VirtualAddress = NULL; - CurrentDescriptor->BufferAddress = 0; - } else { - e1000_rxfree_cnt++; - - RxSwPacket->VirtualAddress = RxSwPacket->skb->tail; - CurrentDescriptor->BufferAddress = 0; - CurrentDescriptor->BufferAddress += - virt_to_bus(RxSwPacket->skb->tail); - - - if (e1000_debug_level >= 3) - printk - ("ProcRecInts: virt_addr = 0x%p, phys_addr = 0x%lx\n", - RxSwPacket->VirtualAddress, - (uintptr_t)CurrentDescriptor->BufferAddress); - } - - /* Advance our pointers to the next descriptor (checking for wrap). */ - if (CurrentDescriptor == Adapter->LastRxDescriptor) - Adapter->NextRxDescriptorToCheck = Adapter->FirstRxDescriptor; - else - Adapter->NextRxDescriptorToCheck++; - - LastDescriptorProcessed = CurrentDescriptor; - CurrentDescriptor = Adapter->NextRxDescriptorToCheck; - - if (e1000_debug_level >= 3) - printk("Next RX Desc to check is 0x%p\n", CurrentDescriptor); - - /* Put the buffer that we just indicated back at the end of our list */ - QUEUE_POP_HEAD(&Adapter->RxSwPacketList); - QUEUE_PUSH_TAIL(&Adapter->RxSwPacketList, &RxSwPacket->Link); - - Count++; - - /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ - E1000_WRITE_REG(Rdt0, (((uintptr_t) LastDescriptorProcessed - - (uintptr_t) Adapter->FirstRxDescriptor) >> 4)); - - if (e1000_debug_level >= 3) - printk("Rx Tail pointer is now 0x%lX\n", - (((uintptr_t) CurrentDescriptor - - (uintptr_t) Adapter->FirstRxDescriptor) >> 4)); - - } /* while loop for all packets with DD set */ - - if (e1000_debug_level >= 3) - printk("ProcessReceiveInterrupts: done\n"); - return; -} - -/**************************************************************************** -* Name: e1000_watchdog -* -* Description: This routine monitors the board activity. It also updates the -* statistics that are used by some tools. -* -* Author: IntelCorporation -* -* Born on Date: 8/2/97 -* -* Arguments: NONE -* -* Returns: NONE -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ - - -static void -e1000_watchdog(device_t * dev) -{ - uint16_t LineSpeed, FullDuplex; - bd_config_t *bdp; - PADAPTER_STRUCT Adapter; - - bdp = dev->priv; - Adapter = (PADAPTER_STRUCT) bdp->bddp; - - /* - * the routines in the watchdog should only be executed if the board pointer - * is valid, i.e the adapter is actually present. - */ - if (bdp->flags & BOARD_PRESENT) { - - if(!Adapter->AdapterStopped) { - CheckForLink(Adapter); - } - if(E1000_READ_REG(Status) & E1000_STATUS_LU) { - GetSpeedAndDuplex(Adapter, &LineSpeed, &FullDuplex); - Adapter->cur_line_speed = (uint32_t) LineSpeed; - Adapter->FullDuplex = (uint32_t) FullDuplex; -#ifdef IANS - Adapter->ans_link = IANS_STATUS_LINK_OK; - Adapter->ans_speed = (uint32_t) LineSpeed; - Adapter->ans_duplex = FullDuplex == FULL_DUPLEX ? - BD_ANS_DUPLEX_FULL : BD_ANS_DUPLEX_HALF; -#endif - if(Adapter->LinkIsActive == FALSE) { - printk("e1000: %s %ld Mbps %s Link is Up\n", dev->name, - Adapter->cur_line_speed, - Adapter->FullDuplex == FULL_DUPLEX ? - "Full Duplex" : "Half Duplex"); - Adapter->LinkIsActive = TRUE; - } - } else { - Adapter->cur_line_speed = 0; - Adapter->FullDuplex = 0; -#ifdef IANS - Adapter->ans_link = IANS_STATUS_LINK_FAIL; - Adapter->ans_speed = 0; - Adapter->ans_duplex = 0; -#endif - if(Adapter->LinkIsActive == TRUE) { - printk("e1000: %s Link is Down\n", dev->name); - Adapter->LinkIsActive = FALSE; - } - } - - /* Update the statistics needed by the upper */ - UpdateStatsCounters(bdp); - - } -#ifdef IANS - if (bdp->iANSdata->reporting_mode == IANS_STATUS_REPORTING_ON) { - bd_ans_os_Watchdog(dev, bdp); - } -#endif - /* reset the timer to 2 sec */ - mod_timer(&bdp->timer_id, jiffies + (2 * HZ)); - - return; -} - - -/* pci.c */ - -/***************************************************************************** -* Name: e1000_find_pci_device -* -* Description: This routine finds all PCI adapters that have the given Device -* ID and Vendor ID. It will store the IRQ, I/O, mem address, -* node address, and slot information for each adapter in the -* CardsFound structure. This routine will also enable the bus -* master bit on any of our adapters (some BIOS don't do this). -* -* -* Author: IntelCorporation -* -* Born on Date: 2/1/98 -* -* Arguments: -* vendor_id - Vendor ID of our 82557 based adapter. -* device_id - Device ID of our 82557 based adapter. -* -* Returns: -* B_TRUE - if found pci devices successfully -* B_FALSE - if no pci devices found -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -*****************************************************************************/ -static boolean_t -e1000_find_pci_device(pci_dev_t * pcid, PADAPTER_STRUCT Adapter) -{ - ulong_t PciTrdyTimeOut = 0; - ulong_t PciRetryTimeOut = 0; - int status = 0; - uint_t PciCommandWord = 0; - - if (e1000_debug_level >= 1) - printk("e1000_find_pci_device\n"); - - if ((((ushort_t) pcid->vendor) == E1000_VENDOR_ID) && - ((((ushort_t) pcid->device) == WISEMAN_DEVICE_ID) || - (((ushort_t) pcid->device) == LIVENGOOD_FIBER_DEVICE_ID) || - (((ushort_t) pcid->device) == LIVENGOOD_COPPER_DEVICE_ID))) { - - if (e1000_debug_level >= 2) - printk - ("pcid is ours, vendor = 0x%x, device = 0x%x\n", - pcid->vendor, pcid->device); - - /* Read the values of the Trdy timeout and - * also the retry count register - */ - - pci_read_config_byte(pcid, - PCI_TRDY_TIMEOUT_REGISTER, - (uchar_t *) & PciTrdyTimeOut); - - pci_read_config_byte(pcid, - PCI_RETRY_TIMEOUT_REGISTER, - (uchar_t *) & PciRetryTimeOut); - - pci_read_config_byte(pcid, - PCI_REVISION_ID, - (uchar_t *) & (Adapter->RevID)); - - pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, - (ushort_t *) & (Adapter->SubSystemId)); - - pci_read_config_word(pcid, - PCI_SUBSYSTEM_VENDOR_ID, - (ushort_t *) & (Adapter->SubVendorId)); - - pci_read_config_word(pcid, - PCI_COMMAND, - (ushort_t *) & (Adapter->PciCommandWord)); - - PciCommandWord = Adapter->PciCommandWord; - Adapter->DeviceNum = pcid->devfn; - - Adapter->VendorId = pcid->vendor; - Adapter->DeviceId = pcid->device; - - if (e1000_debug_level >= 2) { - printk("PciTrdyTimeOut = 0x%x\n", (uchar_t) PciTrdyTimeOut); - printk("PciRetryTimeOut = 0x%x\n", (uchar_t) PciRetryTimeOut); - printk("RevID = 0x%x\n", (uchar_t) Adapter->RevID); - printk("SUBSYSTEM_ID = 0x%x\n", Adapter->SubSystemId); - printk("SUBSYSTEM_VENDOR_ID = 0x%x\n", Adapter->SubVendorId); - printk("PciCommandWord = 0x%x\n", - (ushort_t) Adapter->PciCommandWord); - printk("DeviceNum = 0x%x\n", Adapter->DeviceNum); - } - if (e1000_pcimlt_override) - pci_write_config_byte(pcid, - PCI_LATENCY_TIMER, - e1000_pcimlt_override); - - /* code insp #2 */ - if (!(e1000_pcimwi_enable)) { - if (Adapter->PciCommandWord & CMD_MEM_WRT_INVALIDATE) { - PciCommandWord = - Adapter->PciCommandWord & ~CMD_MEM_WRT_INVALIDATE; - pci_write_config_word(pcid, - PCI_COMMAND_REGISTER, - PciCommandWord); - } - } - - /* Set the Trdy timeout to zero if it is not - * already so - */ - if (PciTrdyTimeOut) { - PciTrdyTimeOut = 0; - pci_write_config_byte(pcid, - PCI_TRDY_TIMEOUT_REGISTER, - PciTrdyTimeOut); - - pci_read_config_byte(pcid, - PCI_TRDY_TIMEOUT_REGISTER, - (uchar_t *) & PciTrdyTimeOut); - - if (PciTrdyTimeOut) - status = B_FALSE; - else - status = B_TRUE; - - } else - status = B_TRUE; - - /* Set the retry timeout to zero if it is not - * already so - */ - if (PciRetryTimeOut) { - PciRetryTimeOut = 0; - pci_write_config_byte(pcid, - PCI_RETRY_TIMEOUT_REGISTER, - PciRetryTimeOut); - - pci_read_config_byte(pcid, - PCI_RETRY_TIMEOUT_REGISTER, - (uchar_t *) & PciRetryTimeOut); - - if (PciRetryTimeOut) - status = B_FALSE; - else - status = B_TRUE; - } else - status = B_TRUE; - } - - if (e1000_debug_level >= 1) - printk("find_pci: end, status = 0x%x\n", status); - - return (status); - -} - - -/**************************************************************************** -* Name: e1000_sw_init -* -* Description : This routine initializes all software structures needed by the -* driver. Allocates the per board structure for storing adapter -* information. This routine also allocates all the transmit and -* and receive related data structures for the driver. The memory- -* mapped PCI BAR address space is also allocated in this routine. -* -* Author: IntelCorporation -* -* Born on Date: 7/21/97 -* -* Arguments: -* bdp - Pointer to the DLPI board structure. -* -* Returns: -* B_TRUE - if successfully initialized -* B_FALSE - if S/W initialization failed -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ - -static boolean_t -e1000_sw_init(bd_config_t * bdp) -{ - PADAPTER_STRUCT Adapter; /* stores all adapter specific info */ - ulong_t mem_base; /* Memory base address */ - uint_t bd_no; - int i; - PRX_SW_PACKET RxSwPacket; - - if (e1000_debug_level >= 1) - printk("e1000_sw_init: [brd %d] begin\n", bdp->bd_number); - - Adapter = bdp->bddp; - - mem_base = bdp->mem_start; - bd_no = bdp->bd_number; - - spin_lock_init(&(Adapter->bd_tx_lock)); - - /* - * The board specific information like the memory base address, the IO base - * address and the board number are also stored in the Adapter structure - */ - Adapter->mem_base = mem_base; - Adapter->bd_number = bd_no; - - if (e1000_debug_level >= 2) - printk - ("e1000 - PR0/1000 board located at memory address 0x%lx\n", - mem_base); - - /* First we have to check our "NumTxDescriptors" and make sure it is - * a multiple of 8, because the E1000 requires this... - */ - TxDescriptors[Adapter->bd_number] += (REQ_TX_DESCRIPTOR_MULTIPLE - 1); - TxDescriptors[Adapter->bd_number] &= - (~(REQ_TX_DESCRIPTOR_MULTIPLE - 1)); - - Adapter->NumTxDescriptors = TxDescriptors[Adapter->bd_number]; - - /* - * Allocate memory for the TXSwPacket. The TxSwPacket stores all the - * information needed to transmit a packet on the wire. It stores the - * address of the message to be sent, the number of descriptors used by - * the packet and other miscellaneous information. - */ - if (!(Adapter->e1000_TxSwPacketPtrArea = - (PTX_SW_PACKET) malloc_contig(sizeof(TX_SW_PACKET) * - TxDescriptors - [Adapter->bd_number]))) { - printk("e1000_sw_init TxSwPacketArea alloc failed\n"); - return 0; - } - - if (e1000_debug_level >= 2) - printk("TxSwPacketPtrArea = 0x%p\n", - Adapter->e1000_TxSwPacketPtrArea); - - /* - * Allocate memory for the transmit buffer descriptors that are shared - * between the driver and the E1000. The driver uses these descriptors to - * give packets to the hardware for transmission and the hardware returns - * status information in this memory area once the packet has been - * transmitted. - */ - bdp->base_tx_tbds = (void *) kmalloc( - (sizeof - (E1000_TRANSMIT_DESCRIPTOR) * - TxDescriptors - [Adapter->bd_number]) + 4096, - GFP_KERNEL); - if (bdp->base_tx_tbds == NULL) { - printk("e1000_sw_init e1000_rbd_data alloc failed\n"); - return 0; - } - Adapter->e1000_tbd_data = (PE1000_TRANSMIT_DESCRIPTOR) - (((unsigned long) bdp->base_tx_tbds + 4096) & ~4096); - - if (e1000_debug_level >= 2) - printk("tbd_data = 0x%p\n", Adapter->e1000_tbd_data); - - /* - * Set the first transmit descriptor to the beginning of the allocated - * memory area and the last descriptor to the end of the memory area - */ - Adapter->FirstTxDescriptor = Adapter->e1000_tbd_data; - - Adapter->LastTxDescriptor = - Adapter->FirstTxDescriptor + (Adapter->NumTxDescriptors - 1); - - /* First we have to check our "NumRxDescriptors" and make sure it is - * a multiple of 8, because the E10001000 requires this... - */ - RxDescriptors[Adapter->bd_number] += (REQ_RX_DESCRIPTOR_MULTIPLE - 1); - RxDescriptors[Adapter->bd_number] &= - (~(REQ_RX_DESCRIPTOR_MULTIPLE - 1)); - - Adapter->NumRxDescriptors = RxDescriptors[Adapter->bd_number]; - - /*------------------------------------------------------------------------ - * Allocate memory for the RX_SW_PACKET structures. Each one of these - * structures will contain a virtual and physical address to an actual - * receive buffer in host memory. Since we use one RX_SW_PACKET per received - * packet, the maximum number of RX_SW_PACKETs that we'll need is equal - * to the number of receive descriptors that that we've allocated. - *-------------------------------------------------------------------- - */ - - if (! - (Adapter->RxSwPacketPointerArea = - kmalloc(sizeof(RX_SW_PACKET) * - (RxDescriptors[Adapter->bd_number]), GFP_KERNEL))) { - printk("e1000_sw_init RxSwPacketPointerArea alloc failed\n"); - return 0; - } - - if (e1000_debug_level >= 2) - printk("RxSwPacketPointerArea = 0x%p\n", - Adapter->RxSwPacketPointerArea); - - /*------------------------------------------------------------------------ - * Allocate memory for the receive descriptors (in shared memory), with - * enough room left over to make sure that we can properly align the - * structures. - *---------------------------------------------------------------------- - */ - - bdp->base_rx_rbds = (void *) kmalloc( - (sizeof - (E1000_RECEIVE_DESCRIPTOR) * - RxDescriptors - [Adapter->bd_number]) + 4096, - GFP_KERNEL); - if (bdp->base_rx_rbds == 0) { - printk("e1000_sw_init e1000_rbd_data alloc failed\n"); - return 0; - } - Adapter->e1000_rbd_data = (PE1000_RECEIVE_DESCRIPTOR) - (((unsigned long) bdp->base_rx_rbds + 4096) & ~4096); - - if (e1000_debug_level >= 2) - printk("rbd_data = 0x%p\n", Adapter->e1000_rbd_data); - - Adapter->FirstRxDescriptor = - (PE1000_RECEIVE_DESCRIPTOR) Adapter->e1000_rbd_data; - - Adapter->LastRxDescriptor = - Adapter->FirstRxDescriptor + (Adapter->NumRxDescriptors - 1); - - /*------------------------------------------------------------------------ - * We've allocated receive buffer pointers, and receive descriptors. Now - * Allocate a buffer for each descriptor, and zero the buffer. - *---------------------------------------------------------------------- - */ - - /*------------------------------------------------------------------------ - * For each receive buffer, the Physical address will be stored - * in the RX_SW_PACKET's "PhysicalAddress" field, while the - * virtual address will be stored in the "VirtualAddress" field. - *----------------------------------------------------------------------- - */ - - /* allocate a physreq structure for specifying receive buffer DMA - * requirements. - */ - - /* - * For each RxSwPacket, allocate a receive buffer 2048 bytes in size. The - * RxSwPacket has a pointer to the virtual address of receive buffer. There - * is a one to one correspondance between the RxSwPacket, receive buffer and - * the receive descriptor. - */ - for (i = 0, RxSwPacket = Adapter->RxSwPacketPointerArea; - i < Adapter->NumRxDescriptors; i++, RxSwPacket++) { - -#ifdef IANS - RxSwPacket->skb = alloc_skb(Adapter->RxBufferLen + BD_ANS_INFO_SIZE, - GFP_ATOMIC); -#else - RxSwPacket->skb = alloc_skb(Adapter->RxBufferLen + 2, GFP_ATOMIC); -#endif - if (RxSwPacket->skb == NULL) { - printk("e1000_sw_init SetupReceiveStructures BIG PROBLEM\n"); - return 0; - } else { - /* make the 14 byte mac header align to 16 */ -#ifdef IANS - skb_reserve(RxSwPacket->skb, BD_ANS_INFO_SIZE); -#else - skb_reserve(RxSwPacket->skb, 2); -#endif - /* set who this is from - JR 9/10/99 */ - RxSwPacket->skb->dev = bdp->device; - - RxSwPacket->VirtualAddress = RxSwPacket->skb->tail; - - if (!RxSwPacket->VirtualAddress) { - return RET_STATUS_FAILURE; - } - - /* Zero the [cached] receive buffer. */ - memset((PVOID) RxSwPacket->VirtualAddress, 0, - E1000_SIZE_OF_RECEIVE_BUFFERS); - } - - } /* end of RxSwPacket for loop */ - - - /* - * Set up the multicast table data area - */ -/* - Adapter->pmc_buff->MulticastBuffer = - ((mltcst_cb_t *)&bdp->mc_data)->MulticastBuffer; -*/ - Adapter->pmc_buff = (mltcst_cb_t *) bdp->mc_data; - - if (e1000_debug_level >= 1) - printk("pmc_buff = 0x%p\n", Adapter->pmc_buff); - - return 1; -} - -/**************************************************************************** -* Name: e1000_alloc_space -* -* Description : This routine allocates paragraph ( 16 bit ) aligned memory for -* the driver. Memory allocated is for the following structures -* - BDP ( the main interface struct between dlpi and the driver ) -* - error count structure for adapter statistics -* -* For the MP_VERSION of this driver, each sap structure returned -* by this routine has a pre allocated synchornize var. Ditto for -* BDP's allocated ( they have a spin lock in them ). -* -* Author: IntelCorporation -* -* Born on Date: 7/11/97 -* -* Arguments: -* None -* -* Returns: -* TRUE - if successfully allocated -* FALSE - if S/W allocation failed -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static bd_config_t * -e1000_alloc_space(void) -{ - bd_config_t *bdp, *temp_bd; - PADAPTER_STRUCT Adapter; /* stores all adapter specific info */ - - if (e1000_debug_level >= 1) - printk("e1000_alloc_space: begin\n"); - - /* allocate space for the DL_board_t structures */ - bdp = (bd_config_t *) kmalloc(sizeof(bd_config_t), GFP_KERNEL); - - if (bdp == NULL) { - if (e1000_debug_level >= 2) - printk("e1000_alloc_space e1000_config alloc failed\n"); - return NULL; - } - - /* fill the bdp with zero */ - memset(bdp, 0x00, sizeof(*bdp)); - - if (e1000_debug_level >= 2) - printk("bdp = 0x%p\n", bdp); - - /* if first one, save it, else link it into the chain of bdp's */ - if (e1000first == NULL) { - e1000first = bdp; - bdp->bd_number = 0; - bdp->bd_next = NULL; - bdp->bd_prev = NULL; - - if (e1000_debug_level >= 2) - printk("First one\n"); - - } else { - /* No, so find last in list and link the new one in */ - temp_bd = e1000first; - bdp->bd_number = 1; /* it is at least 1 */ - while (temp_bd->bd_next != NULL) { - temp_bd = (bd_config_t *) temp_bd->bd_next; - bdp->bd_number++; /* set the board number */ - } - temp_bd->bd_next = bdp; - bdp->bd_next = NULL; - bdp->bd_prev = temp_bd; - if (e1000_debug_level >= 2) - printk("Not first one\n"); - - } - - /* - * Allocate the Adapter sturcuture. The Adapter structure contains all the - * information that is specific to that board instance. It contains pointers - * to all the transmit and receive data structures for the board, all the - * PCI related information for the board, and all the statistical counters - * associated with the board. - */ - Adapter = - (PADAPTER_STRUCT) kmalloc(sizeof(ADAPTER_STRUCT), GFP_KERNEL); - if (Adapter == NULL) { - if (e1000_debug_level >= 2) - printk("e1000_sw_init Adapter structure alloc failed\n"); - return (NULL); - } - - memset(Adapter, 0x00, sizeof(ADAPTER_STRUCT)); - - /* - * The Adapter pointer is made to point to the bddp ( Board dependent - * pointer) that is referenced off the bdp ( board ) structure. - */ - bdp->bddp = Adapter; - - if (e1000_debug_level >= 2) - printk("bdp->bddp = 0x%p\n", bdp->bddp); - - /* allocate space for multi-cast address space */ - if (! - (bdp->mc_data = - (pmltcst_cb_t) malloc_contig(sizeof(mltcst_cb_t)))) { - if (e1000_debug_level >= 2) - printk("e1000_alloc_space mc_data alloc failed\n"); - return NULL; - } - memset(bdp->mc_data, 0x00, sizeof(mltcst_cb_t)); - - if (e1000_debug_level >= 2) - printk("bdp->mc_data = 0x%p\n", bdp->mc_data); - - if (e1000_debug_level >= 1) - printk("e1000_alloc_space: end\n"); - - return (bdp); -} - -/**************************************************************************** -* Name: e1000_dealloc_space -* -* Description : This routine frees all the memory allocated by "alloc_space". -* -* Author: IntelCorporation -* -* Born on Date: 7/17/97 -* -* Arguments: -* None -* -* Returns: -* none -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static void -e1000_dealloc_space(bd_config_t * bdp) -{ - if (e1000_debug_level >= 1) - printk("e1000_dealloc_space, bdp = 0x%p\n", bdp); - if (bdp) { - free_contig(bdp->mc_data); - bdp->mc_data = NULL; - - free_contig(bdp->bddp); - bdp->bddp = NULL; - - /* unlink the bdp from the linked list */ - if (bdp == e1000first) { - e1000first = (bd_config_t *) bdp->bd_next; - if (bdp->bd_next) - ((bd_config_t *) bdp->bd_next)->bd_prev = NULL; - } else { - if (bdp->bd_next) - ((bd_config_t *) bdp->bd_next)->bd_prev = bdp->bd_prev; - if (bdp->bd_prev) - ((bd_config_t *) bdp->bd_prev)->bd_next = bdp->bd_next; - } - } - - free_contig(bdp); - bdp = NULL; - - return; -} - -/**************************************************************************** -* Name: malloc_contig -* -* Description : This routine allocates a contigious chunk of memory of -* specified size. -* -* Author: IntelCorporation -* -* Born on Date: 7/18/97 -* -* Arguments: -* size - Size of contigious memory required. -* -* Returns: -* void ptr - if successfully allocated -* NULL - if allocation failed -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static void * -malloc_contig(int size) -{ - void *mem; - - /* allocate memory */ - mem = kmalloc(size, GFP_KERNEL); - if (!mem) - return (NULL); - - return (mem); -} - -/**************************************************************************** -* Name: free_contig -* -* Description : This routine frees up space previously allocated by -* malloc_contig. -* -* Author: IntelCorporation -* -* Born on Date: 1/18/98 -* -* Arguments: -* ptr - Pointer to the memory to free. -* size - Size of memory to free. -* -* Returns: -* TRUE - if successfully initialized -* FALSE - if S/W initialization failed -* -* Modification log: -* Date Who Description -* -------- --- -------------------------------------------------------- -* -****************************************************************************/ -static void -free_contig(void *ptr) -{ - if (ptr) - kfree(ptr); - - ptr = NULL; -} - -static int -e1000_GetBrandingMesg(uint16_t dev, uint16_t sub_ven, uint16_t sub_dev) -{ - char *mesg = NULL; - int i = 0; - - /* Go through the list of all valid subsystem IDs */ - while (e1000_vendor_info_array[i].idstr != NULL) { - /* Look for exact match on sub_dev and sub_ven */ - if ((e1000_vendor_info_array[i].dev == dev) && - (e1000_vendor_info_array[i].sub_ven == sub_ven) && - (e1000_vendor_info_array[i].sub_dev == sub_dev)) { - mesg = e1000_vendor_info_array[i].idstr; - break; - } else if ((e1000_vendor_info_array[i].dev == dev) && - (e1000_vendor_info_array[i].sub_ven == sub_ven) && - (e1000_vendor_info_array[i].sub_dev == CATCHALL)) { - mesg = e1000_vendor_info_array[i].idstr; - } else if ((e1000_vendor_info_array[i].dev == dev) && - (e1000_vendor_info_array[i].sub_ven == CATCHALL) && - (mesg == NULL)) { - mesg = e1000_vendor_info_array[i].idstr; - } - i++; - } - if (mesg != NULL) { - strcpy(e1000id_string, mesg); - return 1; - } else - return 0; -} - -/* fxhw.c */ -static boolean_t -DetectKnownChipset(PADAPTER_STRUCT Adapter) -{ - pci_dev_t *pcid; - ulong_t DataPort; - uchar_t SaveConfig; - uchar_t TestConfig; - - SaveConfig = inb(CF2_SPACE_ENABLE_REGISTER); - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, 0x0E); - - TestConfig = inb(CF2_SPACE_ENABLE_REGISTER); - - if (TestConfig == 0x0E) { - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, SaveConfig); - - return FALSE; - } - - - if ( - (pcid = - pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_440BX_AGP, NULL)) - || (pcid = pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_440BX, NULL)) - || (pcid = pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_440GX, NULL)) - || (pcid = pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_440FX, NULL)) - || (pcid = - pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_430TX, NULL))) { - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, SaveConfig); - - if (e1000_debug_level >= 3) - printk - ("Found a known member of the 430 or 440 chipset family"); - - return TRUE; - } - - - if ( - (pcid = - pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_450NX_PXB, NULL))) { - - pci_read_config_byte(pcid, PCI_REV_ID_REGISTER, (u8 *) & DataPort); - - if (e1000_debug_level >= 3) - printk - ("Found a 450NX chipset with PXB rev ID 0x%x\n", - (uchar_t) DataPort); - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, SaveConfig); - - if (((uchar_t) DataPort) >= PXB_C0_REV_ID) { - if (e1000_debug_level >= 3) - printk("Found a 450NX chipset with C0 or later PXB"); - return FALSE; - } else { - if (e1000_debug_level >= 3) - printk("Found a 450NX chipset with B1 or earlier PXB"); - return TRUE; - } - } - - if ( - (pcid = - pci_find_device(PCI_VENDOR_ID_INTEL, INTEL_450KX_GX_PB, NULL))) { - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, SaveConfig); - - if (e1000_debug_level >= 3) - printk("Found a 450KX or 450GX chipset"); - - return TRUE; - } - - outb((uchar_t) CF2_SPACE_ENABLE_REGISTER, SaveConfig); - - if (e1000_debug_level >= 3) - printk("Did not find a known chipset"); - - return FALSE; -} - -#ifdef MODULE -/* ENTRY POINTS */ -EXPORT_SYMBOL(e1000_open); -EXPORT_SYMBOL(e1000_close); -EXPORT_SYMBOL(e1000_xmit_frame); -EXPORT_SYMBOL(e1000_probe); -EXPORT_SYMBOL(e1000_change_mtu); -EXPORT_SYMBOL(e1000_intr); -/* DEBUG */ -#endif diff -uNr click-1.5.0-dist/drivers/e1000-4.x/src/e1000.h.orig click-1.5.0/drivers/e1000-4.x/src/e1000.h.orig --- click-1.5.0-dist/drivers/e1000-4.x/src/e1000.h.orig Fri Nov 22 17:13:38 2002 +++ click-1.5.0/drivers/e1000-4.x/src/e1000.h.orig Thu Jan 1 01:00:00 1970 @@ -1,244 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - - -/* Linux PRO/1000 Ethernet Driver main header file */ - -#ifndef _E1000_H_ -#define _E1000_H_ -#ifndef __E1000_MAIN__ -#define __NO_VERSION__ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SIOCETHTOOL -#include -#endif -#ifdef NETIF_F_HW_VLAN_TX -#include -#endif - -#define BAR_0 0 -#define BAR_1 1 -#define BAR_5 5 -#define PCI_DMA_64BIT 0xffffffffffffffffULL -#define PCI_DMA_32BIT 0x00000000ffffffffULL - -#include "kcompat.h" - -struct e1000_adapter; - -#include "e1000_hw.h" -#ifdef IANS -#include "base_comm.h" -#include "ans_driver.h" -#include "ans.h" -#endif -#ifdef IDIAG -#include "idiag_pro.h" -#endif - -#if DBG -#define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args) -#else -#define E1000_DBG(args...) -#endif - -#define E1000_ERR(args...) printk(KERN_ERR "e1000: " args) - -#define E1000_MAX_INTR 10 - -/* Supported Rx Buffer Sizes */ -#define E1000_RXBUFFER_2048 2048 -#define E1000_RXBUFFER_4096 4096 -#define E1000_RXBUFFER_8192 8192 -#define E1000_RXBUFFER_16384 16384 - -/* How many Tx Descriptors do we need to call netif_wake_queue ? */ -#define E1000_TX_QUEUE_WAKE 16 -/* How many Rx Buffers do we bundle into one write to the hardware ? */ -#define E1000_RX_BUFFER_WRITE 16 - -#define E1000_JUMBO_PBA 0x00000028 -#define E1000_DEFAULT_PBA 0x00000030 - -#define AUTO_ALL_MODES 0 - -/* only works for sizes that are powers of 2 */ -#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) - -/* wrapper around a pointer to a socket buffer, - * so a DMA handle can be stored along with the buffer */ -struct e1000_buffer { - struct sk_buff *skb; - uint64_t dma; - unsigned long length; - unsigned long time_stamp; -}; - -struct e1000_desc_ring { - /* pointer to the descriptor ring memory */ - void *desc; - /* physical address of the descriptor ring */ - dma_addr_t dma; - /* length of descriptor ring in bytes */ - unsigned int size; - /* number of descriptors in the ring */ - unsigned int count; - /* next descriptor to associate a buffer with */ - unsigned int next_to_use; - /* next descriptor to check for DD status bit */ - unsigned int next_to_clean; - /* array of buffer information structs */ - struct e1000_buffer *buffer_info; -}; - -#define E1000_DESC_UNUSED(R) \ -((((R)->next_to_clean + (R)->count) - ((R)->next_to_use + 1)) % ((R)->count)) - -#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) -#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) -#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc) -#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc) - -/* board specific private data structure */ - -struct e1000_adapter { -#ifdef IANS - void *iANSReserved; - piANSsupport_t iANSdata; - uint32_t ans_link; - uint32_t ans_speed; - uint32_t ans_duplex; - uint32_t ans_suspend; - IANS_BD_TAGGING_MODE tag_mode; -#endif - struct timer_list watchdog_timer; - struct timer_list phy_info_timer; -#ifdef CONFIG_PROC_FS - struct list_head proc_list_head; -#endif -#ifdef NETIF_F_HW_VLAN_TX - struct vlan_group *vlgrp; -#endif - char *id_string; - uint32_t bd_number; - uint32_t rx_buffer_len; - uint32_t part_num; - uint32_t wol; - uint16_t link_speed; - uint16_t link_duplex; - spinlock_t stats_lock; - atomic_t irq_sem; - -#ifdef ETHTOOL_PHYS_ID - struct timer_list blink_timer; - unsigned long led_status; -#endif - - /* TX */ - struct e1000_desc_ring tx_ring; - uint32_t txd_cmd; - uint32_t tx_int_delay; - uint32_t tx_abs_int_delay; - int max_data_per_txd; - - /* RX */ - struct e1000_desc_ring rx_ring; - uint64_t hw_csum_err; - uint64_t hw_csum_good; - uint32_t rx_int_delay; - uint32_t rx_abs_int_delay; - boolean_t rx_csum; - - /* OS defined structs */ - struct net_device *netdev; - struct pci_dev *pdev; - struct net_device_stats net_stats; - - /* structs defined in e1000_hw.h */ - struct e1000_hw hw; - struct e1000_hw_stats stats; - struct e1000_phy_info phy_info; - struct e1000_phy_stats phy_stats; - -#ifdef IDIAG - uint32_t diag_icr; - struct e1000_desc_ring diag_tx_ring; - struct e1000_desc_ring diag_rx_ring; -#endif - -#ifdef E1000_COUNT_ICR - uint64_t icr_txdw; - uint64_t icr_txqe; - uint64_t icr_lsc; - uint64_t icr_rxseq; - uint64_t icr_rxdmt; - uint64_t icr_rxo; - uint64_t icr_rxt; - uint64_t icr_mdac; - uint64_t icr_rxcfg; - uint64_t icr_gpi; -#endif - - uint32_t pci_state[16]; - - /* Semaphore for locking HW access vs. i2c-i8254x SMBUS driver */ - struct semaphore smbus_lock; -}; -#endif /* _E1000_H_ */ diff -uNr click-1.5.0-dist/drivers/e1000-4.x/src/e1000_idiag.c.orig click-1.5.0/drivers/e1000-4.x/src/e1000_idiag.c.orig --- click-1.5.0-dist/drivers/e1000-4.x/src/e1000_idiag.c.orig Fri Nov 22 17:13:39 2002 +++ click-1.5.0/drivers/e1000-4.x/src/e1000_idiag.c.orig Thu Jan 1 01:00:00 1970 @@ -1,1048 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -/* - * Intel PRO diagnostics - */ - -#include "e1000.h" -#include "idiag_pro.h" -#include "idiag_e1000.h" - -extern int e1000_up(struct e1000_adapter *adapter); -extern void e1000_down(struct e1000_adapter *adapter); -extern void e1000_reset(struct e1000_adapter *adapter); - -#define REG_PATTERN_TEST(R, M, W) \ -{ \ - uint32_t pat, value; \ - uint32_t test[] = \ - {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \ - E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \ - value = E1000_READ_REG(&adapter->hw, R); \ - if(value != (test[pat] & W & M)) { \ - param->reg = \ - (adapter->hw.mac_type < e1000_82543) ? \ - E1000_82542_##R : E1000_##R; \ - param->write_value = test[pat] & W; \ - param->read_value = value; \ - return IDIAG_PRO_STAT_TEST_FAILED; \ - } \ - } \ -} - -#define REG_SET_AND_CHECK(R, M, W) \ -{ \ - uint32_t value; \ - E1000_WRITE_REG(&adapter->hw, R, W & M); \ - value = E1000_READ_REG(&adapter->hw, R); \ - if ((W & M) != (value & M)) { \ - param->reg = (adapter->hw.mac_type < e1000_82543) ? \ - E1000_82542_##R : E1000_##R; \ - param->write_value = W & M; \ - param->read_value = value & M; \ - return IDIAG_PRO_STAT_TEST_FAILED; \ - } \ -} - -static enum idiag_pro_stat -e1000_diag_reg_test(struct e1000_adapter *adapter, - uint8_t *diag_param) -{ - struct idiag_e1000_diag_reg_test_param *param = - (struct idiag_e1000_diag_reg_test_param *) diag_param; - uint32_t value; - uint32_t i; - - /* The status register is Read Only, so a write should fail. - * Some bits that get toggled are ignored. - */ - value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833)); - E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF)); - if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) { - param->reg = E1000_STATUS; - param->write_value = 0xFFFFFFFF; - param->read_value = value; - return IDIAG_PRO_STAT_TEST_FAILED; - } - - REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF); - REG_PATTERN_TEST(RDH, 0x0000FFFF, 0x0000FFFF); - REG_PATTERN_TEST(RDT, 0x0000FFFF, 0x0000FFFF); - REG_PATTERN_TEST(FCRTH, 0x0000FFF8, 0x0000FFF8); - REG_PATTERN_TEST(FCTTV, 0x0000FFFF, 0x0000FFFF); - REG_PATTERN_TEST(TIPG, 0x3FFFFFFF, 0x3FFFFFFF); - REG_PATTERN_TEST(TDBAH, 0xFFFFFFFF, 0xFFFFFFFF); - REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF); - - REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000); - REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB); - REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000); - - if(adapter->hw.mac_type >= e1000_82543) { - - REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF); - REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); - REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF); - REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); - REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF); - - for(i = 0; i < E1000_RAR_ENTRIES; i++) { - REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF, - 0xFFFFFFFF); - REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF, - 0xFFFFFFFF); - } - - } else { - - REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF); - REG_PATTERN_TEST(RDBAL, 0xFFFFF000, 0xFFFFFFFF); - REG_PATTERN_TEST(TXCW, 0x0000FFFF, 0x0000FFFF); - REG_PATTERN_TEST(TDBAL, 0xFFFFF000, 0xFFFFFFFF); - - } - - for(i = 0; i < E1000_MC_TBL_SIZE; i++) - REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF); - - return IDIAG_PRO_STAT_OK; -} - - -static enum idiag_pro_stat -e1000_diag_eeprom_test(struct e1000_adapter *adapter, - uint8_t *diag_param) -{ - struct idiag_e1000_diag_eeprom_test_param *param = - (struct idiag_e1000_diag_eeprom_test_param *) diag_param; - uint16_t temp; - uint16_t checksum = 0; - uint16_t i; - - /* Read and add up the contents of the EEPROM */ - for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { - if((e1000_read_eeprom(&adapter->hw, i, &temp)) < 0) { - param->actual_checksum = checksum; - param->expected_checksum = EEPROM_SUM; - return IDIAG_PRO_STAT_TEST_FATAL; - } - checksum += temp; - } - - /* If Checksum is not Correct return error else test passed */ - if(checksum != (uint16_t) EEPROM_SUM) { - param->actual_checksum = checksum; - param->expected_checksum = EEPROM_SUM; - return IDIAG_PRO_STAT_TEST_FAILED; - } - - return IDIAG_PRO_STAT_OK; -} - -static void -e1000_diag_intr(int irq, - void *data, - struct pt_regs *regs) -{ - struct net_device *netdev = (struct net_device *) data; - struct e1000_adapter *adapter = netdev->priv; - - adapter->diag_icr |= E1000_READ_REG(&adapter->hw, ICR); - - return; -} - -static enum idiag_pro_stat -e1000_diag_intr_test(struct e1000_adapter *adapter, - uint8_t *diag_param) -{ - struct net_device *netdev = adapter->netdev; - enum idiag_e1000_diag_intr_test_param *param = - (enum idiag_e1000_diag_intr_test_param *) diag_param; - uint32_t icr, i, mask; - - *param = IDIAG_E1000_INTR_TEST_OK; - - /* Hook up diag interrupt handler just for this test */ - if(request_irq - (netdev->irq, &e1000_diag_intr, SA_SHIRQ, netdev->name, netdev)) - return IDIAG_PRO_STAT_TEST_FATAL; - - /* Disable all the interrupts */ - E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); - msec_delay(10); - - /* Interrupts are disabled, so read interrupt cause - * register (icr) twice to verify that there are no interrupts - * pending. icr is clear on read. - */ - icr = E1000_READ_REG(&adapter->hw, ICR); - icr = E1000_READ_REG(&adapter->hw, ICR); - - if(icr != 0) { - /* if icr is non-zero, there is no point - * running other interrupt tests. - */ - *param = IDIAG_E1000_INTR_TEST_NOT_EXEC; - return IDIAG_PRO_STAT_TEST_FAILED; - } - - /* Test each interrupt */ - for(i = 0; i < 10; i++) { - - /* Interrupt to test */ - mask = 1 << i; - - /* Disable the interrupt to be reported in - * the cause register and then force the same - * interrupt and see if one gets posted. If - * an interrupt was posted to the bus, the - * test failed. - */ - adapter->diag_icr = 0; - E1000_WRITE_REG(&adapter->hw, IMC, mask); - E1000_WRITE_REG(&adapter->hw, ICS, mask); - msec_delay(10); - - if(adapter->diag_icr & mask) { - *param = IDIAG_E1000_INTR_TEST_FAILED_WHILE_DISABLED; - break; - } - - /* Enable the interrupt to be reported in - * the cause register and then force the same - * interrupt and see if one gets posted. If - * an interrupt was not posted to the bus, the - * test failed. - */ - adapter->diag_icr = 0; - E1000_WRITE_REG(&adapter->hw, IMS, mask); - E1000_WRITE_REG(&adapter->hw, ICS, mask); - msec_delay(10); - - if(!(adapter->diag_icr & mask)) { - *param = IDIAG_E1000_INTR_TEST_FAILED_WHILE_ENABLED; - break; - } - - /* Disable the other interrupts to be reported in - * the cause register and then force the other - * interrupts and see if any get posted. If - * an interrupt was posted to the bus, the - * test failed. - */ - adapter->diag_icr = 0; - E1000_WRITE_REG(&adapter->hw, IMC, ~mask); - E1000_WRITE_REG(&adapter->hw, ICS, ~mask); - msec_delay(10); - - if(adapter->diag_icr) { - *param = IDIAG_E1000_INTR_TEST_FAILED_MASKED_ENABLED; - break; - } - } - - /* Disable all the interrupts */ - E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); - msec_delay(10); - - /* Unhook diag interrupt handler */ - free_irq(netdev->irq, netdev); - - return (*param == - IDIAG_E1000_INTR_TEST_OK) ? IDIAG_PRO_STAT_OK : - IDIAG_PRO_STAT_TEST_FAILED; -} - -static void -e1000_free_desc_rings(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *txdr = &adapter->diag_tx_ring; - struct e1000_desc_ring *rxdr = &adapter->diag_rx_ring; - struct pci_dev *pdev = adapter->pdev; - int i; - - if(txdr->desc && txdr->buffer_info) { - for(i = 0; i < txdr->count; i++) { - if(txdr->buffer_info[i].dma) - pci_unmap_single(pdev, txdr->buffer_info[i].dma, - txdr->buffer_info[i].length, - PCI_DMA_TODEVICE); - if(txdr->buffer_info[i].skb) - dev_kfree_skb(txdr->buffer_info[i].skb); - } - } - - if(rxdr->desc && rxdr->buffer_info) { - for(i = 0; i < rxdr->count; i++) { - if(rxdr->buffer_info[i].dma) - pci_unmap_single(pdev, rxdr->buffer_info[i].dma, - rxdr->buffer_info[i].length, - PCI_DMA_FROMDEVICE); - if(rxdr->buffer_info[i].skb) - dev_kfree_skb(rxdr->buffer_info[i].skb); - } - } - - if(txdr->desc) - pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); - if(rxdr->desc) - pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); - - if(txdr->buffer_info) - kfree(txdr->buffer_info); - if(rxdr->buffer_info) - kfree(rxdr->buffer_info); - - return; -} - -static int -e1000_setup_desc_rings(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *txdr = &adapter->diag_tx_ring; - struct e1000_desc_ring *rxdr = &adapter->diag_rx_ring; - struct pci_dev *pdev = adapter->pdev; - uint32_t rctl; - int size, i; - - /* Setup Tx descriptor ring and Tx buffers */ - - txdr->count = 80; - - size = txdr->count * sizeof(struct e1000_buffer); - if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) - goto err_nomem; - memset(txdr->buffer_info, 0, size); - - txdr->size = txdr->count * sizeof(struct e1000_tx_desc); - E1000_ROUNDUP(txdr->size, 4096); - if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) - goto err_nomem; - memset(txdr->desc, 0, txdr->size); - txdr->next_to_use = txdr->next_to_clean = 0; - - E1000_WRITE_REG(&adapter->hw, TDBAL, - ((uint64_t) txdr->dma & 0x00000000FFFFFFFF)); - E1000_WRITE_REG(&adapter->hw, TDBAH, ((uint64_t) txdr->dma >> 32)); - E1000_WRITE_REG(&adapter->hw, TDLEN, - txdr->count * sizeof(struct e1000_tx_desc)); - E1000_WRITE_REG(&adapter->hw, TDH, 0); - E1000_WRITE_REG(&adapter->hw, TDT, 0); - E1000_WRITE_REG(&adapter->hw, TCTL, - E1000_TCTL_PSP | E1000_TCTL_EN | - E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | - E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT); - - for(i = 0; i < txdr->count; i++) { - struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i); - struct sk_buff *skb; - unsigned int size = 1024; - - if(!(skb = alloc_skb(size, GFP_KERNEL))) - goto err_nomem; - skb_put(skb, size); - txdr->buffer_info[i].skb = skb; - txdr->buffer_info[i].length = skb->len; - txdr->buffer_info[i].dma = - pci_map_single(pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); - tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma); - tx_desc->lower.data = cpu_to_le32(skb->len); - tx_desc->lower.data |= E1000_TXD_CMD_EOP; - tx_desc->lower.data |= E1000_TXD_CMD_IFCS; - tx_desc->lower.data |= E1000_TXD_CMD_RPS; - tx_desc->upper.data = 0; - } - - /* Setup Rx descriptor ring and Rx buffers */ - - rxdr->count = 80; - - size = rxdr->count * sizeof(struct e1000_buffer); - if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) - goto err_nomem; - memset(rxdr->buffer_info, 0, size); - - rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); - if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) - goto err_nomem; - memset(rxdr->desc, 0, rxdr->size); - rxdr->next_to_use = rxdr->next_to_clean = 0; - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN); - E1000_WRITE_REG(&adapter->hw, RDBAL, - ((uint64_t) rxdr->dma & 0xFFFFFFFF)); - E1000_WRITE_REG(&adapter->hw, RDBAH, ((uint64_t) rxdr->dma >> 32)); - E1000_WRITE_REG(&adapter->hw, RDLEN, rxdr->size); - E1000_WRITE_REG(&adapter->hw, RDH, 0); - E1000_WRITE_REG(&adapter->hw, RDT, 0); - rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | - E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | - (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT); - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - - for(i = 0; i < rxdr->count; i++) { - struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); - struct sk_buff *skb; - - if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL))) - goto err_nomem; - skb_reserve(skb, 2); - rxdr->buffer_info[i].skb = skb; - rxdr->buffer_info[i].length = E1000_RXBUFFER_2048; - rxdr->buffer_info[i].dma = - pci_map_single(pdev, skb->data, E1000_RXBUFFER_2048, - PCI_DMA_FROMDEVICE); - rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma); - memset(skb->data, 0x00, skb->len); - } - - return 0; - - err_nomem: - e1000_free_desc_rings(adapter); - return -ENOMEM; -} - -/** - * e1000_phy_disable_receiver - This routine disables the receiver - * during loopback testing to insure that if, in the middle of a - * loopback test, a link partner is connected, it won't change the - * speed or link status and thus cause a failure. - * - * @adapter: board private structure - **/ - -static void -e1000_phy_disable_receiver(struct e1000_adapter *adapter) -{ - /* Write out to PHY registers 29 and 30 to disable the Receiver. */ - e1000_write_phy_reg(&adapter->hw, 29, 0x001F); - e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC); - e1000_write_phy_reg(&adapter->hw, 29, 0x001A); - e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0); - - return; -} - -/** - * e1000_phy_reset_clk_and_crs - This routine resets the TX_CLK and - * TX_CRS registers on the non-integrated PHY. - * - * @adapter: board private structure - **/ - -static void -e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter) -{ - uint16_t phy_reg; - - /* Because we reset the PHY above, we need to re-force TX_CLK in the - * Extended PHY Specific Control Register to 25MHz clock. This - * value defaults back to a 2.5MHz clock when the PHY is reset. - */ - e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); - phy_reg |= M88E1000_EPSCR_TX_CLK_25; - e1000_write_phy_reg(&adapter->hw, - M88E1000_EXT_PHY_SPEC_CTRL, phy_reg); - - /* In addition, because of the s/w reset above, we need to enable - * CRS on TX. This must be set for both full and half duplex - * operation. - */ - e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); - phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - e1000_write_phy_reg(&adapter->hw, - M88E1000_PHY_SPEC_CTRL, phy_reg); -} - -/** - * e1000_nonintegrated_phy_loopback - This routine enables the PHY - * loopback circuit to work on the non-integrated PHY, under *any* link - * condition. - * - * @adapter: board private structure - * - * Returns 0 on success, 1 on failure - **/ - -static int -e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter) -{ - uint32_t ctrl_reg; - uint16_t phy_reg; - int status = 1; - - /* Setup the Device Control Register for PHY loopback test. */ - - ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); - ctrl_reg |= (E1000_CTRL_ILOS | /* Invert Loss-Of-Signal */ - E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ - E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ - E1000_CTRL_SPD_1000 | /* Force Speed to 1000 */ - E1000_CTRL_FD); /* Force Duplex to FULL */ - - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); - - /* Read the PHY Specific Control Register (0x10) */ - e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg); - - /* Clear Auto-Crossover bits in PHY Specific Control Register - * (bits 6:5). - */ - phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE; - e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg); - - /* Perform software reset on the PHY */ - e1000_phy_reset(&adapter->hw); - - /* Have to setup TX_CLK and TX_CRS after software reset */ - e1000_phy_reset_clk_and_crs(adapter); - - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); - - /* Wait for reset to complete. */ - usec_delay(500); - - /* Have to setup TX_CLK and TX_CRS after software reset */ - e1000_phy_reset_clk_and_crs(adapter); - - /* Write out to PHY registers 29 and 30 to disable the Receiver. */ - e1000_phy_disable_receiver(adapter); - - /* Set the loopback bit in the PHY control register. */ - e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); - phy_reg |= MII_CR_LOOPBACK; - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); - - /* Setup TX_CLK and TX_CRS one more time. */ - e1000_phy_reset_clk_and_crs(adapter); - - status = 0; - - /* Check Phy Configuration */ - e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); - if(phy_reg != 0x4100) { - status = 1; - } - - e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg); - if(phy_reg != 0x0070) { - status = 1; - } - - e1000_read_phy_reg(&adapter->hw, 29, &phy_reg); - if(phy_reg != 0x001A) { - status = 1; - } - - return status; -} - -/** - * e1000_integrated_phy_loopback - This routine is used by diagnostic - * software to put the 82544, 82540, 82545, and 82546 MAC based network - * cards into loopback mode. - * - * @adapter: board private structure - * @speed: speed - * - * Current procedure is to: - * 1) Disable auto-MDI/MDIX - * 2) Perform SW phy reset (bit 15 of PHY_CTRL) - * 3) Disable autoneg and reset - * 4) For the specified speed, set the loopback - * mode for that speed. Also force the MAC - * to the correct speed and duplex for the - * specified operation. - * 5) If this is an 82543, setup the TX_CLK and - * TX_CRS again. - * 6) Disable the receiver so a cable disconnect - * and reconnect will not cause autoneg to - * begin. - * - * Returns 0 on success, 1 on failure - **/ - -static int -e1000_integrated_phy_loopback(struct e1000_adapter *adapter, - uint16_t speed) -{ - uint32_t ctrl_reg = 0; - uint32_t stat_reg = 0; - boolean_t loopback_mode_set = FALSE; - - adapter->hw.autoneg = FALSE; - - /* Set up desired loopback speed and duplex depending on input - * into this function. - */ - switch (speed) { - case SPEED_1000: - /* Set up the MII control reg to the desired loopback speed. */ - - /* Auto-MDI/MDIX Off */ - e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, - 0x0808); - /* reset to update Auto-MDI/MDIX */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); - /* autoneg off */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); - /* force 1000, set loopback */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140); - - /* Now set up the MAC to the same speed/duplex as the PHY. */ - ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); - ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ - ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ - E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ - E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ - E1000_CTRL_FD); /* Force Duplex to FULL */ - - if(adapter->hw.media_type == e1000_media_type_copper) { - ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ - } else { - /* Set the ILOS bit on the fiber Nic is half - * duplex link is detected. */ - stat_reg = E1000_READ_REG(&adapter->hw, STATUS); - if((stat_reg & E1000_STATUS_FD) == 0) - ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); - } - - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); - loopback_mode_set = TRUE; - break; - - case SPEED_100: - /* Set up the MII control reg to the desired loopback speed. */ - - /* Auto-MDI/MDIX Off */ - e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, - 0x0808); - /* reset to update Auto-MDI/MDIX */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); - /* autoneg off */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); - /* reset to update autoneg */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); - /* MAC interface speed to 100Mbps */ - e1000_write_phy_reg(&adapter->hw, - M88E1000_EXT_PHY_SPEC_CTRL, 0x0c14); - /* reset to update MAC interface speed */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0xe100); - /* force 100, set loopback */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x6100); - - /* Now set up the MAC to the same speed/duplex as the PHY. */ - ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); - ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ - ctrl_reg |= (E1000_CTRL_ILOS | /* Invert Loss-Of-Signal */ - E1000_CTRL_SLU | /* Set the Force Link Bit */ - E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ - E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ - E1000_CTRL_SPD_100 |/* Force Speed to 100 */ - E1000_CTRL_FD); /* Force Duplex to FULL */ - - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); - loopback_mode_set = TRUE; - break; - - case SPEED_10: - /* Set up the MII control reg to the desired loopback speed. */ - - /* Auto-MDI/MDIX Off */ - e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, - 0x0808); - /* reset to update Auto-MDI/MDIX */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); - /* autoneg off */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); - /* reset to update autoneg */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); - /* MAC interface speed to 10Mbps */ - e1000_write_phy_reg(&adapter->hw, - M88E1000_EXT_PHY_SPEC_CTRL, 0x0c04); - /* reset to update MAC interface speed */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100); - /* force 10, set loopback */ - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4100); - - /* Now set up the MAC to the same speed/duplex as the PHY. */ - ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); - ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ - ctrl_reg |= (E1000_CTRL_SLU | /* Set the Force Link Bit */ - E1000_CTRL_FRCSPD |/* Set the Force Speed Bit */ - E1000_CTRL_FRCDPX |/* Set the Force Duplex Bit */ - E1000_CTRL_SPD_10 |/* Force Speed to 10 */ - E1000_CTRL_FD); /* Force Duplex to FULL */ - - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg); - loopback_mode_set = TRUE; - break; - - default: - loopback_mode_set = FALSE; - break; - } - - /* Disable the receiver on the PHY so when a cable is plugged - * in, the PHY does not begin to autoneg when a cable is - * reconnected to the NIC. - */ - e1000_phy_disable_receiver(adapter); - - usec_delay(500); - - return loopback_mode_set ? 0 : 1; -} - -/** - * e1000_set_phy_loopback - Set the PHY into loopback mode. - * @adapter: board private structure - * - * Returns 0 on success, 1 on failure - **/ - -static int -e1000_set_phy_loopback(struct e1000_adapter *adapter) -{ - uint16_t phy_reg = 0; - uint16_t speed = 0; - uint16_t duplex = 0; - int status = 1; - int count; - - switch (adapter->hw.mac_type) { - case e1000_82543: - if(adapter->hw.media_type == e1000_media_type_copper) { - /* Attempt to setup Loopback mode on Non- - * integrated PHY. Some PHY registers get - * corrupted at random, so attempt this - * 10 times. - */ - for(count = 0; count < 10; count++) - if(!e1000_nonintegrated_phy_loopback(adapter)) - break; - status = 0; - } - break; - - case e1000_82544: - if(adapter->hw.media_type == e1000_media_type_copper) - e1000_get_speed_and_duplex(&adapter->hw, &speed, - &duplex); - status = e1000_integrated_phy_loopback(adapter, speed); - break; - - case e1000_82540: - case e1000_82545: - case e1000_82546: - e1000_get_speed_and_duplex(&adapter->hw, &speed, &duplex); - status = e1000_integrated_phy_loopback(adapter, speed); - break; - - default: - /* Default PHY loopback work is to read the MII - * control register and assert bit 14 (loopback mode). - */ - e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); - phy_reg |= MII_CR_LOOPBACK; - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, - phy_reg); - status = 0; - break; - } - - return status; -} - -static int -e1000_set_loopback_mode(struct e1000_adapter *adapter, - enum idiag_e1000_diag_loopback_mode mode) -{ - uint32_t rctl; - uint16_t phy_reg; - int status = 1; - - switch (mode) { - - case IDIAG_E1000_DIAG_NONE_LB: - /* Clear bits 7:6 to turn off loopback mode */ - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - /* Only modify the GMII/MII PHY device if the - * media type is copper. - */ - if(adapter->hw.media_type == e1000_media_type_copper || - (adapter->hw.media_type == e1000_media_type_fiber && - (adapter->hw.mac_type == e1000_82545 || - adapter->hw.mac_type == e1000_82546))) { - adapter->hw.autoneg = TRUE; - /* De-assert bit 14 (loopback mode) in PHY */ - e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); - /* Only turn off PHY loopback if enabled */ - if(phy_reg & MII_CR_LOOPBACK) { - phy_reg &= ~MII_CR_LOOPBACK; - e1000_write_phy_reg(&adapter->hw, PHY_CTRL, - phy_reg); - /* Reset the PHY to make sure we - * regain link */ - e1000_phy_reset(&adapter->hw); - } - } - status = 0; - break; - - - case IDIAG_E1000_DIAG_MAC_LB: - /* Not supported */ - break; - - case IDIAG_E1000_DIAG_PHY_TCVR_LB: - if(adapter->hw.media_type == e1000_media_type_fiber) { - if(adapter->hw.mac_type == e1000_82545 || - adapter->hw.mac_type == e1000_82546) { - status = e1000_set_phy_loopback(adapter); - } else { - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl |= E1000_RCTL_LBM_TCVR; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - status = 0; - } - } - if(adapter->hw.media_type == e1000_media_type_copper) { - status = e1000_set_phy_loopback(adapter); - } - break; - } - - return status; -} - -static void -e1000_create_lbtest_frame(struct sk_buff *skb, - unsigned int frame_size) -{ - memset(skb->data, 0xFF, frame_size); - frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; - memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); - memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); - memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); -} - -static int -e1000_check_lbtest_frame(struct sk_buff *skb, - unsigned int frame_size) -{ - frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; - if(*(skb->data + 3) == 0xFF) { - if((*(skb->data + frame_size / 2 + 10) == 0xBE) && - (*(skb->data + frame_size / 2 + 12) == 0xAF)) { - return 1; - } - } - return 0; -} - -static enum idiag_e1000_diag_loopback_result -e1000_loopback_test(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *txdr = &adapter->diag_tx_ring; - struct e1000_desc_ring *rxdr = &adapter->diag_rx_ring; - struct pci_dev *pdev = adapter->pdev; - int i; - - E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); - - for(i = 0; i < 64; i++) { - e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); - pci_dma_sync_single(pdev, txdr->buffer_info[i].dma, - txdr->buffer_info[i].length, - PCI_DMA_TODEVICE); - } - E1000_WRITE_REG(&adapter->hw, TDT, i); - - msec_delay(200); - - pci_dma_sync_single(pdev, rxdr->buffer_info[0].dma, - rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE); - if(e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024)) - return IDIAG_E1000_LOOPBACK_TEST_OK; - else - return IDIAG_E1000_LOOPBACK_TEST_FAILED; -} - -static enum idiag_pro_stat -e1000_diag_loopback_test(struct e1000_adapter *adapter, - uint8_t *diag_param) -{ - struct idiag_e1000_diag_loopback_test_param *param = - (struct idiag_e1000_diag_loopback_test_param *) diag_param; - - if(param->mode == IDIAG_E1000_DIAG_MAC_LB) { - /* Loopback test not support */ - param->result = IDIAG_E1000_LOOPBACK_TEST_NOT_EXEC; - return IDIAG_PRO_STAT_NOT_SUPPORTED; - } - - if(e1000_setup_desc_rings(adapter)) { - param->result = IDIAG_E1000_LOOPBACK_TEST_NOT_EXEC; - return IDIAG_PRO_STAT_TEST_FAILED; - } - - if(e1000_set_loopback_mode(adapter, param->mode)) { - param->result = IDIAG_E1000_LOOPBACK_TEST_NOT_EXEC; - e1000_free_desc_rings(adapter); - return IDIAG_PRO_STAT_TEST_FAILED; - } - param->result = e1000_loopback_test(adapter); - e1000_set_loopback_mode(adapter, IDIAG_E1000_DIAG_NONE_LB); - - e1000_free_desc_rings(adapter); - - return (param->result == - IDIAG_E1000_LOOPBACK_TEST_OK) ? IDIAG_PRO_STAT_OK : - IDIAG_PRO_STAT_TEST_FAILED; -} - -static enum idiag_pro_stat -e1000_diag_link_test(struct e1000_adapter *adapter, - uint8_t *diag_param) -{ - e1000_check_for_link(&adapter->hw); - - if(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) - return IDIAG_PRO_STAT_OK; - else - return IDIAG_PRO_STAT_TEST_FAILED; -} - -int -e1000_diag_ioctl(struct net_device *netdev, - struct ifreq *ifr) -{ - struct e1000_adapter *adapter = netdev->priv; - struct idiag_pro_data *diag_data = - (struct idiag_pro_data *) ifr->ifr_data; - boolean_t run_offline; - boolean_t interface_up = netif_running(netdev); - - diag_data->status = IDIAG_PRO_STAT_NOT_SUPPORTED; - - if(!capable(CAP_NET_ADMIN)) - /* must have admin capabilities */ - return -EPERM; - - if(diag_data->interface_ver != IDIAG_PRO_VERSION) - /* incorrect diagnostics interface version */ - return -EFAULT; - - if(diag_data->cmd != IDIAG_PRO_IDENTIFY_DRIVER && - diag_data->driver_id != IDIAG_E1000_DRIVER) - /* incorrect driver identifier */ - return -EFAULT; - - /* Some test requring exclusive access to hardware, so - * we need to teardown the hardware setup, run the test, - * and restore the hardware to resume the network - * connection. - */ - run_offline = (diag_data->cmd == IDIAG_E1000_DIAG_REG_TEST || - diag_data->cmd == IDIAG_E1000_DIAG_INTR_TEST || - diag_data->cmd == IDIAG_E1000_DIAG_LOOPBACK_TEST); - - if(run_offline) { - if(interface_up) - e1000_down(adapter); - else - e1000_reset(adapter); - } - - /* Run the diagnotic test */ - switch (diag_data->cmd) { - - case IDIAG_PRO_IDENTIFY_DRIVER: - diag_data->driver_id = IDIAG_E1000_DRIVER; - diag_data->status = IDIAG_PRO_STAT_OK; - break; - - case IDIAG_E1000_DIAG_REG_TEST: - diag_data->status = - e1000_diag_reg_test(adapter, diag_data->diag_param); - break; - - case IDIAG_E1000_DIAG_XSUM_TEST: - diag_data->status = - e1000_diag_eeprom_test(adapter, diag_data->diag_param); - break; - - case IDIAG_E1000_DIAG_INTR_TEST: - diag_data->status = - e1000_diag_intr_test(adapter, diag_data->diag_param); - break; - - case IDIAG_E1000_DIAG_LOOPBACK_TEST: - diag_data->status = - e1000_diag_loopback_test(adapter, - diag_data->diag_param); - break; - - case IDIAG_E1000_DIAG_LINK_TEST: - diag_data->status = - e1000_diag_link_test(adapter, diag_data->diag_param); - break; - - default: - diag_data->status = IDIAG_PRO_STAT_NOT_SUPPORTED; - break; - } - - if(run_offline) { - e1000_reset(adapter); - if(interface_up) { - if(e1000_up(adapter)) { - diag_data->status = IDIAG_PRO_STAT_TEST_FATAL; - return -EFAULT; - } - } - } - - return 0; -} - diff -uNr click-1.5.0-dist/drivers/e1000-4.x/src/e1000_main.c.orig click-1.5.0/drivers/e1000-4.x/src/e1000_main.c.orig --- click-1.5.0-dist/drivers/e1000-4.x/src/e1000_main.c.orig Fri Nov 22 17:13:40 2002 +++ click-1.5.0/drivers/e1000-4.x/src/e1000_main.c.orig Thu Jan 1 01:00:00 1970 @@ -1,2536 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#define __E1000_MAIN__ -#ifdef IANS -#define _IANS_MAIN_MODULE_C_ -#endif -#include "e1000.h" - -/* Change Log - * - * 4.3.15 8/9/02 - * o Clean up: prepended a shortened version of the license that references - * the full license in LICENSE. - * o Clean up: copied small packets to small socket buffers for truesize - * bug that is exposed with the NFS mount daemon. - * o Clean up: added pci reads for pci posting issues. - * o Bug fix: added memory barriers for IA64. - * o Feature: added locking mechanism for asf functionality. - * - * 4.3.2 7/5/02 - * o Bug fix: perform controller reset using I/O rather than mmio because - * some chipsets try to perform a 64-bit write, but the controller ignores - * the upper 32-bit write once the reset is intiated by the lower 32-bit - * write, causing a master abort. - * o Bug fix: fixed jumbo frames sized from 1514 to 2048. - * o ASF support: disable ARP when driver is loaded or resumed; enable when - * driver is removed or suspended. - * o Bug fix: changed default setting for RxIntDelay to 0 for 82542/3/4 - * controllers to workaround h/w errata where controller will hang when - * RxIntDelay <> 0 under certian network conditions. - * o Clean up: removed unused and undocumented user-settable settings for - * PHY. - * o Bug fix: ethtool GEEPROM was using byte address rather than word - * addressing. - * o Feature: added support for ethtool SEEPROM. - * o Feature: added support for entropy pool. - * - * 4.2.17 5/30/02 - */ - -char e1000_driver_name[] = "e1000"; -char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "4.3.15"; -char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation."; - -/* e1000_pci_tbl - PCI Device ID Table - * - * Private driver_data field (last one) stores an index into e1000_strings - * Wildcard entries (PCI_ANY_ID) should come last - * Last entry must be all 0s - * - * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, - * Class, Class Mask, String Index } - */ -static struct pci_device_id e1000_pci_tbl[] __devinitdata = { - /* Intel(R) PRO/1000 Network Connection */ - {0x8086, 0x1000, 0x8086, 0x1000, 0, 0, 0}, - {0x8086, 0x1001, 0x8086, 0x1003, 0, 0, 0}, - {0x8086, 0x1004, 0x8086, 0x1004, 0, 0, 0}, - {0x8086, 0x1008, 0x8086, 0x1107, 0, 0, 0}, - {0x8086, 0x1009, 0x8086, 0x1109, 0, 0, 0}, - {0x8086, 0x100C, 0x8086, 0x1112, 0, 0, 0}, - {0x8086, 0x100E, 0x8086, 0x001E, 0, 0, 0}, - /* Compaq Gigabit Ethernet Server Adapter */ - {0x8086, 0x1000, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - {0x8086, 0x1001, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - {0x8086, 0x1004, 0x0E11, PCI_ANY_ID, 0, 0, 1}, - /* IBM Mobile, Desktop & Server Adapters */ - {0x8086, 0x1000, 0x1014, PCI_ANY_ID, 0, 0, 2}, - {0x8086, 0x1001, 0x1014, PCI_ANY_ID, 0, 0, 2}, - {0x8086, 0x1004, 0x1014, PCI_ANY_ID, 0, 0, 2}, - /* Generic */ - {0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x100C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - /* required last entry */ - {0,} -}; - -MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); - -static char *e1000_strings[] = { - "Intel(R) PRO/1000 Network Connection", - "Compaq Gigabit Ethernet Server Adapter", - "IBM Mobile, Desktop & Server Adapters" -}; - -/* Local Function Prototypes */ - -int e1000_up(struct e1000_adapter *adapter); -void e1000_down(struct e1000_adapter *adapter); -void e1000_reset(struct e1000_adapter *adapter); -void e1000_smbus_lock(struct pci_dev *pdev, boolean_t lock); - -static int e1000_init_module(void); -static void e1000_exit_module(void); -static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void e1000_remove(struct pci_dev *pdev); -static void e1000_sw_init(struct e1000_adapter *adapter); -static int e1000_open(struct net_device *netdev); -static int e1000_close(struct net_device *netdev); -static int e1000_setup_tx_resources(struct e1000_adapter *adapter); -static int e1000_setup_rx_resources(struct e1000_adapter *adapter); -static void e1000_configure_tx(struct e1000_adapter *adapter); -static void e1000_configure_rx(struct e1000_adapter *adapter); -static void e1000_setup_rctl(struct e1000_adapter *adapter); -static void e1000_clean_tx_ring(struct e1000_adapter *adapter); -static void e1000_clean_rx_ring(struct e1000_adapter *adapter); -static void e1000_free_tx_resources(struct e1000_adapter *adapter); -static void e1000_free_rx_resources(struct e1000_adapter *adapter); -static void e1000_set_multi(struct net_device *netdev); -static void e1000_update_phy_info(unsigned long data); -static void e1000_watchdog(unsigned long data); -static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); -static struct net_device_stats * e1000_get_stats(struct net_device *netdev); -static int e1000_change_mtu(struct net_device *netdev, int new_mtu); -static int e1000_set_mac(struct net_device *netdev, void *p); -static void e1000_update_stats(struct e1000_adapter *adapter); -static inline void e1000_irq_disable(struct e1000_adapter *adapter); -static inline void e1000_irq_enable(struct e1000_adapter *adapter); -static void e1000_intr(int irq, void *data, struct pt_regs *regs); -static void e1000_clean_tx_irq(struct e1000_adapter *adapter); -static void e1000_clean_rx_irq(struct e1000_adapter *adapter); -static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter); -static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); -static void e1000_enter_82542_rst(struct e1000_adapter *adapter); -static void e1000_leave_82542_rst(struct e1000_adapter *adapter); -static inline void e1000_rx_checksum(struct e1000_adapter *adapter, - struct e1000_rx_desc *rx_desc, - struct sk_buff *skb); -static boolean_t e1000_smbus_arp_enable(struct e1000_adapter *adapter, - boolean_t arp_enable); -#ifdef HAVE_TX_TIMEOUT -static void e1000_tx_timeout(struct net_device *dev); -#endif - -#ifdef NETIF_F_HW_VLAN_TX -static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); -static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); -static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); -#endif - -static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); -static int e1000_suspend(struct pci_dev *pdev, uint32_t state); -#ifdef CONFIG_PM -static int e1000_resume(struct pci_dev *pdev); -#endif - -struct notifier_block e1000_notifier = { - notifier_call: e1000_notify_reboot, - next: NULL, - priority: 0 -}; - -/* Exported from other modules */ - -extern void e1000_check_options(struct e1000_adapter *adapter); -extern void e1000_proc_dev_setup(struct e1000_adapter *adapter); -extern void e1000_proc_dev_free(struct e1000_adapter *adapter); -extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr); -#ifdef IDIAG -extern int e1000_diag_ioctl(struct net_device *netdev, struct ifreq *ifr); -#endif - -static struct pci_driver e1000_driver = { - name: e1000_driver_name, - id_table: e1000_pci_tbl, - probe: e1000_probe, - remove: __devexit_p(e1000_remove), - /* Power Managment Hooks */ -#ifdef CONFIG_PM - suspend: e1000_suspend, - resume: e1000_resume -#endif -}; - -MODULE_AUTHOR("Intel Corporation, "); -MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver"); -MODULE_LICENSE("GPL"); - -#ifdef EXPORT_SYMTAB -EXPORT_SYMBOL(e1000_smbus_lock); -#endif - -/** - * e1000_init_module - Driver Registration Routine - * - * e1000_init_module is the first routine called when the driver is - * loaded. All it does is register with the PCI subsystem. - **/ - -static int __init -e1000_init_module(void) -{ - int ret; - printk(KERN_INFO "%s - version %s\n", - e1000_driver_string, e1000_driver_version); - - printk(KERN_INFO "%s\n", e1000_copyright); - - ret = pci_module_init(&e1000_driver); - if(ret >= 0) - register_reboot_notifier(&e1000_notifier); - return ret; -} - -module_init(e1000_init_module); - -/** - * e1000_exit_module - Driver Exit Cleanup Routine - * - * e1000_exit_module is called just before the driver is removed - * from memory. - **/ - -static void __exit -e1000_exit_module(void) -{ - unregister_reboot_notifier(&e1000_notifier); - pci_unregister_driver(&e1000_driver); -} - -module_exit(e1000_exit_module); - - -int -e1000_up(struct e1000_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - - if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, - netdev->name, netdev)) - return -1; - - /* hardware has been reset, we need to reload some things */ - - e1000_set_multi(netdev); -#ifdef IANS - if((ANS_PRIVATE_DATA_FIELD(adapter)->tag_mode) != IANS_BD_TAGGING_NONE) - bd_ans_hw_EnableVLAN(adapter); -#endif - - e1000_configure_tx(adapter); - e1000_setup_rctl(adapter); - e1000_configure_rx(adapter); - e1000_alloc_rx_buffers(adapter); - - mod_timer(&adapter->watchdog_timer, jiffies); - e1000_irq_enable(adapter); - - return 0; -} - -void -e1000_down(struct e1000_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - - e1000_irq_disable(adapter); - free_irq(netdev->irq, netdev); - del_timer_sync(&adapter->watchdog_timer); - del_timer_sync(&adapter->phy_info_timer); - adapter->link_speed = 0; - adapter->link_duplex = 0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - e1000_reset(adapter); - e1000_clean_tx_ring(adapter); - e1000_clean_rx_ring(adapter); -} - -void -e1000_reset(struct e1000_adapter *adapter) -{ - /* Repartition Pba for greater than 9k mtu - * To take effect CTRL.RST is required. - */ - - if(adapter->rx_buffer_len > E1000_RXBUFFER_8192) - E1000_WRITE_REG(&adapter->hw, PBA, E1000_JUMBO_PBA); - else - E1000_WRITE_REG(&adapter->hw, PBA, E1000_DEFAULT_PBA); - - adapter->hw.fc = adapter->hw.original_fc; - down(&adapter->smbus_lock); - e1000_reset_hw(&adapter->hw); - up(&adapter->smbus_lock); - if(adapter->hw.mac_type >= e1000_82544) - E1000_WRITE_REG(&adapter->hw, WUC, 0); - e1000_init_hw(&adapter->hw); - e1000_reset_adaptive(&adapter->hw); - e1000_phy_get_info(&adapter->hw, &adapter->phy_info); -} - -/** - * e1000_probe - Device Initialization Routine - * @pdev: PCI device information struct - * @ent: entry in e1000_pci_tbl - * - * Returns 0 on success, negative on failure - * - * e1000_probe initializes an adapter identified by a pci_dev structure. - * The OS initialization, configuring of the adapter private structure, - * and a hardware reset occur. - **/ - -static int __devinit -e1000_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *netdev; - struct e1000_adapter *adapter; - static int cards_found = 0; - unsigned long mmio_start; - int mmio_len; - int pci_using_dac; - int i; - - if((i = pci_enable_device(pdev))) - return i; - - if(!(i = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) { - pci_using_dac = 1; - } else { - if((i = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) { - E1000_ERR("No usable DMA configuration, aborting\n"); - return i; - } - pci_using_dac = 0; - } - - if((i = pci_request_regions(pdev, e1000_driver_name))) - return i; - - pci_set_master(pdev); - - netdev = alloc_etherdev(sizeof(struct e1000_adapter)); - if(!netdev) - goto err_alloc_etherdev; - - SET_MODULE_OWNER(netdev); - - pci_set_drvdata(pdev, netdev); - adapter = netdev->priv; - adapter->netdev = netdev; - adapter->pdev = pdev; - adapter->hw.back = adapter; - - mmio_start = pci_resource_start(pdev, BAR_0); - mmio_len = pci_resource_len(pdev, BAR_0); - - adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); - if(!adapter->hw.hw_addr) - goto err_ioremap; - - for(i = BAR_1; i <= BAR_5; i++) { - if(pci_resource_len(pdev, i) == 0) - continue; - if(pci_resource_flags(pdev, i) & IORESOURCE_IO) { - adapter->hw.io_base = pci_resource_start(pdev, i); - break; - } - } - - netdev->open = &e1000_open; - netdev->stop = &e1000_close; - netdev->hard_start_xmit = &e1000_xmit_frame; - netdev->get_stats = &e1000_get_stats; - netdev->set_multicast_list = &e1000_set_multi; - netdev->set_mac_address = &e1000_set_mac; - netdev->change_mtu = &e1000_change_mtu; - netdev->do_ioctl = &e1000_ioctl; -#ifdef HAVE_TX_TIMEOUT - netdev->tx_timeout = &e1000_tx_timeout; - netdev->watchdog_timeo = HZ; -#endif -#ifdef NETIF_F_HW_VLAN_TX - netdev->vlan_rx_register = e1000_vlan_rx_register; - netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid; - netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid; -#endif - - netdev->irq = pdev->irq; - netdev->mem_start = mmio_start; - netdev->base_addr = adapter->hw.io_base; - - adapter->bd_number = cards_found; - adapter->id_string = e1000_strings[ent->driver_data]; - - /* setup the private structure */ - - e1000_sw_init(adapter); - -#ifdef MAX_SKB_FRAGS - if(adapter->hw.mac_type >= e1000_82543) { -#ifdef NETIF_F_HW_VLAN_TX - netdev->features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; -#else - netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM; -#endif - } else { - netdev->features = NETIF_F_SG; - } - - if(pci_using_dac) - netdev->features |= NETIF_F_HIGHDMA; -#endif - - /* make sure the EEPROM is good */ - - if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) { - printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n"); - goto err_eeprom; - } - - /* copy the MAC address out of the EEPROM */ - - e1000_read_mac_addr(&adapter->hw); - memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); - - if(!is_valid_ether_addr(netdev->dev_addr)) - goto err_eeprom; - - e1000_read_part_num(&adapter->hw, &(adapter->part_num)); - - e1000_get_bus_info(&adapter->hw); - - if((adapter->hw.mac_type == e1000_82544) && - (adapter->hw.bus_type == e1000_bus_type_pcix)) - - adapter->max_data_per_txd = 4096; - else - adapter->max_data_per_txd = MAX_JUMBO_FRAME_SIZE; - -#ifdef IANS - adapter->iANSdata = kmalloc(sizeof(iANSsupport_t), GFP_KERNEL); - - if(!adapter->iANSdata) - goto err_eeprom; - - memset(adapter->iANSdata, 0, sizeof(iANSsupport_t)); - bd_ans_drv_InitANS(adapter, adapter->iANSdata); -#endif - - init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &e1000_watchdog; - adapter->watchdog_timer.data = (unsigned long) adapter; - - init_timer(&adapter->phy_info_timer); - adapter->phy_info_timer.function = &e1000_update_phy_info; - adapter->phy_info_timer.data = (unsigned long) adapter; - - register_netdev(netdev); - - /* we're going to reset, so assume we have no link for now */ - - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string); - e1000_check_options(adapter); - e1000_proc_dev_setup(adapter); - - /* Initial Wake on LAN setting - * If APM wake is enabled in the EEPROM, - * enable the ACPI Magic Packet filter - */ - - if((adapter->hw.mac_type >= e1000_82544) && - (E1000_READ_REG(&adapter->hw, WUC) & E1000_WUC_APME)) - adapter->wol |= E1000_WUFC_MAG; - - /* reset the hardware with the new settings */ - - e1000_reset(adapter); - - cards_found++; - return 0; - -err_eeprom: - iounmap(adapter->hw.hw_addr); -err_ioremap: - pci_release_regions(pdev); - kfree(netdev); -err_alloc_etherdev: - return -ENOMEM; -} - -/** - * e1000_remove - Device Removal Routine - * @pdev: PCI device information struct - * - * e1000_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. The could be caused by a - * Hot-Plug event, or because the driver is going to be removed from - * memory. - **/ - -static void __devexit -e1000_remove(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct e1000_adapter *adapter = netdev->priv; - - e1000_smbus_arp_enable(adapter, TRUE); - - unregister_netdev(netdev); - - e1000_phy_hw_reset(&adapter->hw); - - e1000_proc_dev_free(adapter); - -#ifdef IANS - if(adapter->iANSdata) - kfree(adapter->iANSdata); -#endif - iounmap(adapter->hw.hw_addr); - pci_release_regions(pdev); - - kfree(netdev); -} - -/** - * e1000_sw_init - Initialize general software structures (struct e1000_adapter) - * @adapter: board private structure to initialize - * - * e1000_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). - **/ - -static void __devinit -e1000_sw_init(struct e1000_adapter *adapter) -{ - struct e1000_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* PCI config space info */ - - pci_read_config_word(pdev, PCI_VENDOR_ID, &hw->vendor_id); - pci_read_config_word(pdev, PCI_DEVICE_ID, &hw->device_id); - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, - &hw->subsystem_vendor_id); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id); - - pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - hw->max_frame_size = netdev->mtu + - ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; - - /* identify the MAC */ - - if (e1000_set_mac_type(hw)) { - E1000_ERR("Unknown MAC Type\n"); - BUG(); - } - - /* flow control settings */ - - hw->fc_high_water = FC_DEFAULT_HI_THRESH; - hw->fc_low_water = FC_DEFAULT_LO_THRESH; - hw->fc_pause_time = FC_DEFAULT_TX_TIMER; - hw->fc_send_xon = 1; - - /* Media type - copper or fiber */ - - if(hw->mac_type >= e1000_82543) { - uint32_t status = E1000_READ_REG(hw, STATUS); - - if(status & E1000_STATUS_TBIMODE) - hw->media_type = e1000_media_type_fiber; - else - hw->media_type = e1000_media_type_copper; - } else { - hw->media_type = e1000_media_type_fiber; - } - - if(hw->mac_type < e1000_82543) - hw->report_tx_early = 0; - else - hw->report_tx_early = 1; - - hw->wait_autoneg_complete = FALSE; - hw->tbi_compatibility_en = TRUE; - hw->adaptive_ifs = TRUE; - - /* Copper options */ - - if(hw->media_type == e1000_media_type_copper) { - hw->mdix = AUTO_ALL_MODES; - hw->disable_polarity_correction = FALSE; - } - - atomic_set(&adapter->irq_sem, 1); - spin_lock_init(&adapter->stats_lock); - init_MUTEX(&adapter->smbus_lock); -} - -/** - * e1000_open - Called when a network interface is made active - * @netdev: network interface device structure - * - * Returns 0 on success, negative value on failure - * - * The open entry point is called when a network interface is made - * active by the system (IFF_UP). At this point all resources needed - * for transmit and receive operations are allocated, the interrupt - * handler is registered with the OS, the watchdog timer is started, - * and the stack is notified that the interface is ready. - **/ - -static int -e1000_open(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - - /* allocate transmit descriptors */ - - if(e1000_setup_tx_resources(adapter)) - goto err_setup_tx; - - /* allocate receive descriptors */ - - if(e1000_setup_rx_resources(adapter)) - goto err_setup_rx; - - if(e1000_up(adapter)) - goto err_up; - - MOD_INC_USE_COUNT; - return 0; - -err_up: - e1000_free_rx_resources(adapter); -err_setup_rx: - e1000_free_tx_resources(adapter); -err_setup_tx: - e1000_reset(adapter); - - return -EBUSY; -} - -/** - * e1000_close - Disables a network interface - * @netdev: network interface device structure - * - * Returns 0, this is not allowed to fail - * - * The close entry point is called when an interface is de-activated - * by the OS. The hardware is still under the drivers control, but - * needs to be disabled. A global MAC reset is issued to stop the - * hardware, and all transmit and receive resources are freed. - **/ - -static int -e1000_close(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - - e1000_down(adapter); - - e1000_free_tx_resources(adapter); - e1000_free_rx_resources(adapter); - - MOD_DEC_USE_COUNT; - return 0; -} - -/** - * e1000_setup_tx_resources - allocate Tx resources (Descriptors) - * @adapter: board private structure - * - * Return 0 on success, negative on failure - **/ - -static int -e1000_setup_tx_resources(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *txdr = &adapter->tx_ring; - struct pci_dev *pdev = adapter->pdev; - int size; - - size = sizeof(struct e1000_buffer) * txdr->count; - txdr->buffer_info = kmalloc(size, GFP_KERNEL); - if(!txdr->buffer_info) { - return -ENOMEM; - } - memset(txdr->buffer_info, 0, size); - - /* round up to nearest 4K */ - - txdr->size = txdr->count * sizeof(struct e1000_tx_desc); - E1000_ROUNDUP(txdr->size, 4096); - - txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); - if(!txdr->desc) { - kfree(txdr->buffer_info); - return -ENOMEM; - } - memset(txdr->desc, 0, txdr->size); - - txdr->next_to_use = 0; - txdr->next_to_clean = 0; - - return 0; -} - -/** - * e1000_configure_tx - Configure 8254x Transmit Unit after Reset - * @adapter: board private structure - * - * Configure the Tx unit of the MAC after a reset. - **/ - -static void -e1000_configure_tx(struct e1000_adapter *adapter) -{ - uint64_t tdba = adapter->tx_ring.dma; - uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc); - uint32_t tctl, tipg; - - E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL)); - E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32)); - - E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen); - - /* Setup the HW Tx Head and Tail descriptor pointers */ - - E1000_WRITE_REG(&adapter->hw, TDH, 0); - E1000_WRITE_REG(&adapter->hw, TDT, 0); - - /* Set the default values for the Tx Inter Packet Gap timer */ - - switch (adapter->hw.mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - tipg = DEFAULT_82542_TIPG_IPGT; - tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; - break; - default: - if(adapter->hw.media_type == e1000_media_type_fiber) - tipg = DEFAULT_82543_TIPG_IPGT_FIBER; - else - tipg = DEFAULT_82543_TIPG_IPGT_COPPER; - tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; - } - E1000_WRITE_REG(&adapter->hw, TIPG, tipg); - - /* Set the Tx Interrupt Delay register */ - - E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay); - if(adapter->hw.mac_type >= e1000_82540) - E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay); - - /* Program the Transmit Control Register */ - - tctl = E1000_READ_REG(&adapter->hw, TCTL); - - tctl &= ~E1000_TCTL_CT; - tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | - (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); - - E1000_WRITE_REG(&adapter->hw, TCTL, tctl); - - e1000_config_collision_dist(&adapter->hw); - - /* Setup Transmit Descriptor Settings for this adapter */ - adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE; - - if(adapter->hw.report_tx_early == 1) - adapter->txd_cmd |= E1000_TXD_CMD_RS; - else - adapter->txd_cmd |= E1000_TXD_CMD_RPS; -} - -/** - * e1000_setup_rx_resources - allocate Rx resources (Descriptors) - * @adapter: board private structure - * - * Returns 0 on success, negative on failure - **/ - -static int -e1000_setup_rx_resources(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *rxdr = &adapter->rx_ring; - struct pci_dev *pdev = adapter->pdev; - int size; - - size = sizeof(struct e1000_buffer) * rxdr->count; - rxdr->buffer_info = kmalloc(size, GFP_KERNEL); - if(!rxdr->buffer_info) { - return -ENOMEM; - } - memset(rxdr->buffer_info, 0, size); - - /* Round up to nearest 4K */ - - rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); - E1000_ROUNDUP(rxdr->size, 4096); - - rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); - - if(!rxdr->desc) { - kfree(rxdr->buffer_info); - return -ENOMEM; - } - memset(rxdr->desc, 0, rxdr->size); - - rxdr->next_to_clean = 0; - rxdr->next_to_use = 0; - - return 0; -} - -/** - * e1000_setup_rctl - configure the receive control register - * @adapter: Board private structure - **/ - -static void -e1000_setup_rctl(struct e1000_adapter *adapter) -{ - uint32_t rctl; - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - - rctl &= ~(3 << E1000_RCTL_MO_SHIFT); - - rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | - E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | - (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT); - - if(adapter->hw.tbi_compatibility_on == 1) - rctl |= E1000_RCTL_SBP; - else - rctl &= ~E1000_RCTL_SBP; - - rctl &= ~(E1000_RCTL_SZ_4096); - switch (adapter->rx_buffer_len) { - case E1000_RXBUFFER_2048: - default: - rctl |= E1000_RCTL_SZ_2048; - rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); - break; - case E1000_RXBUFFER_4096: - rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case E1000_RXBUFFER_8192: - rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - case E1000_RXBUFFER_16384: - rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE; - break; - } - - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); -} - -/** - * e1000_configure_rx - Configure 8254x Receive Unit after Reset - * @adapter: board private structure - * - * Configure the Rx unit of the MAC after a reset. - **/ - -static void -e1000_configure_rx(struct e1000_adapter *adapter) -{ - uint64_t rdba = adapter->rx_ring.dma; - uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc); - uint32_t rctl; - uint32_t rxcsum; - - /* make sure receives are disabled while setting up the descriptors */ - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN); - - /* set the Receive Delay Timer Register */ - - if(adapter->hw.mac_type >= e1000_82540) { - E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay); - E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay); - - /* Set the interrupt throttling rate. Value is calculated - * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */ -#define MAX_INTS_PER_SEC 8000 -#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) - E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR); - -#ifdef HAVE_TX_TIMEOUT - } else { - E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay); -#endif - } - - /* Setup the Base and Length of the Rx Descriptor Ring */ - - E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL)); - E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32)); - - E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen); - - /* Setup the HW Rx Head and Tail Descriptor Pointers */ - E1000_WRITE_REG(&adapter->hw, RDH, 0); - E1000_WRITE_REG(&adapter->hw, RDT, 0); - - /* Enable 82543 Receive Checksum Offload for TCP and UDP */ - if((adapter->hw.mac_type >= e1000_82543) && - (adapter->rx_csum == TRUE)) { - rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM); - rxcsum |= E1000_RXCSUM_TUOFL; - E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum); - } - - /* Enable Receives */ - - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); -} - -/** - * e1000_free_tx_resources - Free Tx Resources - * @adapter: board private structure - * - * Free all transmit software resources - **/ - -static void -e1000_free_tx_resources(struct e1000_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - - e1000_clean_tx_ring(adapter); - - kfree(adapter->tx_ring.buffer_info); - adapter->tx_ring.buffer_info = NULL; - - pci_free_consistent(pdev, adapter->tx_ring.size, - adapter->tx_ring.desc, adapter->tx_ring.dma); - - adapter->tx_ring.desc = NULL; -} - -/** - * e1000_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure - **/ - -static void -e1000_clean_tx_ring(struct e1000_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - int i; - - /* Free all the Tx ring sk_buffs */ - - for(i = 0; i < adapter->tx_ring.count; i++) { - if(adapter->tx_ring.buffer_info[i].skb) { - - pci_unmap_page(pdev, - adapter->tx_ring.buffer_info[i].dma, - adapter->tx_ring.buffer_info[i].length, - PCI_DMA_TODEVICE); - - dev_kfree_skb(adapter->tx_ring.buffer_info[i].skb); - - adapter->tx_ring.buffer_info[i].skb = NULL; - } - } - - size = sizeof(struct e1000_buffer) * adapter->tx_ring.count; - memset(adapter->tx_ring.buffer_info, 0, size); - - /* Zero out the descriptor ring */ - - memset(adapter->tx_ring.desc, 0, adapter->tx_ring.size); - - adapter->tx_ring.next_to_use = 0; - adapter->tx_ring.next_to_clean = 0; - - E1000_WRITE_REG(&adapter->hw, TDH, 0); - E1000_WRITE_REG(&adapter->hw, TDT, 0); -} - -/** - * e1000_free_rx_resources - Free Rx Resources - * @adapter: board private structure - * - * Free all receive software resources - **/ - -static void -e1000_free_rx_resources(struct e1000_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - - e1000_clean_rx_ring(adapter); - - kfree(adapter->rx_ring.buffer_info); - adapter->rx_ring.buffer_info = NULL; - - pci_free_consistent(pdev, adapter->rx_ring.size, - adapter->rx_ring.desc, adapter->rx_ring.dma); - - adapter->rx_ring.desc = NULL; -} - -/** - * e1000_clean_rx_ring - Free Rx Buffers - * @adapter: board private structure - **/ - -static void -e1000_clean_rx_ring(struct e1000_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - int i; - - /* Free all the Rx ring sk_buffs */ - - for(i = 0; i < adapter->rx_ring.count; i++) { - if(adapter->rx_ring.buffer_info[i].skb) { - - pci_unmap_single(pdev, - adapter->rx_ring.buffer_info[i].dma, - adapter->rx_ring.buffer_info[i].length, - PCI_DMA_FROMDEVICE); - - dev_kfree_skb(adapter->rx_ring.buffer_info[i].skb); - - adapter->rx_ring.buffer_info[i].skb = NULL; - } - } - - size = sizeof(struct e1000_buffer) * adapter->rx_ring.count; - memset(adapter->rx_ring.buffer_info, 0, size); - - /* Zero out the descriptor ring */ - - memset(adapter->rx_ring.desc, 0, adapter->rx_ring.size); - - adapter->rx_ring.next_to_clean = 0; - adapter->rx_ring.next_to_use = 0; - - E1000_WRITE_REG(&adapter->hw, RDH, 0); - E1000_WRITE_REG(&adapter->hw, RDT, 0); -} - -/* The 82542 2.0 (revision 2) needs to have the receive unit in reset - * and memory write and invalidate disabled for certain operations - */ -static void -e1000_enter_82542_rst(struct e1000_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - uint32_t rctl; - - e1000_pci_clear_mwi(&adapter->hw); - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl |= E1000_RCTL_RST; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - E1000_WRITE_FLUSH(&adapter->hw); - mdelay(5); - - if(netif_running(netdev)) - e1000_clean_rx_ring(adapter); -} - -static void -e1000_leave_82542_rst(struct e1000_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - uint32_t rctl; - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl &= ~E1000_RCTL_RST; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - E1000_WRITE_FLUSH(&adapter->hw); - mdelay(5); - - if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE) - e1000_pci_set_mwi(&adapter->hw); - - if(netif_running(netdev)) { - e1000_configure_rx(adapter); - e1000_alloc_rx_buffers(adapter); - } -} - -/** - * e1000_set_mac - Change the Ethernet Address of the NIC - * @netdev: network interface device structure - * @p: pointer to an address structure - * - * Returns 0 on success, negative on failure - **/ - -static int -e1000_set_mac(struct net_device *netdev, void *p) -{ - struct e1000_adapter *adapter = netdev->priv; - struct sockaddr *addr = p; - - /* 82542 2.0 needs to be in reset to write receive address registers */ - - if(adapter->hw.mac_type == e1000_82542_rev2_0) - e1000_enter_82542_rst(adapter); - - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); - - e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0); - - if(adapter->hw.mac_type == e1000_82542_rev2_0) - e1000_leave_82542_rst(adapter); - - return 0; -} - -/** - * e1000_set_multi - Multicast and Promiscuous mode set - * @netdev: network interface device structure - * - * The set_multi entry point is called whenever the multicast address - * list or the network interface flags are updated. This routine is - * resposible for configuring the hardware for proper multicast, - * promiscuous mode, and all-multi behavior. - **/ - -static void -e1000_set_multi(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - struct e1000_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr; - uint32_t rctl; - uint32_t hash_value; - int i; - - /* Check for Promiscuous and All Multicast modes */ - - rctl = E1000_READ_REG(hw, RCTL); - - if(netdev->flags & IFF_PROMISC) { - rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); - } else if(netdev->flags & IFF_ALLMULTI) { - rctl |= E1000_RCTL_MPE; - rctl &= ~E1000_RCTL_UPE; - } else { - rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); - } - - E1000_WRITE_REG(hw, RCTL, rctl); - - /* 82542 2.0 needs to be in reset to write receive address registers */ - - if(hw->mac_type == e1000_82542_rev2_0) - e1000_enter_82542_rst(adapter); - - /* load the first 15 multicast address into the exact filters 1-15 - * RAR 0 is used for the station MAC adddress - * if there are not 15 addresses, go ahead and clear the filters - */ - mc_ptr = netdev->mc_list; - - for(i = 1; i < E1000_RAR_ENTRIES; i++) { - if(mc_ptr) { - e1000_rar_set(hw, mc_ptr->dmi_addr, i); - mc_ptr = mc_ptr->next; - } else { - E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); - E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0); - } - } - - /* clear the old settings from the multicast hash table */ - - for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) - E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); - - /* load any remaining addresses into the hash table */ - - for(; mc_ptr; mc_ptr = mc_ptr->next) { - hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr); - e1000_mta_set(hw, hash_value); - } - - if(hw->mac_type == e1000_82542_rev2_0) - e1000_leave_82542_rst(adapter); -} - -#ifdef IANS - -static void -e1000_tx_flush(struct e1000_adapter *adapter) -{ - uint32_t ctrl, tctl, txcw, icr; - - e1000_irq_disable(adapter); - - /* TODO , does the ILOS trick work for 82542 also? */ - - if(adapter->hw.mac_type < e1000_82543) { - /* Transmit Unit Reset */ - - tctl = E1000_READ_REG(&adapter->hw, TCTL); - E1000_WRITE_REG(&adapter->hw, TCTL, tctl | E1000_TCTL_RST); - E1000_WRITE_REG(&adapter->hw, TCTL, tctl); - e1000_clean_tx_ring(adapter); - e1000_configure_tx(adapter); - - } else { - /* turn off autoneg, set link up, and invert loss of signal */ - - txcw = E1000_READ_REG(&adapter->hw, TXCW); - E1000_WRITE_REG(&adapter->hw, TXCW, txcw & ~E1000_TXCW_ANE); - - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl | E1000_CTRL_SLU | E1000_CTRL_ILOS); - - /* delay to flush queue, then clean up */ - - mdelay(10); - - e1000_clean_tx_irq(adapter); - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - E1000_WRITE_REG(&adapter->hw, TXCW, txcw); - - /* clear the link status change interrupts this caused */ - - icr = E1000_READ_REG(&adapter->hw, ICR); - } - - e1000_irq_enable(adapter); -} - -#endif - -/* need to wait a few seconds after link up to get diagnostic information from the phy */ - -static void -e1000_update_phy_info(unsigned long data) -{ - struct e1000_adapter *adapter = (struct e1000_adapter *) data; - e1000_phy_get_info(&adapter->hw, &adapter->phy_info); -} - -/** - * e1000_watchdog - Timer Call-back - * @data: pointer to netdev cast into an unsigned long - **/ - -static void -e1000_watchdog(unsigned long data) -{ - struct e1000_adapter *adapter = (struct e1000_adapter *) data; - struct net_device *netdev = adapter->netdev; - struct e1000_desc_ring *txdr = &adapter->tx_ring; - int i; - - e1000_check_for_link(&adapter->hw); - - if(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) { - if(!netif_carrier_ok(netdev)) { -#ifdef IANS - if((adapter->iANSdata->iANS_status == IANS_COMMUNICATION_UP) && - (adapter->iANSdata->reporting_mode == IANS_STATUS_REPORTING_ON)) - if(ans_notify) - ans_notify(netdev, IANS_IND_XMIT_QUEUE_READY); -#endif - e1000_get_speed_and_duplex(&adapter->hw, - &adapter->link_speed, - &adapter->link_duplex); - - printk(KERN_INFO - "e1000: %s NIC Link is Up %d Mbps %s\n", - netdev->name, adapter->link_speed, - adapter->link_duplex == FULL_DUPLEX ? - "Full Duplex" : "Half Duplex"); - - netif_carrier_on(netdev); - netif_wake_queue(netdev); - mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); - } - } else { - if(netif_carrier_ok(netdev)) { - adapter->link_speed = 0; - adapter->link_duplex = 0; - printk(KERN_INFO - "e1000: %s NIC Link is Down\n", - netdev->name); - netif_carrier_off(netdev); - netif_stop_queue(netdev); - mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); - } - } - - e1000_update_stats(adapter); - e1000_update_adaptive(&adapter->hw); - -#ifdef IANS -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) - unsigned long flags; -#endif - if(adapter->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - - if(adapter->iANSdata->reporting_mode == IANS_STATUS_REPORTING_ON) - bd_ans_os_Watchdog(netdev, adapter); - - if(!netif_carrier_ok(netdev)) { - /* don't sit on SKBs while link is down */ - - if(E1000_DESC_UNUSED(&adapter->tx_ring) + 1 < adapter->tx_ring.count) { - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) - spin_lock_irqsave(&netdev->xmit_lock, flags); - e1000_tx_flush(adapter); - spin_unlock_irqrestore(&netdev->xmit_lock, flags); -#else - e1000_tx_flush(adapter); -#endif - } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) - spin_lock_irqsave(&netdev->queue_lock, flags); - qdisc_reset(netdev->qdisc); - spin_unlock_irqrestore(&netdev->queue_lock, flags); -#else - qdisc_reset(netdev->qdisc); -#endif - } - } -} -#endif - /* Early detection of hung controller */ - i = txdr->next_to_clean; - if(txdr->buffer_info[i].dma && - time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) && - !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) - netif_stop_queue(netdev); - - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); -} - -#define E1000_TX_FLAGS_CSUM 0x00000001 -#define E1000_TX_FLAGS_VLAN 0x00000002 -#define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 -#define E1000_TX_FLAGS_VLAN_SHIFT 16 - -static inline boolean_t -e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) -{ - struct e1000_context_desc *context_desc; - int i; - uint8_t css, cso; - - if(skb->ip_summed == CHECKSUM_HW) { - css = skb->h.raw - skb->data; - cso = (skb->h.raw + skb->csum) - skb->data; - - i = adapter->tx_ring.next_to_use; - context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i); - - context_desc->upper_setup.tcp_fields.tucss = css; - context_desc->upper_setup.tcp_fields.tucso = cso; - context_desc->upper_setup.tcp_fields.tucse = 0; - context_desc->tcp_seg_setup.data = 0; - context_desc->cmd_and_length = - cpu_to_le32(adapter->txd_cmd | E1000_TXD_CMD_DEXT); - - i = (i + 1) % adapter->tx_ring.count; - adapter->tx_ring.next_to_use = i; - - return TRUE; - } - - return FALSE; -} - -static inline int -e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb) -{ - struct e1000_desc_ring *tx_ring = &adapter->tx_ring; - int len, offset, size, count, i; - -#ifdef MAX_SKB_FRAGS - int f; - len = skb->len - skb->data_len; -#else - len = skb->len; -#endif - - i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count; - count = 0; - - offset = 0; - - while(len) { - i = (i + 1) % tx_ring->count; - size = min(len, adapter->max_data_per_txd); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = - pci_map_single(adapter->pdev, - skb->data + offset, - size, - PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; - - len -= size; - offset += size; - count++; - } - -#ifdef MAX_SKB_FRAGS - for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) { - struct skb_frag_struct *frag; - - frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; - offset = 0; - - while(len) { - i = (i + 1) % tx_ring->count; - size = min(len, adapter->max_data_per_txd); - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = - pci_map_page(adapter->pdev, - frag->page, - frag->page_offset + offset, - size, - PCI_DMA_TODEVICE); - - len -= size; - offset += size; - count++; - } - } -#endif - tx_ring->buffer_info[i].skb = skb; - - return count; -} - -static inline void -e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags) -{ - struct e1000_desc_ring *tx_ring = &adapter->tx_ring; - struct e1000_tx_desc *tx_desc = NULL; - uint32_t txd_upper, txd_lower; - int i; - - txd_upper = 0; - txd_lower = adapter->txd_cmd; - - if(tx_flags & E1000_TX_FLAGS_CSUM) { - txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; - txd_upper |= E1000_TXD_POPTS_TXSM << 8; - } - - if(tx_flags & E1000_TX_FLAGS_VLAN) { - txd_lower |= E1000_TXD_CMD_VLE; - txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK); - } - - i = tx_ring->next_to_use; - - while(count--) { - tx_desc = E1000_TX_DESC(*tx_ring, i); - tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); - tx_desc->lower.data = - cpu_to_le32(txd_lower | tx_ring->buffer_info[i].length); - tx_desc->upper.data = cpu_to_le32(txd_upper); - i = (i + 1) % tx_ring->count; - } - - tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP); - - /* Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). */ - wmb(); - - tx_ring->next_to_use = i; - E1000_WRITE_REG(&adapter->hw, TDT, i); -} - -#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0)) -#ifdef IANS -#define ANS_XMIT_FULL() do { \ - iANSsupport_t *ans = adapter->iANSdata; \ - if((ans->iANS_status == IANS_COMMUNICATION_UP) && \ - (ans->reporting_mode == IANS_STATUS_REPORTING_ON) && \ - (ans_notify)) \ - ans_notify(netdev, IANS_IND_XMIT_QUEUE_FULL); \ -} while (0) -#endif - -static int -e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - int tx_flags = 0, count; - -#ifdef MAX_SKB_FRAGS - int f; -#endif - - if(!netif_carrier_ok(netdev)) { - netif_stop_queue(netdev); -#ifdef IANS - ANS_XMIT_FULL(); -#endif - return 1; - } - -#ifdef MAX_SKB_FRAGS - count = TXD_USE_COUNT(skb->len - skb->data_len, - adapter->max_data_per_txd); - for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, - adapter->max_data_per_txd); - if(skb->ip_summed == CHECKSUM_HW) - count++; -#else - count = TXD_USE_COUNT(skb->len, adapter->max_data_per_txd); -#endif - - if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) { - netif_stop_queue(netdev); -#ifdef IANS - ANS_XMIT_FULL(); -#endif - return 1; - } - - if(e1000_tx_csum(adapter, skb)) - tx_flags |= E1000_TX_FLAGS_CSUM; - -#ifdef IANS -if(adapter->iANSdata->iANS_status == IANS_COMMUNICATION_UP) { - struct e1000_tx_desc *tx_desc; - tx_desc = E1000_TX_DESC(adapter->tx_ring, adapter->tx_ring.next_to_use); - - if(bd_ans_os_Transmit(adapter, tx_desc, &skb) == BD_ANS_FAILURE) - return 1; - - if(tx_desc->lower.data & E1000_TXD_CMD_VLE) { - tx_flags |= E1000_TX_FLAGS_VLAN; - tx_flags |= (tx_desc->upper.data & E1000_TX_FLAGS_VLAN_MASK); - } -} -#endif -#ifdef NETIF_F_HW_VLAN_TX - if(adapter->vlgrp && vlan_tx_tag_present(skb)) { - tx_flags |= E1000_TX_FLAGS_VLAN; - tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); - } -#endif - - count = e1000_tx_map(adapter, skb); - - e1000_tx_queue(adapter, count, tx_flags); - - netdev->trans_start = jiffies; - - return 0; -} - -#ifdef HAVE_TX_TIMEOUT -/** - * e1000_tx_timeout - Respond to a Tx Hang - * @netdev: network interface device structure - **/ - -static void -e1000_tx_timeout(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - - e1000_down(adapter); -#ifdef IANS - if((adapter->iANSdata->iANS_status == IANS_COMMUNICATION_UP) && - (adapter->iANSdata->reporting_mode == IANS_STATUS_REPORTING_ON)) { - netif_carrier_off(netdev); - bd_ans_os_Watchdog(netdev, adapter); - netif_carrier_on(netdev); - } -#endif - e1000_up(adapter); -} -#endif - -/** - * e1000_get_stats - Get System Network Statistics - * @netdev: network interface device structure - * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. - **/ - -static struct net_device_stats * -e1000_get_stats(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev->priv; - - return &adapter->net_stats; -} - -/** - * e1000_change_mtu - Change the Maximum Transfer Unit - * @netdev: network interface device structure - * @new_mtu: new value for maximum frame size - * - * Returns 0 on success, negative on failure - **/ - -static int -e1000_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct e1000_adapter *adapter = netdev->priv; - int old_mtu = adapter->rx_buffer_len; - int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - - if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || - (max_frame > MAX_JUMBO_FRAME_SIZE)) { - E1000_ERR("Invalid MTU setting\n"); - return -EINVAL; - } - - if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) { - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - - } else if(adapter->hw.mac_type < e1000_82543) { - E1000_ERR("Jumbo Frames not supported on 82542\n"); - return -EINVAL; - - } else if(max_frame <= E1000_RXBUFFER_4096) { - adapter->rx_buffer_len = E1000_RXBUFFER_4096; - - } else if(max_frame <= E1000_RXBUFFER_8192) { - adapter->rx_buffer_len = E1000_RXBUFFER_8192; - - } else { - adapter->rx_buffer_len = E1000_RXBUFFER_16384; - } - - if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) { - - e1000_down(adapter); - e1000_up(adapter); - } - - netdev->mtu = new_mtu; - adapter->hw.max_frame_size = max_frame; - - return 0; -} - -/** - * e1000_update_stats - Update the board statistics counters - * @adapter: board private structure - **/ - -static void -e1000_update_stats(struct e1000_adapter *adapter) -{ - struct e1000_hw *hw = &adapter->hw; - unsigned long flags; - uint16_t phy_tmp; - -#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF - - spin_lock_irqsave(&adapter->stats_lock, flags); - - /* these counters are modified from e1000_adjust_tbi_stats, - * called from the interrupt context, so they must only - * be written while holding adapter->stats_lock - */ - - adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS); - adapter->stats.gprc += E1000_READ_REG(hw, GPRC); - adapter->stats.gorcl += E1000_READ_REG(hw, GORCL); - adapter->stats.gorch += E1000_READ_REG(hw, GORCH); - adapter->stats.bprc += E1000_READ_REG(hw, BPRC); - adapter->stats.mprc += E1000_READ_REG(hw, MPRC); - adapter->stats.roc += E1000_READ_REG(hw, ROC); - adapter->stats.prc64 += E1000_READ_REG(hw, PRC64); - adapter->stats.prc127 += E1000_READ_REG(hw, PRC127); - adapter->stats.prc255 += E1000_READ_REG(hw, PRC255); - adapter->stats.prc511 += E1000_READ_REG(hw, PRC511); - adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023); - adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522); - - spin_unlock_irqrestore(&adapter->stats_lock, flags); - - /* the rest of the counters are only modified here */ - - adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS); - adapter->stats.mpc += E1000_READ_REG(hw, MPC); - adapter->stats.scc += E1000_READ_REG(hw, SCC); - adapter->stats.ecol += E1000_READ_REG(hw, ECOL); - adapter->stats.mcc += E1000_READ_REG(hw, MCC); - adapter->stats.latecol += E1000_READ_REG(hw, LATECOL); - adapter->stats.dc += E1000_READ_REG(hw, DC); - adapter->stats.sec += E1000_READ_REG(hw, SEC); - adapter->stats.rlec += E1000_READ_REG(hw, RLEC); - adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC); - adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC); - adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC); - adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC); - adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC); - adapter->stats.gptc += E1000_READ_REG(hw, GPTC); - adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL); - adapter->stats.gotch += E1000_READ_REG(hw, GOTCH); - adapter->stats.rnbc += E1000_READ_REG(hw, RNBC); - adapter->stats.ruc += E1000_READ_REG(hw, RUC); - adapter->stats.rfc += E1000_READ_REG(hw, RFC); - adapter->stats.rjc += E1000_READ_REG(hw, RJC); - adapter->stats.torl += E1000_READ_REG(hw, TORL); - adapter->stats.torh += E1000_READ_REG(hw, TORH); - adapter->stats.totl += E1000_READ_REG(hw, TOTL); - adapter->stats.toth += E1000_READ_REG(hw, TOTH); - adapter->stats.tpr += E1000_READ_REG(hw, TPR); - adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64); - adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127); - adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255); - adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511); - adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023); - adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522); - adapter->stats.mptc += E1000_READ_REG(hw, MPTC); - adapter->stats.bptc += E1000_READ_REG(hw, BPTC); - - /* used for adaptive IFS */ - - hw->tx_packet_delta = E1000_READ_REG(hw, TPT); - adapter->stats.tpt += hw->tx_packet_delta; - hw->collision_delta = E1000_READ_REG(hw, COLC); - adapter->stats.colc += hw->collision_delta; - - if(hw->mac_type >= e1000_82543) { - adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC); - adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC); - adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS); - adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR); - adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC); - adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC); - } - - /* Fill out the OS statistics structure */ - - adapter->net_stats.rx_packets = adapter->stats.gprc; - adapter->net_stats.tx_packets = adapter->stats.gptc; - adapter->net_stats.rx_bytes = adapter->stats.gorcl; - adapter->net_stats.tx_bytes = adapter->stats.gotcl; - adapter->net_stats.multicast = adapter->stats.mprc; - adapter->net_stats.collisions = adapter->stats.colc; - - /* Rx Errors */ - - adapter->net_stats.rx_errors = adapter->stats.rxerrc + - adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.rlec + adapter->stats.rnbc + - adapter->stats.mpc + adapter->stats.cexterr; - adapter->net_stats.rx_dropped = adapter->stats.rnbc; - adapter->net_stats.rx_length_errors = adapter->stats.rlec; - adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; - adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; - adapter->net_stats.rx_fifo_errors = adapter->stats.mpc; - adapter->net_stats.rx_missed_errors = adapter->stats.mpc; - - /* Tx Errors */ - - adapter->net_stats.tx_errors = adapter->stats.ecol + - adapter->stats.latecol; - adapter->net_stats.tx_aborted_errors = adapter->stats.ecol; - adapter->net_stats.tx_window_errors = adapter->stats.latecol; - - /* Tx Dropped needs to be maintained elsewhere */ - - /* Phy Stats */ - - if(hw->media_type == e1000_media_type_copper) { - if((adapter->link_speed == SPEED_1000) && - (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) { - phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; - adapter->phy_stats.idle_errors += phy_tmp; - } - - if(!e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp)) - adapter->phy_stats.receive_errors += phy_tmp; - } -} - -/** - * e1000_irq_disable - Mask off interrupt generation on the NIC - * @adapter: board private structure - **/ - -static inline void -e1000_irq_disable(struct e1000_adapter *adapter) -{ - atomic_inc(&adapter->irq_sem); - E1000_WRITE_REG(&adapter->hw, IMC, ~0); - E1000_WRITE_FLUSH(&adapter->hw); - synchronize_irq(); -} - -/** - * e1000_irq_enable - Enable default interrupt generation settings - * @adapter: board private structure - **/ - -static inline void -e1000_irq_enable(struct e1000_adapter *adapter) -{ - if(atomic_dec_and_test(&adapter->irq_sem)) { - E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK); - E1000_WRITE_FLUSH(&adapter->hw); - } -} - -/** - * e1000_intr - Interrupt Handler - * @irq: interrupt number - * @data: pointer to a network interface device structure - * @pt_regs: CPU registers structure - **/ - -static void -e1000_intr(int irq, void *data, struct pt_regs *regs) -{ - struct net_device *netdev = data; - struct e1000_adapter *adapter = netdev->priv; - uint32_t icr; - int i = E1000_MAX_INTR; - - while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) { - - if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - adapter->hw.get_link_status = 1; - mod_timer(&adapter->watchdog_timer, jiffies); - } - - e1000_clean_rx_irq(adapter); - e1000_clean_tx_irq(adapter); - i--; - -#ifdef E1000_COUNT_ICR - adapter->icr_txdw += icr & 0x01; - icr >>= 1; - adapter->icr_txqe += icr & 0x01; - icr >>= 1; - adapter->icr_lsc += icr & 0x01; - icr >>= 1; - adapter->icr_rxseq += icr & 0x01; - icr >>= 1; - adapter->icr_rxdmt += icr & 0x01; - icr >>= 2; - adapter->icr_rxo += icr & 0x01; - icr >>= 1; - adapter->icr_rxt += icr & 0x01; - icr >>= 2; - adapter->icr_mdac += icr & 0x01; - icr >>= 1; - adpater->icr_rxcfg += icr & 0x01; - icr >>= 1; - adpater->icr_gpi += icr & 0x01; -#endif - } -} - -/** - * e1000_clean_tx_irq - Reclaim resources after transmit completes - * @adapter: board private structure - **/ - -static void -e1000_clean_tx_irq(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *tx_ring = &adapter->tx_ring; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_tx_desc *tx_desc; - int i; - - i = tx_ring->next_to_clean; - tx_desc = E1000_TX_DESC(*tx_ring, i); - - while(tx_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { - - if(tx_ring->buffer_info[i].dma) { - - pci_unmap_page(pdev, - tx_ring->buffer_info[i].dma, - tx_ring->buffer_info[i].length, - PCI_DMA_TODEVICE); - - tx_ring->buffer_info[i].dma = 0; - } - - if(tx_ring->buffer_info[i].skb) { - - dev_kfree_skb_any(tx_ring->buffer_info[i].skb); - - tx_ring->buffer_info[i].skb = NULL; - } - - tx_desc->upper.data = 0; - - i = (i + 1) % tx_ring->count; - tx_desc = E1000_TX_DESC(*tx_ring, i); - } - - tx_ring->next_to_clean = i; - - if(netif_queue_stopped(netdev) && netif_carrier_ok(netdev) && - (E1000_DESC_UNUSED(tx_ring) > E1000_TX_QUEUE_WAKE)) { - -#ifdef IANS -{ - iANSsupport_t *ans = adapter->iANSdata; - - if((ans->iANS_status == IANS_COMMUNICATION_UP) && - (ans->reporting_mode == IANS_STATUS_REPORTING_ON) && - (ans_notify)) - ans_notify(netdev, IANS_IND_XMIT_QUEUE_READY); -} -#endif - netif_wake_queue(netdev); - } -} - -/** - * e1000_clean_rx_irq - Send received data up the network stack, - * @adapter: board private structure - **/ - -static void -e1000_clean_rx_irq(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *rx_ring = &adapter->rx_ring; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_rx_desc *rx_desc; - struct sk_buff *skb; - unsigned long flags; - uint32_t length; - uint8_t last_byte; - int i; - - i = rx_ring->next_to_clean; - rx_desc = E1000_RX_DESC(*rx_ring, i); - - while(rx_desc->status & E1000_RXD_STAT_DD) { - - pci_unmap_single(pdev, - rx_ring->buffer_info[i].dma, - rx_ring->buffer_info[i].length, - PCI_DMA_FROMDEVICE); - - skb = rx_ring->buffer_info[i].skb; - length = le16_to_cpu(rx_desc->length); - - if(!(rx_desc->status & E1000_RXD_STAT_EOP)) { - - /* All receives must fit into a single buffer */ - - E1000_DBG("Receive packet consumed multiple buffers\n"); - - dev_kfree_skb_irq(skb); - rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; - - i = (i + 1) % rx_ring->count; - - rx_desc = E1000_RX_DESC(*rx_ring, i); - continue; - } - - if(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) { - - last_byte = *(skb->data + length - 1); - - if(TBI_ACCEPT(&adapter->hw, rx_desc->status, - rx_desc->errors, length, last_byte)) { - - spin_lock_irqsave(&adapter->stats_lock, flags); - - e1000_tbi_adjust_stats(&adapter->hw, - &adapter->stats, - length, skb->data); - - spin_unlock_irqrestore(&adapter->stats_lock, - flags); - length--; - } else { - - dev_kfree_skb_irq(skb); - rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; - - i = (i + 1) % rx_ring->count; - - rx_desc = E1000_RX_DESC(*rx_ring, i); - continue; - } - } - - /* Good Receive */ - skb_put(skb, length - ETHERNET_FCS_SIZE); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) - /* NFS mountd workaround on 2.2.x */ - if(length < 512) { - struct sk_buff *tmp_skb; - tmp_skb = alloc_skb(E1000_RXBUFFER_2048>>1, GFP_ATOMIC); - if(tmp_skb != NULL) { - tmp_skb->dev = skb->dev; - skb_reserve(tmp_skb, skb->data - skb->head); - skb_put(tmp_skb, skb->len); - memcpy(tmp_skb->head, skb->head, - tmp_skb->end - tmp_skb->head); - dev_kfree_skb(skb); - skb = tmp_skb; - } - } -#endif - - /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, rx_desc, skb); - -#ifdef IANS -{ - iANSsupport_t *ans = adapter->iANSdata; - - if(ans->iANS_status == IANS_COMMUNICATION_UP) { - if(bd_ans_os_Receive(adapter, rx_desc, skb) == BD_ANS_FAILURE) - dev_kfree_skb_irq(skb); - else - netif_rx(skb); - } else { -#endif - skb->protocol = eth_type_trans(skb, netdev); -#ifdef NETIF_F_HW_VLAN_TX - if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) { - vlan_hwaccel_rx(skb, adapter->vlgrp, - (rx_desc->special & E1000_RXD_SPC_VLAN_MASK)); - } else { - netif_rx(skb); - } -#else - netif_rx(skb); -#endif -#ifdef IANS - } -} -#endif - netdev->last_rx = jiffies; - - rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; - - i = (i + 1) % rx_ring->count; - - rx_desc = E1000_RX_DESC(*rx_ring, i); - } - - rx_ring->next_to_clean = i; - - e1000_alloc_rx_buffers(adapter); -} - -/** - * e1000_alloc_rx_buffers - Replace used receive buffers - * @data: address of board private structure - **/ - -static void -e1000_alloc_rx_buffers(struct e1000_adapter *adapter) -{ - struct e1000_desc_ring *rx_ring = &adapter->rx_ring; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_rx_desc *rx_desc; - struct sk_buff *skb; - int reserve_len; - int i; - -#ifdef IANS - reserve_len = BD_ANS_INFO_SIZE; - E1000_ROUNDUP(reserve_len, 16); - reserve_len += 2; -#else - reserve_len = 2; -#endif - - i = rx_ring->next_to_use; - - while(!rx_ring->buffer_info[i].skb) { - rx_desc = E1000_RX_DESC(*rx_ring, i); - - skb = alloc_skb(adapter->rx_buffer_len + reserve_len, - GFP_ATOMIC); - - if(!skb) { - /* Better luck next round */ - break; - } - - /* Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after - * the 14 byte MAC header is removed - */ - skb_reserve(skb, reserve_len); - - skb->dev = netdev; - - rx_ring->buffer_info[i].skb = skb; - rx_ring->buffer_info[i].length = adapter->rx_buffer_len; - rx_ring->buffer_info[i].dma = - pci_map_single(pdev, - skb->data, - adapter->rx_buffer_len, - PCI_DMA_FROMDEVICE); - - rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); - - if(!(i % E1000_RX_BUFFER_WRITE)) { - /* Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). */ - wmb(); - - E1000_WRITE_REG(&adapter->hw, RDT, i); - } - - i = (i + 1) % rx_ring->count; - } - - rx_ring->next_to_use = i; -} - -/** - * e1000_ioctl - - * @netdev: - * @ifreq: - * @cmd: - **/ - -static int -e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - switch (cmd) { -#ifdef IANS - case IANS_BASE_SIOC: { - IANS_BD_PARAM_HEADER *header; - - header = (IANS_BD_PARAM_HEADER *) ifr->ifr_data; - if((header->Opcode != IANS_OP_EXT_GET_STATUS) && - (!capable(CAP_NET_ADMIN))) - return -EPERM; - - return bd_ans_os_Ioctl(netdev, ifr, cmd); - } -#endif -#ifdef IDIAG - case IDIAG_PRO_BASE_SIOC: - return e1000_diag_ioctl(netdev, ifr); -#endif -#ifdef SIOCETHTOOL - case SIOCETHTOOL: - return e1000_ethtool_ioctl(netdev, ifr); -#endif - default: - return -EOPNOTSUPP; - } -} - -/** - * e1000_rx_checksum - Receive Checksum Offload for 82543 - * @adapter: board private structure - * @rx_desc: receive descriptor - * @sk_buff: socket buffer with received data - **/ - -static inline void -e1000_rx_checksum(struct e1000_adapter *adapter, - struct e1000_rx_desc *rx_desc, - struct sk_buff *skb) -{ - /* 82543 or newer only */ - if((adapter->hw.mac_type < e1000_82543) || - /* Ignore Checksum bit is set */ - (rx_desc->status & E1000_RXD_STAT_IXSM) || - /* TCP Checksum has not been calculated */ - (!(rx_desc->status & E1000_RXD_STAT_TCPCS))) { - skb->ip_summed = CHECKSUM_NONE; - return; - } - - /* At this point we know the hardware did the TCP checksum */ - /* now look at the TCP checksum error bit */ - if(rx_desc->errors & E1000_RXD_ERR_TCPE) { - /* let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; - adapter->hw_csum_err++; - } else { - /* TCP checksum is good */ - skb->ip_summed = CHECKSUM_UNNECESSARY; - adapter->hw_csum_good++; - } -} - -void -e1000_pci_set_mwi(struct e1000_hw *hw) -{ - struct e1000_adapter *adapter = hw->back; - -#ifdef HAVE_PCI_SET_MWI - pci_set_mwi(adapter->pdev); -#else - pci_write_config_word(adapter->pdev, PCI_COMMAND, - adapter->hw.pci_cmd_word | - PCI_COMMAND_INVALIDATE); -#endif -} - -void -e1000_pci_clear_mwi(struct e1000_hw *hw) -{ - struct e1000_adapter *adapter = hw->back; - -#ifdef HAVE_PCI_SET_MWI - pci_clear_mwi(adapter->pdev); -#else - pci_write_config_word(adapter->pdev, PCI_COMMAND, - adapter->hw.pci_cmd_word & - ~PCI_COMMAND_INVALIDATE); -#endif -} - -void -e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) -{ - struct e1000_adapter *adapter = hw->back; - - pci_read_config_word(adapter->pdev, reg, value); -} - -void -e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) -{ - struct e1000_adapter *adapter = hw->back; - - pci_write_config_word(adapter->pdev, reg, *value); -} - -uint32_t -e1000_io_read(struct e1000_hw *hw, uint32_t port) -{ - return inl(port); -} - -void -e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value) -{ - outl(value, port); -} - -#ifdef NETIF_F_HW_VLAN_TX -static void -e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct e1000_adapter *adapter = netdev->priv; - uint32_t ctrl, rctl; - - e1000_irq_disable(adapter); - adapter->vlgrp = grp; - - if(grp) { - /* enable VLAN tag insert/strip */ - - E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); - - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - ctrl |= E1000_CTRL_VME; - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - - /* enable VLAN receive filtering */ - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl |= E1000_RCTL_VFE; - rctl &= ~E1000_RCTL_CFIEN; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - } else { - /* disable VLAN tag insert/strip */ - - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - ctrl &= ~E1000_CTRL_VME; - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - - /* disable VLAN filtering */ - - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl &= ~E1000_RCTL_VFE; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - } - - e1000_irq_enable(adapter); -} - -static void -e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) -{ - struct e1000_adapter *adapter = netdev->priv; - uint32_t vfta, index; - - /* add VID to filter table */ - - index = (vid >> 5) & 0x7F; - vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); - vfta |= (1 << (vid & 0x1F)); - e1000_write_vfta(&adapter->hw, index, vfta); -} - -static void -e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) -{ - struct e1000_adapter *adapter = netdev->priv; - uint32_t vfta, index; - - e1000_irq_disable(adapter); - - if(adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; - - e1000_irq_enable(adapter); - - /* remove VID from filter table*/ - - index = (vid >> 5) & 0x7F; - vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); - vfta &= ~(1 << (vid & 0x1F)); - e1000_write_vfta(&adapter->hw, index, vfta); -} -#endif - -static int -e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) -{ - struct pci_dev *pdev = NULL; - - switch(event) { - case SYS_DOWN: - case SYS_HALT: - case SYS_POWER_OFF: - pci_for_each_dev(pdev) { - if(pci_dev_driver(pdev) == &e1000_driver) - e1000_suspend(pdev, 3); - } - } - return NOTIFY_DONE; -} - -static int -e1000_suspend(struct pci_dev *pdev, uint32_t state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct e1000_adapter *adapter = netdev->priv; - uint32_t ctrl, ctrl_ext, rctl; - - netif_device_detach(netdev); - - if(netif_running(netdev)) - e1000_down(adapter); - - if(adapter->wol) { - e1000_setup_rctl(adapter); - e1000_set_multi(netdev); - - if(adapter->wol & E1000_WUFC_MC) { - rctl = E1000_READ_REG(&adapter->hw, RCTL); - rctl |= E1000_RCTL_MPE; - E1000_WRITE_REG(&adapter->hw, RCTL, rctl); - } - - if(adapter->hw.media_type == e1000_media_type_fiber) { - #define E1000_CTRL_ADVD3WUC 0x00100000 - ctrl = E1000_READ_REG(&adapter->hw, CTRL); - ctrl |= E1000_CTRL_ADVD3WUC; - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - - ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA; - E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext); - } - - E1000_WRITE_REG(&adapter->hw, WUC, 0); - E1000_WRITE_REG(&adapter->hw, WUFC, adapter->wol); - pci_enable_wake(pdev, 3, 1); - } else { - E1000_WRITE_REG(&adapter->hw, WUC, 0); - E1000_WRITE_REG(&adapter->hw, WUFC, 0); - pci_enable_wake(pdev, 3, 0); - } - - pci_save_state(pdev, adapter->pci_state); - - if(!e1000_smbus_arp_enable(adapter, TRUE)) - pci_set_power_state(pdev, 3); - - return 0; -} - -#ifdef CONFIG_PM -static int -e1000_resume(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct e1000_adapter *adapter = netdev->priv; - - pci_set_power_state(pdev, 0); - pci_restore_state(pdev, adapter->pci_state); - pci_enable_wake(pdev, 0, 0); - - /* Clear the wakeup status bits */ - - E1000_WRITE_REG(&adapter->hw, WUS, ~0); - - if(netif_running(netdev)) - e1000_up(adapter); - - netif_device_attach(netdev); - - e1000_smbus_arp_enable(adapter, FALSE); - - return 0; -} -#endif - -/** - * e1000_smbus_lock - Exported for lock/unlock external smbus hw access - * @pdev: PCI device information struct - * @lock: TRUE to lock hw access; FALSE to unlock - * - * e1000_smbus_lock is designed to allow synchronization between e1000 - * driver and i2c-i8254x SMBUS bus driver when accessing e1000 hardware - **/ -void -e1000_smbus_lock(struct pci_dev *pdev, boolean_t lock) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct e1000_adapter *adapter = netdev->priv; - - if (lock) - down(&adapter->smbus_lock); - else - up(&adapter->smbus_lock); -} - -static boolean_t -e1000_smbus_arp_enable(struct e1000_adapter *adapter, boolean_t arp_enable) -{ - uint32_t manc; - boolean_t ret_val = FALSE; - - if(adapter->hw.mac_type < e1000_82540) - return ret_val; - - down(&adapter->smbus_lock); - manc = E1000_READ_REG(&adapter->hw, MANC); - if(!arp_enable) { - manc &= ~(E1000_MANC_ARP_EN); - } else if(manc & E1000_MANC_SMBUS_EN) { - manc |= E1000_MANC_ARP_EN; - ret_val = TRUE; - } - E1000_WRITE_REG(&adapter->hw, MANC, manc); - up(&adapter->smbus_lock); - - return ret_val; -} - -/* e1000_main.c */ diff -uNr click-1.5.0-dist/drivers/e1000-4.x/src/e1000_param.c.orig click-1.5.0/drivers/e1000-4.x/src/e1000_param.c.orig --- click-1.5.0-dist/drivers/e1000-4.x/src/e1000_param.c.orig Fri Nov 22 17:13:40 2002 +++ click-1.5.0/drivers/e1000-4.x/src/e1000_param.c.orig Thu Jan 1 01:00:00 1970 @@ -1,657 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include "e1000.h" - -/* This is the only thing that needs to be changed to adjust the - * maximum number of ports that the driver can manage. - */ - -#define E1000_MAX_NIC 32 - -#define OPTION_UNSET -1 -#define OPTION_DISABLED 0 -#define OPTION_ENABLED 1 - -/* Module Parameters are always initialized to -1, so that the driver - * can tell the difference between no user specified value or the - * user asking for the default value. - * The true default values are loaded in when e1000_check_options is called. - * - * This is a GCC extension to ANSI C. - * See the item "Labeled Elements in Initializers" in the section - * "Extensions to the C Language Family" of the GCC documentation. - */ - -#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } - -/* All parameters are treated the same, as an integer array of values. - * This macro just reduces the need to repeat the same declaration code - * over and over (plus this helps to avoid typo bugs). - */ - -#define E1000_PARAM(X, S) \ -static const int __devinitdata X[E1000_MAX_NIC + 1] = E1000_PARAM_INIT; \ -MODULE_PARM(X, "1-" __MODULE_STRING(E1000_MAX_NIC) "i"); \ -MODULE_PARM_DESC(X, S); - -/* Transmit Descriptor Count - * - * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers - * Valid Range: 80-4096 for 82544 - * - * Default Value: 256 - */ - -E1000_PARAM(TxDescriptors, "Number of transmit descriptors"); - -/* Receive Descriptor Count - * - * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers - * Valid Range: 80-4096 for 82544 - * - * Default Value: 80 - */ - -E1000_PARAM(RxDescriptors, "Number of receive descriptors"); - -/* User Specified Speed Override - * - * Valid Range: 0, 10, 100, 1000 - * - 0 - auto-negotiate at all supported speeds - * - 10 - only link at 10 Mbps - * - 100 - only link at 100 Mbps - * - 1000 - only link at 1000 Mbps - * - * Default Value: 0 - */ - -E1000_PARAM(Speed, "Speed setting"); - -/* User Specified Duplex Override - * - * Valid Range: 0-2 - * - 0 - auto-negotiate for duplex - * - 1 - only link at half duplex - * - 2 - only link at full duplex - * - * Default Value: 0 - */ - -E1000_PARAM(Duplex, "Duplex setting"); - -/* Auto-negotiation Advertisement Override - * - * Valid Range: 0x01-0x0F, 0x20-0x2F - * - * The AutoNeg value is a bit mask describing which speed and duplex - * combinations should be advertised during auto-negotiation. - * The supported speed and duplex modes are listed below - * - * Bit 7 6 5 4 3 2 1 0 - * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 - * Duplex Full Full Half Full Half - * - * Default Value: 0x2F - */ - -E1000_PARAM(AutoNeg, "Advertised auto-negotiation setting"); - -/* User Specified Flow Control Override - * - * Valid Range: 0-3 - * - 0 - No Flow Control - * - 1 - Rx only, respond to PAUSE frames but do not generate them - * - 2 - Tx only, generate PAUSE frames but ignore them on receive - * - 3 - Full Flow Control Support - * - * Default Value: Read flow control settings from the EEPROM - */ - -E1000_PARAM(FlowControl, "Flow Control setting"); - -/* XsumRX - Receive Checksum Offload Enable/Disable - * - * Valid Range: 0, 1 - * - 0 - disables all checksum offload - * - 1 - enables receive IP/TCP/UDP checksum offload - * on 82543 based NICs - * - * Default Value: 1 - */ - -E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); - -/* Transmit Interrupt Delay in units of 1.024 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 64 - */ - -E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay"); - -/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 0 - */ - -E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); - -/* Receive Interrupt Delay in units of 1.024 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 0/128 - */ - -E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); - -/* Receive Absolute Interrupt Delay in units of 1.024 microseconds - * - * Valid Range: 0-65535 - * - * Default Value: 128 - */ - -E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); - -#define AUTONEG_ADV_DEFAULT 0x2F -#define AUTONEG_ADV_MASK 0x2F -#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL - -#define DEFAULT_TXD 256 -#define MAX_TXD 256 -#define MIN_TXD 80 -#define MAX_82544_TXD 4096 - -#define DEFAULT_RXD 80 -#define MAX_RXD 256 -#define MIN_RXD 80 -#define MAX_82544_RXD 4096 - -#define DEFAULT_RDTR 128 -#define DEFAULT_RDTR_82544 0 -#define MAX_RXDELAY 0xFFFF -#define MIN_RXDELAY 0 - -#define DEFAULT_RADV 128 -#define MAX_RXABSDELAY 0xFFFF -#define MIN_RXABSDELAY 0 - -#define DEFAULT_TIDV 64 -#define MAX_TXDELAY 0xFFFF -#define MIN_TXDELAY 0 - -#define DEFAULT_TADV 64 -#define MAX_TXABSDELAY 0xFFFF -#define MIN_TXABSDELAY 0 - -struct e1000_option { - enum { enable_option, range_option, list_option } type; - char *name; - char *err; - int def; - union { - struct { /* range_option info */ - int min; - int max; - } r; - struct { /* list_option info */ - int nr; - struct e1000_opt_list { int i; char *str; } *p; - } l; - } arg; -}; - - -static int __devinit -e1000_validate_option(int *value, struct e1000_option *opt) -{ - if(*value == OPTION_UNSET) { - *value = opt->def; - return 0; - } - - switch (opt->type) { - case enable_option: - switch (*value) { - case OPTION_ENABLED: - printk(KERN_INFO "%s Enabled\n", opt->name); - return 0; - case OPTION_DISABLED: - printk(KERN_INFO "%s Disabled\n", opt->name); - return 0; - } - break; - case range_option: - if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - printk(KERN_INFO "%s set to %i\n", opt->name, *value); - return 0; - } - break; - case list_option: { - int i; - struct e1000_opt_list *ent; - - for(i = 0; i < opt->arg.l.nr; i++) { - ent = &opt->arg.l.p[i]; - if(*value == ent->i) { - if(ent->str[0] != '\0') - printk(KERN_INFO "%s\n", ent->str); - return 0; - } - } - } - break; - default: - BUG(); - } - - printk(KERN_INFO "Invalid %s specified (%i) %s\n", - opt->name, *value, opt->err); - *value = opt->def; - return -1; -} - -static void e1000_check_fiber_options(struct e1000_adapter *adapter); -static void e1000_check_copper_options(struct e1000_adapter *adapter); - -/** - * e1000_check_options - Range Checking for Command Line Parameters - * @adapter: board private structure - * - * This routine checks all command line paramters for valid user - * input. If an invalid value is given, or if no user specified - * value exists, a default value is used. The final value is stored - * in a variable in the adapter structure. - **/ - -void __devinit -e1000_check_options(struct e1000_adapter *adapter) -{ - int bd = adapter->bd_number; - if(bd >= E1000_MAX_NIC) { - printk(KERN_NOTICE - "Warning: no configuration for board #%i\n", bd); - printk(KERN_NOTICE "Using defaults for all values\n"); - bd = E1000_MAX_NIC; - } - - { /* Transmit Descriptor Count */ - struct e1000_option opt = { - type: range_option, - name: "Transmit Descriptors", - err: "using default of " __MODULE_STRING(DEFAULT_TXD), - def: DEFAULT_TXD, - arg: { r: { min: MIN_TXD }} - }; - struct e1000_desc_ring *tx_ring = &adapter->tx_ring; - e1000_mac_type mac_type = adapter->hw.mac_type; - opt.arg.r.max = mac_type < e1000_82544 ? MAX_TXD : MAX_82544_TXD; - - tx_ring->count = TxDescriptors[bd]; - e1000_validate_option(&tx_ring->count, &opt); - E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); - } - { /* Receive Descriptor Count */ - struct e1000_option opt = { - type: range_option, - name: "Receive Descriptors", - err: "using default of " __MODULE_STRING(DEFAULT_RXD), - def: DEFAULT_RXD, - arg: { r: { min: MIN_RXD }} - }; - struct e1000_desc_ring *rx_ring = &adapter->rx_ring; - e1000_mac_type mac_type = adapter->hw.mac_type; - opt.arg.r.max = mac_type < e1000_82544 ? MAX_RXD : MAX_82544_RXD; - - rx_ring->count = RxDescriptors[bd]; - e1000_validate_option(&rx_ring->count, &opt); - E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); - } - { /* Checksum Offload Enable/Disable */ - struct e1000_option opt = { - type: enable_option, - name: "Checksum Offload", - err: "defaulting to Enabled", - def: OPTION_ENABLED - }; - - int rx_csum = XsumRX[bd]; - e1000_validate_option(&rx_csum, &opt); - adapter->rx_csum = rx_csum; - } - { /* Flow Control */ - - struct e1000_opt_list fc_list[] = - {{ e1000_fc_none, "Flow Control Disabled" }, - { e1000_fc_rx_pause,"Flow Control Receive Only" }, - { e1000_fc_tx_pause,"Flow Control Transmit Only" }, - { e1000_fc_full, "Flow Control Enabled" }, - { e1000_fc_default, "Flow Control Hardware Default" }}; - - struct e1000_option opt = { - type: list_option, - name: "Flow Control", - err: "reading default settings from EEPROM", - def: e1000_fc_default, - arg: { l: { nr: ARRAY_SIZE(fc_list), p: fc_list }} - }; - - int fc = FlowControl[bd]; - e1000_validate_option(&fc, &opt); - adapter->hw.fc = adapter->hw.original_fc = fc; - } - { /* Transmit Interrupt Delay */ - char *tidv = "using default of " __MODULE_STRING(DEFAULT_TIDV); - struct e1000_option opt = { - type: range_option, - name: "Transmit Interrupt Delay", - arg: { r: { min: MIN_TXDELAY, max: MAX_TXDELAY }} - }; - opt.def = DEFAULT_TIDV; - opt.err = tidv; - - adapter->tx_int_delay = TxIntDelay[bd]; - e1000_validate_option(&adapter->tx_int_delay, &opt); - } - { /* Transmit Absolute Interrupt Delay */ - char *tadv = "using default of " __MODULE_STRING(DEFAULT_TADV); - struct e1000_option opt = { - type: range_option, - name: "Transmit Absolute Interrupt Delay", - arg: { r: { min: MIN_TXABSDELAY, max: MAX_TXABSDELAY }} - }; - opt.def = DEFAULT_TADV; - opt.err = tadv; - - adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; - e1000_validate_option(&adapter->tx_abs_int_delay, &opt); - } - { /* Receive Interrupt Delay */ - char *rdtr = "using default of " __MODULE_STRING(DEFAULT_RDTR); - char *rdtr_82544 = "using default of " - __MODULE_STRING(DEFAULT_RDTR_82544); - struct e1000_option opt = { - type: range_option, - name: "Receive Interrupt Delay", - arg: { r: { min: MIN_RXDELAY, max: MAX_RXDELAY }} - }; - e1000_mac_type mac_type = adapter->hw.mac_type; - opt.def = mac_type > e1000_82544 ? DEFAULT_RDTR : 0; - opt.err = mac_type > e1000_82544 ? rdtr : rdtr_82544; - - adapter->rx_int_delay = RxIntDelay[bd]; - e1000_validate_option(&adapter->rx_int_delay, &opt); - } - { /* Receive Absolute Interrupt Delay */ - char *radv = "using default of " __MODULE_STRING(DEFAULT_RADV); - struct e1000_option opt = { - type: range_option, - name: "Receive Absolute Interrupt Delay", - arg: { r: { min: MIN_RXABSDELAY, max: MAX_RXABSDELAY }} - }; - opt.def = DEFAULT_RADV; - opt.err = radv; - - adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; - e1000_validate_option(&adapter->rx_abs_int_delay, &opt); - } - - switch(adapter->hw.media_type) { - case e1000_media_type_fiber: - e1000_check_fiber_options(adapter); - break; - case e1000_media_type_copper: - e1000_check_copper_options(adapter); - break; - default: - BUG(); - } -} - -/** - * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version - * @adapter: board private structure - * - * Handles speed and duplex options on fiber adapters - **/ - -static void __devinit -e1000_check_fiber_options(struct e1000_adapter *adapter) -{ - int bd = adapter->bd_number; - bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; - - if((Speed[bd] != OPTION_UNSET)) { - printk(KERN_INFO "Speed not valid for fiber adapters, " - "parameter ignored\n"); - } - if((Duplex[bd] != OPTION_UNSET)) { - printk(KERN_INFO "Duplex not valid for fiber adapters, " - "parameter ignored\n"); - } - if((AutoNeg[bd] != OPTION_UNSET)) { - printk(KERN_INFO "AutoNeg not valid for fiber adapters, " - "parameter ignored\n"); - } -} - -/** - * e1000_check_copper_options - Range Checking for Link Options, Copper Version - * @adapter: board private structure - * - * Handles speed and duplex options on copper adapters - **/ - -static void __devinit -e1000_check_copper_options(struct e1000_adapter *adapter) -{ - int speed, dplx; - int bd = adapter->bd_number; - bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; - - { /* Speed */ - struct e1000_opt_list speed_list[] = {{ 0, "" }, - { SPEED_10, "" }, - { SPEED_100, "" }, - { SPEED_1000, "" }}; - struct e1000_option opt = { - type: list_option, - name: "Speed", - err: "parameter ignored", - def: 0, - arg: { l: { nr: ARRAY_SIZE(speed_list), p: speed_list }} - }; - - speed = Speed[bd]; - e1000_validate_option(&speed, &opt); - } - { /* Duplex */ - struct e1000_opt_list dplx_list[] = {{ 0, "" }, - { HALF_DUPLEX, "" }, - { FULL_DUPLEX, "" }}; - struct e1000_option opt = { - type: list_option, - name: "Duplex", - err: "parameter ignored", - def: 0, - arg: { l: { nr: ARRAY_SIZE(dplx_list), p: dplx_list }} - }; - - dplx = Duplex[bd]; - e1000_validate_option(&dplx, &opt); - } - - if(AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) { - printk(KERN_INFO - "AutoNeg specified along with Speed or Duplex, " - "parameter ignored\n"); - adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT; - } else { /* Autoneg */ - struct e1000_opt_list an_list[] = - #define AA "AutoNeg advertising " - {{ 0x01, AA "10/HD" }, - { 0x02, AA "10/FD" }, - { 0x03, AA "10/FD, 10/HD" }, - { 0x04, AA "100/HD" }, - { 0x05, AA "100/HD, 10/HD" }, - { 0x06, AA "100/HD, 10/FD" }, - { 0x07, AA "100/HD, 10/FD, 10/HD" }, - { 0x08, AA "100/FD" }, - { 0x09, AA "100/FD, 10/HD" }, - { 0x0a, AA "100/FD, 10/FD" }, - { 0x0b, AA "100/FD, 10/FD, 10/HD" }, - { 0x0c, AA "100/FD, 100/HD" }, - { 0x0d, AA "100/FD, 100/HD, 10/HD" }, - { 0x0e, AA "100/FD, 100/HD, 10/FD" }, - { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, - { 0x20, AA "1000/FD" }, - { 0x21, AA "1000/FD, 10/HD" }, - { 0x22, AA "1000/FD, 10/FD" }, - { 0x23, AA "1000/FD, 10/FD, 10/HD" }, - { 0x24, AA "1000/FD, 100/HD" }, - { 0x25, AA "1000/FD, 100/HD, 10/HD" }, - { 0x26, AA "1000/FD, 100/HD, 10/FD" }, - { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, - { 0x28, AA "1000/FD, 100/FD" }, - { 0x29, AA "1000/FD, 100/FD, 10/HD" }, - { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, - { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, - { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, - { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, - { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, - { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }}; - - struct e1000_option opt = { - type: list_option, - name: "AutoNeg", - err: "parameter ignored", - def: AUTONEG_ADV_DEFAULT, - arg: { l: { nr: ARRAY_SIZE(an_list), p: an_list }} - }; - - int an = AutoNeg[bd]; - e1000_validate_option(&an, &opt); - adapter->hw.autoneg_advertised = an; - } - - switch (speed + dplx) { - case 0: - adapter->hw.autoneg = 1; - if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET) - printk(KERN_INFO - "Speed and duplex autonegotiation enabled\n"); - break; - case HALF_DUPLEX: - printk(KERN_INFO "Half Duplex specified without Speed\n"); - printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | - ADVERTISE_100_HALF; - break; - case FULL_DUPLEX: - printk(KERN_INFO "Full Duplex specified without Speed\n"); - printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_10_FULL | - ADVERTISE_100_FULL | - ADVERTISE_1000_FULL; - break; - case SPEED_10: - printk(KERN_INFO "10 Mbps Speed specified without Duplex\n"); - printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_10_HALF | - ADVERTISE_10_FULL; - break; - case SPEED_10 + HALF_DUPLEX: - printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n"); - adapter->hw.autoneg = 0; - adapter->hw.forced_speed_duplex = e1000_10_half; - adapter->hw.autoneg_advertised = 0; - break; - case SPEED_10 + FULL_DUPLEX: - printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n"); - adapter->hw.autoneg = 0; - adapter->hw.forced_speed_duplex = e1000_10_full; - adapter->hw.autoneg_advertised = 0; - break; - case SPEED_100: - printk(KERN_INFO "100 Mbps Speed specified without Duplex\n"); - printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_100_HALF | - ADVERTISE_100_FULL; - break; - case SPEED_100 + HALF_DUPLEX: - printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n"); - adapter->hw.autoneg = 0; - adapter->hw.forced_speed_duplex = e1000_100_half; - adapter->hw.autoneg_advertised = 0; - break; - case SPEED_100 + FULL_DUPLEX: - printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n"); - adapter->hw.autoneg = 0; - adapter->hw.forced_speed_duplex = e1000_100_full; - adapter->hw.autoneg_advertised = 0; - break; - case SPEED_1000: - printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n"); - printk(KERN_INFO - "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; - break; - case SPEED_1000 + HALF_DUPLEX: - printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n"); - printk(KERN_INFO - "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; - break; - case SPEED_1000 + FULL_DUPLEX: - printk(KERN_INFO - "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); - adapter->hw.autoneg = 1; - adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL; - break; - default: - BUG(); - } - - /* Speed, AutoNeg and MDI/MDI-X must all play nice */ - if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) { - printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are " - "incompatible. Setting MDI-X to a compatible value.\n"); - } -} - diff -uNr click-1.5.0-dist/elements/analysis/fromdagdump.cc click-1.5.0/elements/analysis/fromdagdump.cc --- click-1.5.0-dist/elements/analysis/fromdagdump.cc Mon Jan 9 18:02:04 2006 +++ click-1.5.0/elements/analysis/fromdagdump.cc Thu Feb 1 14:02:03 2007 @@ -446,7 +446,7 @@ return 0; case H_EXTEND_INTERVAL: { Timestamp tv; - if (cp_time(s, &tv)) { + if (cp_timeval(s, &tv)) { fd->_last_time += tv; if (fd->_end_h) fd->_have_last_time = true, fd->set_active(true); diff -uNr click-1.5.0-dist/elements/analysis/fromnlanrdump.cc click-1.5.0/elements/analysis/fromnlanrdump.cc --- click-1.5.0-dist/elements/analysis/fromnlanrdump.cc Mon Jan 9 18:02:49 2006 +++ click-1.5.0/elements/analysis/fromnlanrdump.cc Thu Feb 1 14:02:03 2007 @@ -383,7 +383,7 @@ return 0; case H_EXTEND_INTERVAL: { Timestamp tv; - if (cp_time(s, &tv)) { + if (cp_timeval(s, &tv)) { fd->_last_time += tv; if (fd->_end_h) fd->_have_last_time = true, fd->set_active(true); diff -uNr click-1.5.0-dist/elements/analysis/fromtcpdump.cc click-1.5.0/elements/analysis/fromtcpdump.cc --- click-1.5.0-dist/elements/analysis/fromtcpdump.cc Sat Apr 1 03:24:53 2006 +++ click-1.5.0/elements/analysis/fromtcpdump.cc Thu Feb 1 14:02:03 2007 @@ -393,7 +393,7 @@ // first, read timestamp const char *s2 = find(s, end, ' '); - if (!cp_time(line.substring(s, s2), &q->timestamp_anno())) + if (!cp_timeval(line.substring(s, s2), &q->timestamp_anno())) break; s = s2 + 1; diff -uNr click-1.5.0-dist/elements/analysis/timefilter.cc click-1.5.0/elements/analysis/timefilter.cc --- click-1.5.0-dist/elements/analysis/timefilter.cc Wed Dec 21 03:24:26 2005 +++ click-1.5.0/elements/analysis/timefilter.cc Thu Feb 1 14:02:03 2007 @@ -152,7 +152,7 @@ switch ((intptr_t)thunk) { case H_EXTEND_INTERVAL: { Timestamp t; - if (cp_time(s, &t)) { + if (cp_timeval(s, &t)) { tf->_last += t; if (tf->_last_h) tf->_last_h_ready = true; diff -uNr click-1.5.0-dist/elements/bsdmodule/anydevice.cc click-1.5.0/elements/bsdmodule/anydevice.cc --- click-1.5.0-dist/elements/bsdmodule/anydevice.cc Fri Sep 16 15:33:26 2005 +++ click-1.5.0/elements/bsdmodule/anydevice.cc Thu Feb 1 14:02:04 2007 @@ -147,7 +147,7 @@ return NULL; // look first by device names - String dev_name = dev->if_name; + String dev_name = dev->if_xname; for (AnyDevice *d = _unknown_map; d; d = d->next()) if (d->devname() == dev_name) return d; diff -uNr click-1.5.0-dist/elements/bsdmodule/fastudpsrc.cc click-1.5.0/elements/bsdmodule/fastudpsrc.cc --- click-1.5.0-dist/elements/bsdmodule/fastudpsrc.cc Mon Jan 9 18:11:50 2006 +++ click-1.5.0/elements/bsdmodule/fastudpsrc.cc Thu Feb 1 14:02:04 2007 @@ -96,12 +96,12 @@ // Create an mbuf with an mbuf cluster so copies are quick // (we just add a reference to the cluster rather than doing // a memory copy). - MGETHDR(_m, M_WAIT, MT_DATA); + MGETHDR(_m, M_TRYWAIT, MT_DATA); if (_m == NULL) { click_chatter("unable to get mbuf for FastUDPSource"); return -1; } - MCLGET(_m, M_WAIT); + MCLGET(_m, M_TRYWAIT); if ((_m->m_flags & M_EXT) == 0) { m_freem(_m); click_chatter("unable to get mbuf cluster for FastUDPSource"); @@ -165,20 +165,8 @@ return 0; } - if (mclrefcnt[mtocl(_m->m_ext.ext_buf)] >= SCHAR_MAX) { - caddr_t mcl, mcl0; - MCLALLOC(mcl, M_WAIT); - if (!mcl) { - click_chatter("failure to allocate new mbuf cluster\n"); - return 0; - } - - bcopy(_m->m_data, mcl, _m->m_len); - mcl0 = _m->m_ext.ext_buf; - _m->m_data = mcl; - _m->m_ext.ext_buf = mcl; - MCLFREE(mcl0); - } + // FreeBSD's mbuf cluster refcounting was completely rewritten, + // so we don't need to check for the lame 127 references limitation. -bms bool need_packet = false; if (_rate_limited) { @@ -193,7 +181,7 @@ if (!need_packet) return 0; // nothing to pull - m = m_copypacket(_m, M_WAIT); + m = m_copypacket(_m, M_TRYWAIT); if (!m) { click_chatter("unable to m_copypacket\n"); return 0; // bad luck. diff -uNr click-1.5.0-dist/elements/bsdmodule/fromdevice.cc click-1.5.0/elements/bsdmodule/fromdevice.cc --- click-1.5.0-dist/elements/bsdmodule/fromdevice.cc Sun Sep 18 15:14:51 2005 +++ click-1.5.0/elements/bsdmodule/fromdevice.cc Thu Feb 1 14:02:04 2007 @@ -61,7 +61,7 @@ /* * Process incoming packets using the ng_ether_input_p hook. - * The if_poll_intren (normally unused) field from the struct ifnet is + * The if_spare2 (normally unused) field from the struct ifnet is * used as a pointer to the fromdevice data structure. Call it "xp". * * If xp == NULL, no FromDevice element is registered on this @@ -78,7 +78,7 @@ void click_ether_input(struct ifnet *ifp, struct mbuf **mp, struct ether_header *eh) { - if (ifp->if_poll_intren == NULL) // not for click. + if (ifp->if_spare2 == NULL) // not for click. return ; struct mbuf *m = *mp; @@ -89,8 +89,9 @@ *mp = NULL; // tell ether_input no further processing needed. - FromDevice *me = (FromDevice *)(ifp->if_poll_intren); + FromDevice *me = (FromDevice *)(ifp->if_spare2); +#if 0 /* XXX: needs rewriting for polling(4) rewrite. -bms */ /* * If sysctl kern.polling.enable == 2 we should take care of polling * this NIC from inside a Click thread, so steal the handler from BSD. @@ -106,26 +107,27 @@ me->_poll_status_tick = ticks; prp->handler = NULL; prp->ifp = NULL; - printf("Click FromDevice(%s%d) taking control over NIC driver polling\n", ifp->if_name, ifp->if_unit); + printf("Click FromDevice(%s) taking control over NIC driver polling\n", ifp->if_xname); me->_polling = -1; // wakeup task thread only once more break; } if (!me->_polling) { - printf("Strange, couldn't find polling handler for %s%d\n", - ifp->if_name, ifp->if_unit); + printf("Strange, couldn't find polling handler for %s\n", + ifp->if_xname); me->_polling = -2; // Do not bother trying to register again } } +#endif // put the ethernet header back into the mbuf. M_PREPEND(m, sizeof(*eh), M_WAIT); bcopy(eh, mtod(m, struct ether_header *), sizeof(*eh)); - if (IF_QFULL(me->_inq)) { - IF_DROP(me->_inq); + if (_IF_QFULL(me->_inq)) { + _IF_DROP(me->_inq); m_freem(m); } else - IF_ENQUEUE(me->_inq, m); + _IF_ENQUEUE(me->_inq, m); if (me->_polling != 1) me->intr_reschedule(); if (me->_polling == -1) @@ -137,9 +139,9 @@ /* * Process outgoing packets using the ng_ether_output_p hook. - * If if_poll_xmit == NULL, no FromHost element is registered on this + * If if_spare3 == NULL, no FromHost element is registered on this * interface, so return 0 to pass the packet back to FreeBSD. - * Otherwise, if_poll_xmit points to the element, which in turn contains + * Otherwise, if_spare3 points to the element, which in turn contains * a queue. Append the packet there, clear *mp to grab the pkt from FreeBSD, * and possibly wakeup the element. * @@ -150,19 +152,19 @@ click_ether_output(struct ifnet *ifp, struct mbuf **mp) { int s = splimp(); - if (ifp->if_poll_xmit == NULL) { // not for click... + if (ifp->if_spare3 == NULL) { // not for click... splx(s); return 0; } struct mbuf *m = *mp; *mp = NULL; // tell ether_output no further processing needed - FromHost *me = (FromHost *)(ifp->if_poll_xmit); - if (IF_QFULL(me->_inq)) { - IF_DROP(me->_inq); + FromHost *me = (FromHost *)(ifp->if_spare3); + if (_IF_QFULL(me->_inq)) { + _IF_DROP(me->_inq); m_freem(m); } else - IF_ENQUEUE(me->_inq, m); + _IF_ENQUEUE(me->_inq, m); me->intr_reschedule(); splx(s); return 0; @@ -280,7 +282,7 @@ malloc(sizeof (struct ifqueue), M_DEVBUF, M_NOWAIT|M_ZERO); assert(_inq); _inq->ifq_maxlen = QSIZE; - (FromDevice *)(device()->if_poll_intren) = this; + (FromDevice *)(device()->if_spare2) = this; } else { if (_readers == 0) printf("Warning, _readers mismatch (should not be 0)\n"); @@ -324,7 +326,7 @@ if (_readers == 0) { // flush queue q = _inq ; _inq = NULL ; - device()->if_poll_intren = NULL ; + device()->if_spare2 = NULL ; } if (_polling == 1) { // return polling handler to the kernel struct pollrec *prp = pr; @@ -334,7 +336,7 @@ break; prp->handler = _poll_handler; prp->ifp = _dev; - if (*poll_handlers == 0 && (_dev->if_flags & IFF_RUNNING)) + if (*poll_handlers == 0 && (_dev->if_drv_flags & IFF_DRV_RUNNING)) *poll_handlers = 1; } splx(s); @@ -355,12 +357,14 @@ ifpromisc(device(), 0); } +#if 0 /* XXX: method signature has disappeared. -bms */ void FromDevice::take_state(Element *e, ErrorHandler *errh) { FromDevice *fd = (FromDevice *)e->cast("FromDevice"); if (!fd) return; } +#endif bool FromDevice::run_task() @@ -368,6 +372,7 @@ int npq = 0; // click_chatter("FromDevice::run_task()."); +#if 0 /* XXX: See polling(4). -bms */ if (_dev && _polling == 1) { if (_dev->if_ipending & IFF_POLLING) { enum poll_cmd cmd; @@ -387,13 +392,15 @@ break; prp->handler = _poll_handler; prp->ifp = _dev; - if (*poll_handlers == 0 && (_dev->if_flags & IFF_RUNNING)) + if (*poll_handlers == 0 && + (_dev->if_drv_flags & IFF_DRV_RUNNING)) *poll_handlers = 1; } else _poll_handler(_dev, cmd, _burst); } else _polling = 0; // No more polling } +#endif #ifdef FROMDEVICE_TSTAMP if (_tstamp) { diff -uNr click-1.5.0-dist/elements/bsdmodule/fromhost.cc click-1.5.0/elements/bsdmodule/fromhost.cc --- click-1.5.0-dist/elements/bsdmodule/fromhost.cc Sun Sep 18 15:14:50 2005 +++ click-1.5.0/elements/bsdmodule/fromhost.cc Thu Feb 1 14:02:04 2007 @@ -57,15 +57,17 @@ int FromHost::initialize(ErrorHandler *errh) { +#if 1 /* XXX: Needs rewritten to use new polling and netisr handlers. -bms */ + return -1; +#else // create queue int s = splimp(); - if (device()->if_poll_xmit != NULL) { + if (device()->if_spare3 != NULL) { splx(s); - click_chatter("FromHost: %s%d already in use", - device()->if_name, device()->if_unit); + click_chatter("FromHost: %s already in use", device()->if_xname); return -1; } - (FromHost *)(device()->if_poll_xmit) = this; + (FromHost *)(device()->if_spare3) = this; _inq = (struct ifqueue *) malloc(sizeof (struct ifqueue), M_DEVBUF, M_NOWAIT|M_ZERO); assert(_inq); @@ -73,6 +75,7 @@ ScheduleInfo::initialize_task(this, &_task, true, errh); splx(s); return 0; +#endif } void @@ -85,7 +88,7 @@ int s = splimp(); struct ifqueue *q = _inq ; _inq = NULL; - device()->if_poll_xmit = NULL; + device()->if_spare3 = NULL; splx(s); int i, max = q->ifq_maxlen ; diff -uNr click-1.5.0-dist/elements/bsdmodule/todevice.cc click-1.5.0/elements/bsdmodule/todevice.cc --- click-1.5.0-dist/elements/bsdmodule/todevice.cc Mon Jan 9 18:11:57 2006 +++ click-1.5.0/elements/bsdmodule/todevice.cc Thu Feb 1 14:02:04 2007 @@ -28,6 +28,7 @@ #include #include +#include /* for watching when devices go offline */ static AnyDeviceMap to_device_map; @@ -132,7 +133,7 @@ int sent = 0; // click_chatter("ToDevice::run_task()."); - while (sent < _burst && (busy = IF_QFULL(&device()->if_snd)) == 0) { + while (sent < _burst && (busy = _IF_QFULL(&device()->if_snd)) == 0) { Packet *p = input(0).pull(); if (!p) diff -uNr click-1.5.0-dist/elements/bsdmodule/tohost.cc click-1.5.0/elements/bsdmodule/tohost.cc --- click-1.5.0-dist/elements/bsdmodule/tohost.cc Mon Jan 9 18:11:54 2006 +++ click-1.5.0/elements/bsdmodule/tohost.cc Thu Feb 1 14:02:04 2007 @@ -115,7 +115,12 @@ m->m_pkthdr.rcvif = NULL; // tell click-ether-input to ignore this m_adj(m, ETHER_HDR_LEN); +#if 1 + /* XXX: ether_input() is now declared static. -bms */ + (*ifp->if_input)(ifp, m); +#else ether_input(ifp, eh, m); +#endif } String diff -uNr click-1.5.0-dist/elements/grid/filterbyhops.cc click-1.5.0/elements/grid/filterbyhops.cc --- click-1.5.0-dist/elements/grid/filterbyhops.cc Sun Sep 18 14:36:32 2005 +++ click-1.5.0/elements/grid/filterbyhops.cc Thu Feb 1 14:02:04 2007 @@ -24,7 +24,7 @@ #include #include #include "grid.hh" -#include +//#include CLICK_DECLS FilterByGridHops::FilterByGridHops() diff -uNr click-1.5.0-dist/elements/standard/delayshaper.cc click-1.5.0/elements/standard/delayshaper.cc --- click-1.5.0-dist/elements/standard/delayshaper.cc Mon Jan 9 18:07:36 2006 +++ click-1.5.0/elements/standard/delayshaper.cc Thu Feb 1 14:02:04 2007 @@ -122,7 +122,7 @@ DelayShaper::write_param(const String &s, Element *e, void *, ErrorHandler *errh) { DelayShaper *u = (DelayShaper *)e; - if (!cp_time(cp_uncomment(s), &u->_delay)) + if (!cp_timeval(cp_uncomment(s), &u->_delay)) return errh->error("delay must be a timestamp"); return 0; } diff -uNr click-1.5.0-dist/elements/standard/script.cc click-1.5.0/elements/standard/script.cc --- click-1.5.0-dist/elements/standard/script.cc Tue Mar 21 17:13:05 2006 +++ click-1.5.0/elements/standard/script.cc Thu Feb 1 14:02:04 2007 @@ -226,7 +226,7 @@ wait_time: case INSN_WAIT_TIME: { Timestamp ts; - if (cp_time(conf[i], &ts)) + if (cp_timeval(conf[i], &ts)) add_insn(INSN_WAIT_TIME, ts.sec(), ts.subsec()); else goto syntax_error; diff -uNr click-1.5.0-dist/elements/userlevel/fromdump.cc click-1.5.0/elements/userlevel/fromdump.cc --- click-1.5.0-dist/elements/userlevel/fromdump.cc Mon Jan 9 17:55:50 2006 +++ click-1.5.0/elements/userlevel/fromdump.cc Thu Feb 1 14:02:03 2007 @@ -519,7 +519,7 @@ return 0; case H_EXTEND_INTERVAL: { Timestamp ts; - if (cp_time(s, &ts)) { + if (cp_timeval(s, &ts)) { fd->_last_time += ts; if (fd->_end_h) fd->_have_last_time = true, fd->set_active(true); diff -uNr click-1.5.0-dist/elements/wifi/fromhandler.cc click-1.5.0/elements/wifi/fromhandler.cc --- click-1.5.0-dist/elements/wifi/fromhandler.cc Thu Feb 16 03:03:20 2006 +++ click-1.5.0/elements/wifi/fromhandler.cc Thu Feb 1 14:02:03 2007 @@ -92,7 +92,7 @@ int n = s.find_left('|', 0); if (n > 0) { String ts = s.substring(0, n-1); - if (!cp_time(ts, &t)) { + if (!cp_timeval(ts, &t)) { click_chatter("parsing time failed\n"); } s = s.substring(n+2, s.length() - n - 1); diff -uNr click-1.5.0-dist/include/click/confparse.hh click-1.5.0/include/click/confparse.hh --- click-1.5.0-dist/include/click/confparse.hh Fri May 19 08:35:41 2006 +++ click-1.5.0/include/click/confparse.hh Thu Feb 1 14:02:03 2007 @@ -111,8 +111,8 @@ bool cp_seconds_as(int want_power, const String&, uint32_t*); bool cp_seconds_as_milli(const String&, uint32_t*); bool cp_seconds_as_micro(const String&, uint32_t*); -bool cp_time(const String&, struct timeval*); -bool cp_time(const String&, Timestamp*); +bool cp_timeval(const String&, struct timeval*); +bool cp_timeval(const String&, Timestamp*); bool cp_bandwidth(const String&, uint32_t*); diff -uNr click-1.5.0-dist/include/click/task.hh click-1.5.0/include/click/task.hh --- click-1.5.0-dist/include/click/task.hh Wed Dec 21 03:26:21 2005 +++ click-1.5.0/include/click/task.hh Thu Feb 1 14:02:03 2007 @@ -9,19 +9,13 @@ #endif CLICK_DECLS -#ifdef CLICK_BSDMODULE -# include -# include /* MARKO XXX */ -#endif - -#if CLICK_BSDMODULE && !BSD_NETISRSCHED -# define SPLCHECK \ - int s = splimp(); \ - if (s == 0) \ - panic("not spl'ed: %d\n", s); \ - splx(s) +#if CLICK_BSDMODULE +extern "C" { + #include + #include +} #else -# define SPLCHECK +#define GIANT_REQUIRED #endif #define PASS_GT(a, b) ((int)(a - b) > 0) @@ -319,8 +313,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - // assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif if (scheduled()) { #ifdef HAVE_TASK_HEAP @@ -401,8 +394,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - // assert(!intr_nesting_level); it happens all the time from fromdevice! - SPLCHECK; + GIANT_REQUIRED; #endif if (!scheduled()) { @@ -443,7 +435,7 @@ inline void Task::fast_schedule() { - SPLCHECK; + GIANT_REQUIRED; assert(_tickets >= 1); #if HAVE_TASK_HEAP _pass = (_thread->active() ? _thread->_task_heap[0]->_pass : 0); @@ -465,7 +457,7 @@ #endif #if CLICK_BSDMODULE // assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif if (!scheduled()) { _prev = _thread->_prev; @@ -494,7 +486,7 @@ inline void Task::reschedule() { - SPLCHECK; + GIANT_REQUIRED; assert(_thread); if (!scheduled()) true_reschedule(); diff -uNr click-1.5.0-dist/lib/confparse.cc click-1.5.0/lib/confparse.cc --- click-1.5.0-dist/lib/confparse.cc Thu Feb 23 01:19:55 2006 +++ click-1.5.0/lib/confparse.cc Thu Feb 1 14:02:03 2007 @@ -1303,7 +1303,7 @@ return cp_seconds_as(6, str_in, return_value); } -bool cp_time(const String &str, Timestamp* return_value) +bool cp_timeval(const String &str, Timestamp* return_value) { int power = 0, factor = 1; const char *after_unit = read_unit(str.begin(), str.end(), seconds_units, sizeof(seconds_units), seconds_prefixes, &power, &factor); @@ -1320,9 +1320,9 @@ return true; } -bool cp_time(const String &str, timeval *return_value) +bool cp_timeval(const String &str, timeval *return_value) { - return cp_time(str, (Timestamp*) return_value); + return cp_timeval(str, (Timestamp*) return_value); } @@ -2275,7 +2275,7 @@ case cpiTimeval: case cpiInterval: { struct timeval tv; - if (!cp_time(arg, &tv)) { + if (!cp_timeval(arg, &tv)) { if (cp_errno == CPE_NEGATIVE) errh->error("%s (%s) must be >= 0", argname, desc); else diff -uNr click-1.5.0-dist/lib/routerthread.cc click-1.5.0/lib/routerthread.cc --- click-1.5.0-dist/lib/routerthread.cc Fri May 19 00:56:09 2006 +++ click-1.5.0/lib/routerthread.cc Thu Feb 1 14:02:03 2007 @@ -422,7 +422,7 @@ if (_greedy) /* do nothing */; else if (active()) { // just schedule others for a moment - yield(curproc, NULL); + yield(curthread, NULL); } else { _sleep_ident = &_sleep_ident; // arbitrary address, != NULL tsleep(&_sleep_ident, PPAUSE, "pause", 1); diff -uNr click-1.5.0-dist/lib/task.cc click-1.5.0/lib/task.cc --- click-1.5.0-dist/lib/task.cc Wed Dec 21 03:30:37 2005 +++ click-1.5.0/lib/task.cc Thu Feb 1 14:02:03 2007 @@ -220,8 +220,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif if (_thread) { lock_tasks(); @@ -242,8 +241,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - // assert(!intr_nesting_level); it happens all the time from fromdevice! - SPLCHECK; + // GIANT_REQUIRED; #endif if (!scheduled()) { @@ -271,9 +269,6 @@ if (in_interrupt()) goto skip_lock; #endif -#if CLICK_BSDMODULE - SPLCHECK; -#endif if (attempt_lock_tasks()) { if (_router->_running >= Router::RUNNING_BACKGROUND) { if (!scheduled()) { @@ -308,8 +303,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif // unschedule() and move to a quiescent thread, so that subsequent // reschedule()s won't have any effect @@ -340,8 +334,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif assert(_thread); lock_tasks(); @@ -369,8 +362,7 @@ assert(!in_interrupt()); #endif #if CLICK_BSDMODULE - assert(!intr_nesting_level); - SPLCHECK; + GIANT_REQUIRED; #endif if (thread_id < RouterThread::THREAD_QUIESCENT) thread_id = RouterThread::THREAD_QUIESCENT;