diff -ur --new-file old/atm/.kernel new/atm/.kernel --- old/atm/.kernel Fri Nov 19 13:19:19 1999 +++ new/atm/.kernel Fri Jan 21 05:40:56 2000 @@ -1,2 +1,2 @@ # this file is used to control automated generation of differences -2.3.28 +2.3.40 diff -ur --new-file old/atm/CHANGES new/atm/CHANGES --- old/atm/CHANGES Wed Dec 1 02:07:13 1999 +++ new/atm/CHANGES Fri Jan 21 19:27:12 2000 @@ -1,3 +1,78 @@ +Version 0.64 to 0.65 (21-JAN-2000) +==================== + +Bug fixes +--------- + + - fixed 32/64 bit %p formatting problem in /proc/atm/vc + - atmtcp: fixed RX/TX statistics (by Jens Axboe) + - sparc64-specific ioctl 32/64 bit marshalling fixes (by Christophe Lizzi, + with further improvements by Jens Axboe) + - zeppelin -l option handling (reported by Mike Prudence, fixed by Heikki + Vatiainen) + - mkpatch didn't include drivers/atm/eni.h + - updated eni.h (tx->backlog_len was missing) + - fixed various uint32_t build problems of user space tools by including + atm.h before anything other ATM headers (first reported by Rashmi Dravid) + - "natmtcp virtual" didn't parse the command line properly + - natmtcp's TCP link changed VPI/VCI to 0.0 on close + - CLIP: fixed crash after sending ARP (reported by Rui Prior) + +New features +------------ + + - upgraded to 2.3.40 (with help from Jens Axboe) + - added sparc64 changes for ENI driver (by Heikki Vatiainen) + - added the Fore PCA-200E(/SBA-200E) driver (by Uwe Dannowski and Christophe + Lizzi) + - added the Interphase ATM PCI (i)Chip (x575, x525, x531, etc.) driver (by + Monalisa Agrawal and Peter Wang) + - added ABR fields to struct atm_trafprm (by Peter Wang) + - nicstar driver now supports setting of the CLP bit (by Rui Prior) + - added ENI_SETMULT ioctl and enitune utility to change ENI buffer size + multipliers at run time + +Other changes +------------- + + - atmsigd: changed default UNI version from 3.0 to dynamic (which defaults + to 3.0) + - atmtcp: removed ugly ../../net/atm/protocols.h include + - ioctls now internally return -ENOIOCTLCMD if ioctl command number is not + recognized + - removed ATM_CREATE_LEAF ioctl (wasn't used and suggested the wrong design + approach anyway) + - updated README.DRIVERS + - natmtcp now uses port 2812 (assigned by IANA) + - moved Documentation/atm.txt to Documentation/networking + - improved atm_kptr_int_t for non-Sparc architectures (by Christophe Lizzi) + - removed two compiler warnings from nicstar.c + - some minor nicstar cleanup (by Rui Prior) + - added "vbr" and "abr" to text2qos/qos2text ("vbr" not used for anything + right now) + - natmtcp: added commands "create", "remove", "switch", corresponding to + options -p, -r, and -s of atmtcp + - natmtcp: added link type "print" (write PDU content to stdout) + - natmtcp: now uses atm_kptr_int_t for VCC kernel pointer instead of unsigned + long + - added apologetic man page for natmtcp + - renamed natmtcp to atmtcp and removed the old atmtcp + - changed some user-space code to avoid patronizing "ambiguous `else'" + warnings from egcs, adding as few ugly redundant curly braces as possible + - fixed some other compiler warnings + - kernel part: trimmed operations structure initializers which consisted + mainly of NULL pointers + - kernel pointers sent as opaque references to user space are now of type + atm_kptr_t. Added support functions kptr_eq and kptr_print. (With help from + Richard Johnson and Mitchell Blank) + - removed various "overriding commands" warnings in user-space build process + - mkdist now creates arcvie in current directory if ~/l/arch doesn't exist + - make clean && make now works also if dependencies are present (make clean + used to remove sigd/q.out.h, which the dependencies required) + - atmtcp uses command bg instead of -b for backgrounding. Also, listen-bg + listens and backgrounds before calling accept. + + Version 0.63 to 0.64 (1-DEC-1999) ==================== diff -ur --new-file old/atm/README new/atm/README --- old/atm/README Tue Nov 30 22:28:57 1999 +++ new/atm/README Fri Jan 21 05:41:15 2000 @@ -1,4 +1,4 @@ -ATM on Linux, release 0.64 (beta) by Werner Almesberger, EPFL ICA +ATM on Linux, release 0.65 (beta) by Werner Almesberger, EPFL ICA ============================================== Werner.Almesberger@epfl.ch This is experimental software. There are known bugs and certainly even @@ -9,7 +9,7 @@ device drivers, source for demons, management and test tools, and some documentation. -The kernel patch is relative to the 2.3.28 kernel. +The kernel patch is relative to the 2.3.40 kernel. Please see http://icawww1.epfl.ch/linux-atm/info.html for a list of features supported by ATM on Linux. diff -ur --new-file old/atm/README.DRIVERS new/atm/README.DRIVERS --- old/atm/README.DRIVERS Tue Aug 4 20:34:57 1998 +++ new/atm/README.DRIVERS Tue Jan 18 08:31:42 2000 @@ -1,6 +1,9 @@ -If you're just looking for the device drivers: they're in -atm.patch +If you're just looking for the device drivers: they're either +already in the mainstream kernel (see below) or in atm.patch After applying that patch to the appropriate kernel source tree (see file USAGE for details), you'll find them in the directory drivers/atm + +Driver which haven't been integrated yet can be found on +http://icawww1.epfl.ch/linux-atm/info.html diff -ur --new-file old/atm/Rules.make new/atm/Rules.make --- old/atm/Rules.make Thu Oct 21 19:39:46 1999 +++ new/atm/Rules.make Fri Jan 21 16:30:11 2000 @@ -1,6 +1,11 @@ +# The UNI version can be configured at run time. This is the default. Use the +# explicit version selections below only in case of problems. +# +STANDARDS=-DDYNAMIC_UNI +# # Default is UNI 3.0, for good reasons, see below. # -STANDARDS=-DUNI30 +# STANDARDS=-DUNI30 # # Note: some UNI 3.0 switches will show really strange behaviour if confronted # with using 3.1 signaling, so be sure to test your network *very* @@ -20,11 +25,6 @@ # # STANDARDS=-DUNI40 -DQ2963_1 # -# When using atmsigd.new, the UNI version is configured at run time. Enable -# this with (note that this probably breaks the old atmsigd) -# -# STANDARDS=-DDYNAMIC_UNI -# # If you're using a Cisco LS100 or LS7010 switch, you should add the following # line to work around a bug in their point-to-multipoint signaling (it got # confused when receiving a CALL PROCEEDING, so we don't send it, which of @@ -95,6 +95,20 @@ ifeq (/usr/lib/libmpr.a,$(wildcard /usr/lib/libmpr.a)) LDLIBS += -lmpr endif +# +# Allow Makefiles to override depend, clean, and spotless +# +ifeq ($(DEPEND),) +DEPEND = depend_default +endif + +ifeq ($(CLEAN),) +CLEAN = clean_default +endif + +ifeq ($(SPOTLESS),) +SPOTLESS = spotless_default +endif LINK.c = $(CC) $(LDFLAGS) @@ -163,20 +177,26 @@ @for n in "" $(SUBDIRS); do [ -z "$$n" ] || \ make -C $$n filenames || exit; done -depend: +depend: $(DEPEND) + +depend_default: $(CPP) -M *.c $(INCLUDES) -I$(TOPDIR)/lib >.tmpdepend mv .tmpdepend .depend for n in "" $(SUBDIRS); do [ -z "$$n" ] || \ make -C $$n depend || exit; done -clean: +clean: $(CLEAN) + +clean_default: rm -f *.o core .checker y.tab.h y.tab.c lex.yy.c $(TRASH) for n in "" $(SUBDIRS); do [ -z "$$n" ] || \ make -C $$n clean || exit; done -spotless: clean +spotless: $(SPOTLESS) + +spotless_default: clean rm -f $(BOOTPGMS) $(SYSPGMS) $(USRPGMS) $(PGMS) *.a - rm -f .depend .checker + rm -f .depend .checker $(TRASH_SPOTLESS) for n in "" $(SUBDIRS); do [ -z "$$n" ] || \ make -C $$n spotless || exit; done diff -ur --new-file old/atm/USAGE new/atm/USAGE --- old/atm/USAGE Wed Dec 1 02:08:36 1999 +++ new/atm/USAGE Fri Jan 21 09:17:27 2000 @@ -1,4 +1,4 @@ -%:Usage instructions - ATM on Linux, release 0.64 +%:Usage instructions - ATM on Linux, release 0.65 %:------------------------------------------------- %: %: @@ -20,9 +20,9 @@ In order to install this package, you need - the package itself - ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.64.tar.gz - - the Linux kernel, version 2.3.28, e.g. from - ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.28.tar.gz + ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.65.tar.gz + - the Linux kernel, version 2.3.40, e.g. from + ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.40.tar.gz - Perl, version 4 or 5 - if you want memory debugging: MPR version 1.6, e.g. from ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz @@ -36,11 +36,11 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.64.tar.gz +tar xfz atm-0.65.tar.gz and the kernel source: -tar xfz linux-2.3.28.tar.gz +tar xfz linux-2.3.40.tar.gz Finally, you can extract the ATM-related patches: @@ -56,7 +56,7 @@ atm/qgen/ Q.2931-style message handling atm/ilmid/ ILMI address registration demon: ilmid atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmtcp, - esi, sonetdiag, saaldump, and zntune + enitune, esi, sonetdiag, saaldump, and zntune atm/test/ Test programs: align, aping, aread, awrite, br, bw, isp, ttcp_atm, window atm/arpd/ ATMARP tools and demon: atmarp, atmarpd @@ -197,7 +197,7 @@ outside of the ATM context. For such packages, only patches are contained in the ATM on Linux distribution. The complete packages can be obtained either from the original source (described in atm/extra/extra.html) or from -ftp://lrcftp.epfl.ch/pub/linux/atm/extra/ . +ftp://icaftp.epfl.ch/pub/linux/atm/extra/ . The packages are automatically downloaded, patched, and built by running make in the atm/extra/ directory (requires that the Lynx @@ -235,22 +235,28 @@ run both sides on the same system to create two connected "interfaces") and run the following command on one of them (let's call it "a"): - a# atmtcp -l + a# atmtcp virtual listen Then, on the other system ("b"), run - b# atmtcp -c + b# atmtcp virtual connect -Both atmtcps will report on their progress and the kernel should display a -message like +Both atmtcps will report on their progress and the kernel should display +messages like -atmtcp (itf 1): ready +Link 0: virtual interface 2 +Link 1: incoming ATMTCP connection from 127.0.0.1 -on each system. Note that atmtcp keeps running and that interrupting it +and + +Link 0: virtual interface 3 +Link 1: ATMTCP connection to localhost + +on the two systems. Note that atmtcp keeps running and that interrupting it breaks the virtual wire. Multiple "wires" can be attached to the same machine by specifying a port -number (default is 8401). Note that no AAL processing is performed. It is +number (default is 2812). Note that no AAL processing is performed. It is therefore not possible to receive data using a different AAL (e.g. AAL0) than the one with which the data was sent. @@ -915,7 +921,7 @@ ========== [1] Almesberger, Werner. Linux ATM API, - ftp://lrcftp.epfl.ch/pub/linux/atm/api/ , July 1996. + ftp://icaftp.epfl.ch/pub/linux/atm/api/ , July 1996. [2] Laubach, Mark. Classical IP and ARP over ATM, RFC1577, January 1994. [6] Cole, Christopher. Bridging mini-Howto, diff -ur --new-file old/atm/VERSION new/atm/VERSION --- old/atm/VERSION Tue Nov 30 22:29:01 1999 +++ new/atm/VERSION Fri Jan 21 19:29:10 2000 @@ -1 +1 @@ -0.64 +0.65 diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c --- old/atm/arpd/arp.c Tue Nov 30 22:02:42 1999 +++ new/atm/arpd/arp.c Tue Jan 18 22:34:13 2000 @@ -1,6 +1,6 @@ /* arp.c - ARP state machine */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -260,10 +260,11 @@ ITF *itf; diag(COMPONENT,DIAG_DEBUG,"sending an InARP request for each IP interface"); - for (vcc = entry->vccs; vcc; vcc = vcc->next) - if (!vcc->connecting) - if (entry->itf) inarp_for_itf(vcc,entry->itf); - else for (itf = itfs; itf; itf = itf->next) inarp_for_itf(vcc,itf); + for (vcc = entry->vccs; vcc; vcc = vcc->next) { + if (vcc->connecting) continue; + if (entry->itf) inarp_for_itf(vcc,entry->itf); + else for (itf = itfs; itf; itf = itf->next) inarp_for_itf(vcc,itf); + } } @@ -501,7 +502,7 @@ * If we still don't have an entry, we try to use the entry that already * belongs to the VCC (InARP), or we create a new one (ARP). */ - if (!entry) + if (!entry) { if (vcc) { entry = vcc->entry; if (!entry->itf) { @@ -521,6 +522,7 @@ entry = alloc_entry(1); entry->flags = ATF_PUBL; } + } if (!atmsvc_addr_in_use(*addr)) addr = NULL; if (entry->addr && addr && (entry->flags & ATF_PERM) && !atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0,0)) @@ -574,9 +576,10 @@ connect_me(entry); send_notifications(entry,1); } - if ((entry->flags & ATF_ARPSRV) || !(entry->flags & ATF_PERM)) + if ((entry->flags & ATF_ARPSRV) || !(entry->flags & ATF_PERM)) { if (entry->itf->arp_srv) START_TIMER(entry,CREVAL); else START_TIMER(entry,SREVAL); + } entry->state = as_valid; } @@ -708,17 +711,19 @@ TL_LEN); else { memcpy(addr->sas_addr.pub,num,num_tl & TL_LEN); - if (sub) + if (sub) { if (sub_tl != ATM_ESA_LEN) { diag(COMPONENT,DIAG_ERROR,"bad ESA length (%d)",sub_tl); *addr->sas_addr.pub = 0; } else memcpy(addr->sas_addr.prv,sub,ATM_ESA_LEN); + } } - else if (num) + else if (num) { if (num_tl != ATM_ESA_LEN) diag(COMPONENT,DIAG_ERROR,"bad ESA length (%d)",num_tl); else memcpy(addr->sas_addr.prv,num,ATM_ESA_LEN); + } } @@ -879,16 +884,16 @@ entry->qos = *qos; entry->sndbuf = sndbuf; entry->flags = flags; - if (!(flags & ATF_PERM) || (flags & ATF_ARPSRV)) + if (!(flags & ATF_PERM) || (flags & ATF_ARPSRV)) { if (itf->arp_srv) START_TIMER(entry,CREVAL); else START_TIMER(entry,SREVAL); + } entry->itf = itf; Q_INSERT_HEAD(itf->table,entry); - if (flags & ATF_ARPSRV) { - entry->state = as_invalid; - itf->arp_srv = entry; - (void) want_arp_srv(itf); - } + if (!(flags & ATF_ARPSRV)) return 0; + entry->state = as_invalid; + itf->arp_srv = entry; + (void) want_arp_srv(itf); return 0; } @@ -1000,10 +1005,9 @@ } for (entry = vcc->entry->itf->table; entry; entry = next) { next = entry->next; - if (entry != vcc->entry && entry->state == as_resolv) - if (entry->vccs || (entry->flags & ATF_PERM)) - entry->state = as_invalid; - else discard_entry(entry); + if (entry == vcc->entry || entry->state != as_resolv) continue; + if (entry->vccs || (entry->flags & ATF_PERM)) entry->state = as_invalid; + else discard_entry(entry); } START_TIMER(vcc->entry,RETRY); free(vcc); diff -ur --new-file old/atm/arpd/table.c new/atm/arpd/table.c --- old/atm/arpd/table.c Tue Nov 30 22:58:35 1999 +++ new/atm/arpd/table.c Tue Jan 18 22:30:21 2000 @@ -1,6 +1,6 @@ /* table.c - ATMARP table */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -242,10 +242,11 @@ out_error = 0; dump_all(); if (fclose(out_file) < 0) out_error = errno; - if (!out_error) + if (!out_error) { if (rename(ATMARP_TMP_DUMP_FILE,ATMARP_DUMP_FILE) < 0) out_error = errno; else table_uptodate = 1; + } unlink(ATMARP_TMP_DUMP_FILE); return out_error; } diff -ur --new-file old/atm/atm.patch new/atm/atm.patch --- old/atm/atm.patch Wed Dec 1 02:06:44 1999 +++ new/atm/atm.patch Fri Jan 21 19:37:28 2000 @@ -1,5 +1,5 @@ ---- ref/CREDITS Fri Nov 12 13:36:13 1999 -+++ work/CREDITS Mon Nov 22 13:55:13 1999 +--- ref/CREDITS Tue Jan 18 07:19:08 2000 ++++ work/CREDITS Fri Jan 21 16:01:02 2000 @@ -38,11 +38,11 @@ S: United Kingdom @@ -11,7 +11,7 @@ S: Ecole Polytechnique Federale de Lausanne -S: DI-LRC -S: INR (Ecublens) -+S: ICA ++S: DSC ICA +S: INN (Ecublens) S: CH-1015 Lausanne S: Switzerland @@ -29,9 +29,9 @@ +S: Australia + N: James Banks - E: james.banks@caldera.com + E: james@sovereign.org D: TLAN network driver -@@ -1701,6 +1709,10 @@ +@@ -1735,6 +1743,10 @@ N: Frederic Potter E: Frederic.Potter@masi.ibp.fr D: Some PCI kernel support @@ -42,9 +42,19 @@ N: Stefan Probst E: sp@caldera.de ---- ref/Documentation/Configure.help Fri Nov 12 19:12:11 1999 -+++ work/Documentation/Configure.help Mon Nov 22 13:46:58 1999 -@@ -3931,11 +3931,29 @@ +--- ref/Documentation/Configure.help Fri Jan 21 00:00:16 2000 ++++ work/Documentation/Configure.help Fri Jan 21 16:01:02 2000 +@@ -3839,7 +3839,8 @@ + of your ATM card below. + + Note that you need a set of user-space programs to actually make use +- of ATM. See the file Documentation/atm.txt for further details. ++ of ATM. See the file Documentation/networking/atm.txt for further ++ details. + + Classical IP over ATM + CONFIG_ATM_CLIP +@@ -3981,12 +3982,30 @@ overhead for timer synchronization and also per-packet overhead for time conversion. @@ -54,7 +64,7 @@ The NICStAR chipset family is used in a large number of ATM NICs for 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE series. -+ + +ForeRunner LE155 PHYsical layer +CONFIG_ATM_NICSTAR_USE_SUNI + Support for the S-UNI and compatible PHYsical layer chips. These are @@ -72,12 +82,356 @@ + you to control the loopback mode of the chip via a dedicated IOCTL. + This driver is required for proper handling of temporary carrier + loss, so if you have a 25Mbps NICStAR based ATM card you must say Y. - ++ Madge Ambassador (Collage PCI 155 Server) CONFIG_ATM_AMBASSADOR ---- ref/arch/sparc64/config.in Fri Nov 5 19:22:51 1999 -+++ work/arch/sparc64/config.in Mon Nov 22 13:56:06 1999 -@@ -215,6 +215,9 @@ + This is a driver for ATMizer based ATM card produced by Madge +@@ -4020,6 +4039,109 @@ + dynamically using an ioctl (not yet) or changed by sending the + string "Dxxxx" to VCI 1023 (where x is a hex digit). See the file + drivers/atm/horizon.h for the meanings of the bits in the mask. ++ ++ When active, these messages can have a significant impact on the ++ speed of the driver, and the size of your syslog files! When ++ inactive, they will have only a modest impact on performance. ++ ++FORE Systems 200E-series ++CONFIG_ATM_FORE200E ++ This is a driver for the FORE Systems 200E-series ATM adapter ++ cards. It simultaneously supports PCA-200E and SBA-200E models ++ on PCI and SBUS hosts. Say Y (or M to compile as a module ++ named fore_200e.o) here if you have one of these ATM adapters. ++ ++ See the file Documentation/networking/fore200e.txt for further ++ details. ++ ++Enable PCA-200E card support on PCI-based hosts ++CONFIG_ATM_FORE200E_PCA ++ Enable this if you want your PCA-200E cards to be probed. ++ ++Use default PCA-200E firmware ++CONFIG_ATM_FORE200E_PCA_DEFAULT_FW ++ Use the default PCA-200E firmware data shipped with the driver. ++ ++ Normal users do not have to deal with the firmware stuff, so ++ this feature is normally enabled. ++ ++Pathname of user-supplied binary firmware ++CONFIG_ATM_FORE200E_PCA_FW ++ This defines the pathname of an alternative PCA-200E binary ++ firmware image supplied by the user. This pathname may be ++ absolute or relative to the drivers/atm directory. ++ ++ The driver comes with an adequate firmware image, so normal users ++ do not have to supply an alternative one. They just enable the use ++ of the default firmware instead. ++ ++Enable SBA-200E card support on SBUS-based hosts ++CONFIG_ATM_FORE200E_SBA ++ Enable this if you want your SBA-200E cards to be probed. ++ ++Use default SBA-200E firmware ++CONFIG_ATM_FORE200E_SBA_DEFAULT_FW ++ Use the default SBA-200E firmware data shipped with the driver. ++ ++ Normal users do not have to deal with the firmware stuff, so ++ this feature is normally enabled. ++ ++Pathname of user-supplied binary firmware ++CONFIG_ATM_FORE200E_SBA_FW ++ This defines the pathname of an alternative SBA-200E binary ++ firmware image supplied by the user. This pathname may be ++ absolute or relative to the drivers/atm directory. ++ ++ The driver comes with an adequate firmware image, so normal users ++ do not have to supply an alternative one. They just enable the use ++ of the default firmware instead. ++ ++Maximum number of tx retries ++CONFIG_ATM_FORE200E_TX_RETRY ++ Specifies the number of times the driver attempts to transmit ++ a message before giving up, if the transmit queue of the ATM card ++ is transiently saturated. ++ ++ Saturation of the transmit queue may occur only under extreme ++ conditions, e.g. when a fast host continuously submits very small ++ frames (<64 bytes) or raw AAL0 cells (48 bytes) to the ATM adapter. ++ ++ Note that under common conditions, it is unlikely that you encounter ++ a saturation of the transmit queue, so the retry mechanism never ++ comes into play. ++ ++Debugging level (0-3) ++CONFIG_ATM_FORE200E_DEBUG ++ Specifies the level of debugging messages issued by the driver. ++ The verbosity of the driver increases with the value of this ++ parameter. ++ ++ When active, these messages can have a significant impact on ++ the performances of the driver, and the size of your syslog files! ++ Keep the debugging level to 0 during normal operations. ++ ++Interphase ATM PCI x575/x525/x531 ++CONFIG_ATM_IA ++ This is a driver for the Interphase (i)ChipSAR adapter cards ++ which include a variety of variants in term of the size of the ++ control memory (128K-1KVC, 512K-4KVC), the size of the packet ++ memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3, ++ UTP155, UTP25, DS3 and E3). Go to: ++ www.iphase.com/products/ClassSheet.cfm?ClassID=ATM ++ for more info about the cards. Say Y (or M to compile as a module ++ named iphase.o) here if you have one of these cards. ++ ++ See the file Documentation/networking/iphase.txt for further ++ details. ++ ++Enable debugging messages ++CONFIG_ATM_IA_DEBUG ++ Somewhat useful debugging messages are available. The choice of ++ messages is controlled by a bitmap. This may be specified as a ++ module argument (kernel command line argument as well?), changed ++ dynamically using an ioctl (Get the debug utility, iadbg, from ++ ftp.iphase.com/pub/atm/pci). See the file drivers/atm/iphase.h ++ for the meanings of the bits in the mask. + + When active, these messages can have a significant impact on the + speed of the driver, and the size of your syslog files! When +--- ref/Documentation/atm.txt Wed Sep 8 20:14:31 1999 ++++ work/Documentation/atm.txt Fri Jan 21 16:01:02 2000 +@@ -1,8 +0,0 @@ +-In order to use anything but the most primitive functions of ATM, +-several user-mode programs are required to assist the kernel. These +-programs and related material can be found via the ATM on Linux Web +-page at http://icawww1.epfl.ch/linux-atm/ +- +-If you encounter problems with ATM, please report them on the ATM +-on Linux mailing list. Subscription information, archives, etc., +-can be found on http://icawww1.epfl.ch/linux-atm/ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/Documentation/networking/atm.txt Fri Jan 21 16:01:02 2000 +@@ -0,0 +1,8 @@ ++In order to use anything but the most primitive functions of ATM, ++several user-mode programs are required to assist the kernel. These ++programs and related material can be found via the ATM on Linux Web ++page at http://icawww1.epfl.ch/linux-atm/ ++ ++If you encounter problems with ATM, please report them on the ATM ++on Linux mailing list. Subscription information, archives, etc., ++can be found on http://icawww1.epfl.ch/linux-atm/ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/Documentation/networking/fore200e.txt Fri Jan 21 16:01:02 2000 +@@ -0,0 +1,47 @@ ++Fore PCA-200E/SBA-200E ATM NIC Firmware ++--------------------------------------- ++ ++The driver is shipped with firmware data being uploaded to the ATM adapters ++at system boot time or at module loading time. The supplied firmware images ++should work with all adapters. ++ ++However, if you encounter problems (firmware doesn't start or the driver ++is unable to read PROM data), you may consider trying another firmware ++version. Alternative binary firmware images can be found somewhere on the ++ForeThough CD-ROM supplied with your adapter by FORE Systems. ++ ++You can also get the latest firmware images from FORE Systems at ++http://www.fore.com. Register TACTics Online and go to ++the 'software updates' pages. The firmware binaries are part of ++the various ForeThough software distributions. ++ ++Notice that different versions of the PCA-200E firmware exist, depending ++on the endianess of the host architecture. The driver is shipped with ++both little and big endian PCA firmware images. ++ ++Name and location of the new firmware images can be set at kernel ++configuration time. ++ ++ ++Firmware updates ++---------------- ++ ++1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix) ++ (see the README file) to some directory, such as linux/drivers/atm. ++ ++2. Reconfigure your kernel to set the new firmware name and location. ++ Expected pathnames are absolute or relative to the drivers/atm directory. ++ ++3. Delete the files drivers/atm/fore200e_pca_fw.[co] and/or fore200e_sba_fw.[co] ++ to ensure that the new firmware will be used when rebuilding the kernel or ++ the module. ++ ++4. Rebuild and re-install your kernel or your module. ++ ++ ++Feedback ++-------- ++ ++Feedback is welcome. Please send success stories/bug reports/ ++patches/improvement/comments/flames to . ++ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/Documentation/networking/iphase.txt Fri Jan 21 16:01:02 2000 +@@ -0,0 +1,158 @@ ++ ++ READ ME FISRT ++ ATM (i)Chip IA Linux Driver Source ++-------------------------------------------------------------------------------- ++ Read This Before You Begin! ++-------------------------------------------------------------------------------- ++ ++Description ++----------- ++ ++This is the README file for the Interphase PCI ATM (i)Chip IA Linux driver ++source release. ++ ++The features and limitations of this driver are as follows: ++ - A single VPI (VPI value of 0) is supported. ++ - Supports 4K VCs for the server board (with 512K control memory) and 1K ++ VCs for the client board (with 128K control memory). ++ - UBR, ABR and CBR service categories are supported. ++ - Only AAL5 is supported. ++ - Supports setting of PCR on the VCs. ++ - Multiple adapters in a system are supported. ++ - All variants of Interphase ATM PCI (i)Chip adapter cards are supported, ++ including x575 (OC3, control memory 128K , 512K and packet memory 128K, ++ 512K and 1M), x525 (UTP25) and x531 (DS3 and E3). See ++ http://www.iphase.com/products/ClassSheet.cfm?ClassID=ATM ++ for details. ++ - Only x86 platforms are supported. ++ - SMP is supported. ++ ++ ++Before You Start ++---------------- ++ ++ ++Installation ++------------ ++ ++1. Installing the adapters in the system ++ To install the ATM adapters in the system, follow the steps below. ++ a. Login as root. ++ b. Shut down the system and power off the system. ++ c. Install one or more ATM adapters in the system. ++ d. Connect each adapter to a port on an ATM switch. The green 'Link' ++ LED on the front panel of the adapter will be on if the adapter is ++ connected to the switch properly when the system is powered up. ++ e. Power on and boot the system. ++ ++2. [ Removed ] ++ ++3. Rebuild kernel with ABR support ++ [ a. and b. removed ] ++ c. Reconfigure the kernel, choose the Interphase ia driver through "make ++ menuconfig" or "make xconfig". ++ d. Rebuild the kernel, loadable modules and the atm tools. ++ e. Install the new built kernel and modules and reboot. ++ ++4. Load the adapter hardware driver (ia driver) if it is built as a module ++ a. Login as root. ++ b. Change directory to /lib/modules//atm. ++ c. Run "insmod suni.o;insmod iphase.o" ++ The yellow 'status' LED on the front panel of the adapter will blink ++ while the driver is loaded in the system. ++ d. To verify that the 'ia' driver is loaded successfully, run the ++ following command: ++ ++ cat /proc/atm/devices ++ ++ If the driver is loaded successfully, the output of the command will ++ be similar to the following lines: ++ ++ Itf Type ESI/"MAC"addr AAL(TX,err,RX,err,drop) ... ++ 0 ia xxxxxxxxx 0 ( 0 0 0 0 0 ) 5 ( 0 0 0 0 0 ) ++ ++ You can also check the system log file /var/log/messages for messages ++ related to the ATM driver. ++ ++5. Ia Driver Configuration ++ ++5.1 Configuration of adapter buffers ++ The (i)Chip boards have 3 different packet RAM size variants: 128K, 512K and ++ 1M. The RAM size decides the number of buffers and buffer size. The default ++ size and number of buffers are set as following: ++ ++ Totol Rx RAM Tx RAM Rx Buf Tx Buf Rx buf Tx buf ++ RAM size size size size size cnt cnt ++ -------- ------ ------ ------ ------ ------ ------ ++ 128K 64K 64K 10K 10K 6 6 ++ 512K 256K 256K 10K 10K 25 25 ++ 1M 512K 512K 10K 10K 51 51 ++ ++ These setting should work well in most environments, but can be ++ changed by typing the following command: ++ ++ insmod /ia.o IA_RX_BUF= IA_RX_BUF_SZ= \ ++ IA_TX_BUF= IA_TX_BUF_SZ= ++ Where: ++ RX_CNT = number of receive buffers in the range (1-128) ++ RX_SIZE = size of receive buffers in the range (48-64K) ++ TX_CNT = number of transmit buffers in the range (1-128) ++ TX_SIZE = size of transmit buffers in the range (48-64K) ++ ++ 1. Transmit and receive buffer size must be a multiple of 4. ++ 2. Care should be taken so that the memory required for the ++ transmit and receive buffers is less than or equal to the ++ total adapter packet memory. ++ ++5.2 Turn on ia debug trace ++ ++ When the ia driver is built with the CONFIG_ATM_IA_DEBUG flag, the driver ++ can provide more debug trace if needed. There is a bit mask variable, ++ IADebugFlag, which controls the output of the traces. You can find the bit ++ map of the IADebugFlag in iphase.h. ++ The debug trace can be turn on through the insmod command line option, for ++ example, "insmod iphase.o IADebugFlag=0xffffffff" can turn on all the debug ++ traces together with loading the driver. ++ ++6. Ia Driver Test Using ttcp_atm and PVC ++ ++ For the PVC setup, the test machines can either be connected back-to-back or ++ through a switch. If connected through the switch, the switch must be ++ configured for the PVC(s). ++ ++ a. For UBR test: ++ At the test machine intended to receive data, type: ++ ttcp_atm -r -a -s 0.100 ++ At the other test machine, type: ++ ttcp_atm -t -a -s 0.100 -n 10000 ++ Run "ttcp_atm -h" to display more options of the ttcp_atm tool. ++ b. For ABR test: ++ It is the same as the UBR testing, but with an extra command option: ++ -Pabr:max_pcr= ++ where: ++ xxx = the maximum peak cell rate, from 170 - 353207. ++ This option must be set on both the machines. ++ c. For CBR test: ++ It is the same as the UBR testing, but with an extra command option: ++ -Pcbr:max_pcr= ++ where: ++ xxx = the maximum peak cell rate, from 170 - 353207. ++ This option may only be set on the trasmit machine. ++ ++ ++OUTSTANDING ISSUES ++------------------ ++ ++ ++ ++Contact Information ++------------------- ++ ++ Customer Support: ++ United States: Telephone: (214) 654-5555 ++ Fax: (214) 654-5500 ++ E-Mail: intouch@iphase.com ++ Europe: Telephone: 33 (0)1 41 15 44 00 ++ Fax: 33 (0)1 41 15 12 13 ++ World Wide Web: http://www.iphase.com ++ Anonymous FTP: ftp.iphase.com +--- ref/arch/sparc64/config.in Fri Jan 14 09:50:53 2000 ++++ work/arch/sparc64/config.in Fri Jan 21 16:01:03 2000 +@@ -216,6 +216,9 @@ # bool ' FDDI driver support' CONFIG_FDDI # if [ "$CONFIG_FDDI" = "y" ]; then # fi @@ -87,9 +441,9 @@ fi endmenu fi ---- ref/arch/sparc64/kernel/ioctl32.c Fri Sep 10 20:06:19 1999 -+++ work/arch/sparc64/kernel/ioctl32.c Mon Nov 22 13:56:06 1999 -@@ -60,6 +60,17 @@ +--- ref/arch/sparc64/kernel/ioctl32.c Thu Jan 13 21:03:00 2000 ++++ work/arch/sparc64/kernel/ioctl32.c Fri Jan 21 16:01:03 2000 +@@ -60,6 +60,18 @@ #include @@ -103,11 +457,12 @@ +#include +#include +#include ++#include + /* Use this to get at 32-bit user passed pointers. See sys_sparc32.c for description about these. */ #define A(__x) ((unsigned long)(__x)) -@@ -1694,6 +1705,144 @@ +@@ -1734,6 +1746,214 @@ return 0; } @@ -117,8 +472,13 @@ + __kernel_caddr_t32 arg; +}; + ++struct atm_iobuf32 { ++ int length; ++ __kernel_caddr_t32 buffer; ++}; ++ +#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32) -+#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atmif_sioc32) ++#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atmif_iobuf32) +#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32) +#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32) +#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32) @@ -135,7 +495,7 @@ +static struct { + unsigned int cmd32; + unsigned int cmd; -+} atmioc_map[] = { ++} atm_ioctl_map[] = { + { ATM_GETLINKRATE32, ATM_GETLINKRATE }, + { ATM_GETNAMES32, ATM_GETNAMES }, + { ATM_GETTYPE32, ATM_GETTYPE }, @@ -152,7 +512,59 @@ + { ATM_GETSTATZ32, ATM_GETSTATZ } +}; + -+#define NR_ATMIOC (sizeof(atmioc_map)/sizeof(atmioc_map[0])) ++#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0])) ++ ++static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg) ++{ ++ struct atm_iobuf32 iobuf32; ++ struct atm_iobuf iobuf = { 0, NULL }; ++ mm_segment_t old_fs; ++ int err; ++ ++ err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg, ++ sizeof(struct atm_iobuf32)); ++ if (err) ++ return -EFAULT; ++ ++ iobuf.length = iobuf32.length; ++ ++ if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) { ++ iobuf.buffer = (void*)(unsigned long)iobuf32.buffer; ++ } else { ++ iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL); ++ if (iobuf.buffer == NULL) { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length); ++ if (err) { ++ err = -EFAULT; ++ goto out; ++ } ++ } ++ ++ old_fs = get_fs(); set_fs (KERNEL_DS); ++ err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); ++ set_fs (old_fs); ++ if (err) ++ goto out; ++ ++ if (iobuf.buffer && iobuf.length > 0) { ++ err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length); ++ if (err) { ++ err = -EFAULT; ++ goto out; ++ } ++ } ++ err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); ++ ++out: ++ if (iobuf32.buffer && iobuf32.length > 0) ++ kfree(iobuf.buffer); ++ ++ return err; ++} + + +static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -170,8 +582,8 @@ + sioc.number = sioc32.number; + sioc.length = sioc32.length; + -+ if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc.length == 0) { -+ sioc.arg = NULL; ++ if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) { ++ sioc.arg = (void*)(unsigned long)sioc32.arg; + } else { + sioc.arg = kmalloc(sioc.length, GFP_KERNEL); + if (sioc.arg == NULL) { @@ -179,7 +591,7 @@ + goto out; + } + -+ err = copy_from_user(sioc.arg, A(sioc32.arg), sioc.length); ++ err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length); + if (err) { + err = -EFAULT; + goto out; @@ -189,10 +601,10 @@ + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&sioc); + set_fs (old_fs); -+ if(err) ++ if (err) + goto out; + -+ if(sioc.arg && sioc.length > 0) { ++ if (sioc.arg && sioc.length > 0) { + err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length); + if (err) { + err = -EFAULT; @@ -202,10 +614,10 @@ + err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); + + out: -+ if(sioc.arg) -+ kfree(sioc.arg); ++ if (sioc32.arg && sioc32_length > 0) ++ kfree(sioc.arg); + -+ return err; ++ return err; +} + + @@ -214,18 +626,36 @@ + int i; + unsigned int cmd = 0; + -+ for (i = 0; i < NR_ATMIOC; i++) { -+ if (cmd32 == atmioc_map[i].cmd32) { -+ cmd = atmioc_map[i].cmd; -+ break; -+ } -+ } -+ if (i == NR_ATMIOC) -+ return -EINVAL; ++ switch (cmd32) { ++ case SUNI_GETLOOP: ++ case SUNI_SETLOOP: ++ case SONET_GETSTAT: ++ case SONET_GETSTATZ: ++ case SONET_GETDIAG: ++ case SONET_SETDIAG: ++ case SONET_CLRDIAG: ++ case SONET_SETFRAMING: ++ case SONET_GETFRAMING: ++ case SONET_GETFRSENSE: ++ return do_atmif_sioc(fd, cmd32, arg); ++ } ++ ++ if (cmd == 0) { ++ for (i = 0; i < NR_ATM_IOCTL; i++) { ++ if (cmd32 == atm_ioctl_map[i].cmd32) { ++ cmd = atm_ioctl_map[i].cmd; ++ break; ++ } ++ } ++ } ++ ++ if (i == NR_ATM_IOCTL) ++ return -ENOIOCTLCMD; + + switch (cmd) { -+ case ATM_GETLINKRATE: + case ATM_GETNAMES: ++ return do_atm_iobuf(fd, cmd, arg); ++ case ATM_GETLINKRATE: + case ATM_GETTYPE: + case ATM_GETESI: + case ATM_GETADDR: @@ -239,20 +669,15 @@ + case ATM_GETSTAT: + case ATM_GETSTATZ: + return do_atmif_sioc(fd, cmd, arg); -+ break; -+ -+ default: -+ /* fill in from net/atm/common.c default */ -+ break; + } + -+ return 0; ++ return -ENOIOCTLCMD; +} + asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; -@@ -1880,6 +2029,23 @@ +@@ -1921,6 +2141,33 @@ error = do_video_ioctl(fd, cmd, arg); goto out; @@ -270,13 +695,23 @@ + case ATM_SETESIF32: + case ATM_GETSTAT32: + case ATM_GETSTATZ32: ++ case SUNI_GETLOOP: ++ case SUNI_SETLOOP: ++ case SONET_GETSTAT: ++ case SONET_GETSTATZ: ++ case SONET_GETDIAG: ++ case SONET_SETDIAG: ++ case SONET_CLRDIAG: ++ case SONET_SETFRAMING: ++ case SONET_GETFRAMING: ++ case SONET_GETFRSENSE: + error = do_atm_ioctl(fd, cmd, arg); + goto out; + /* List here exlicitly which ioctl's are known to have * compatable types passed or none at all... */ -@@ -2374,6 +2540,31 @@ +@@ -2427,6 +2674,24 @@ case RAW_SETBIND: case RAW_GETBIND: @@ -295,13 +730,6 @@ + case ATMARP_ENCAP: + case ATMTCP_CREATE: + case ATMTCP_REMOVE: -+ case SONET_GETSTAT: -+ case SONET_GETSTATZ: -+ case SONET_SETDIAG: -+ case SONET_CLRDIAG: -+ case SONET_SETFRAMING: -+ case SONET_GETFRAMING: -+ case SONET_GETFRSENSE: + case ATMMPC_CTRL: + case ATMMPC_DATA: + @@ -309,7 +737,7 @@ goto out; --- ref/drivers/atm/Config.in Thu Oct 7 19:17:09 1999 -+++ work/drivers/atm/Config.in Mon Nov 22 13:56:06 1999 ++++ work/drivers/atm/Config.in Fri Jan 21 16:01:03 2000 @@ -8,7 +8,7 @@ fi if [ "$CONFIG_PCI" = "y" ]; then @@ -344,8 +772,44 @@ fi tristate 'Madge Ambassador (Collage PCI 155 Server)' CONFIG_ATM_AMBASSADOR if [ "$CONFIG_ATM_AMBASSADOR" != "n" ]; then +@@ -43,5 +46,35 @@ + if [ "$CONFIG_ATM_HORIZON" != "n" ]; then + bool ' Enable debugging messages' CONFIG_ATM_HORIZON_DEBUG + fi ++ tristate 'Interphase ATM PCI x575/x525/x531' CONFIG_ATM_IA ++ if [ "$CONFIG_ATM_IA" != "n" ]; then ++ bool ' Enable debugging messages' CONFIG_ATM_IA_DEBUG ++ fi ++fi ++#if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then ++if [ "$CONFIG_PCI" = "y" ]; then ++ tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E ++ if [ "$CONFIG_ATM_FORE200E" != "n" ]; then ++ if [ "$CONFIG_PCI" = "y" ]; then ++ bool ' PCA-200E support' CONFIG_ATM_FORE200E_PCA y ++ if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then ++ bool ' Use default PCA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_PCA_DEFAULT_FW ++ if [ "$CONFIG_ATM_FORE200E_PCA_DEFAULT_FW" = "n" ]; then ++ string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW ++ fi ++ fi ++ fi ++# if [ "$CONFIG_SBUS" = "y" ]; then ++# bool ' SBA-200E support' CONFIG_ATM_FORE200E_SBA y ++# if [ "$CONFIG_ATM_FORE200E_SBA" = "y" ]; then ++# bool ' Use default SBA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_SBA_DEFAULT_FW ++# if [ "$CONFIG_ATM_FORE200E_SBA_DEFAULT_FW" = "n" ]; then ++# string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_SBA_FW "" ++# fi ++# fi ++# fi ++ int ' Maximum number of tx retries' CONFIG_ATM_FORE200E_TX_RETRY 16 ++ int ' Debugging level (0-3)' CONFIG_ATM_FORE200E_DEBUG 0 ++ fi + fi + endmenu --- ref/drivers/atm/Makefile Wed Sep 8 20:14:31 1999 -+++ work/drivers/atm/Makefile Mon Nov 22 13:46:58 1999 ++++ work/drivers/atm/Makefile Fri Jan 21 16:01:03 2000 @@ -43,12 +43,18 @@ ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y) NEED_SUNI_LX = suni.o @@ -365,22 +829,313 @@ endif endif -@@ -72,6 +78,12 @@ +@@ -68,20 +74,88 @@ + endif + endif + ++ifeq ($(CONFIG_ATM_TCP),y) ++L_OBJS += atmtcp.o ++else ++ ifeq ($(CONFIG_ATM_TCP),m) ++ M_OBJS += atmtcp.o ++ endif ++endif ++ ++ifeq ($(CONFIG_ATM_FORE200E_PCA),y) ++FORE200E_FW_OBJS += fore200e_pca_fw.o ++ ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) ++# guess the target endianess to choose the right PCA-200E firmware image ++ CONFIG_ATM_FORE200E_PCA_FW := $(shell if test -n "`$(CC) -E -dM ../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo pca200e.bin; else echo pca200e_ecd.bin2; fi) ++ endif ++endif ++ifeq ($(CONFIG_ATM_FORE200E_SBA),y) ++FORE200E_FW_OBJS += fore200e_sba_fw.o ++ ifeq ($(CONFIG_ATM_FORE200E_SBA_DEFAULT_FW),y) ++ CONFIG_ATM_FORE200E_SBA_FW := sba200e_ecd.bin2 ++ endif ++endif ++ifeq ($(CONFIG_ATM_FORE200E),y) ++L_OBJS += fore200e.o $(FORE200E_FW_OBJS) ++else ++ ifeq ($(CONFIG_ATM_FORE200E),m) ++ M_OBJS += fore_200e.o ++ endif ++endif ++ ++ifeq ($(CONFIG_ATM_IA),y) ++L_OBJS += iphase.o ++NEED_SUNI_LX = suni.o ++else ++ifeq ($(CONFIG_ATM_IA),m) ++ M_OBJS += iphase.o ++ NEED_SUNI_MX = suni.o ++ endif ++endif ++ + ifeq ($(NEED_SUNI_LX),) MX_OBJS += $(NEED_SUNI_MX) else LX_OBJS += $(NEED_SUNI_LX) -+endif -+ + endif + +-ifeq ($(CONFIG_ATM_TCP),y) +-L_OBJS += atmtcp.o +ifeq ($(NEED_IDT77105_LX),) + MX_OBJS += $(NEED_IDT77105_MX) -+else + else +- ifeq ($(CONFIG_ATM_TCP),m) +- M_OBJS += atmtcp.o +- endif + LX_OBJS += $(NEED_IDT77105_LX) endif - ifeq ($(CONFIG_ATM_TCP),y) + EXTRA_CFLAGS=-g + + include $(TOPDIR)/Rules.make ++ ++# FORE Systems 200E-series firmware magic ++fore200e_pca_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_PCA_FW)) \ ++ fore200e_mkfirm ++ ./fore200e_mkfirm -k -b _fore200e_pca_fw \ ++ -i $(CONFIG_ATM_FORE200E_PCA_FW) -o $@ ++ ++fore200e_sba_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_SBA_FW)) \ ++ fore200e_mkfirm ++ ./fore200e_mkfirm -k -b _fore200e_sba_fw \ ++ -i $(CONFIG_ATM_FORE200E_SBA_FW) -o $@ ++ ++fore200e_mkfirm: fore200e_mkfirm.c ++ $(HOSTCC) $(HOSTCFLAGS) $< -o $@ ++ ++# deal with the various suffixes of the firmware images ++%.bin: %.data ++ objcopy -Iihex $< -Obinary $@.gz ++ gzip -df $@.gz ++ ++%.bin1: %.data ++ objcopy -Iihex $< -Obinary $@.gz ++ gzip -df $@.gz ++ ++%.bin2: %.data ++ objcopy -Iihex $< -Obinary $@.gz ++ gzip -df $@.gz ++ ++# module build ++fore_200e.o: fore200e.o $(FORE200E_FW_OBJS) ++ $(LD) -r -o $@ $< $(FORE200E_FW_OBJS) +--- ref/drivers/atm/ambassador.c Wed Sep 29 23:02:59 1999 ++++ work/drivers/atm/ambassador.c Fri Jan 21 16:01:03 2000 +@@ -1405,7 +1405,7 @@ + dont_panic (dev); + } else { + // moan +- return -EINVAL; ++ return -ENOIOCTLCMD; + } + } + #endif +@@ -1654,21 +1654,11 @@ + /********** Operation Structure **********/ + + static const struct atmdev_ops amb_ops = { +- NULL, // no amb_dev_close +- amb_open, +- amb_close, +- NULL, // no amb_ioctl, +- NULL, // no amb_getsockopt, +- NULL, // no amb_setsockopt, +- amb_send, +- amb_sg_send, +- NULL, // no send_oam - not in fact used yet +- NULL, // no amb_phy_put - not needed in this driver +- NULL, // no amb_phy_get - not needed in this driver +- NULL, // no feedback - feedback to the driver! +- NULL, // no amb_change_qos +- NULL, // amb_free_rx_skb not used until checked by someone else +- amb_proc_read ++ open: amb_open, ++ close: amb_close, ++ send: amb_send, ++ sg_send: amb_sg_send, ++ proc_read: amb_proc_read + }; + + /********** housekeeping **********/ +--- ref/drivers/atm/atmdev_init.c Thu Aug 26 21:42:33 1999 ++++ work/drivers/atm/atmdev_init.c Fri Jan 21 16:01:03 2000 +@@ -28,6 +28,12 @@ + #ifdef CONFIG_ATM_HORIZON + extern int hrz_detect(void); + #endif ++#ifdef CONFIG_ATM_FORE200E ++extern int fore200e_detect(void); ++#endif ++#ifdef CONFIG_ATM_IA ++extern int ia_detect(void); ++#endif + + + int __init atmdev_init(void) +@@ -55,6 +61,12 @@ + #endif + #ifdef CONFIG_ATM_HORIZON + devs += hrz_detect(); ++#endif ++#ifdef CONFIG_ATM_IA ++ devs += ia_detect(); ++#endif ++#ifdef CONFIG_ATM_FORE200E ++ devs += fore200e_detect(); + #endif + return devs; + } +--- ref/drivers/atm/atmtcp.c Wed Sep 8 20:14:31 1999 ++++ work/drivers/atm/atmtcp.c Fri Jan 21 16:01:03 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/atmtcp.c - ATM over TCP "device" driver */ + +-/* Written 1997-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include +@@ -8,7 +8,9 @@ + #include + #include + #include +-#include "../../net/atm/protocols.h" /* @@@ fix this */ ++ ++ ++extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */ + + + #define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data)) +@@ -56,7 +58,8 @@ + *new_msg = *msg; + new_msg->hdr.length = ATMTCP_HDR_MAGIC; + new_msg->type = type; +- new_msg->vcc = (unsigned long) vcc; ++ memset(&new_msg->vcc,0,sizeof(atm_kptr_t)); ++ *(struct atm_vcc **) &new_msg->vcc = vcc; + old_flags = vcc->flags; + out_vcc->push(out_vcc,skb); + while (!((vcc->flags ^ old_flags) & flag)) { +@@ -72,7 +75,7 @@ + + static int atmtcp_recv_control(const struct atmtcp_control *msg) + { +- struct atm_vcc *vcc = (struct atm_vcc *) msg->vcc; ++ struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc; + + vcc->vpi = msg->addr.sap_addr.vpi; + vcc->vci = msg->addr.sap_addr.vci; +@@ -143,7 +146,7 @@ + struct atm_cirange ci; + struct atm_vcc *vcc; + +- if (cmd != ATM_SETCIRANGE) return -EINVAL; ++ if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD; + if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT; + if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS; + if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS; +@@ -190,6 +193,8 @@ + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); + out_vcc->push(out_vcc,new_skb); ++ vcc->stats->tx++; ++ out_vcc->stats->rx++; + return 0; + } + +@@ -258,6 +263,8 @@ + new_skb->stamp = xtime; + memcpy(skb_put(new_skb,skb->len),skb->data,skb->len); + out_vcc->push(out_vcc,new_skb); ++ vcc->stats->tx++; ++ out_vcc->stats->rx++; + done: + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); +@@ -271,21 +278,12 @@ + + + static struct atmdev_ops atmtcp_v_dev_ops = { +- atmtcp_v_dev_close, +- atmtcp_v_open, +- atmtcp_v_close, +- atmtcp_v_ioctl, +- NULL, /* no getsockopt */ +- NULL, /* no setsockopt */ +- atmtcp_v_send, +- NULL, /* no direct writes */ +- NULL, /* no send_oam */ +- NULL, /* no phy_put */ +- NULL, /* no phy_get */ +- NULL, /* no feedback */ +- NULL, /* no change_qos */ +- NULL, /* no free_rx_skb */ +- atmtcp_v_proc /* proc_read */ ++ dev_close: atmtcp_v_dev_close, ++ open: atmtcp_v_open, ++ close: atmtcp_v_close, ++ ioctl: atmtcp_v_ioctl, ++ send: atmtcp_v_send, ++ proc_read: atmtcp_v_proc + }; + + +@@ -295,21 +293,8 @@ + + + static struct atmdev_ops atmtcp_c_dev_ops = { +- NULL, /* no dev_close */ +- NULL, /* no open */ +- atmtcp_c_close, +- NULL, /* no ioctl */ +- NULL, /* no getsockopt */ +- NULL, /* no setsockopt */ +- atmtcp_c_send, +- NULL, /* no sg_send */ +- NULL, /* no send_oam */ +- NULL, /* no phy_put */ +- NULL, /* no phy_get */ +- NULL, /* no feedback */ +- NULL, /* no change_qos */ +- NULL, /* no free_rx_skb */ +- NULL /* no proc_read */ ++ close: atmtcp_c_close, ++ send: atmtcp_c_send + }; + + --- ref/drivers/atm/eni.c Wed Sep 8 20:14:31 1999 -+++ work/drivers/atm/eni.c Wed Dec 1 03:27:07 1999 -@@ -1151,7 +1151,8 @@ ++++ work/drivers/atm/eni.c Fri Jan 21 17:27:47 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/eni.c - Efficient Networks ENI155P device driver */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include +@@ -774,7 +774,7 @@ + eni_vcc = ENI_VCC(vcc); + eni_vcc->rx = NULL; + if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0; +- size = vcc->qos.rxtp.max_sdu*3; /* @@@ improve this */ ++ size = vcc->qos.rxtp.max_sdu*eni_dev->rx_mult/100; + if (size > MID_MAX_BUF_SIZE && vcc->qos.rxtp.max_sdu <= + MID_MAX_BUF_SIZE) + size = MID_MAX_BUF_SIZE; +@@ -885,6 +885,7 @@ + return -ENOMEM; + } + memset(eni_dev->rx_map,0,PAGE_SIZE); ++ eni_dev->rx_mult = DEFAULT_RX_MULT; + eni_dev->fast = eni_dev->last_fast = NULL; + eni_dev->slow = eni_dev->last_slow = NULL; + init_waitqueue_head(&eni_dev->rx_wait); +@@ -1151,7 +1152,8 @@ if (tx->send) while ((skb = skb_dequeue(&tx->backlog))) { res = do_tx(skb); @@ -390,7 +1145,16 @@ DPRINTK("re-queuing TX PDU\n"); skb_queue_head(&tx->backlog,skb); requeued++; -@@ -1287,6 +1288,7 @@ +@@ -1258,7 +1260,7 @@ + unlimited = ubr && (!rate || rate <= -ATM_OC3_PCR || + rate >= ATM_OC3_PCR); + if (!unlimited) { +- size = txtp->max_sdu*3; /* @@@ improve */ ++ size = txtp->max_sdu*eni_dev->tx_mult/100; + if (size > MID_MAX_BUF_SIZE && txtp->max_sdu <= + MID_MAX_BUF_SIZE) + size = MID_MAX_BUF_SIZE; +@@ -1287,6 +1289,7 @@ tx->send = mem; tx->words = size >> 2; skb_queue_head_init(&tx->backlog); @@ -398,7 +1162,93 @@ for (order = 0; size > (1 << (order+10)); order++); eni_out((order << MID_SIZE_SHIFT) | ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)), -@@ -1971,21 +1973,6 @@ +@@ -1390,6 +1393,7 @@ + eni_dev = ENI_DEV(dev); + eni_dev->lost = 0; + eni_dev->tx_bw = ATM_OC3_PCR; ++ eni_dev->tx_mult = DEFAULT_TX_MULT; + init_waitqueue_head(&eni_dev->tx_wait); + eni_dev->ubr = NULL; + skb_queue_head_init(&eni_dev->tx_queue); +@@ -1643,7 +1647,7 @@ + struct midway_eprom *eprom; + struct eni_dev *eni_dev; + struct pci_dev *pci_dev; +- unsigned int real_base,base; ++ unsigned long real_base,base; + unsigned char revision; + int error,i,last; + +@@ -1668,7 +1672,7 @@ + "(0x%02x)\n",dev->number,error); + return error; + } +- printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,", ++ printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,", + dev->number,revision,real_base,eni_dev->irq); + if (!(base = (unsigned long) ioremap_nocache(real_base,MAP_MAX_SIZE))) { + printk("\n"); +@@ -1676,6 +1680,9 @@ + "mapping\n",dev->number); + return error; + } ++#ifdef __sparc_v9__ ++ base=real_base; /* Found this by trial and error - check this @@@ */ ++#endif + eni_dev->base_diff = real_base-base; + /* id may not be present in ASIC Tonga boards - check this @@@ */ + if (!eni_dev->asic) { +@@ -1748,6 +1755,10 @@ + "master (0x%02x)\n",dev->number,error); + return error; + } ++#ifdef __sparc_v9__ /* copied from drivers/net/sunhme.c */ ++ /* NOTE: Cache line size is in 32-bit word units. */ ++ pci_write_config_byte(eni_dev->pci_dev, PCI_CACHE_LINE_SIZE, 0x10); ++#endif + if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL, + END_SWAP_DMA))) { + printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap " +@@ -1947,12 +1958,29 @@ + + static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) + { ++ struct eni_dev *eni_dev = ENI_DEV(dev); ++ + if (cmd == ENI_MEMDUMP) { ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + printk(KERN_WARNING "Please use /proc/atm/" DEV_LABEL ":%d " + "instead of obsolete ioctl ENI_MEMDUMP\n",dev->number); + dump(dev); + return 0; + } ++ if (cmd == ENI_SETMULT) { ++ struct eni_multipliers mult; ++ ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ if (copy_from_user(&mult,(void *) arg, ++ sizeof(struct eni_multipliers))) ++ return -EFAULT; ++ if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) || ++ mult.tx > 65536 || mult.rx > 65536) ++ return -EINVAL; ++ if (mult.tx) eni_dev->tx_mult = mult.tx; ++ if (mult.rx) eni_dev->rx_mult = mult.rx; ++ return 0; ++ } + if (cmd == ATM_SETCIRANGE) { + struct atm_cirange ci; + +@@ -1963,7 +1991,7 @@ + return 0; + return -EINVAL; + } +- if (!dev->phy->ioctl) return -EINVAL; ++ if (!dev->phy->ioctl) return -ENOIOCTLCMD; + return dev->phy->ioctl(dev,cmd,arg); + } + +@@ -1971,21 +1999,6 @@ static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen) { @@ -420,7 +1270,7 @@ return -EINVAL; } -@@ -2027,7 +2014,8 @@ +@@ -2027,7 +2040,8 @@ cli(); /* brute force */ if (skb_peek(&ENI_VCC(vcc)->tx->backlog) || do_tx(skb)) { skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb); @@ -430,7 +1280,28 @@ } restore_flags(flags); return 0; -@@ -2116,13 +2104,17 @@ +@@ -2068,9 +2082,8 @@ + return sprintf(page,DEV_LABEL "(itf %d) signal %s, %dkB, " + "%d cps remaining\n",dev->number,signal[(int) dev->signal], + eni_dev->mem >> 10,eni_dev->tx_bw); +- left--; +- if (!left) +- return sprintf(page,"Bursts: TX" ++ if (!--left) ++ return sprintf(page,"%4sBursts: TX" + #if !defined(CONFIG_ATM_ENI_BURST_TX_16W) && \ + !defined(CONFIG_ATM_ENI_BURST_TX_8W) && \ + !defined(CONFIG_ATM_ENI_BURST_TX_4W) && \ +@@ -2111,18 +2124,25 @@ + #ifndef CONFIG_ATM_ENI_TUNE_BURST + " (default)" + #endif +- "\n"); ++ "\n",""); ++ if (!--left) ++ return sprintf(page,"%4sBuffer multipliers: tx %d%%, rx %d%%\n", ++ "",eni_dev->tx_mult,eni_dev->rx_mult); + for (i = 0; i < NR_CHAN; i++) { struct eni_tx *tx = eni_dev->tx+i; if (!tx->send) continue; @@ -454,7 +1325,7 @@ } for (vcc = dev->vccs; vcc; vcc = vcc->next) { struct eni_vcc *eni_vcc = ENI_VCC(vcc); -@@ -2139,8 +2131,8 @@ +@@ -2139,8 +2159,8 @@ if (eni_vcc->tx) length += sprintf(page+length,", "); } if (eni_vcc->tx) @@ -465,97 +1336,4236 @@ page[length] = '\n'; return length+1; } ---- ref/drivers/atm/horizon.c Wed Sep 8 20:14:31 1999 -+++ work/drivers/atm/horizon.c Mon Nov 22 13:56:06 1999 -@@ -2623,12 +2623,10 @@ - switch (level) { - case SOL_SOCKET: - switch (optname) { -- case SO_BCTXOPT: -- // return the right thing -- break; -- case SO_BCRXOPT: -- // return the right thing -- break; -+// case SO_BCTXOPT: -+// break; -+// case SO_BCRXOPT: -+// break; - default: - return -ENOPROTOOPT; - break; -@@ -2645,12 +2643,10 @@ - switch (level) { - case SOL_SOCKET: - switch (optname) { -- case SO_BCTXOPT: -- // not settable -- break; -- case SO_BCRXOPT: -- // not settable -- break; -+// case SO_BCTXOPT: -+// break; -+// case SO_BCRXOPT: -+// break; - default: - return -ENOPROTOOPT; - break; ---- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/idt77105.c Mon Nov 22 13:46:58 1999 -@@ -0,0 +1,385 @@ -+/* drivers/atm/idt77105.c - IDT77105 (PHY) driver */ -+ -+/* Written 1999 by Greg Banks, NEC Australia . Based on suni.c */ +@@ -2159,21 +2179,17 @@ + + + static const struct atmdev_ops ops = { +- NULL, /* no dev_close */ +- eni_open, +- eni_close, +- eni_ioctl, +- eni_getsockopt, +- eni_setsockopt, +- eni_send, +- eni_sg_send, +- NULL, /* no send_oam */ +- eni_phy_put, +- eni_phy_get, +- NULL, /* no feedback */ +- eni_change_qos, /* no change_qos */ +- NULL, /* no free_rx_skb */ +- eni_proc_read ++ open: eni_open, ++ close: eni_close, ++ ioctl: eni_ioctl, ++ getsockopt: eni_getsockopt, ++ setsockopt: eni_setsockopt, ++ send: eni_send, ++ sg_send: eni_sg_send, ++ phy_put: eni_phy_put, ++ phy_get: eni_phy_get, ++ change_qos: eni_change_qos, ++ proc_read: eni_proc_read + }; + + +--- ref/drivers/atm/eni.h Mon Aug 23 18:56:31 1999 ++++ work/drivers/atm/eni.h Fri Jan 21 16:47:37 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */ + +-/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #ifndef DRIVER_ATM_ENI_H +@@ -24,6 +24,9 @@ + #define RX_DMA_BUF 8 /* burst and skip a few things */ + #define TX_DMA_BUF 100 /* should be enough for 64 kB */ + ++#define DEFAULT_RX_MULT 300 /* max_sdu*3 */ ++#define DEFAULT_TX_MULT 300 /* max_sdu*3 */ ++ + + struct eni_free { + unsigned long start; /* counting in bytes */ +@@ -40,6 +43,7 @@ + int reserved; /* reserved peak cell rate */ + int shaping; /* shaped peak cell rate */ + struct sk_buff_head backlog; /* queue of waiting TX buffers */ ++ int backlog_len; /* length of backlog in bytes */ + }; + + struct eni_vcc { +@@ -51,7 +55,7 @@ + struct eni_tx *tx; /* TXer, NULL if none */ + int rxing; /* number of pending PDUs */ + int servicing; /* number of waiting VCs (0 or 1) */ +- int txing; /* number of pending TX cells/PDUs */ ++ int txing; /* number of pending TX bytes */ + struct timeval timestamp; /* for RX timing */ + struct atm_vcc *next; /* next pending RX */ + struct sk_buff *last; /* last PDU being DMAed (used to carry +@@ -75,6 +79,7 @@ + wait_queue_head_t tx_wait; /* for close */ + int tx_bw; /* remaining bandwidth */ + u32 dma[TX_DMA_BUF*2]; /* DMA request scratch area */ ++ int tx_mult; /* buffer size multiplier (percent) */ + /*-------------------------------- RX part */ + u32 serv_read; /* host service read index */ + struct atm_vcc *fast,*last_fast;/* queues of VCCs with pending PDUs */ +@@ -82,6 +87,7 @@ + struct atm_vcc **rx_map; /* for fast lookups */ + struct sk_buff_head rx_queue; /* PDUs currently being RX-DMAed */ + wait_queue_head_t rx_wait; /* for close */ ++ int rx_mult; /* buffer size multiplier (percent) */ + /*-------------------------------- statistics */ + unsigned long lost; /* number of lost cells (RX) */ + /*-------------------------------- memory management */ +@@ -94,7 +100,7 @@ + /*-------------------------------- general information */ + int mem; /* RAM on board (in bytes) */ + int asic; /* PCI interface type, 0 for FPGA */ +- unsigned char irq; /* IRQ */ ++ unsigned int irq; /* IRQ */ + struct pci_dev *pci_dev; /* PCI stuff */ + }; + +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/fore200e.c Fri Jan 21 16:01:04 2000 +@@ -0,0 +1,2921 @@ ++/* ++ $Id: $ + ++ A FORE Systems 200E-series driver for ATM on Linux. ++ Christophe Lizzi (lizzi@cnam.fr), October-December 1999. + -+#include -+#include ++ Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de). ++ ++ This driver simultaneously supports PCA-200E and SBA-200E adapters ++ on i386, alpha (untested), powerpc, sparc and sparc64 (with additional ++ 64 bit fixes to the linux-atm core) hosts. ++ ++ ++ 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 ++*/ ++ ++ ++#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 "idt77105.h" ++#ifdef CONFIG_ATM_FORE200E_PCA ++#include ++#endif + -+#undef GENERAL_DEBUG ++#ifdef CONFIG_ATM_FORE200E_SBA ++#include ++#include ++#include ++#include ++#include ++#endif + -+#ifdef GENERAL_DEBUG -+#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) -+#else -+#define DPRINTK(format,args...) ++#ifdef MODULE ++#include +#endif + ++#include "fore200e.h" ++#include "suni.h" + -+struct idt77105_priv { -+ struct idt77105_stats stats; /* link diagnostics */ -+ struct atm_dev *dev; /* device back-pointer */ -+ struct idt77105_priv *next; -+ int loop_mode; -+ unsigned char old_mcr; /* storage of MCR reg while signal lost */ -+}; ++#if 1 /* ensure correct handling of 52-byte AAL0 SDUs used by atmdump-like apps */ ++#define FORE200E_52BYTE_AAL0_SDU ++#endif + ++#define FORE200E_VERSION "0.1e" + -+#define PRIV(dev) ((struct idt77105_priv *) dev->phy_data) + -+#define PUT(val,reg) dev->ops->phy_put(dev,val,IDT77105_##reg) -+#define GET(reg) dev->ops->phy_get(dev,IDT77105_##reg) ++#define FORE200E "fore200e: " + -+static void idt77105_stats_timer_func(unsigned long); -+static void idt77105_restart_timer_func(unsigned long); ++#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0) ++#define DPRINTK(level, format, args...) do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \ ++ printk(FORE200E format, ##args); } while(0) ++#else ++#define DPRINTK(level, format, args...) while(0) ++#endif + + -+static struct timer_list stats_timer = { NULL, NULL, 0L, 0L, -+ &idt77105_stats_timer_func }; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)) /* XXX 2.3.x? */ ++#define FORE200E_PCI_BASE_ADDR base_address[0] ++#else ++#define FORE200E_PCI_BASE_ADDR resource[0].start ++#endif ++ ++ ++#define FORE200E_ALIGN(addr, alignment) \ ++ ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr)) ++ ++#define FORE200E_DMA_INDEX(dma, type, index) ((dma) + (index) * sizeof(type)) ++ ++#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) ++ ++ ++#define MSECS(ms) (((ms)*HZ/1000)+1) ++ ++ ++extern const struct atmdev_ops fore200e_ops; ++extern const struct fore200e_bus fore200e_bus[]; ++ ++static struct fore200e* fore200e_boards = NULL; ++ ++ ++#ifdef MODULE ++MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen"); ++MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION); ++MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E"); ++#endif ++ ++ ++static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = { ++ { BUFFER_S1_NBR, BUFFER_L1_NBR }, ++ { BUFFER_S2_NBR, BUFFER_L2_NBR } ++}; ++ ++static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = { ++ { BUFFER_S1_SIZE, BUFFER_L1_SIZE }, ++ { BUFFER_S2_SIZE, BUFFER_L2_SIZE } ++}; ++ ++ ++#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0) ++static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" }; ++#endif ++ ++ ++#if 0 /* currently unused */ ++static int ++fore200e_fore2atm_aal(enum fore200e_aal aal) ++{ ++ switch(aal) { ++ case FORE200E_AAL0: return ATM_AAL0; ++ case FORE200E_AAL34: return ATM_AAL34; ++ case FORE200E_AAL5: return ATM_AAL5; ++ } ++ ++ return -EINVAL; ++} ++#endif ++ ++ ++static enum fore200e_aal ++fore200e_atm2fore_aal(int aal) ++{ ++ switch(aal) { ++ case ATM_AAL0: return FORE200E_AAL0; ++ case ATM_AAL34: return FORE200E_AAL34; ++ case ATM_AAL1: ++ case ATM_AAL2: ++ case ATM_AAL5: return FORE200E_AAL5; ++ } ++ ++ return -EINVAL; ++} ++ ++ ++static char* ++fore200e_irq_itoa(int irq) ++{ ++#if defined(__sparc_v9__) ++ return __irq_itoa(irq); ++#else ++ static char str[8]; ++ sprintf(str, "%d", irq); ++ return str; ++#endif ++} ++ ++ ++/* allocate and initialize a chunk of memory */ ++ ++static void* ++fore200e_kmalloc(int size, int flags) ++{ ++ void* chunk = kmalloc(size, flags); ++ ++ if (chunk) ++ memset(chunk, 0x00, size); ++ else ++ printk(FORE200E "kmalloc() failed, requested size = %d, flags = 0x%x\n", size, flags); ++ ++ return chunk; ++} ++ ++ ++/* free a chunk of memory */ ++ ++static void ++fore200e_kfree(void** chunk) ++{ ++ if (chunk && *chunk) { ++ void* tmp = *chunk; ++ *chunk = (void*) 0xDEADDEAD; /* XXX for debugging purposes */ ++ kfree(tmp); ++ } ++} ++ ++ ++/* allocate and align a chunk of memory */ ++ ++static int ++fore200e_align_alloc(void** aligned, void** raw, int size, int alignment) ++{ ++ unsigned long offset = 0; ++ ++ if (alignment <= sizeof(int)) ++ alignment = 0; ++ ++ *raw = fore200e_kmalloc(size + alignment, GFP_KERNEL | GFP_DMA); ++ if (*raw == NULL) ++ return -ENOMEM; ++ ++ if (alignment > 0) ++ offset = FORE200E_ALIGN(*raw, alignment); ++ ++ *aligned = *raw + offset; ++ ++ return 0; ++} ++ ++ ++/* free and aligned chunk of memory */ ++ ++static void ++fore200e_align_free(void** raw) ++{ ++ fore200e_kfree(raw); ++} ++ ++ ++#if 0 /* currently unused */ ++static int ++fore200e_checkup(struct fore200e* fore200e) ++{ ++ u32 hb1, hb2; ++ ++ hb1 = fore200e->bus->read(&fore200e->cp_queues->heartbeat); ++ fore200e_spin(10); ++ hb2 = fore200e->bus->read(&fore200e->cp_queues->heartbeat); ++ ++ if (hb2 <= hb1) { ++ printk(FORE200E "device %s heartbeat is not counting upwards, hb1 = %x; hb2 = %x\n", ++ fore200e->name, hb1, hb2); ++ return -EIO; ++ } ++ printk(FORE200E "device %s heartbeat is ok\n", fore200e->name); ++ ++ return 0; ++} ++#endif ++ ++ ++static void ++fore200e_spin(int msecs) ++{ ++ unsigned long timeout = jiffies + MSECS(msecs); ++ while (jiffies < timeout); ++} ++ ++ ++static int ++fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs) ++{ ++ unsigned long timeout = jiffies + MSECS(msecs); ++ int ok; ++ ++ do { ++ if ((ok = (fore200e->bus->read(addr) == val))) ++ break; ++ ++ } while (jiffies < timeout); ++ ++#if 1 ++ if (!ok) { ++ printk(FORE200E "cmd polling failed, got status 0x%x, expected 0x%x\n", ++ fore200e->bus->read(addr), val); ++ } ++#endif ++ ++ return ok; ++} ++ ++ ++static void ++fore200e_free_rx_buf(struct fore200e* fore200e) ++{ ++ int scheme, magn, nbr; ++ struct buffer* buffer; ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { ++ ++ if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) { ++ ++ for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) { ++ if (buffer[ nbr ].data_raw != NULL) ++ fore200e_align_free((void**)&buffer[ nbr ].data_raw); ++ } ++ } ++ } ++ } ++} ++ ++ ++static void ++fore200e_uninit_bs_queue(struct fore200e* fore200e) ++{ ++ int scheme, magn; ++ void *addr; ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { ++ ++ if ((addr = fore200e->host_bsq[ scheme ][ magn ].status_raw)) ++ fore200e->bus->dma_free((void**)&addr); ++ ++ if ((addr = fore200e->host_bsq[ scheme ][ magn ].rbd_block_raw)) ++ fore200e->bus->dma_free((void**)&addr); ++ } ++ } ++} ++ ++ ++static int ++fore200e_reset(struct fore200e* fore200e, int diag) ++{ ++ int ok; ++ ++ fore200e->cp_monitor = (struct cp_monitor*)(fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET); ++ ++ fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat); ++ ++ fore200e->bus->reset(fore200e); ++ ++ if (diag) { ++ ok = fore200e_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000); ++ if (ok == 0) { ++ ++ printk(FORE200E "device %s self-test failed\n", fore200e->name); ++ return -ENODEV; ++ } ++ ++ printk(FORE200E "device %s self-test passed\n", fore200e->name); ++ ++ fore200e->state = FORE200E_STATE_RESET; ++ } ++ ++ return 0; ++} ++ ++ ++static void ++fore200e_shutdown(struct fore200e* fore200e) ++{ ++ printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n", ++ fore200e->name, fore200e->phys_base, ++ fore200e_irq_itoa(fore200e->irq)); ++ ++ if (fore200e->state > FORE200E_STATE_RESET) { ++ /* first, reset the board to prevent further interrupts or data transfers */ ++ fore200e_reset(fore200e, 0); ++ } ++ ++ /* then, release all allocated resources */ ++ switch(fore200e->state) { ++ ++ case FORE200E_STATE_COMPLETE: ++ if (fore200e->stats) ++ kfree(fore200e->stats); ++ ++ case FORE200E_STATE_IRQ: ++ free_irq(fore200e->irq, fore200e->atm_dev); ++ ++ case FORE200E_STATE_ALLOC_BUF: ++ fore200e_free_rx_buf(fore200e); ++ ++ case FORE200E_STATE_INIT_BSQ: ++ fore200e_uninit_bs_queue(fore200e); ++ ++ case FORE200E_STATE_INIT_RXQ: ++ fore200e->bus->dma_free((void**)&fore200e->host_rxq.status_raw); ++ fore200e->bus->dma_free((void**)&fore200e->host_rxq.rpd_raw); ++ ++ case FORE200E_STATE_INIT_TXQ: ++ fore200e->bus->dma_free((void**)&fore200e->host_txq.status_raw); ++ fore200e->bus->dma_free((void**)&fore200e->host_txq.tpd_raw); ++ ++ case FORE200E_STATE_INIT_CMDQ: ++ fore200e->bus->dma_free((void**)&fore200e->host_cmdq.status_raw); ++ ++ case FORE200E_STATE_INITIALIZE: ++ /* nothing to do for that state */ ++ ++ case FORE200E_STATE_START_FW: ++ /* nothing to do for that state */ ++ ++ case FORE200E_STATE_LOAD_FW: ++ /* nothing to do for that state */ ++ ++ case FORE200E_STATE_RESET: ++ /* nothing to do for that state */ ++ ++ case FORE200E_STATE_MAP: ++ fore200e->bus->unmap(fore200e); ++ ++ case FORE200E_STATE_CONFIGURE: ++ /* nothing to do for that state */ ++ ++ case FORE200E_STATE_REGISTER: ++ /* XXX shouldn't we *start* by deregistering the device? */ ++ atm_dev_deregister(fore200e->atm_dev); ++ ++ case FORE200E_STATE_BLANK: ++ /* nothing to do for that state */ ++ } ++} ++ ++ ++#ifdef CONFIG_ATM_FORE200E_PCA ++ ++static u32 fore200e_pca_read(volatile u32* addr) ++{ ++#if defined(__BIG_ENDIAN) ++ /* on big-endian hosts, the board is configured to convert the endianess of ++ slave RAM accesses, so we do not use the regular readl()/writel() primitives */ ++#if defined(__powerpc__) ++ eieio(); /* enforce in-order execution of I/O */ ++#endif ++ return *addr; ++#elif defined(__LITTLE_ENDIAN) ++ return readl(addr); ++#else ++#error unknown endianess ++#endif ++} ++ ++ ++static void fore200e_pca_write(u32 val, volatile u32* addr) ++{ ++#if defined(__BIG_ENDIAN) ++ /* same comment as above */ ++#if defined(__powerpc__) ++ eieio(); /* enforce in-order execution of I/O */ ++#endif ++ *addr = val; ++#elif defined(__LITTLE_ENDIAN) ++ writel(val, addr); ++#else ++#error unknown endianess ++#endif ++} ++ ++ ++static u32 ++fore200e_pca_virt_to_dma(void* addr) ++{ ++ return (u32) virt_to_bus(addr); ++} ++ ++ ++ ++static int ++fore200e_pca_dma_alloc(void** aligned, void** raw, u32* dma, int size, int nbr, int alignment) ++{ ++ if (fore200e_align_alloc(aligned, raw, size * nbr, alignment) < 0) ++ return -ENOMEM; ++ ++ *dma = fore200e_pca_virt_to_dma(*aligned); ++ ++ return 0; ++} ++ ++ ++ ++static void ++fore200e_pca_dma_free(void** raw) ++{ ++ fore200e_align_free(raw); ++} ++ ++ ++static int ++fore200e_pca_irq_check(struct fore200e* fore200e) ++{ ++ /* this is a 1 bit register */ ++ return readl(fore200e->regs.pca.psr); ++} ++ ++ ++static void ++fore200e_pca_irq_ack(struct fore200e* fore200e) ++{ ++ writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr); ++} ++ ++ ++static void ++fore200e_pca_reset(struct fore200e* fore200e) ++{ ++ writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr); ++ fore200e_spin(10); ++ writel(0, fore200e->regs.pca.hcr); ++} ++ ++ ++static int __init ++fore200e_pca_map(struct fore200e* fore200e) ++{ ++ DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); ++ ++#if !defined(__sparc_v9__) ++ fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH); ++#else ++ fore200e->virt_base = (void*)fore200e->phys_base; ++#endif ++ ++ if (fore200e->virt_base == NULL) { ++ printk(FORE200E "can't map device %s\n", fore200e->name); ++ return -EFAULT; ++ } ++ ++ DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); ++ ++ /* gain access to the PCA-200E specific registers */ ++ fore200e->regs.pca.hcr = (u32*)(fore200e->virt_base + PCA200E_HCR_OFFSET); ++ fore200e->regs.pca.imr = (u32*)(fore200e->virt_base + PCA200E_IMR_OFFSET); ++ fore200e->regs.pca.psr = (u32*)(fore200e->virt_base + PCA200E_PSR_OFFSET); ++ ++ fore200e->state = FORE200E_STATE_MAP; ++ return 0; ++} ++ ++ ++static void ++fore200e_pca_unmap(struct fore200e* fore200e) ++{ ++ DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name); ++ ++ /* XXX iounmap() is empty on powerpc (at least in 2.2.12 and 2.3.18), so ++ we get a kernel panic if the module is loaded and unloaded several times */ ++ if (fore200e->virt_base != NULL) ++ iounmap(fore200e->virt_base); ++} ++ ++ ++static int __init ++fore200e_pca_configure(struct fore200e* fore200e) ++{ ++#if defined(__BIG_ENDIAN) ++ struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; ++#endif ++ ++ DPRINTK(2, "device %s being configured\n", fore200e->name); ++ ++#if 0 && defined(__powerpc__) || defined(__sparc_v9__) /* XXX really required? */ ++ { ++ u16 command; ++ pci_read_config_word(pci_dev, PCI_COMMAND, &command); ++ command = PCI_COMMAND_MEMORY | ++ PCI_COMMAND_MASTER | ++ PCI_COMMAND_PARITY | ++ PCI_COMMAND_SERR; ++ pci_write_config_word(pci_dev, PCI_COMMAND, command); ++ } ++#endif ++ ++#if defined(__powerpc__) ++ if (pci_dev->irq == 0) { ++ u8 intr_line; ++ pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &intr_line); ++ ++ /* pci_dev->irq is not set on my Motorola MTX (PReP PowerPC) running a 2.2.7 kernel */ ++ fore200e->irq = pci_dev->irq = intr_line; ++ } ++ if (pci_dev->irq == 0xFF) { ++ printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n"); ++ return -EIO; ++ } ++#endif ++ ++#if defined(__BIG_ENDIAN) ++ { ++ u8 master_ctrl; ++ pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl); ++ /* request the PCA board to convert the endianess of slave RAM accesses */ ++ master_ctrl = PCA200E_CTRL_DIS_CACHE_RD | ++ PCA200E_CTRL_DIS_WRT_INVAL | ++ PCA200E_CTRL_LARGE_PCI_BURSTS | ++ PCA200E_CTRL_CONVERT_ENDIAN; ++ pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl); ++ } ++#endif ++ ++ fore200e->state = FORE200E_STATE_CONFIGURE; ++ return 0; ++} ++ ++ ++static struct fore200e* __init ++fore200e_pca_detect(const struct fore200e_bus* bus, int index) ++{ ++ struct fore200e* fore200e; ++ struct pci_dev* pci_dev = NULL; ++ int count = index; ++ ++ if (pci_present() == 0) { ++ printk(FORE200E "no PCI subsystem\n"); ++ return NULL; ++ } ++ ++ do { ++ pci_dev = pci_find_device(PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, pci_dev); ++ if (pci_dev == NULL) ++ return NULL; ++ } while (count--); ++ ++ fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL); ++ if (fore200e == NULL) ++ return NULL; ++ ++ fore200e->bus = bus; ++ fore200e->bus_dev = pci_dev; ++ fore200e->irq = pci_dev->irq; ++ fore200e->phys_base = (pci_dev->FORE200E_PCI_BASE_ADDR & PCI_BASE_ADDRESS_MEM_MASK); ++ ++#if defined(__powerpc__) ++ fore200e->phys_base += KERNELBASE; ++#endif ++ ++ sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1); ++ ++ pci_set_master(pci_dev); ++ ++ return fore200e; ++} ++ ++ ++static int __init ++fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; ++ struct prom_opcode opcode; ++ int ok; ++ ++ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); ++ ++ opcode.opcode = OPCODE_GET_PROM; ++ opcode.pad = 0; ++ ++ fore200e->bus->write(fore200e->bus->virt_to_dma((void*) prom), &entry->cp_entry->cmd.prom_block.prom_haddr); ++ ++ *entry->status = STATUS_PENDING; ++ ++ fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.prom_block.opcode); ++ ++ ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); ++ ++ *entry->status = STATUS_FREE; ++ ++ if (ok == 0) { ++ printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name); ++ return -EIO; ++ } ++ ++#if defined(__BIG_ENDIAN) ++ ++#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) )) ++ ++ /* MAC address is stored as little-endian */ ++ swap_here(&prom->mac_addr[0]); ++ swap_here(&prom->mac_addr[4]); ++#endif ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_pca_proc_read(struct fore200e* fore200e, char *page) ++{ ++ struct pci_dev* pci_dev = fore200e->bus_dev; ++ ++ return sprintf(page, " PCI bus/slot/function:\t%d/%d/%d\n", ++ pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); ++} ++ ++#endif /* CONFIG_ATM_FORE200E_PCA */ ++ ++ ++ ++ ++#ifdef CONFIG_ATM_FORE200E_SBA ++ ++static u32 ++fore200e_sba_read(volatile u32* addr) ++{ ++ return *addr; ++} ++ ++ ++static void ++fore200e_sba_write(u32 val, volatile u32* addr) ++{ ++ *addr = val; ++} ++ ++ ++static u32 ++fore200e_sba_virt_to_dma(void* addr) ++{ ++ return sbus_dvma_addr(addr); ++} ++ ++ ++/* allocate a DMA'able consistent chunk of memory */ ++ ++static int ++fore200e_sba_dma_alloc(void** aligned, void** raw, u32* dma, int size, int nbr, int alignment) ++{ ++ /* returned chunks are page-aligned */ ++ *aligned = sparc_dvma_malloc(size * nbr, "", dma); ++ ++ if (*aligned == NULL || *dma == 0) ++ return -ENOMEM; ++ ++ *raw = (void*)(unsigned long) *dma; /* XXX there is no sparc_dvma_free() anyway */ ++ ++ return 0; ++} ++ ++ ++/* free a DMA'able chunk of memory */ ++ ++static void ++fore200e_sba_dma_free(void** raw) ++{ ++ /* XXX there is no sparc_dvma_free() */ ++} ++ ++ ++static void ++fore200e_sba_irq_enable(struct fore200e* fore200e) ++{ ++ u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; ++ fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr); ++} ++ ++ ++static int ++fore200e_sba_irq_check(struct fore200e* fore200e) ++{ ++ return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ; ++} ++ ++ ++static void ++fore200e_sba_irq_ack(struct fore200e* fore200e) ++{ ++ u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; ++ fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr); ++} ++ ++ ++static void ++fore200e_sba_dma_sync(struct fore200e* fore200e, u32 haddr, int len) ++{ ++#ifdef NEED_DMA_SYNCHRONIZATION ++ mmu_sync_dma(haddr, len, ((struct linux_sbus_device*)fore200e->bus_dev)->my_bus); ++#endif ++} ++ ++ ++static void ++fore200e_sba_reset(struct fore200e* fore200e) ++{ ++ fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); ++ fore200e_spin(10); ++ fore200e->bus->write(0, fore200e->regs.sba.hcr); ++} ++ ++ ++static int __init ++fore200e_sba_map(struct fore200e* fore200e) ++{ ++ struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; ++ ++ /* gain access to the SBA-200E specific registers */ ++ ++ prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[0], sbus_dev->num_registers, sbus_dev); ++ fore200e->regs.sba.hcr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[0].phys_addr, 0, ++ sbus_dev->reg_addrs[0].reg_size, ++ "SBA HCR", ++ sbus_dev->reg_addrs[0].which_io, 0); ++ if (fore200e->regs.sba.hcr == NULL) { ++ printk(FORE200E "unable to map HCR register of device %s\n", fore200e->name); ++ return -EFAULT; ++ } ++ ++ prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[1], sbus_dev->num_registers, sbus_dev); ++ fore200e->regs.sba.bsr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[1].phys_addr, 0, ++ sbus_dev->reg_addrs[1].reg_size, ++ "SBA BSR", ++ sbus_dev->reg_addrs[1].which_io, 0); ++ if (fore200e->regs.sba.bsr == NULL) { ++ printk(FORE200E "unable to map BSR register of device %s\n", fore200e->name); ++ return -EFAULT; ++ } ++ ++ prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[2], sbus_dev->num_registers, sbus_dev); ++ fore200e->regs.sba.isr = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[2].phys_addr, 0, ++ sbus_dev->reg_addrs[2].reg_size, ++ "SBA ISR", ++ sbus_dev->reg_addrs[2].which_io, 0); ++ if (fore200e->regs.sba.isr == NULL) { ++ printk(FORE200E "unable to map ISR register of device %s\n", fore200e->name); ++ return -EFAULT; ++ } ++ ++ fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ ++ ++ ++ prom_apply_sbus_ranges(sbus_dev->my_bus, &sbus_dev->reg_addrs[3], sbus_dev->num_registers, sbus_dev); ++ fore200e->virt_base = (u32*)sparc_alloc_io(sbus_dev->reg_addrs[3].phys_addr, 0, ++ sbus_dev->reg_addrs[3].reg_size, ++ "SBA RAM", ++ sbus_dev->reg_addrs[3].which_io, 0); ++ if (fore200e->virt_base == NULL) { ++ printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); ++ return -EFAULT; ++ } ++ ++ DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); ++ ++ fore200e->state = FORE200E_STATE_MAP; ++ return 0; ++} ++ ++ ++static void ++fore200e_sba_unmap(struct fore200e* fore200e) ++{ ++ struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; ++ ++ sparc_free_io((void*)fore200e->regs.sba.hcr, sbus_dev->reg_addrs[0].reg_size); ++ sparc_free_io((void*)fore200e->regs.sba.bsr, sbus_dev->reg_addrs[1].reg_size); ++ sparc_free_io((void*)fore200e->regs.sba.isr, sbus_dev->reg_addrs[2].reg_size); ++ sparc_free_io((void*)fore200e->virt_base, sbus_dev->reg_addrs[3].reg_size); ++} ++ ++ ++static int __init ++fore200e_sba_configure(struct fore200e* fore200e) ++{ ++ fore200e->state = FORE200E_STATE_CONFIGURE; ++ return 0; ++} ++ ++ ++static struct fore200e* __init ++fore200e_sba_detect(const struct fore200e_bus* bus, int index) ++{ ++ struct fore200e* fore200e; ++ struct linux_sbus* sbus; ++ struct linux_sbus_device* sbus_dev = 0; ++ unsigned int curr = 0; ++ ++ for_each_sbus (sbus) { ++ for_each_sbusdev (sbus_dev, sbus) { ++ if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) { ++ if (curr >= index) ++ goto found; ++ curr++; ++ } ++ } ++ } ++ return NULL; ++ ++ found: ++#if 1 ++ if (sbus_dev->num_registers != 4) { ++ printk(FORE200E "this %s device has %d instead of 4 registers\n", ++ bus->model_name, sbus_dev->num_registers); ++ return NULL; ++ } ++#endif ++ ++ fore200e = fore200e_kmalloc(sizeof(struct fore200e), GFP_KERNEL); ++ if (fore200e == NULL) ++ return NULL; ++ ++ fore200e->bus = bus; ++ fore200e->bus_dev = sbus_dev; ++ fore200e->irq = sbus_dev->irqs[ 0 ]; ++ ++ fore200e->phys_base = (unsigned long)sbus_dev; ++ ++ sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1); ++ ++ return fore200e; ++} ++ ++ ++static int __init ++fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom) ++{ ++ struct linux_sbus_device* sbus_dev; ++ int len; ++ ++ sbus_dev = fore200e->bus_dev; ++ ++ len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4); ++ if (len < 0) ++ return -EBUSY; ++ ++ len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4); ++ if (len < 0) ++ return -EBUSY; ++ ++ prom_getproperty(sbus_dev->prom_node, "serialnumber", ++ (char*)&prom->serial_number, sizeof(prom->serial_number)); ++ ++ prom_getproperty(sbus_dev->prom_node, "promversion", ++ (char*)&prom->hw_revision, sizeof(prom->hw_revision)); ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_sba_proc_read(struct fore200e* fore200e, char *page) ++{ ++ struct linux_sbus_device* sbus_dev = (struct linux_sbus_device*)fore200e->bus_dev; ++ ++ return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name); ++} ++#endif /* CONFIG_ATM_FORE200E_SBA */ ++ ++ ++static void ++fore200e_irq_tx(struct fore200e* fore200e) ++{ ++ struct host_txq_entry* entry; ++ int i; ++ ++ entry = fore200e->host_txq.host_entry; ++ ++ for (i = 0; i < QUEUE_SIZE_TX; i++) { ++ ++ if (*entry->status & STATUS_COMPLETE) { ++ ++ DPRINTK(3, "TX COMPLETED: entry = %p, vcc = %p, skb = %p\n", entry, entry->vcc, entry->skb); ++ ++ /* free copy of misaligned data */ ++ if (entry->data) ++ kfree(entry->data); ++ ++ /* notify tx completion */ ++ if (entry->vcc->pop) ++ entry->vcc->pop(entry->vcc, entry->skb); ++ else ++ dev_kfree_skb(entry->skb); ++ ++ /* check error condition */ ++ if (*entry->status & STATUS_ERROR) ++ entry->vcc->stats->tx_err++; ++ else ++ entry->vcc->stats->tx++; ++ ++ *entry->status = STATUS_FREE; ++ ++ fore200e->host_txq.txing--; ++ } ++ entry++; ++ } ++} ++ ++ ++static void ++fore200e_supply(struct fore200e* fore200e) ++{ ++ int scheme, magn, i; ++ ++ struct host_bsq* bsq; ++ struct host_bsq_entry* entry; ++ struct buffer* buffer; ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { ++ ++ bsq = &fore200e->host_bsq[ scheme ][ magn ]; ++ ++ if (fore200e_rx_buf_nbr[ scheme ][ magn ] - bsq->count > RBD_BLK_SIZE) { ++ ++ DPRINTK(2, "supplying rx buffers to queue %d / %d, count = %d\n", ++ scheme, magn, bsq->count); ++ ++ entry = &bsq->host_entry[ bsq->head ]; ++ ++ FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS); ++ ++ for (i = 0; i < RBD_BLK_SIZE; i++) { ++ ++ buffer = &bsq->buffer[ bsq->free ]; ++ ++ FORE200E_NEXT_ENTRY(bsq->free, fore200e_rx_buf_nbr[ scheme ][ magn ]); ++ ++ entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data_dma; ++ entry->rbd_block->rbd[ i ].handle = FORE200E_BUF2HDL(buffer); ++ } ++ ++ /* increase the number of supplied rx buffers */ ++ bsq->count += RBD_BLK_SIZE; ++ ++ *entry->status = STATUS_PENDING; ++ fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr); ++ } ++ } ++ } ++} ++ ++ ++ ++static struct atm_vcc* ++fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd) ++{ ++ struct atm_vcc* vcc; ++ ++ for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { ++ ++ if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) ++ break; ++ } ++ ++ return vcc; ++} ++ ++ ++static void ++fore200e_push_rpd(struct fore200e* fore200e, struct rpd* rpd) ++{ ++ struct atm_vcc* vcc; ++ struct sk_buff* skb; ++ struct buffer* buffer; ++ struct fore200e_vcc* fore200e_vcc; ++ int i, pdu_len = 0; ++#ifdef FORE200E_52BYTE_AAL0_SDU ++ u32 cell_header = 0; ++#endif ++ ++ vcc = fore200e_find_vcc(fore200e, rpd); ++ if (vcc == NULL) { ++ ++ printk(FORE200E "no vcc found for PDU received on %d.%d.%d\n", ++ fore200e->atm_dev->number, rpd->atm_header.vpi, rpd->atm_header.vci); ++ return; ++ } ++ ++ fore200e_vcc = FORE200E_VCC(vcc); ++ ++#ifdef FORE200E_52BYTE_AAL0_SDU ++ if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) { ++ ++ cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) | ++ (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) | ++ (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) | ++ (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) | ++ rpd->atm_header.clp; ++ pdu_len = 4; ++ } ++#endif ++ ++ /* compute total PDU length */ ++ for (i = 0; i < rpd->nseg; i++) ++ pdu_len += rpd->rsd[ i ].length; ++ ++ skb = alloc_skb(pdu_len, GFP_ATOMIC); ++ if (skb == NULL) { ++ ++ printk(FORE200E "unable to alloc new skb, rx PDU length = %d\n", pdu_len); ++ vcc->stats->rx_drop++; ++ return; ++ } ++ ++ skb->stamp = vcc->timestamp = xtime; ++ ++#ifdef FORE200E_52BYTE_AAL0_SDU ++ if (cell_header) { ++ *((u32*)skb_put(skb, 4)) = cell_header; ++ } ++#endif ++ ++ /* reassemble segments */ ++ for (i = 0; i < rpd->nseg; i++) { ++ ++ /* rebuild rx buffer address from rsd handle */ ++ buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle); ++ ++ /* ensure DMA synchronisation */ ++ if (fore200e->bus->dma_sync) ++ fore200e->bus->dma_sync(fore200e, buffer->data_dma, rpd->rsd[ i ].length); ++ ++ memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data_align, rpd->rsd[ i ].length); ++ } ++ ++ DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize); ++ ++ if (pdu_len < fore200e_vcc->rx_min_pdu) ++ fore200e_vcc->rx_min_pdu = pdu_len; ++ if (pdu_len > fore200e_vcc->rx_max_pdu) ++ fore200e_vcc->rx_max_pdu = pdu_len; ++ ++ /* push PDU */ ++ if (atm_charge(vcc, skb->truesize) == 0) { ++ ++ DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n", ++ vcc->itf, vcc->vpi, vcc->vci); ++ ++ dev_kfree_skb(skb); ++ return; ++ } ++ ++ vcc->push(vcc, skb); ++ vcc->stats->rx++; ++} ++ ++ ++static void ++fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd) ++{ ++ struct buffer* buffer; ++ int i; ++ ++ for (i = 0; i < rpd->nseg; i++) { ++ ++ /* rebuild rx buffer address from rsd handle */ ++ buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle); ++ ++ /* decrease the number of supplied rx buffers */ ++ fore200e->host_bsq[ buffer->scheme ][ buffer->magn ].count--; ++ } ++} ++ ++ ++static void ++fore200e_irq_rx(struct fore200e* fore200e) ++{ ++ struct host_rxq* rxq = &fore200e->host_rxq; ++ struct host_rxq_entry* entry; ++ ++ for (;;) { ++ ++ entry = &rxq->host_entry[ rxq->head ]; ++ ++ /* no more received PDUs */ ++ if ((*entry->status & STATUS_COMPLETE) == 0) ++ break; ++ ++ FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX); ++ ++ if ((*entry->status & STATUS_ERROR) == 0) { ++ ++ fore200e_push_rpd(fore200e, entry->rpd); ++ } ++ else { ++ printk(FORE200E "damaged PDU on %d.%d.%d\n", ++ fore200e->atm_dev->number, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci); ++ } ++ ++ fore200e_collect_rpd(fore200e, entry->rpd); ++ ++ fore200e_supply(fore200e); ++ ++ /* rewrite the rpd address to ack the received PDU */ ++ fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr); ++ *entry->status = STATUS_FREE; ++ } ++} ++ ++ ++static void ++fore200e_interrupt(int irq, void* dev, struct pt_regs* regs) ++{ ++ struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev); ++ ++ if (fore200e->bus->irq_check(fore200e) == 0) { ++ ++ DPRINTK(3, "unexpected interrupt on device %c\n", fore200e->name[9]); ++ return; ++ } ++ DPRINTK(3, "valid interrupt on device %c\n", fore200e->name[9]); ++ ++ fore200e_irq_rx(fore200e); ++ ++ if (fore200e->host_txq.txing) ++ fore200e_irq_tx(fore200e); ++ ++ fore200e->bus->irq_ack(fore200e); ++} ++ ++ ++static int ++fore200e_select_scheme(struct atm_vcc* vcc) ++{ ++ int scheme; ++ ++#if 1 ++ /* fairly balance VCs over (identical) buffer schemes */ ++ scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO; ++#else ++ /* bit 7 of VPI magically selects the second buffer scheme */ ++ if (vcc->vpi & (1<<7)) { ++ vcc->vpi &= ((1<<7) - 1); /* reset the magic bit */ ++ scheme = BUFFER_SCHEME_TWO; ++ } ++ else { ++ scheme = BUFFER_SCHEME_ONE; ++ } ++#endif ++ ++ DPRINTK(1, "vpvc %d.%d.%d uses the %s buffer scheme\n", ++ vcc->itf, vcc->vpi, vcc->vci, scheme == BUFFER_SCHEME_ONE ? "first" : "second"); ++ ++ return scheme; ++} ++ ++ ++ ++static int ++fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; ++ struct activate_opcode activ_opcode; ++ struct deactivate_opcode deactiv_opcode; ++ struct vpvc vpvc; ++ int ok; ++ enum fore200e_aal aal = fore200e_atm2fore_aal(vcc->qos.aal); ++ ++ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); ++ ++ if (activate) { ++ FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc); ++ ++ activ_opcode.opcode = OPCODE_ACTIVATE_VCIN; ++ activ_opcode.aal = aal; ++ activ_opcode.scheme = FORE200E_VCC(vcc)->scheme; ++ activ_opcode.pad = 0; ++ } ++ else { ++ deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN; ++ deactiv_opcode.pad = 0; ++ } ++ ++ vpvc.vci = vcc->vci; ++ vpvc.vpi = vcc->vpi; ++ ++ *entry->status = STATUS_PENDING; ++ ++ if (activate) { ++ ++#ifdef FORE200E_52BYTE_AAL0_SDU ++ mtu = 48; ++#endif ++ /* the MTU is unused by the cp, except in the case of AAL0 */ ++ fore200e->bus->write(mtu, &entry->cp_entry->cmd.activate_block.mtu); ++ fore200e->bus->write(*(u32*)&vpvc, (u32*)&entry->cp_entry->cmd.activate_block.vpvc); ++ fore200e->bus->write(*(u32*)&activ_opcode, (u32*)&entry->cp_entry->cmd.activate_block.opcode); ++ } ++ else { ++ fore200e->bus->write(*(u32*)&vpvc, (u32*)&entry->cp_entry->cmd.deactivate_block.vpvc); ++ fore200e->bus->write(*(u32*)&deactiv_opcode, (u32*)&entry->cp_entry->cmd.deactivate_block.opcode); ++ } ++ ++ ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); ++ ++ *entry->status = STATUS_FREE; ++ ++ if (ok == 0) { ++ printk(FORE200E "unable to %s vpvc %d.%d on device %s\n", ++ activate ? "open" : "close", vcc->vpi, vcc->vci, fore200e->name); ++ return -EIO; ++ } ++ ++ DPRINTK(1, "vpvc %d.%d %sed on device %s\n", vcc->vpi, vcc->vci, ++ activate ? "open" : "clos", fore200e->name); ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci) ++{ ++ struct atm_vcc* walk; ++ ++ /* find a free VPI */ ++ if (*vpi == ATM_VPI_ANY) { ++ ++ for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next) { ++ ++ if ((walk->vci == *vci) && (walk->vpi == *vpi)) { ++ (*vpi)++; ++ walk = vcc->dev->vccs; ++ } ++ } ++ } ++ ++ /* find a free VCI */ ++ if (*vci == ATM_VCI_ANY) { ++ ++ for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk; walk = walk->next) { ++ ++ if ((walk->vpi = *vpi) && (walk->vci == *vci)) { ++ *vci = walk->vci + 1; ++ walk = vcc->dev->vccs; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ ++#define FORE200E_MAX_BACK2BACK_CELLS 255 /* XXX depends on CDVT */ ++ ++static void ++fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate) ++{ ++ if (qos->txtp.max_pcr < ATM_OC3_PCR) { ++ ++ /* compute the data cells to idle cells ratio from the PCR */ ++ rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR; ++ rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells; ++ } ++ else { ++ /* disable rate control */ ++ rate->data_cells = rate->idle_cells = 0; ++ } ++} ++ ++ ++static int ++fore200e_open(struct atm_vcc *vcc, short vpi, int vci) ++{ ++ ++ struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ struct fore200e_vcc* fore200e_vcc; ++ ++ /* find a free VPI/VCI */ ++ fore200e_walk_vccs(vcc, &vpi, &vci); ++ ++ vcc->vpi = vpi; ++ vcc->vci = vci; ++ ++ /* ressource checking only ? */ ++ if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) ++ return 0; ++ ++ vcc->flags |= ATM_VF_ADDR; ++ vcc->itf = vcc->dev->number; ++ ++ DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; " ++ "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n", ++ vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), ++ fore200e_traffic_class[ vcc->qos.txtp.traffic_class ], ++ vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu, ++ fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ], ++ vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu); ++ ++ if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) { ++ ++ down(&fore200e->rate_sf); ++ if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) { ++ up(&fore200e->rate_sf); ++ return -EAGAIN; ++ } ++ /* reserving the pseudo-CBR bandwidth at this point grants us ++ to reduce the length of the critical section protected ++ by 'rate_sf'. in counterpart, we have to reset the available ++ bandwidth if we later encounter an error */ ++ ++ fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr; ++ up(&fore200e->rate_sf); ++ } ++ ++ fore200e_vcc = fore200e_kmalloc(sizeof(struct fore200e_vcc), GFP_KERNEL); ++ if (fore200e_vcc == NULL) { ++ down(&fore200e->rate_sf); ++ fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; ++ up(&fore200e->rate_sf); ++ return -ENOMEM; ++ } ++ ++ FORE200E_VCC(vcc) = fore200e_vcc; ++ ++ if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) { ++ kfree(fore200e_vcc); ++ down(&fore200e->rate_sf); ++ fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; ++ up(&fore200e->rate_sf); ++ return -EBUSY; ++ } ++ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif ++ ++ /* compute rate control parameters */ ++ if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) { ++ ++ fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate); ++ ++ DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n", ++ vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), ++ vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr, ++ fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells); ++ } ++ ++ fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = 65536; ++ fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0; ++ ++ vcc->flags |= ATM_VF_READY; ++ return 0; ++} ++ ++ ++ ++static void ++fore200e_close(struct atm_vcc* vcc) ++{ ++ struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ ++ DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal)); ++ ++ fore200e_activate_vcin(fore200e, 0, vcc, 0); ++ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif ++ ++ kfree(FORE200E_VCC(vcc)); ++ ++ if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) { ++ down(&fore200e->rate_sf); ++ fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; ++ up(&fore200e->rate_sf); ++ } ++} ++ ++ ++#if 0 ++#define FORE200E_SYNC_SEND /* wait tx completion before returning */ ++#endif ++ ++ ++static int ++fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) ++{ ++ struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc); ++ struct host_txq* txq = &fore200e->host_txq; ++ struct host_txq_entry* entry; ++ struct tpd* tpd; ++ struct tpd_haddr tpd_haddr; ++ unsigned long flags; ++ int retry = CONFIG_ATM_FORE200E_TX_RETRY; ++ int tx_copy = 0; ++ int tx_len = skb->len; ++ u32* cell_header = NULL; ++ unsigned char* skb_data; ++ int skb_len; ++ ++#ifdef FORE200E_52BYTE_AAL0_SDU ++ if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) { ++ cell_header = (u32*) skb->data; ++ skb_data = skb->data + 4; /* skip 4-byte cell header */ ++ skb_len = tx_len = skb->len - 4; ++ ++ DPRINTK(3, "skipping user-supplied cell header 0x%08x", *cell_header); ++ } ++ else ++#endif ++ { ++ skb_data = skb->data; ++ skb_len = skb->len; ++ } ++ ++ retry_here: ++ ++ spin_lock_irqsave(&fore200e->tx_lock, flags); ++ ++ entry = &txq->host_entry[ txq->head ]; ++ ++ if (*entry->status != STATUS_FREE) { ++ ++ /* try to free completed tx queue entries */ ++ fore200e_irq_tx(fore200e); ++ ++ if (*entry->status != STATUS_FREE) { ++ ++ spin_unlock_irqrestore(&fore200e->tx_lock, flags); ++ ++ /* retry once again? */ ++ if(--retry > 0) ++ goto retry_here; ++ ++ vcc->stats->tx_err++; ++ ++ printk(FORE200E "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n", ++ fore200e->name, fore200e->cp_queues->heartbeat); ++ ++ return -EIO; ++ } ++ } ++ ++ tpd = entry->tpd; ++ ++ if (((unsigned long)skb_data) & 0x3) { ++ ++ DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name); ++ tx_copy = 1; ++ tx_len = skb_len; ++ } ++ ++ if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) { ++ ++ /* this simply NUKES the PCA-200E board */ ++ DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name); ++ tx_copy = 1; ++ tx_len = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD; ++ } ++ ++ if (tx_copy) { ++ ++ entry->data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA); ++ if (entry->data == NULL) { ++ ++ spin_unlock_irqrestore(&fore200e->tx_lock, flags); ++ return -ENOMEM; ++ } ++ ++ memcpy(entry->data, skb_data, skb_len); ++ if (skb_len < tx_len) ++ memset(entry->data + skb_len, 0x00, tx_len - skb_len); ++ ++ tpd->tsd[ 0 ].buffer = fore200e->bus->virt_to_dma(entry->data); ++ } ++ else { ++ entry->data = NULL; ++ tpd->tsd[ 0 ].buffer = fore200e->bus->virt_to_dma(skb_data); ++ } ++ ++ tpd->tsd[ 0 ].length = tx_len; ++ ++ FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX); ++ txq->txing++; ++ ++ spin_unlock_irqrestore(&fore200e->tx_lock, flags); ++ ++ /* ensure DMA synchronisation */ ++ if (fore200e->bus->dma_sync) ++ fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length); ++ ++ DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", ++ vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), ++ tpd->tsd[0].length, skb_len); ++ ++ if (skb_len < fore200e_vcc->tx_min_pdu) ++ fore200e_vcc->tx_min_pdu = skb_len; ++ if (skb_len > fore200e_vcc->tx_max_pdu) ++ fore200e_vcc->tx_max_pdu = skb_len; ++ ++ entry->vcc = vcc; ++ entry->skb = skb; ++ ++ /* set tx rate control information */ ++ tpd->rate.data_cells = fore200e_vcc->rate.data_cells; ++ tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells; ++ ++ if (cell_header) { ++ tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP); ++ tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; ++ tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT; ++ tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT; ++ tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT; ++ } ++ else { ++ /* set the ATM header, common to all cells conveying the PDU */ ++ tpd->atm_header.clp = 0; ++ tpd->atm_header.plt = 0; ++ tpd->atm_header.vci = vcc->vci; ++ tpd->atm_header.vpi = vcc->vpi; ++ tpd->atm_header.gfc = 0; ++ } ++ ++ tpd->spec.length = tx_len; ++ tpd->spec.nseg = 1; ++ tpd->spec.aal = fore200e_atm2fore_aal(vcc->qos.aal); ++#ifdef FORE200E_SYNC_SEND ++ tpd->spec.intr = 0; ++#else ++ tpd->spec.intr = 1; ++#endif ++ ++ tpd_haddr.size = sizeof(struct tpd) / 32; /* size is expressed in 32 byte blocks */ ++ tpd_haddr.pad = 0; ++ tpd_haddr.haddr = entry->tpd_dma >> 5; /* shift the address, as we are in a bitfield */ ++ ++ *entry->status = STATUS_PENDING; ++ fore200e->bus->write(*(u32*)&tpd_haddr, (u32*)&entry->cp_entry->tpd_haddr); ++ ++ ++#ifdef FORE200E_SYNC_SEND ++ { ++ int ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 10); ++ ++ if (ok == 0) { ++ printk(FORE200E "synchronous tx on %d:%d:%d failed\n", vcc->itf, vcc->vpi, vcc->vci); ++ ++ entry->vcc->stats->tx_err++; ++ return -EIO; ++ } ++ entry->vcc->stats->tx++; ++ ++ DPRINTK(3, "synchronous tx on %d:%d:%d succeeded\n", vcc->itf, vcc->vpi, vcc->vci); ++ ++ /* free tmp copy of misaligned data */ ++ if (entry->data) ++ kfree(entry->data); ++ ++ /* notify tx completion */ ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); ++ } ++#endif ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_getstats(struct fore200e* fore200e) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; ++ struct stats_opcode opcode; ++ int ok; ++ ++ if (fore200e->stats == NULL) { ++ fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA); ++ if (fore200e->stats == NULL) ++ return -ENOMEM; ++ } ++ ++ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); ++ ++ opcode.opcode = OPCODE_GET_STATS; ++ opcode.pad = 0; ++ ++ fore200e->bus->write(fore200e->bus->virt_to_dma((void*) fore200e->stats), ++ &entry->cp_entry->cmd.stats_block.stats_haddr); ++ ++ *entry->status = STATUS_PENDING; ++ ++ fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.stats_block.opcode); ++ ++ ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); ++ ++ *entry->status = STATUS_FREE; ++ ++ if (ok == 0) { ++ printk(FORE200E "unable to get statistics from device %s\n", fore200e->name); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_getsockopt (struct atm_vcc* vcc, int level, int optname, void* optval, int optlen) ++{ ++ // struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ ++ DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n", ++ vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen); ++ ++ return -EINVAL; ++} ++ ++ ++static int ++fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void* optval, int optlen) ++{ ++ // struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ ++ DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n", ++ vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen); ++ ++ return -EINVAL; ++} ++ ++ ++#if 0 /* currently unused */ ++static int ++fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; ++ struct oc3_opcode opcode; ++ int ok; ++ ++ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); ++ ++ opcode.opcode = OPCODE_GET_OC3; ++ opcode.reg = 0; ++ opcode.value = 0; ++ opcode.mask = 0; ++ ++ fore200e->bus->write(fore200e->bus->virt_to_dma((void*) regs), ++ &entry->cp_entry->cmd.oc3_block.regs_haddr); ++ ++ *entry->status = STATUS_PENDING; ++ ++ fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode); ++ ++ ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); ++ ++ *entry->status = STATUS_FREE; ++ ++ if (ok == 0) { ++ printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name); ++ return -EIO; ++ } ++ ++ return 0; ++} ++#endif ++ ++ ++static int ++fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ]; ++ struct oc3_opcode opcode; ++ int ok; ++ ++ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); ++ ++ opcode.opcode = OPCODE_SET_OC3; ++ opcode.reg = reg; ++ opcode.value = value; ++ opcode.mask = mask; ++ ++ fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr); ++ ++ *entry->status = STATUS_PENDING; ++ ++ fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode); ++ ++ ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400); ++ ++ *entry->status = STATUS_FREE; ++ ++ if (ok == 0) { ++ printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_setloop(struct fore200e* fore200e, int loop_mode) ++{ ++ u32 mct_value, mct_mask; ++ int error; ++ ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ switch (loop_mode) { ++ ++ case SUNI_LM_NONE: ++ mct_value = 0; ++ mct_mask = SUNI_MCT_DLE | SUNI_MCT_LLE; ++ break; ++ ++ case SUNI_LM_DIAG: ++ mct_value = mct_mask = SUNI_MCT_DLE; ++ break; ++ ++ case SUNI_LM_LOOP: ++ mct_value = mct_mask = SUNI_MCT_LLE; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask); ++ if ( error == 0) ++ fore200e->loop_mode = loop_mode; ++ ++ return error; ++} ++ ++ ++static inline unsigned int ++fore200e_dma_swap(unsigned int in) ++{ ++#if defined(__i386__) ++ return swab32(in); ++#else ++ return in; ++#endif ++} ++ ++ ++static int ++fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats* arg) ++{ ++ struct sonet_stats tmp; ++ ++ if (fore200e_getstats(fore200e) < 0) ++ return -EIO; ++ ++ tmp.section_bip = fore200e_dma_swap(fore200e->stats->oc3.section_bip8_errors); ++ tmp.line_bip = fore200e_dma_swap(fore200e->stats->oc3.line_bip24_errors); ++ tmp.path_bip = fore200e_dma_swap(fore200e->stats->oc3.path_bip8_errors); ++ tmp.line_febe = fore200e_dma_swap(fore200e->stats->oc3.line_febe_errors); ++ tmp.path_febe = fore200e_dma_swap(fore200e->stats->oc3.path_febe_errors); ++ tmp.corr_hcs = fore200e_dma_swap(fore200e->stats->oc3.corr_hcs_errors); ++ tmp.uncorr_hcs = fore200e_dma_swap(fore200e->stats->oc3.ucorr_hcs_errors); ++ tmp.tx_cells = fore200e_dma_swap(fore200e->stats->aal0.cells_transmitted) + ++ fore200e_dma_swap(fore200e->stats->aal34.cells_transmitted) + ++ fore200e_dma_swap(fore200e->stats->aal5.cells_transmitted); ++ tmp.rx_cells = fore200e_dma_swap(fore200e->stats->aal0.cells_received) + ++ fore200e_dma_swap(fore200e->stats->aal34.cells_received) + ++ fore200e_dma_swap(fore200e->stats->aal5.cells_received); ++ ++ if (arg) ++ return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0; ++ ++ return 0; ++} ++ ++ ++static int ++fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg) ++{ ++ struct fore200e* fore200e = FORE200E_DEV(dev); ++ ++ DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg); ++ ++ switch (cmd) { ++ ++ case SONET_GETSTAT: ++ return fore200e_fetch_stats(fore200e, (struct sonet_stats*)arg); ++ ++ case SONET_GETDIAG: ++ return put_user(0, (int*)arg) ? -EFAULT : 0; ++ ++ case SUNI_SETLOOP: ++ return fore200e_setloop(fore200e, (int)(unsigned long)arg); ++ ++ case SUNI_GETLOOP: ++ return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0; ++ } ++ ++ return -ENOSYS; /* not implemented */ ++} ++ ++ ++static int ++fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) ++{ ++ struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc); ++ struct fore200e* fore200e = FORE200E_DEV(vcc->dev); ++ ++ DPRINTK(2, "change_qos %d.%d.%d, " ++ "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; " ++ "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n" ++ "available_cell_rate = %u", ++ vcc->itf, vcc->vpi, vcc->vci, ++ fore200e_traffic_class[ qos->txtp.traffic_class ], ++ qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu, ++ fore200e_traffic_class[ qos->rxtp.traffic_class ], ++ qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu, ++ flags, fore200e->available_cell_rate); ++ ++ if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) { ++ ++ down(&fore200e->rate_sf); ++ if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) { ++ up(&fore200e->rate_sf); ++ return -EAGAIN; ++ } ++ ++ fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; ++ fore200e->available_cell_rate -= qos->txtp.max_pcr; ++ up(&fore200e->rate_sf); ++ ++ memcpy(&vcc->qos, qos, sizeof(struct atm_qos)); ++ ++ /* update rate control parameters */ ++ fore200e_rate_ctrl(qos, &fore200e_vcc->rate); ++ ++ vcc->flags |= ATM_VF_HASQOS; ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++ ++static int __init ++fore200e_irq_request(struct fore200e* fore200e) ++{ ++ if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { ++ ++ printk(FORE200E "unable to reserve IRQ %s for device %s\n", ++ fore200e_irq_itoa(fore200e->irq), fore200e->name); ++ return -EBUSY; ++ } ++ ++ printk(FORE200E "IRQ %s reserved for device %s\n", ++ fore200e_irq_itoa(fore200e->irq), fore200e->name); ++ ++ fore200e->state = FORE200E_STATE_IRQ; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_get_esi(struct fore200e* fore200e) ++{ ++ struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); ++ int ok, i; ++ ++ ok = fore200e->bus->prom_read(fore200e, prom); ++ if (ok < 0) ++ return -EBUSY; ++ ++ printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ fore200e->name, ++ (prom->hw_revision & 0xFF) + '@', /* probably meaningless with SBA boards */ ++ prom->serial_number & 0xFFFF, ++ prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ], ++ prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]); ++ ++ for (i = 0; i < ESI_LEN; i++) { ++ fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ]; ++ } ++ ++ fore200e_kfree((void**)&prom); ++ ++ return 0; ++} ++ ++ ++static int __init ++fore200e_alloc_rx_buf(struct fore200e* fore200e) ++{ ++ int scheme, magn, nbr, size, i; ++ ++ struct host_bsq* bsq; ++ struct buffer* buffer; ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { ++ ++ bsq = &fore200e->host_bsq[ scheme ][ magn ]; ++ ++ nbr = fore200e_rx_buf_nbr[ scheme ][ magn ]; ++ size = fore200e_rx_buf_size[ scheme ][ magn ]; ++ ++ DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn); ++ ++ /* allocate the array of receive buffers */ ++ buffer = bsq->buffer = fore200e_kmalloc(nbr * sizeof(struct buffer), GFP_KERNEL); ++ ++ if (buffer == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < nbr; i++) { ++ ++ buffer[ i ].scheme = scheme; ++ buffer[ i ].magn = magn; ++ ++ /* allocate and align the receive buffer body */ ++ if (fore200e_align_alloc((void**) &buffer[ i ].data_align, ++ (void**) &buffer[ i ].data_raw, ++ size, ++ fore200e->bus->buffer_alignment) < 0) { ++ ++ while (i > 0) ++ fore200e_align_free((void**)&buffer[ --i ].data_raw); ++ fore200e_kfree((void**)&buffer); ++ ++ return -ENOMEM; ++ } ++ ++ /* finally get the physical base address of the buffer body */ ++ buffer[ i ].data_dma = fore200e->bus->virt_to_dma(buffer[ i ].data_align); ++ } ++ ++ /* set next free buffer index */ ++ bsq->free = 0; ++ } ++ } ++ ++ fore200e->state = FORE200E_STATE_ALLOC_BUF; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_init_bs_queue(struct fore200e* fore200e) ++{ ++ int scheme, magn, i; ++ ++ struct host_bsq* bsq; ++ struct cp_bsq_entry* cp_entry; ++ u32 status_dma; ++ u32 rbd_block_dma; ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { ++ ++ DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn); ++ ++ bsq = &fore200e->host_bsq[ scheme ][ magn ]; ++ ++ /* allocate and align the array of status words */ ++ if (fore200e->bus->dma_alloc((void**) &bsq->status_align, ++ (void**) &bsq->status_raw, ++ &status_dma, ++ sizeof(enum status), ++ QUEUE_SIZE_BS, ++ fore200e->bus->status_alignment) < 0) { ++ return -ENOMEM; ++ } ++ ++ /* allocate and align the array of receive buffer descriptors */ ++ if (fore200e->bus->dma_alloc((void**) &bsq->rbd_block_align, ++ (void**) &bsq->rbd_block_raw, ++ &rbd_block_dma, ++ sizeof(struct rbd_block), ++ QUEUE_SIZE_BS, ++ fore200e->bus->descr_alignment) < 0) { ++ ++ fore200e->bus->dma_free((void**)&bsq->status_raw); ++ return -ENOMEM; ++ } ++ ++ /* get the base address of the cp resident buffer supply queue entries */ ++ cp_entry = (struct cp_bsq_entry*)(fore200e->virt_base + ++ fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ])); ++ ++ /* fill the host resident and cp resident buffer supply queue entries */ ++ for (i = 0; i < QUEUE_SIZE_BS; i++) { ++ ++ bsq->host_entry[ i ].status = &bsq->status_align[ i ]; ++ bsq->host_entry[ i ].rbd_block = &bsq->rbd_block_align[i]; ++ bsq->host_entry[ i ].rbd_block_dma = FORE200E_DMA_INDEX(rbd_block_dma, struct rbd, i); ++ bsq->host_entry[ i ].cp_entry = &cp_entry[ i ]; ++ ++ *bsq->host_entry[ i ].status = STATUS_FREE; ++ ++ fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); ++ } ++ } ++ } ++ ++ fore200e->state = FORE200E_STATE_INIT_BSQ; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_init_rx_queue(struct fore200e* fore200e) ++{ ++ struct host_rxq* rxq = &fore200e->host_rxq; ++ struct cp_rxq_entry* cp_entry; ++ u32 status_dma; ++ u32 rpd_dma; ++ int i; ++ ++ DPRINTK(2, "receive queue is being initialized\n"); ++ ++ /* allocate and align the array of status words */ ++ if (fore200e->bus->dma_alloc((void**) &rxq->status_align, ++ (void**) &rxq->status_raw, ++ &status_dma, ++ sizeof(enum status), ++ QUEUE_SIZE_RX, ++ fore200e->bus->status_alignment) < 0) { ++ return -ENOMEM; ++ } ++ ++ /* allocate and align the array of receive PDU descriptors */ ++ if (fore200e->bus->dma_alloc((void**) &rxq->rpd_align, ++ (void**) &rxq->rpd_raw, ++ &rpd_dma, ++ sizeof(struct rpd), ++ QUEUE_SIZE_RX, ++ fore200e->bus->descr_alignment) < 0) { ++ ++ fore200e->bus->dma_free((void**)&rxq->status_raw); ++ return -ENOMEM; ++ } ++ ++ /* get the base address of the cp resident rx queue entries */ ++ cp_entry = (struct cp_rxq_entry*)(fore200e->virt_base + ++ fore200e->bus->read(&fore200e->cp_queues->cp_rxq)); ++ ++ /* fill the host resident and cp resident rx entries */ ++ for (i=0; i < QUEUE_SIZE_RX; i++) { ++ ++ rxq->host_entry[ i ].status = &rxq->status_align[ i ]; ++ rxq->host_entry[ i ].rpd = &rxq->rpd_align[ i ]; ++ rxq->host_entry[ i ].rpd_dma = FORE200E_DMA_INDEX(rpd_dma, struct rpd, i); ++ rxq->host_entry[ i ].cp_entry = &cp_entry[ i ]; ++ ++ *rxq->host_entry[ i ].status = STATUS_FREE; ++ ++ fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); ++ fore200e->bus->write(FORE200E_DMA_INDEX(rpd_dma, struct rpd, i), &cp_entry[ i ].rpd_haddr); ++ } ++ ++ /* set the head entry of the queue */ ++ rxq->head = 0; ++ ++ fore200e->state = FORE200E_STATE_INIT_RXQ; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_init_tx_queue(struct fore200e* fore200e) ++{ ++ struct host_txq* txq = &fore200e->host_txq; ++ struct cp_txq_entry* cp_entry; ++ u32 status_dma; ++ u32 tpd_dma; ++ int i; ++ ++ DPRINTK(2, "transmit queue is being initialized\n"); ++ ++ /* allocate and align the array of status words */ ++ if (fore200e->bus->dma_alloc((void**) &txq->status_align, ++ (void**) &txq->status_raw, ++ &status_dma, ++ sizeof(enum status), ++ QUEUE_SIZE_TX, ++ fore200e->bus->status_alignment) < 0) { ++ return -ENOMEM; ++ } ++ ++ /* allocate and align the array of transmit PDU descriptors */ ++ if (fore200e->bus->dma_alloc((void**) &txq->tpd_align, ++ (void**) &txq->tpd_raw, ++ &tpd_dma, ++ sizeof(struct tpd), ++ QUEUE_SIZE_TX, ++ fore200e->bus->descr_alignment) < 0) { ++ ++ fore200e->bus->dma_free((void**)&txq->status_raw); ++ return -ENOMEM; ++ } ++ ++ /* get the base address of the cp resident tx queue entries */ ++ cp_entry = (struct cp_txq_entry*)(fore200e->virt_base + ++ fore200e->bus->read(&fore200e->cp_queues->cp_txq)); ++ ++ /* fill the host resident and cp resident tx entries */ ++ for (i=0; i < QUEUE_SIZE_TX; i++) { ++ ++ txq->host_entry[ i ].status = &txq->status_align[ i ]; ++ txq->host_entry[ i ].tpd = &txq->tpd_align[ i ]; ++ txq->host_entry[ i ].tpd_dma = FORE200E_DMA_INDEX(tpd_dma, struct tpd, i); ++ txq->host_entry[ i ].cp_entry = &cp_entry[ i ]; ++ ++ *txq->host_entry[ i ].status = STATUS_FREE; ++ ++ fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); ++ ++ /* although there is a one-to-one mapping of tx queue entries and tpds, ++ we do not write here the DMA (physical) base address of each tpd into the related ++ cp resident entry, because the cp relies on this write to detect that a new pdu ++ has been submitted for tx */ ++ } ++ ++ /* set the head entry of the queue */ ++ txq->head = 0; ++ ++ fore200e->state = FORE200E_STATE_INIT_TXQ; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_init_cmd_queue(struct fore200e* fore200e) ++{ ++ struct host_cmdq* cmdq = &fore200e->host_cmdq; ++ struct cp_cmdq_entry* cp_entry; ++ u32 status_dma; ++ int i; ++ ++ DPRINTK(2, "command queue is being initialized\n"); ++ ++ /* allocate and align the array of status words */ ++ if (fore200e->bus->dma_alloc((void**) &cmdq->status_align, ++ (void**) &cmdq->status_raw, ++ &status_dma, ++ sizeof(enum status), ++ QUEUE_SIZE_CMD, ++ fore200e->bus->status_alignment) < 0) { ++ return -ENOMEM; ++ } ++ ++ /* get the base address of the cp resident cmd queue entries */ ++ cp_entry = (struct cp_cmdq_entry*)(fore200e->virt_base + ++ fore200e->bus->read(&fore200e->cp_queues->cp_cmdq)); ++ ++ /* fill the host resident and cp resident cmd entries */ ++ for (i=0; i < QUEUE_SIZE_CMD; i++) { ++ ++ cmdq->host_entry[ i ].status = &cmdq->status_align[ i ]; ++ cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ]; ++ ++ *cmdq->host_entry[ i ].status = STATUS_FREE; ++ ++ fore200e->bus->write(FORE200E_DMA_INDEX(status_dma, enum status, i), &cp_entry[ i ].status_haddr); ++ } ++ ++ /* set the head entry of the queue */ ++ cmdq->head = 0; ++ ++ fore200e->state = FORE200E_STATE_INIT_CMDQ; ++ return 0; ++} ++ ++ ++static void __init ++fore200e_param_bs_queue(struct fore200e* fore200e, ++ enum buffer_scheme scheme, enum buffer_magn magn, ++ int queue_length, int pool_size, int supply_blksize) ++{ ++ struct bs_spec* bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ]; ++ ++ /* dumb value; the firmware doesn't allow us to activate a VC while ++ selecting a buffer scheme with zero-sized rbd pools */ ++ ++ if (pool_size == 0) ++ pool_size = 64; ++ ++ fore200e->bus->write(queue_length, &bs_spec->queue_length); ++ fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size); ++ fore200e->bus->write(pool_size, &bs_spec->pool_size); ++ fore200e->bus->write(supply_blksize, &bs_spec->supply_blksize); ++} ++ ++ ++static int __init ++fore200e_initialize(struct fore200e* fore200e) ++{ ++ struct cp_queues* cpq; ++ int ok, scheme, magn; ++ ++ DPRINTK(2, "device %s being initialized\n", fore200e->name); ++ ++ spin_lock_init(&fore200e->tx_lock); ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)) ++ fore200e->rate_sf = MUTEX; ++#else ++ init_MUTEX(&fore200e->rate_sf); ++#endif ++ ++ cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET); ++ ++ /* enable cp to host interrupts */ ++ fore200e->bus->write(1, &cpq->imask); ++ ++ if (fore200e->bus->irq_enable) ++ fore200e->bus->irq_enable(fore200e); ++ ++ fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect); ++ ++ fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len); ++ fore200e->bus->write(QUEUE_SIZE_RX, &cpq->init.rx_queue_len); ++ fore200e->bus->write(QUEUE_SIZE_TX, &cpq->init.tx_queue_len); ++ ++ fore200e->bus->write(RSD_EXTENSION, &cpq->init.rsd_extension); ++ fore200e->bus->write(TSD_EXTENSION, &cpq->init.tsd_extension); ++ ++ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) ++ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) ++ fore200e_param_bs_queue(fore200e, scheme, magn, ++ QUEUE_SIZE_BS, ++ fore200e_rx_buf_nbr[ scheme ][ magn ], ++ RBD_BLK_SIZE); ++ ++ /* issue the initialize command */ ++ fore200e->bus->write(STATUS_PENDING, &cpq->init.status); ++ fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode); ++ ++ ok = fore200e_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000); ++ if (ok == 0) { ++ printk(FORE200E "device %s initialization failed\n", fore200e->name); ++ return -ENODEV; ++ } ++ ++ printk(FORE200E "device %s initialized\n", fore200e->name); ++ ++ fore200e->state = FORE200E_STATE_INITIALIZE; ++ return 0; ++} ++ ++ ++static void __init ++fore200e_monitor_putc(struct fore200e* fore200e, char c) ++{ ++ struct cp_monitor* monitor = fore200e->cp_monitor; ++ ++#if 0 ++ printk("%c", c); ++#endif ++ fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send); ++} ++ ++ ++static int __init ++fore200e_monitor_getc(struct fore200e* fore200e) ++{ ++ struct cp_monitor* monitor = fore200e->cp_monitor; ++ unsigned long timeout = jiffies + MSECS(50); ++ int c; ++ ++ while (jiffies < timeout) { ++ ++ c = (int) fore200e->bus->read(&monitor->soft_uart.recv); ++ ++ if (c & FORE200E_CP_MONITOR_UART_AVAIL) { ++ ++ fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv); ++#if 0 ++ printk("%c", c & 0xFF); ++#endif ++ return c & 0xFF; ++ } ++ } ++ ++ return -1; ++} ++ ++ ++static void __init ++fore200e_monitor_puts(struct fore200e* fore200e, char* str) ++{ ++ while(*str) { ++ ++ /* the i960 monitor doesn't accept any new character if it has something to say */ ++ while (fore200e_monitor_getc(fore200e) >= 0); ++ ++ fore200e_monitor_putc(fore200e, *str++); ++ } ++ ++ while (fore200e_monitor_getc(fore200e) >= 0); ++} ++ ++ ++static int __init ++fore200e_start_fw(struct fore200e* fore200e) ++{ ++ int ok; ++ char cmd[ 48 ]; ++ struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data; ++ ++ DPRINTK(2, "device %s firmware being started\n", fore200e->name); ++ ++ sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset)); ++ ++ fore200e_monitor_puts(fore200e, cmd); ++ ++ ok = fore200e_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000); ++ if (ok == 0) { ++ printk(FORE200E "device %s firmware didn't start\n", fore200e->name); ++ return -ENODEV; ++ } ++ ++ printk(FORE200E "device %s firmware started\n", fore200e->name); ++ ++ fore200e->state = FORE200E_STATE_START_FW; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_load_fw(struct fore200e* fore200e) ++{ ++ u32* fw_data = (u32*) fore200e->bus->fw_data; ++ u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32); ++ ++ struct fw_header* fw_header = (struct fw_header*) fw_data; ++ ++ u32* load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset); ++ ++ DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n", ++ fore200e->name, load_addr, fw_size); ++ ++#if 1 ++ if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) { ++ printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name); ++ return -ENODEV; ++ } ++#endif ++ ++ for (; fw_size--; fw_data++, load_addr++) ++ fore200e->bus->write(le32_to_cpu(*fw_data), load_addr); ++ ++ fore200e->state = FORE200E_STATE_LOAD_FW; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_register(struct fore200e* fore200e) ++{ ++ struct atm_dev* atm_dev; ++ ++ DPRINTK(2, "device %s being registered\n", fore200e->name); ++ ++ atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, 0); ++ if (atm_dev == NULL) { ++ printk(FORE200E "unable to register device %s\n", fore200e->name); ++ return -ENODEV; ++ } ++ ++ FORE200E_DEV(atm_dev) = fore200e; ++ fore200e->atm_dev = atm_dev; ++ ++ atm_dev->ci_range.vpi_bits = 8; ++ atm_dev->ci_range.vci_bits = 10; ++ ++ fore200e->available_cell_rate = ATM_OC3_PCR; ++ ++ fore200e->state = FORE200E_STATE_REGISTER; ++ return 0; ++} ++ ++ ++static int __init ++fore200e_init(struct fore200e* fore200e) ++{ ++ if (fore200e_register(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e->bus->configure(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e->bus->map(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e_reset(fore200e, 1) < 0) ++ return -ENODEV; ++ ++ if (fore200e_load_fw(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e_start_fw(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e_initialize(fore200e) < 0) ++ return -ENODEV; ++ ++ if (fore200e_init_cmd_queue(fore200e) < 0) ++ return -ENOMEM; ++ ++ if (fore200e_init_tx_queue(fore200e) < 0) ++ return -ENOMEM; ++ ++ if (fore200e_init_rx_queue(fore200e) < 0) ++ return -ENOMEM; ++ ++ if (fore200e_init_bs_queue(fore200e) < 0) ++ return -ENOMEM; ++ ++ if (fore200e_alloc_rx_buf(fore200e) < 0) ++ return -ENOMEM; ++ ++ fore200e_supply(fore200e); ++ ++ if (fore200e_get_esi(fore200e) < 0) ++ return -EIO; ++ ++ if (fore200e_irq_request(fore200e) < 0) ++ return -EBUSY; ++ ++ /* all done, board initialization is complete */ ++ fore200e->state = FORE200E_STATE_COMPLETE; ++ return 0; ++} ++ ++ ++int __init ++fore200e_detect(void) ++{ ++ const struct fore200e_bus* bus; ++ struct fore200e* fore200e; ++ int index, link; ++ ++ printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION "\n"); ++ ++ /* for each configured bus interface */ ++ for (link = 0, bus = fore200e_bus; bus->model_name; bus++) { ++ ++ /* detect all boards present on that bus */ ++ for (index = 0; (fore200e = bus->detect(bus, index)); index++) { ++ ++ printk(FORE200E "device %s found at 0x%lx, IRQ %s\n", ++ fore200e->bus->model_name, ++ fore200e->phys_base, fore200e_irq_itoa(fore200e->irq)); ++ ++ sprintf(fore200e->name, "%s-%d", bus->model_name, index); ++ ++ if (fore200e_init(fore200e) < 0) { ++ ++ fore200e_shutdown(fore200e); ++ break; ++ } ++ ++ link++; ++ ++ fore200e->next = fore200e_boards; ++ fore200e_boards = fore200e; ++ } ++ } ++ ++#if 0 /* XXX uncomment this to forbid module unloading */ ++#ifdef MODULE ++ if (link > 0) ++ MOD_INC_USE_COUNT; ++#endif ++#endif ++ ++ return link; ++} ++ ++ ++#ifdef MODULE ++static void ++fore200e_cleanup(struct fore200e** head) ++{ ++ struct fore200e* fore200e = *head; ++ ++ fore200e_shutdown(fore200e); ++ ++ *head = fore200e->next; ++ ++ kfree(fore200e); ++} ++#endif ++ ++ ++static int ++fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) ++{ ++ struct fore200e* fore200e = FORE200E_DEV(dev); ++ int len, left = *pos; ++ ++ if (!left--) { ++ ++ if (fore200e_getstats(fore200e) < 0) ++ return -EIO; ++ ++ len = sprintf(page,"\n" ++ " device:\n" ++ " internal name:\t\t%s\n", fore200e->name); ++ ++ /* print bus-specific information */ ++ if (fore200e->bus->proc_read) ++ len += fore200e->bus->proc_read(fore200e, page + len); ++ ++ len += sprintf(page + len, ++ " interrupt line:\t\t%s\n" ++ " physical base address:\t0x%p\n" ++ " virtual base address:\t0x%p\n" ++ " factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n" ++ " board serial number:\t\t%d\n\n", ++ fore200e_irq_itoa(fore200e->irq), ++ (void*)fore200e->phys_base, ++ (void*)fore200e->virt_base, ++ fore200e->esi[0], fore200e->esi[1], fore200e->esi[2], ++ fore200e->esi[3], fore200e->esi[4], fore200e->esi[5], ++ fore200e->esi[4] * 256 + fore200e->esi[5]); ++ ++ return len; ++ } ++ ++ if (!left--) ++ return sprintf(page, ++ " supplied small bufs (1):\t%d\n" ++ " supplied large bufs (1):\t%d\n" ++ " supplied small bufs (2):\t%d\n" ++ " supplied large bufs (2):\t%d\n", ++ fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].count, ++ fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].count, ++ fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].count, ++ fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].count); ++ if (!left--) { ++ u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat); ++ ++ len = sprintf(page,"\n\n" ++ " cell processor:\n" ++ " heartbeat state:\t\t"); ++ ++ if (hb >> 16 != 0xDEAD) ++ len += sprintf(page + len, "0x%08x\n", hb); ++ else ++ len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF); ++ ++ return len; ++ } ++ ++ if (!left--) { ++ static const char* media_name[] = { ++ "unshielded twisted pair", ++ "multimode optical fiber ST", ++ "multimode optical fiber SC", ++ "single-mode optical fiber ST", ++ "single-mode optical fiber SC", ++ "unknown" ++ }; ++ ++ static const char* oc3_mode[] = { ++ "normal operation", ++ "diagnostic loopback", ++ "line loopback" ++ }; ++ ++ u32 fw_release = fore200e->bus->read(&fore200e->cp_queues->fw_release); ++ u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release); ++ u32 oc3_revision = fore200e->bus->read(&fore200e->cp_queues->oc3_revision); ++ u32 media_index = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type)); ++ ++ if (media_index < 0 || media_index > 4) ++ media_index = 5; ++ ++ return sprintf(page, ++ " firmware release:\t\t%d.%d.%d\n" ++ " monitor release:\t\t%d.%d\n" ++ " media type:\t\t\t%s\n" ++ " OC-3 revision:\t\t0x%x\n" ++ " OC-3 mode:\t\t\t%s", ++ fw_release >> 16, fw_release << 16 >> 24, fw_release << 24 >> 24, ++ mon960_release >> 16, mon960_release << 16 >> 16, ++ media_name[ media_index ], ++ oc3_revision, ++ oc3_mode[ fore200e->loop_mode ]); ++ } ++ ++ if (!left--) { ++ struct cp_monitor* cp_monitor = fore200e->cp_monitor; ++ ++ return sprintf(page, ++ "\n\n" ++ " monitor:\n" ++ " version number:\t\t%d\n" ++ " boot status word:\t\t0x%08x\n", ++ fore200e->bus->read(&cp_monitor->mon_version), ++ fore200e->bus->read(&cp_monitor->bstat)); ++ } ++ ++ if (!left--) ++ return sprintf(page, ++ "\n" ++ " device statistics:\n" ++ " 4b5b:\n" ++ " crc_header_errors:\t\t%10u\n" ++ " framing_errors:\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->phy.crc_header_errors), ++ fore200e_dma_swap(fore200e->stats->phy.framing_errors)); ++ ++ if (!left--) ++ return sprintf(page, "\n" ++ " OC-3:\n" ++ " section_bip8_errors:\t%10u\n" ++ " path_bip8_errors:\t\t%10u\n" ++ " line_bip24_errors:\t\t%10u\n" ++ " line_febe_errors:\t\t%10u\n" ++ " path_febe_errors:\t\t%10u\n" ++ " corr_hcs_errors:\t\t%10u\n" ++ " ucorr_hcs_errors:\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->oc3.section_bip8_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.path_bip8_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.line_bip24_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.line_febe_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.path_febe_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.corr_hcs_errors), ++ fore200e_dma_swap(fore200e->stats->oc3.ucorr_hcs_errors)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " ATM:\t\t\t\t cells\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " vpi out of range:\t\t%10u\n" ++ " vpi no conn:\t\t%10u\n" ++ " vci out of range:\t\t%10u\n" ++ " vci no conn:\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->atm.cells_transmitted), ++ fore200e_dma_swap(fore200e->stats->atm.cells_received), ++ fore200e_dma_swap(fore200e->stats->atm.vpi_bad_range), ++ fore200e_dma_swap(fore200e->stats->atm.vpi_no_conn), ++ fore200e_dma_swap(fore200e->stats->atm.vci_bad_range), ++ fore200e_dma_swap(fore200e->stats->atm.vci_no_conn)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " AAL0:\t\t\t cells\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " dropped:\t\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->aal0.cells_transmitted), ++ fore200e_dma_swap(fore200e->stats->aal0.cells_received), ++ fore200e_dma_swap(fore200e->stats->aal0.cells_dropped)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " AAL3/4:\n" ++ " SAR sublayer:\t\t cells\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " dropped:\t\t\t%10u\n" ++ " CRC errors:\t\t%10u\n" ++ " protocol errors:\t\t%10u\n\n" ++ " CS sublayer:\t\t PDUs\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " dropped:\t\t\t%10u\n" ++ " protocol errors:\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->aal34.cells_transmitted), ++ fore200e_dma_swap(fore200e->stats->aal34.cells_received), ++ fore200e_dma_swap(fore200e->stats->aal34.cells_dropped), ++ fore200e_dma_swap(fore200e->stats->aal34.cells_crc_errors), ++ fore200e_dma_swap(fore200e->stats->aal34.cells_protocol_errors), ++ fore200e_dma_swap(fore200e->stats->aal34.cspdus_transmitted), ++ fore200e_dma_swap(fore200e->stats->aal34.cspdus_received), ++ fore200e_dma_swap(fore200e->stats->aal34.cspdus_dropped), ++ fore200e_dma_swap(fore200e->stats->aal34.cspdus_protocol_errors)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " AAL5:\n" ++ " SAR sublayer:\t\t cells\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " dropped:\t\t\t%10u\n" ++ " congestions:\t\t%10u\n\n" ++ " CS sublayer:\t\t PDUs\n" ++ " TX:\t\t\t%10u\n" ++ " RX:\t\t\t%10u\n" ++ " dropped:\t\t\t%10u\n" ++ " CRC errors:\t\t%10u\n" ++ " protocol errors:\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->aal5.cells_transmitted), ++ fore200e_dma_swap(fore200e->stats->aal5.cells_received), ++ fore200e_dma_swap(fore200e->stats->aal5.cells_dropped), ++ fore200e_dma_swap(fore200e->stats->aal5.congestion_experienced), ++ fore200e_dma_swap(fore200e->stats->aal5.cspdus_transmitted), ++ fore200e_dma_swap(fore200e->stats->aal5.cspdus_received), ++ fore200e_dma_swap(fore200e->stats->aal5.cspdus_dropped), ++ fore200e_dma_swap(fore200e->stats->aal5.cspdus_crc_errors), ++ fore200e_dma_swap(fore200e->stats->aal5.cspdus_protocol_errors)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " AUX:\t\t allocation failures\n" ++ " small b1:\t\t\t%10u\n" ++ " large b1:\t\t\t%10u\n" ++ " small b2:\t\t\t%10u\n" ++ " large b2:\t\t\t%10u\n" ++ " RX PDUs:\t\t\t%10u\n", ++ fore200e_dma_swap(fore200e->stats->aux.small_b1_failed), ++ fore200e_dma_swap(fore200e->stats->aux.large_b1_failed), ++ fore200e_dma_swap(fore200e->stats->aux.small_b2_failed), ++ fore200e_dma_swap(fore200e->stats->aux.large_b2_failed), ++ fore200e_dma_swap(fore200e->stats->aux.rpd_alloc_failed)); ++ ++ if (!left--) ++ return sprintf(page,"\n" ++ " receive carrier:\t\t\t%s\n", ++ fore200e->stats->aux.receive_carrier ? "ON" : "OFF!"); ++ ++ if (!left--) { ++ struct atm_vcc *vcc; ++ struct fore200e_vcc* fore200e_vcc; ++ ++ len = sprintf(page,"\n" ++ " VCCs:\n address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n"); ++ ++ for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { ++ ++ fore200e_vcc = FORE200E_VCC(vcc); ++ ++ len += sprintf(page + len, ++ " %x\t%d.%d:%d\t\t(%d/%d)\t(%d/%d)\n", ++ (u32)(unsigned long)vcc, ++ vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), ++ fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu, ++ fore200e_vcc->tx_max_pdu, ++ fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu, ++ fore200e_vcc->rx_max_pdu ++ ); ++ } ++ ++ return len; ++ } ++ ++ return 0; ++} ++ ++ ++#ifdef MODULE ++unsigned int ++init_module(void) ++{ ++ DPRINTK(1, "module loaded\n"); ++ return fore200e_detect() == 0; ++} ++ ++void ++cleanup_module(void) ++{ ++ while (fore200e_boards) { ++ fore200e_cleanup(&fore200e_boards); ++ } ++ DPRINTK(1, "module being removed\n"); ++} ++#endif ++ ++ ++static const struct atmdev_ops fore200e_ops = ++{ ++ open: fore200e_open, ++ close: fore200e_close, ++ ioctl: fore200e_ioctl, ++ getsockopt: fore200e_getsockopt, ++ setsockopt: fore200e_setsockopt, ++ send: fore200e_send, ++ change_qos: fore200e_change_qos, ++ proc_read: fore200e_proc_read ++}; ++ ++ ++#ifdef CONFIG_ATM_FORE200E_PCA ++extern const unsigned char _fore200e_pca_fw_data[]; ++extern const unsigned int _fore200e_pca_fw_size; ++#endif ++#ifdef CONFIG_ATM_FORE200E_SBA ++extern const unsigned char _fore200e_sba_fw_data[]; ++extern const unsigned int _fore200e_sba_fw_size; ++#endif ++ ++static const struct fore200e_bus fore200e_bus[] = { ++#ifdef CONFIG_ATM_FORE200E_PCA ++ { "PCA-200E", "pca200e", 32, 4, 32, ++ _fore200e_pca_fw_data, &_fore200e_pca_fw_size, ++ fore200e_pca_read, ++ fore200e_pca_write, ++ fore200e_pca_virt_to_dma, ++ fore200e_pca_dma_alloc, ++ fore200e_pca_dma_free, ++ fore200e_pca_detect, ++ fore200e_pca_configure, ++ fore200e_pca_map, ++ fore200e_pca_reset, ++ fore200e_pca_prom_read, ++ fore200e_pca_unmap, ++ NULL, ++ fore200e_pca_irq_check, ++ fore200e_pca_irq_ack, ++ NULL, ++ fore200e_pca_proc_read, ++ }, ++#endif ++#ifdef CONFIG_ATM_FORE200E_SBA ++ { "SBA-200E", "sba200e", 32, 64, 32, ++ _fore200e_sba_fw_data, &_fore200e_sba_fw_size, ++ fore200e_sba_read, ++ fore200e_sba_write, ++ fore200e_sba_virt_to_dma, ++ fore200e_sba_dma_alloc, ++ fore200e_sba_dma_free, ++ fore200e_sba_detect, ++ fore200e_sba_configure, ++ fore200e_sba_map, ++ fore200e_sba_reset, ++ fore200e_sba_prom_read, ++ fore200e_sba_unmap, ++ fore200e_sba_irq_enable, ++ fore200e_sba_irq_check, ++ fore200e_sba_irq_ack, ++ fore200e_sba_dma_sync, ++ fore200e_sba_proc_read, ++ }, ++#endif ++ {} ++}; +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/fore200e.h Fri Jan 21 16:01:04 2000 +@@ -0,0 +1,932 @@ ++#ifndef _FORE200E_H ++#define _FORE200E_H ++ ++#ifdef __KERNEL__ ++ ++/* rx buffer sizes */ ++ ++#define SMALL_BUFFER_SIZE 384 /* size of small buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */ ++#define LARGE_BUFFER_SIZE 4032 /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */ ++ ++ ++#define RBD_BLK_SIZE 32 /* nbr of supplied rx buffers per rbd */ ++ ++ ++#define MAX_PDU_SIZE 65535 /* maximum PDU size supported by AALs */ ++ ++ ++#define BUFFER_S1_SIZE SMALL_BUFFER_SIZE /* size of small buffers, scheme 1 */ ++#define BUFFER_L1_SIZE LARGE_BUFFER_SIZE /* size of large buffers, scheme 1 */ ++ ++#define BUFFER_S2_SIZE SMALL_BUFFER_SIZE /* size of small buffers, scheme 2 */ ++#define BUFFER_L2_SIZE LARGE_BUFFER_SIZE /* size of large buffers, scheme 2 */ ++ ++#define BUFFER_S1_NBR (RBD_BLK_SIZE * 2) ++#define BUFFER_L1_NBR (RBD_BLK_SIZE * 2) ++ ++#define BUFFER_S2_NBR (RBD_BLK_SIZE * 2) ++#define BUFFER_L2_NBR (RBD_BLK_SIZE * 2) ++ ++ ++#define QUEUE_SIZE_CMD 16 /* command queue capacity */ ++#define QUEUE_SIZE_RX 64 /* receive queue capacity */ ++#define QUEUE_SIZE_TX 256 /* transmit queue capacity */ ++#define QUEUE_SIZE_BS 16 /* buffer supply queue capacity */ ++ ++#define NBR_CONNECT 1024 /* number of ATM connections */ ++ ++ ++#define TSD_FIXED 2 ++#define TSD_EXTENSION 0 ++#define TSD_NBR (TSD_FIXED + TSD_EXTENSION) ++ ++ ++/* the cp starts putting a received PDU into one *small* buffer, ++ then it uses a number of *large* buffers for the trailing data. ++ we compute here the total number of receive segment descriptors ++ required to hold the largest possible PDU */ ++ ++#define RSD_REQUIRED (((MAX_PDU_SIZE - SMALL_BUFFER_SIZE + LARGE_BUFFER_SIZE) / LARGE_BUFFER_SIZE) + 1) ++ ++#define RSD_FIXED 3 ++ ++/* RSD_REQUIRED receive segment descriptors are enough to describe a max-sized PDU, ++ but we have to keep the size of the receive PDU descriptor multiple of 32 bytes, ++ so we add one extra RSD to RSD_EXTENSION ++ (WARNING: THIS MAY CHANGE IF BUFFER SIZES ARE MODIFIED) */ ++ ++#define RSD_EXTENSION ((RSD_REQUIRED - RSD_FIXED) + 1) ++#define RSD_NBR (RSD_FIXED + RSD_EXTENSION) ++ ++ ++#define FORE200E_DEV(d) ((struct fore200e*)((d)->dev_data)) ++#define FORE200E_VCC(d) ((struct fore200e_vcc*)((d)->dev_data)) ++ ++/* bitfields endian games */ ++ ++#if defined(__LITTLE_ENDIAN_BITFIELD) ++#define BITFIELD2(b1, b2) b1; b2; ++#define BITFIELD3(b1, b2, b3) b1; b2; b3; ++#define BITFIELD4(b1, b2, b3, b4) b1; b2; b3; b4; ++#define BITFIELD5(b1, b2, b3, b4, b5) b1; b2; b3; b4; b5; ++#define BITFIELD6(b1, b2, b3, b4, b5, b6) b1; b2; b3; b4; b5; b6; ++#elif defined(__BIG_ENDIAN_BITFIELD) ++#define BITFIELD2(b1, b2) b2; b1; ++#define BITFIELD3(b1, b2, b3) b3; b2; b1; ++#define BITFIELD4(b1, b2, b3, b4) b4; b3; b2; b1; ++#define BITFIELD5(b1, b2, b3, b4, b5) b5; b4; b3; b2; b1; ++#define BITFIELD6(b1, b2, b3, b4, b5, b6) b6; b5; b4; b3; b2; b1; ++#else ++#error unknown bitfield endianess ++#endif ++ ++ ++/* ATM cell header (minus HEC byte) */ ++ ++typedef struct atm_header { ++ BITFIELD5( ++ u32 clp : 1, /* cell loss priority */ ++ u32 plt : 3, /* payload type */ ++ u32 vci : 16, /* virtual channel identifier */ ++ u32 vpi : 8, /* virtual path identifier */ ++ u32 gfc : 4 /* generic flow control */ ++ ) ++} atm_header_t; ++ ++ ++/* ATM adaptation layer id */ ++ ++typedef enum fore200e_aal { ++ FORE200E_AAL0 = 0, ++ FORE200E_AAL34 = 4, ++ FORE200E_AAL5 = 5, ++} fore200e_aal_t; ++ ++ ++/* transmit PDU descriptor specification */ ++ ++typedef struct tpd_spec { ++ BITFIELD4( ++ u32 length : 16, /* total PDU length */ ++ u32 nseg : 8, /* number of transmit segments */ ++ enum fore200e_aal aal : 4, /* adaptation layer */ ++ u32 intr : 4 /* interrupt requested */ ++ ) ++} tpd_spec_t; ++ ++ ++/* transmit PDU rate control */ ++ ++typedef struct tpd_rate ++{ ++ BITFIELD2( ++ u32 idle_cells : 16, /* number of idle cells to insert */ ++ u32 data_cells : 16 /* number of data cells to transmit */ ++ ) ++} tpd_rate_t; ++ ++ ++/* transmit segment descriptor */ ++ ++typedef struct tsd { ++ u32 buffer; /* transmit buffer DMA address */ ++ u32 length; /* number of bytes in buffer */ ++} tsd_t; ++ ++ ++/* transmit PDU descriptor */ ++ ++typedef struct tpd { ++ struct atm_header atm_header; /* ATM header minus HEC byte */ ++ struct tpd_spec spec; /* tpd specification */ ++ struct tpd_rate rate; /* tpd rate control */ ++ u32 pad; /* reserved */ ++ struct tsd tsd[ TSD_NBR ]; /* transmit segment descriptors */ ++} tpd_t; ++ ++ ++/* receive segment descriptor */ ++ ++typedef struct rsd { ++ u32 handle; /* host supplied receive buffer handle */ ++ u32 length; /* number of bytes in buffer */ ++} rsd_t; ++ ++ ++/* receive PDU descriptor */ ++ ++typedef struct rpd { ++ struct atm_header atm_header; /* ATM header minus HEC byte */ ++ u32 nseg; /* number of receive segments */ ++ struct rsd rsd[ RSD_NBR ]; /* receive segment descriptors */ ++} rpd_t; ++ ++ ++/* buffer scheme */ ++ ++typedef enum buffer_scheme { ++ BUFFER_SCHEME_ONE, ++ BUFFER_SCHEME_TWO, ++ BUFFER_SCHEME_NBR /* always last */ ++} buffer_scheme_t; ++ ++ ++/* buffer magnitude */ ++ ++typedef enum buffer_magn { ++ BUFFER_MAGN_SMALL, ++ BUFFER_MAGN_LARGE, ++ BUFFER_MAGN_NBR /* always last */ ++} buffer_magn_t; ++ ++ ++/* receive buffer descriptor */ ++ ++typedef struct rbd { ++ u32 handle; /* host supplied handle */ ++ u32 buffer_haddr; /* host DMA address of host buffer */ ++} rbd_t; ++ ++ ++/* receive buffer descriptor block */ ++ ++typedef struct rbd_block { ++ struct rbd rbd[ RBD_BLK_SIZE ]; /* receive buffer descriptor */ ++} rbd_block_t; ++ ++ ++/* tpd DMA address */ ++ ++typedef struct tpd_haddr { ++ BITFIELD3( ++ u32 size : 4, /* tpd size expressed in 32 byte blocks */ ++ u32 pad : 1, /* reserved */ ++ u32 haddr : 27 /* tpd DMA addr aligned on 32 byte boundary */ ++ ) ++} tpd_haddr_t; ++ ++ ++/* cp resident transmit queue entry */ ++ ++typedef struct cp_txq_entry { ++ struct tpd_haddr tpd_haddr; /* host DMA address of tpd */ ++ u32 status_haddr; /* host DMA address of completion status */ ++} cp_txq_entry_t; ++ ++ ++/* cp resident receive queue entry */ ++ ++typedef struct cp_rxq_entry { ++ u32 rpd_haddr; /* host DMA address of rpd */ ++ u32 status_haddr; /* host DMA address of completion status */ ++} cp_rxq_entry_t; ++ ++ ++/* cp resident buffer supply queue entry */ ++ ++typedef struct cp_bsq_entry { ++ u32 rbd_block_haddr; /* host DMA address of rbd block */ ++ u32 status_haddr; /* host DMA address of completion status */ ++} cp_bsq_entry_t; ++ ++ ++/* completion status */ ++ ++typedef volatile enum status { ++ STATUS_PENDING = (1<<0), /* initial status (written by host) */ ++ STATUS_COMPLETE = (1<<1), /* completion status (written by cp) */ ++ STATUS_FREE = (1<<2), /* initial status (written by host) */ ++ STATUS_ERROR = (1<<3) /* completion status (written by cp) */ ++} status_t; ++ ++ ++/* cp operation code */ ++ ++typedef enum opcode { ++ OPCODE_INITIALIZE = 1, /* initialize board */ ++ OPCODE_ACTIVATE_VCIN, /* activate incoming VCI */ ++ OPCODE_ACTIVATE_VCOUT, /* activate outgoing VCI */ ++ OPCODE_DEACTIVATE_VCIN, /* deactivate incoming VCI */ ++ OPCODE_DEACTIVATE_VCOUT, /* deactivate incoing VCI */ ++ OPCODE_GET_STATS, /* get board statistics */ ++ OPCODE_SET_OC3, /* set OC-3 registers */ ++ OPCODE_GET_OC3, /* get OC-3 registers */ ++ OPCODE_RESET_STATS, /* reset board statistics */ ++ OPCODE_GET_PROM, /* get expansion PROM data (PCI specific) */ ++ OPCODE_SET_VPI_BITS, /* set x bits of those decoded by the ++ firmware to be low order bits from ++ the VPI field of the ATM cell header */ ++ OPCODE_REQUEST_INTR = (1<<7) /* request interrupt */ ++} opcode_t; ++ ++ ++/* virtual path / virtual channel identifers */ ++ ++typedef struct vpvc { ++ BITFIELD3( ++ u32 vci : 16, /* virtual channel identifier */ ++ u32 vpi : 8, /* virtual path identifier */ ++ u32 pad : 8 /* reserved */ ++ ) ++} vpvc_t; ++ ++ ++/* activate VC command opcode */ ++ ++typedef struct activate_opcode { ++ BITFIELD4( ++ enum opcode opcode : 8, /* cp opcode */ ++ enum fore200e_aal aal : 8, /* adaptation layer */ ++ enum buffer_scheme scheme : 8, /* buffer scheme */ ++ u32 pad : 8 /* reserved */ ++ ) ++} activate_opcode_t; ++ ++ ++/* activate VC command block */ ++ ++typedef struct activate_block { ++ struct activate_opcode opcode; /* activate VC command opcode */ ++ struct vpvc vpvc; /* VPI/VCI */ ++ u32 mtu; /* for AAL0 only */ ++ ++} activate_block_t; ++ ++ ++/* deactivate VC command opcode */ ++ ++typedef struct deactivate_opcode { ++ BITFIELD2( ++ enum opcode opcode : 8, /* cp opcode */ ++ u32 pad : 24 /* reserved */ ++ ) ++} deactivate_opcode_t; ++ ++ ++/* deactivate VC command block */ ++ ++typedef struct deactivate_block { ++ struct deactivate_opcode opcode; /* deactivate VC command opcode */ ++ struct vpvc vpvc; /* VPI/VCI */ ++} deactivate_block_t; ++ ++ ++/* OC-3 registers */ ++ ++typedef struct oc3_regs { ++ u32 reg[ 128 ]; /* see the PMC Sierra PC5346 S/UNI-155-Lite ++ Saturn User Network Interface documentation ++ for a description of the OC-3 chip registers */ ++} oc3_regs_t; ++ ++ ++/* set/get OC-3 regs command opcode */ ++ ++typedef struct oc3_opcode { ++ BITFIELD4( ++ enum opcode opcode : 8, /* cp opcode */ ++ u32 reg : 8, /* register index */ ++ u32 value : 8, /* register value */ ++ u32 mask : 8 /* register mask that specifies which ++ bits of the register value field ++ are significant */ ++ ) ++} oc3_opcode_t; ++ ++ ++/* set/get OC-3 regs command block */ ++ ++typedef struct oc3_block { ++ struct oc3_opcode opcode; /* set/get OC-3 regs command opcode */ ++ u32 regs_haddr; /* host DMA address of OC-3 regs buffer */ ++} oc3_block_t; ++ ++ ++/* physical encoding statistics */ ++ ++typedef struct stats_phy { ++ u32 crc_header_errors; /* cells received with bad header CRC */ ++ u32 framing_errors; /* cells received with bad framing */ ++ u32 pad[ 2 ]; /* i960 padding */ ++} stats_phy_t; ++ ++ ++/* OC-3 statistics */ ++ ++typedef struct stats_oc3 { ++ u32 section_bip8_errors; /* section 8 bit interleaved parity */ ++ u32 path_bip8_errors; /* path 8 bit interleaved parity */ ++ u32 line_bip24_errors; /* line 24 bit interleaved parity */ ++ u32 line_febe_errors; /* line far end block errors */ ++ u32 path_febe_errors; /* path far end block errors */ ++ u32 corr_hcs_errors; /* correctable header check sequence */ ++ u32 ucorr_hcs_errors; /* uncorrectable header check sequence */ ++ u32 pad[ 1 ]; /* i960 padding */ ++} stats_oc3_t; ++ ++ ++/* ATM statistics */ ++ ++typedef struct stats_atm { ++ u32 cells_transmitted; /* cells transmitted */ ++ u32 cells_received; /* cells received */ ++ u32 vpi_bad_range; /* cell drops: VPI out of range */ ++ u32 vpi_no_conn; /* cell drops: no connection for VPI */ ++ u32 vci_bad_range; /* cell drops: VCI out of range */ ++ u32 vci_no_conn; /* cell drops: no connection for VCI */ ++ u32 pad[ 2 ]; /* i960 padding */ ++} stats_atm_t; ++ ++/* AAL0 statistics */ ++ ++typedef struct stats_aal0 { ++ u32 cells_transmitted; /* cells transmitted */ ++ u32 cells_received; /* cells received */ ++ u32 cells_dropped; /* cells dropped */ ++ u32 pad[ 1 ]; /* i960 padding */ ++} stats_aal0_t; ++ ++ ++/* AAL3/4 statistics */ ++ ++typedef struct stats_aal34 { ++ u32 cells_transmitted; /* cells transmitted from segmented PDUs */ ++ u32 cells_received; /* cells reassembled into PDUs */ ++ u32 cells_crc_errors; /* payload CRC error count */ ++ u32 cells_protocol_errors; /* SAR or CS layer protocol errors */ ++ u32 cells_dropped; /* cells dropped: partial reassembly */ ++ u32 cspdus_transmitted; /* CS PDUs transmitted */ ++ u32 cspdus_received; /* CS PDUs received */ ++ u32 cspdus_protocol_errors; /* CS layer protocol errors */ ++ u32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */ ++ u32 pad[ 3 ]; /* i960 padding */ ++} stats_aal34_t; ++ ++ ++/* AAL5 statistics */ ++ ++typedef struct stats_aal5 { ++ u32 cells_transmitted; /* cells transmitted from segmented SDUs */ ++ u32 cells_received; /* cells reassembled into SDUs */ ++ u32 cells_dropped; /* reassembled PDUs dropped (in cells) */ ++ u32 congestion_experienced; /* CRC error and length wrong */ ++ u32 cspdus_transmitted; /* CS PDUs transmitted */ ++ u32 cspdus_received; /* CS PDUs received */ ++ u32 cspdus_crc_errors; /* CS PDUs CRC errors */ ++ u32 cspdus_protocol_errors; /* CS layer protocol errors */ ++ u32 cspdus_dropped; /* reassembled PDUs dropped */ ++ u32 pad[ 3 ]; /* i960 padding */ ++} stats_aal5_t; ++ ++ ++/* auxiliary statistics */ ++ ++typedef struct stats_aux { ++ u32 small_b1_failed; /* receive BD allocation failures */ ++ u32 large_b1_failed; /* receive BD allocation failures */ ++ u32 small_b2_failed; /* receive BD allocation failures */ ++ u32 large_b2_failed; /* receive BD allocation failures */ ++ u32 rpd_alloc_failed; /* receive PDU allocation failures */ ++ u32 receive_carrier; /* no carrier = 0, carrier = 1 */ ++ u32 pad[ 2 ]; /* i960 padding */ ++} stats_aux_t; ++ ++ ++/* whole statistics buffer */ ++ ++typedef struct stats { ++ struct stats_phy phy; /* physical encoding statistics */ ++ struct stats_oc3 oc3; /* OC-3 statistics */ ++ struct stats_atm atm; /* ATM statistics */ ++ struct stats_aal0 aal0; /* AAL0 statistics */ ++ struct stats_aal34 aal34; /* AAL3/4 statistics */ ++ struct stats_aal5 aal5; /* AAL5 statistics */ ++ struct stats_aux aux; /* auxiliary statistics */ ++} stats_t; ++ ++ ++/* get statistics command opcode */ ++ ++typedef struct stats_opcode { ++ BITFIELD2( ++ enum opcode opcode : 8, /* cp opcode */ ++ u32 pad : 24 /* reserved */ ++ ) ++} stats_opcode_t; ++ ++ ++/* get statistics command block */ ++ ++typedef struct stats_block { ++ struct stats_opcode opcode; /* get statistics command opcode */ ++ u32 stats_haddr; /* host DMA address of stats buffer */ ++} stats_block_t; ++ ++ ++/* expansion PROM data (PCI specific) */ ++ ++typedef struct prom_data { ++ u32 hw_revision; /* hardware revision */ ++ u32 serial_number; /* board serial number */ ++ u8 mac_addr[ 8 ]; /* board MAC address */ ++} prom_data_t; ++ ++ ++/* get expansion PROM data command opcode */ ++ ++typedef struct prom_opcode { ++ BITFIELD2( ++ enum opcode opcode : 8, /* cp opcode */ ++ u32 pad : 24 /* reserved */ ++ ) ++} prom_opcode_t; ++ ++ ++/* get expansion PROM data command block */ ++ ++typedef struct prom_block { ++ struct prom_opcode opcode; /* get PROM data command opcode */ ++ u32 prom_haddr; /* host DMA address of PROM buffer */ ++} prom_block_t; ++ ++ ++/* cp command */ ++ ++typedef union cmd { ++ enum opcode opcode; /* operation code */ ++ struct activate_block activate_block; /* activate VC */ ++ struct deactivate_block deactivate_block; /* deactivate VC */ ++ struct stats_block stats_block; /* get statistics */ ++ struct prom_block prom_block; /* get expansion PROM data */ ++ struct oc3_block oc3_block; /* get/set OC-3 registers */ ++ u32 pad[ 4 ]; /* i960 padding */ ++} cmd_t; ++ ++ ++/* cp resident command queue */ ++ ++typedef struct cp_cmdq_entry { ++ union cmd cmd; /* command */ ++ u32 status_haddr; /* host DMA address of completion status */ ++ u32 pad[ 3 ]; /* i960 padding */ ++} cp_cmdq_entry_t; ++ ++ ++/* host resident transmit queue entry */ ++ ++typedef struct host_txq_entry { ++ struct cp_txq_entry* cp_entry; /* addr of cp resident tx queue entry */ ++ enum status* status; /* addr of host resident status */ ++ struct tpd* tpd; /* addr of transmit PDU descriptor */ ++ u32 tpd_dma; /* DMA address of tpd */ ++ struct sk_buff* skb; /* related skb */ ++ struct atm_vcc* vcc; /* related vcc */ ++ void* data; /* copy of misaligned data */ ++} host_txq_entry_t; ++ ++ ++/* host resident receive queue entry */ ++ ++typedef struct host_rxq_entry { ++ struct cp_rxq_entry* cp_entry; /* addr of cp resident rx queue entry */ ++ enum status* status; /* addr of host resident status */ ++ struct rpd* rpd; /* addr of receive PDU descriptor */ ++ u32 rpd_dma; /* DMA address of rpd */ ++} host_rxq_entry_t; ++ ++ ++/* host resident buffer supply queue entry */ ++ ++typedef struct host_bsq_entry { ++ struct cp_bsq_entry* cp_entry; /* addr of cp resident buffer supply queue entry */ ++ enum status* status; /* addr of host resident status */ ++ struct rbd_block* rbd_block; /* addr of receive buffer descriptor block */ ++ u32 rbd_block_dma; /* DMA address od rdb */ ++} host_bsq_entry_t; ++ ++ ++/* host resident command queue entry */ ++ ++typedef struct host_cmdq_entry { ++ struct cp_cmdq_entry* cp_entry; /* addr of cp resident cmd queue entry */ ++ enum status* status; /* addr of host resident status */ ++} host_cmdq_entry_t; ++ ++ ++/* host resident receive buffer */ ++ ++typedef struct buffer { ++ struct buffer* next; /* next receive buffer */ ++ enum buffer_scheme scheme; /* buffer scheme */ ++ enum buffer_magn magn; /* buffer magnitude */ ++ void* data_raw; /* raw buffer data */ ++ void* data_align; /* DMA aligned buffer data */ ++ u32 data_dma; /* DMA address of data */ ++} buffer_t; ++ ++ ++#if (BITS_PER_LONG == 32) ++#define FORE200E_BUF2HDL(buffer) ((u32)(buffer)) ++#define FORE200E_HDL2BUF(handle) ((struct buffer*)(handle)) ++#else /* deal with 64 bit pointers */ ++#define FORE200E_BUF2HDL(buffer) ((u32)((u64)(buffer))) ++#define FORE200E_HDL2BUF(handle) ((struct buffer*)(((u64)(handle)) | PAGE_OFFSET)) ++#endif ++ ++ ++/* host resident command queue */ ++ ++typedef struct host_cmdq { ++ struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ]; /* host resident cmd queue entries */ ++ int head; /* head of cmd queue */ ++ enum status* status_raw; /* raw array of completion status */ ++ enum status* status_align; /* DMA aligned array of completion status */ ++ ++} host_cmdq_t; ++ ++ ++/* host resident transmit queue */ ++ ++typedef struct host_txq { ++ struct host_txq_entry host_entry[ QUEUE_SIZE_TX ]; /* host resident tx queue entries */ ++ int head; /* head of tx queue */ ++ struct tpd* tpd_raw; /* raw array of tpds */ ++ struct tpd* tpd_align; /* DMA aligned array of tpds */ ++ enum status* status_raw; /* raw array of completion status */ ++ enum status* status_align; /* DMA aligned array of completion status */ ++ int txing; /* number of pending PDUs in tx queue */ ++} host_txq_t; ++ ++ ++/* host resident receive queue */ ++ ++typedef struct host_rxq { ++ struct host_rxq_entry host_entry[ QUEUE_SIZE_RX ]; /* host resident rx queue entries */ ++ int head; /* head of rx queue */ ++ struct rpd* rpd_raw; /* raw array of rpds */ ++ struct rpd* rpd_align; /* DMA aligned array of rpds */ ++ enum status* status_raw; /* raw array of completion status */ ++ enum status* status_align; /* DMA aligned array of completion status */ ++} host_rxq_t; ++ ++ ++/* host resident buffer supply queues */ ++ ++typedef struct host_bsq { ++ struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ]; /* host resident buffer supply queue entries */ ++ int head; /* head of buffer supply queue */ ++ struct rbd_block* rbd_block_raw; /* raw array of rbds */ ++ struct rbd_block* rbd_block_align; /* DMA aligned array fo rbds */ ++ enum status* status_raw; /* raw array of completion status */ ++ enum status* status_align; /* DMA aligned array of completion status */ ++ struct buffer* buffer; /* array of rx buffers */ ++ int free; /* index of first free rx buffer */ ++ volatile int count; /* count of supplied rx buffers */ ++} host_bsq_t; ++ ++ ++/* header of the firmware image */ ++ ++typedef struct fw_header { ++ u32 magic; /* magic number */ ++ u32 version; /* firware version id */ ++ u32 load_offset; /* fw load offset in board memory */ ++ u32 start_offset; /* fw execution start address in board memory */ ++} fw_header_t; ++ ++#define FW_HEADER_MAGIC 0x65726f66 /* 'fore' */ ++ ++ ++/* receive buffer supply queues scheme specification */ ++ ++typedef struct bs_spec { ++ u32 queue_length; /* queue capacity */ ++ u32 buffer_size; /* host buffer size */ ++ u32 pool_size; /* number of rbds */ ++ u32 supply_blksize; /* num of rbds in I/O block (multiple ++ of 4 between 4 and 124 inclusive) */ ++} bs_spec_t; ++ ++ ++/* initialization command block (one-time command, not in cmd queue) */ ++ ++typedef struct init_block { ++ enum opcode opcode; /* initialize command */ ++ enum status status; /* related status word */ ++ u32 receive_threshold; /* not used */ ++ u32 num_connect; /* ATM connections */ ++ u32 cmd_queue_len; /* length of command queue */ ++ u32 tx_queue_len; /* length of transmit queue */ ++ u32 rx_queue_len; /* length of receive queue */ ++ u32 rsd_extension; /* number of extra 32 byte blocks */ ++ u32 tsd_extension; /* number of extra 32 byte blocks */ ++ u32 conless_vpvc; /* not used */ ++ u32 pad[ 2 ]; /* force quad alignment */ ++ struct bs_spec bs_spec[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ]; /* buffer supply queues spec */ ++} init_block_t; ++ ++ ++typedef enum media_type { ++ MEDIA_TYPE_CAT5_UTP = 0x06, /* unshielded twisted pair */ ++ MEDIA_TYPE_MM_OC3_ST = 0x16, /* multimode fiber ST */ ++ MEDIA_TYPE_MM_OC3_SC = 0x26, /* multimode fiber SC */ ++ MEDIA_TYPE_SM_OC3_ST = 0x36, /* single-mode fiber ST */ ++ MEDIA_TYPE_SM_OC3_SC = 0x46 /* single-mode fiber SC */ ++} media_type_t; ++ ++#define FORE200E_MEDIA_INDEX(media_type) ((media_type)>>4) ++ ++ ++/* cp resident queues */ ++ ++typedef struct cp_queues { ++ u32 cp_cmdq; /* command queue */ ++ u32 cp_txq; /* transmit queue */ ++ u32 cp_rxq; /* receive queue */ ++ u32 cp_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ]; /* buffer supply queues */ ++ u32 imask; /* 1 enables cp to host interrupts */ ++ u32 istat; /* 1 for interrupt posted */ ++ u32 heap_base; /* offset form beginning of ram */ ++ u32 heap_size; /* space available for queues */ ++ u32 hlogger; /* non zero for host logging */ ++ u32 heartbeat; /* cp heartbeat */ ++ u32 fw_release; /* firmware version */ ++ u32 mon960_release; /* i960 monitor version */ ++ u32 tq_plen; /* transmit throughput measurements */ ++ /* make sure the init block remains on a quad word boundary */ ++ struct init_block init; /* one time cmd, not in cmd queue */ ++ enum media_type media_type; /* media type id */ ++ u32 oc3_revision; /* OC-3 revision number */ ++} cp_queues_t; ++ ++ ++/* boot status */ ++ ++typedef enum boot_status { ++ BSTAT_COLD_START = (u32) 0xc01dc01d, /* cold start */ ++ BSTAT_SELFTEST_OK = (u32) 0x02201958, /* self-test ok */ ++ BSTAT_SELFTEST_FAIL = (u32) 0xadbadbad, /* self-test failed */ ++ BSTAT_CP_RUNNING = (u32) 0xce11feed, /* cp is running */ ++ BSTAT_MON_TOO_BIG = (u32) 0x10aded00 /* i960 monitor is too big */ ++} boot_status_t; ++ ++ ++/* software UART */ ++ ++typedef struct soft_uart { ++ u32 send; /* write register */ ++ u32 recv; /* read register */ ++} soft_uart_t; ++ ++#define FORE200E_CP_MONITOR_UART_FREE 0x00000000 ++#define FORE200E_CP_MONITOR_UART_AVAIL 0x01000000 ++ ++ ++/* i960 monitor */ ++ ++typedef struct cp_monitor { ++ struct soft_uart soft_uart; /* software UART */ ++ enum boot_status bstat; /* boot status */ ++ u32 app_base; /* application base offset */ ++ u32 mon_version; /* i960 monitor version */ ++} cp_monitor_t; ++ ++ ++/* device state */ ++ ++typedef enum fore200e_state { ++ FORE200E_STATE_BLANK, /* initial state */ ++ FORE200E_STATE_REGISTER, /* device registered */ ++ FORE200E_STATE_CONFIGURE, /* bus interface configured */ ++ FORE200E_STATE_MAP, /* board space mapped in host memory */ ++ FORE200E_STATE_RESET, /* board resetted */ ++ FORE200E_STATE_LOAD_FW, /* firmware loaded */ ++ FORE200E_STATE_START_FW, /* firmware started */ ++ FORE200E_STATE_INITIALIZE, /* initialize command successful */ ++ FORE200E_STATE_INIT_CMDQ, /* command queue initialized */ ++ FORE200E_STATE_INIT_TXQ, /* transmit queue initialized */ ++ FORE200E_STATE_INIT_RXQ, /* receive queue initialized */ ++ FORE200E_STATE_INIT_BSQ, /* buffer supply queue initialized */ ++ FORE200E_STATE_ALLOC_BUF, /* receive buffers allocated */ ++ FORE200E_STATE_IRQ, /* host interrupt requested */ ++ FORE200E_STATE_COMPLETE /* initialization completed */ ++} fore200e_state; ++ ++ ++/* PCA-200E registers */ ++ ++typedef struct fore200e_pca_regs { ++ volatile u32* hcr; /* address of host control register */ ++ volatile u32* imr; /* address of host interrupt mask register */ ++ volatile u32* psr; /* address of PCI specific register */ ++} fore200e_pca_regs_t; ++ ++ ++/* SBA-200E registers */ ++ ++typedef struct fore200e_sba_regs { ++ volatile u32* hcr; /* address of host control register */ ++ volatile u32* bsr; /* address of burst transfer size register */ ++ volatile u32* isr; /* address of interrupt level selection register */ ++} fore200e_sba_regs_t; ++ ++ ++/* model-specific registers */ ++ ++typedef union fore200e_regs { ++ struct fore200e_pca_regs pca; /* PCA-200E registers */ ++ struct fore200e_sba_regs sba; /* SBA-200E registers */ ++} fore200e_regs; ++ ++ ++struct fore200e; ++ ++/* bus-dependent data */ ++ ++typedef struct fore200e_bus { ++ char* model_name; /* board model name */ ++ char* proc_name; /* board name under /proc/atm */ ++ int descr_alignment; /* tpd/rpd/rbd DMA alignment requirement */ ++ int buffer_alignment; /* rx buffers DMA alignment requirement */ ++ int status_alignment; /* status words DMA alignment requirement */ ++ const unsigned char* fw_data; /* address of firmware data start */ ++ const unsigned int* fw_size; /* address of firmware data size */ ++ u32 (*read)(volatile u32*); ++ void (*write)(u32, volatile u32*); ++ u32 (*virt_to_dma)(void*); ++ int (*dma_alloc)(void**, void**, u32*, int, int, int); ++ void (*dma_free)(void**); ++ struct fore200e* (*detect)(const struct fore200e_bus*, int); ++ int (*configure)(struct fore200e*); ++ int (*map)(struct fore200e*); ++ void (*reset)(struct fore200e*); ++ int (*prom_read)(struct fore200e*, struct prom_data*); ++ void (*unmap)(struct fore200e*); ++ void (*irq_enable)(struct fore200e*); ++ int (*irq_check)(struct fore200e*); ++ void (*irq_ack)(struct fore200e*); ++ void (*dma_sync)(struct fore200e*, u32, int); ++ int (*proc_read)(struct fore200e*, char*); ++} fore200e_bus_t; ++ ++ ++/* per-device data */ ++ ++typedef struct fore200e { ++ struct fore200e* next; /* next device */ ++ const struct fore200e_bus* bus; /* bus-dependent code and data */ ++ union fore200e_regs regs; /* bus-dependent registers */ ++ struct atm_dev* atm_dev; /* ATM device */ ++ ++ enum fore200e_state state; /* device state */ ++ ++ char name[16]; /* device name */ ++ void* bus_dev; /* bus-specific kernel data */ ++ int irq; /* irq number */ ++ unsigned long phys_base; /* physical base address */ ++ void* virt_base; /* virtual base address */ ++ ++ unsigned char esi[ ESI_LEN ]; /* end system identifier */ ++ ++ struct cp_monitor* cp_monitor; /* i960 monitor address */ ++ struct cp_queues* cp_queues; /* cp resident queues */ ++ struct host_cmdq host_cmdq; /* host resident cmd queue */ ++ struct host_txq host_txq; /* host resident tx queue */ ++ struct host_rxq host_rxq; /* host resident rx queue */ ++ /* host resident buffer supply queues */ ++ struct host_bsq host_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ]; ++ ++ u32 available_cell_rate; /* remaining pseudo-CBR bw on link */ ++ ++ int loop_mode; /* S/UNI loopback mode */ ++ ++ struct stats* stats; /* last snapshot of the stats */ ++ ++ struct semaphore rate_sf; /* protects rate reservation ops */ ++ spinlock_t tx_lock; /* protects tx ops */ ++ ++} fore200e_t; ++ ++ ++/* per-vcc data */ ++ ++typedef struct fore200e_vcc { ++ enum buffer_scheme scheme; /* rx buffer scheme */ ++ struct tpd_rate rate; /* tx rate control data */ ++ int rx_min_pdu; /* size of smallest PDU received */ ++ int rx_max_pdu; /* size of largest PDU received */ ++ int tx_min_pdu; /* size of smallest PDU transmitted */ ++ int tx_max_pdu; /* size of largest PDU transmitted */ ++} fore200e_vcc_t; ++ ++ ++ ++/* 200E-series common memory layout */ ++ ++#define FORE200E_CP_MONITOR_OFFSET 0x00000400 /* i960 monitor interface */ ++#define FORE200E_CP_QUEUES_OFFSET 0x00004d40 /* cp resident queues */ ++ ++ ++/* PCA-200E memory layout */ ++ ++#define PCA200E_IOSPACE_LENGTH 0x00200000 ++ ++#define PCA200E_HCR_OFFSET 0x00100000 /* board control register */ ++#define PCA200E_IMR_OFFSET 0x00100004 /* host IRQ mask register */ ++#define PCA200E_PSR_OFFSET 0x00100008 /* PCI specific register */ ++ ++ ++/* PCA-200E host control register */ ++ ++#define PCA200E_HCR_RESET (1<<0) /* read / write */ ++#define PCA200E_HCR_HOLD_LOCK (1<<1) /* read / write */ ++#define PCA200E_HCR_I960FAIL (1<<2) /* read */ ++#define PCA200E_HCR_INTRB (1<<2) /* write */ ++#define PCA200E_HCR_HOLD_ACK (1<<3) /* read */ ++#define PCA200E_HCR_INTRA (1<<3) /* write */ ++#define PCA200E_HCR_OUTFULL (1<<4) /* read */ ++#define PCA200E_HCR_CLRINTR (1<<4) /* write */ ++#define PCA200E_HCR_ESPHOLD (1<<5) /* read */ ++#define PCA200E_HCR_INFULL (1<<6) /* read */ ++#define PCA200E_HCR_TESTMODE (1<<7) /* read */ ++ ++ ++/* PCA-200E PCI bus interface regs (offsets in PCI config space) */ ++ ++#define PCA200E_PCI_LATENCY 0x40 /* maximum slave latenty */ ++#define PCA200E_PCI_MASTER_CTRL 0x41 /* master control */ ++#define PCA200E_PCI_THRESHOLD 0x42 /* burst / continous req threshold */ ++ ++/* PBI master control register */ ++ ++#define PCA200E_CTRL_DIS_CACHE_RD (1<<0) /* disable cache-line reads */ ++#define PCA200E_CTRL_DIS_WRT_INVAL (1<<1) /* disable writes and invalidates */ ++#define PCA200E_CTRL_2_CACHE_WRT_INVAL (1<<2) /* require 2 cache-lines for writes and invalidates */ ++#define PCA200E_CTRL_IGN_LAT_TIMER (1<<3) /* ignore the latency timer */ ++#define PCA200E_CTRL_ENA_CONT_REQ_MODE (1<<4) /* enable continuous request mode */ ++#define PCA200E_CTRL_LARGE_PCI_BURSTS (1<<5) /* force large PCI bus bursts */ ++#define PCA200E_CTRL_CONVERT_ENDIAN (1<<6) /* convert endianess of slave RAM accesses */ ++ ++ ++ ++#define SBA200E_PROM_NAME "FORE,sba-200e" /* device name in openprom tree */ ++ ++/* SBA-200E host control register */ ++ ++#define SBA200E_HCR_RESET (1<<0) /* read / write (sticky) */ ++#define SBA200E_HCR_HOLD_LOCK (1<<1) /* read / write (sticky) */ ++#define SBA200E_HCR_I960FAIL (1<<2) /* read */ ++#define SBA200E_HCR_I960SETINTR (1<<2) /* write */ ++#define SBA200E_HCR_OUTFULL (1<<3) /* read */ ++#define SBA200E_HCR_INTR_CLR (1<<3) /* write */ ++#define SBA200E_HCR_INTR_ENA (1<<4) /* read / write (sticky) */ ++#define SBA200E_HCR_ESPHOLD (1<<5) /* read */ ++#define SBA200E_HCR_INFULL (1<<6) /* read */ ++#define SBA200E_HCR_TESTMODE (1<<7) /* read */ ++#define SBA200E_HCR_INTR_REQ (1<<8) /* read */ ++ ++#define SBA200E_HCR_STICKY (SBA200E_HCR_RESET | SBA200E_HCR_HOLD_LOCK | SBA200E_HCR_INTR_ENA) ++ ++ ++#endif /* __KERNEL__ */ ++#endif /* _FORE200E_H */ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/fore200e_mkfirm.c Fri Jan 21 16:01:04 2000 +@@ -0,0 +1,155 @@ ++/* ++ $Id: $ ++ ++ mkfirm.c: generates a C readable file from a binary firmware image ++ ++ Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999. ++ ++ This software may be used and distributed according to the terms ++ of the GNU General Public License, incorporated herein by reference. ++*/ ++ ++#include ++#include ++#include ++ ++char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */ ++char* default_infname = ""; ++char* default_outfname = ""; ++ ++char* progname; ++int verbose = 0; ++int inkernel = 0; ++ ++ ++void usage(void) ++{ ++ fprintf(stderr, ++ "%s: [-v] [-k] [-b basename ] [-i firmware.bin] [-o firmware.c]\n", ++ progname); ++ exit(-1); ++} ++ ++ ++int main(int argc, char** argv) ++{ ++ time_t now; ++ char* infname = NULL; ++ char* outfname = NULL; ++ char* basename = NULL; ++ FILE* infile; ++ FILE* outfile; ++ unsigned firmsize; ++ int c; ++ ++ progname = *(argv++); ++ ++ while (argc > 1) { ++ if ((*argv)[0] == '-') { ++ switch ((*argv)[1]) { ++ case 'i': ++ if (argc-- < 3) ++ usage(); ++ infname = *(++argv); ++ break; ++ case 'o': ++ if (argc-- < 3) ++ usage(); ++ outfname = *(++argv); ++ break; ++ case 'b': ++ if (argc-- < 3) ++ usage(); ++ basename = *(++argv); ++ break; ++ case 'v': ++ verbose = 1; ++ break; ++ case 'k': ++ inkernel = 1; ++ break; ++ default: ++ usage(); ++ } ++ } ++ else { ++ usage(); ++ } ++ argc--; ++ argv++; ++ } ++ ++ if (infname != NULL) { ++ infile = fopen(infname, "r"); ++ if (infile == NULL) { ++ fprintf(stderr, "%s: can't open %s for reading\n", ++ progname, infname); ++ exit(-2); ++ } ++ } ++ else { ++ infile = stdin; ++ infname = default_infname; ++ } ++ ++ if (outfname) { ++ outfile = fopen(outfname, "w"); ++ if (outfile == NULL) { ++ fprintf(stderr, "%s: can't open %s for writing\n", ++ progname, outfname); ++ exit(-3); ++ } ++ } ++ else { ++ outfile = stdout; ++ outfname = default_outfname; ++ } ++ ++ if (basename == NULL) ++ basename = default_basename; ++ ++ if (verbose) { ++ fprintf(stderr, "%s: input file = %s\n", progname, infname ); ++ fprintf(stderr, "%s: output file = %s\n", progname, outfname ); ++ fprintf(stderr, "%s: firmware basename = %s\n", progname, basename ); ++ } ++ ++ time(&now); ++ fprintf(outfile, "/*\n generated by %s from %s on %s" ++ " DO NOT EDIT!\n*/\n\n", ++ progname, infname, ctime(&now)); ++ ++ if (inkernel) ++ fprintf(outfile, "#include \n\n" ); ++ ++ /* XXX force 32 bit alignment? */ ++ fprintf(outfile, "const unsigned char%s %s_data[] = {\n", ++ inkernel ? " __initdata" : "", basename ); ++ ++ c = getc(infile); ++ fprintf(outfile,"\t0x%02x", c); ++ firmsize = 1; ++ ++ while ((c = getc(infile)) >= 0) { ++ ++ if (firmsize++ % 8) ++ fprintf(outfile,", 0x%02x", c); ++ else ++ fprintf(outfile,",\n\t0x%02x", c); ++ } ++ ++ fprintf(outfile, "\n};\n\n"); ++ ++ fprintf(outfile, "const unsigned int%s %s_size = %u;\n", ++ inkernel ? " __initdata" : "", basename, firmsize ); ++ ++ if (infile != stdin) ++ fclose(infile); ++ if (outfile != stdout) ++ fclose(outfile); ++ ++ if(verbose) ++ fprintf(stderr, "%s: firmware size = %u\n", progname, firmsize); ++ ++ exit(0); ++} +--- ref/drivers/atm/horizon.c Wed Sep 8 20:14:31 1999 ++++ work/drivers/atm/horizon.c Fri Jan 21 16:01:04 2000 +@@ -2623,12 +2623,10 @@ + switch (level) { + case SOL_SOCKET: + switch (optname) { +- case SO_BCTXOPT: +- // return the right thing +- break; +- case SO_BCRXOPT: +- // return the right thing +- break; ++// case SO_BCTXOPT: ++// break; ++// case SO_BCRXOPT: ++// break; + default: + return -ENOPROTOOPT; + break; +@@ -2645,12 +2643,10 @@ + switch (level) { + case SOL_SOCKET: + switch (optname) { +- case SO_BCTXOPT: +- // not settable +- break; +- case SO_BCRXOPT: +- // not settable +- break; ++// case SO_BCTXOPT: ++// break; ++// case SO_BCRXOPT: ++// break; + default: + return -ENOPROTOOPT; + break; +@@ -2743,21 +2739,11 @@ + } + + static const struct atmdev_ops hrz_ops = { +- NULL, // no hrz_dev_close +- hrz_open, +- hrz_close, +- NULL, // no hrz_ioctl +- NULL, // hrz_getsockopt, +- NULL, // hrz_setsockopt, +- hrz_send, +- hrz_sg_send, +- NULL, // no send_oam - not in fact used yet +- NULL, // no hrz_phy_put - not needed in this driver +- NULL, // no hrz_phy_get - not needed in this driver +- NULL, // no feedback - feedback to the driver! +- NULL, // no hrz_change_qos +- NULL, // no free_rx_skb +- hrz_proc_read ++ open: hrz_open, ++ close: hrz_close, ++ send: hrz_send, ++ sg_send: hrz_sg_send, ++ proc_read: hrz_proc_read + }; + + static int __init hrz_probe (void) { +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/idt77105.c Fri Jan 21 16:01:04 2000 +@@ -0,0 +1,385 @@ ++/* drivers/atm/idt77105.c - IDT77105 (PHY) driver */ ++ ++/* Written 1999 by Greg Banks, NEC Australia . Based on suni.c */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "idt77105.h" ++ ++#undef GENERAL_DEBUG ++ ++#ifdef GENERAL_DEBUG ++#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) ++#else ++#define DPRINTK(format,args...) ++#endif ++ ++ ++struct idt77105_priv { ++ struct idt77105_stats stats; /* link diagnostics */ ++ struct atm_dev *dev; /* device back-pointer */ ++ struct idt77105_priv *next; ++ int loop_mode; ++ unsigned char old_mcr; /* storage of MCR reg while signal lost */ ++}; ++ ++ ++#define PRIV(dev) ((struct idt77105_priv *) dev->phy_data) ++ ++#define PUT(val,reg) dev->ops->phy_put(dev,val,IDT77105_##reg) ++#define GET(reg) dev->ops->phy_get(dev,IDT77105_##reg) ++ ++static void idt77105_stats_timer_func(unsigned long); ++static void idt77105_restart_timer_func(unsigned long); ++ ++ ++static struct timer_list stats_timer = { NULL, NULL, 0L, 0L, ++ &idt77105_stats_timer_func }; +static struct timer_list restart_timer = { NULL, NULL, 0L, 0L, + &idt77105_restart_timer_func }; +static int start_timer = 1; @@ -694,7 +5704,7 @@ + return put_user(PRIV(dev)->loop_mode,(int *) arg) ? + -EFAULT : sizeof(int); + default: -+ return -EINVAL; ++ return -ENOIOCTLCMD; + } +} + @@ -809,183 +5819,4969 @@ + restart_timer.function = idt77105_restart_timer_func; + add_timer(&restart_timer); + } -+ return 0; ++ return 0; ++} ++ ++ ++static const struct atmphy_ops idt77105_ops = { ++ idt77105_start, ++ idt77105_ioctl, ++ idt77105_int ++}; ++ ++ ++int __init idt77105_init(struct atm_dev *dev) ++{ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif /* MODULE */ ++ ++ dev->phy = &idt77105_ops; ++ return 0; ++} ++ ++ ++/* ++ * TODO: this function should be called through phy_ops ++ * but that will not be possible for some time as there is ++ * currently a freeze on modifying that structure ++ * -- Greg Banks, 13 Sep 1999 ++ */ ++int idt77105_stop(struct atm_dev *dev) ++{ ++ struct idt77105_priv *walk, *prev; ++ ++ DPRINTK("%s(itf %d): stopping IDT77105\n",dev->type,dev->number); ++ ++ /* disable interrupts */ ++ PUT( GET(MCR) & ~IDT77105_MCR_EIP, MCR ); ++ ++ /* detach private struct from atm_dev & free */ ++ for (prev = NULL, walk = idt77105_all ; ++ walk != NULL; ++ prev = walk, walk = walk->next) { ++ if (walk->dev == dev) { ++ if (prev != NULL) ++ prev->next = walk->next; ++ else ++ idt77105_all = walk->next; ++ dev->phy = NULL; ++ PRIV(dev) = NULL; ++ kfree(walk); ++ break; ++ } ++ } ++ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif /* MODULE */ ++ return 0; ++} ++ ++ ++ ++EXPORT_SYMBOL(idt77105_init); ++EXPORT_SYMBOL(idt77105_stop); ++ ++#ifdef MODULE ++ ++int init_module(void) ++{ ++ return 0; ++} ++ ++ ++void cleanup_module(void) ++{ ++ /* turn off timers */ ++ del_timer(&stats_timer); ++ del_timer(&restart_timer); ++} ++ ++#endif +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/idt77105.h Fri Jan 21 16:47:47 2000 +@@ -0,0 +1,92 @@ ++/* drivers/atm/idt77105.h - IDT77105 (PHY) declarations */ ++ ++/* Written 1999 by Greg Banks, NEC Australia . Based on suni.h */ ++ ++ ++#ifndef DRIVER_ATM_IDT77105_H ++#define DRIVER_ATM_IDT77105_H ++ ++#include ++#include ++ ++ ++/* IDT77105 registers */ ++ ++#define IDT77105_MCR 0x0 /* Master Control Register */ ++#define IDT77105_ISTAT 0x1 /* Interrupt Status */ ++#define IDT77105_DIAG 0x2 /* Diagnostic Control */ ++#define IDT77105_LEDHEC 0x3 /* LED Driver & HEC Status/Control */ ++#define IDT77105_CTRLO 0x4 /* Low Byte Counter Register */ ++#define IDT77105_CTRHI 0x5 /* High Byte Counter Register */ ++#define IDT77105_CTRSEL 0x6 /* Counter Register Read Select */ ++ ++/* IDT77105 register values */ ++ ++/* MCR */ ++#define IDT77105_MCR_UPLO 0x80 /* R/W, User Prog'le Output Latch */ ++#define IDT77105_MCR_DREC 0x40 /* R/W, Discard Receive Error Cells */ ++#define IDT77105_MCR_ECEIO 0x20 /* R/W, Enable Cell Error Interrupts ++ * Only */ ++#define IDT77105_MCR_TDPC 0x10 /* R/W, Transmit Data Parity Check */ ++#define IDT77105_MCR_DRIC 0x08 /* R/W, Discard Received Idle Cells */ ++#define IDT77105_MCR_HALTTX 0x04 /* R/W, Halt Tx */ ++#define IDT77105_MCR_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */ ++#define IDT77105_MCR_EIP 0x01 /* R/W, Enable Interrupt Pin */ ++ ++/* ISTAT */ ++#define IDT77105_ISTAT_GOODSIG 0x40 /* R, Good Signal Bit */ ++#define IDT77105_ISTAT_HECERR 0x20 /* sticky, HEC Error*/ ++#define IDT77105_ISTAT_SCR 0x10 /* sticky, Short Cell Received */ ++#define IDT77105_ISTAT_TPE 0x08 /* sticky, Transmit Parity Error */ ++#define IDT77105_ISTAT_RSCC 0x04 /* sticky, Rx Signal Condition Change */ ++#define IDT77105_ISTAT_RSE 0x02 /* sticky, Rx Symbol Error */ ++#define IDT77105_ISTAT_RFO 0x01 /* sticky, Rx FIFO Overrun */ ++ ++/* DIAG */ ++#define IDT77105_DIAG_FTD 0x80 /* R/W, Force TxClav deassert */ ++#define IDT77105_DIAG_ROS 0x40 /* R/W, RxClav operation select */ ++#define IDT77105_DIAG_MPCS 0x20 /* R/W, Multi-PHY config'n select */ ++#define IDT77105_DIAG_RFLUSH 0x10 /* R/W, clear receive FIFO */ ++#define IDT77105_DIAG_ITPE 0x08 /* R/W, Insert Tx payload error */ ++#define IDT77105_DIAG_ITHE 0x04 /* R/W, Insert Tx HEC error */ ++#define IDT77105_DIAG_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */ ++#define IDT77105_DIAG_LCMASK 0x03 /* R/W, Loopback Control */ ++ ++#define IDT77105_DIAG_LC_NORMAL 0x00 /* Receive from network */ ++#define IDT77105_DIAG_LC_PHY_LOOPBACK 0x02 ++#define IDT77105_DIAG_LC_LINE_LOOPBACK 0x03 ++ ++/* LEDHEC */ ++#define IDT77105_LEDHEC_DRHC 0x40 /* R/W, Disable Rx HEC check */ ++#define IDT77105_LEDHEC_DTHC 0x20 /* R/W, Disable Tx HEC calculation */ ++#define IDT77105_LEDHEC_RPWMASK 0x18 /* R/W, RxRef pulse width select */ ++#define IDT77105_LEDHEC_TFS 0x04 /* R, Tx FIFO Status (1=empty) */ ++#define IDT77105_LEDHEC_TLS 0x02 /* R, Tx LED Status (1=lit) */ ++#define IDT77105_LEDHEC_RLS 0x01 /* R, Rx LED Status (1=lit) */ ++ ++#define IDT77105_LEDHEC_RPW_1 0x00 /* RxRef active for 1 RxClk cycle */ ++#define IDT77105_LEDHEC_RPW_2 0x08 /* RxRef active for 2 RxClk cycle */ ++#define IDT77105_LEDHEC_RPW_4 0x10 /* RxRef active for 4 RxClk cycle */ ++#define IDT77105_LEDHEC_RPW_8 0x18 /* RxRef active for 8 RxClk cycle */ ++ ++/* CTRSEL */ ++#define IDT77105_CTRSEL_SEC 0x08 /* W, Symbol Error Counter */ ++#define IDT77105_CTRSEL_TCC 0x04 /* W, Tx Cell Counter */ ++#define IDT77105_CTRSEL_RCC 0x02 /* W, Rx Cell Counter */ ++#define IDT77105_CTRSEL_RHEC 0x01 /* W, Rx HEC Error Counter */ ++ ++#ifdef __KERNEL__ ++int idt77105_init(struct atm_dev *dev) __init; ++int idt77105_stop(struct atm_dev *dev); ++#endif ++ ++/* ++ * Tunable parameters ++ */ ++ ++/* Time between samples of the hardware cell counters. Should be <= 1 sec */ ++#define IDT77105_STATS_TIMER_PERIOD (HZ) ++/* Time between checks to see if the signal has been found again */ ++#define IDT77105_RESTART_TIMER_PERIOD (5 * HZ) ++ ++#endif +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/iphase.c Fri Jan 21 16:01:05 2000 +@@ -0,0 +1,3315 @@ ++/****************************************************************************** ++ iphase.c: Device driver for Interphase ATM PCI adapter cards ++ Author: Peter Wang ++ Interphase Corporation ++ Version: 1.0 ++******************************************************************************* ++ ++ This software may be used and distributed according to the terms ++ of the GNU Public License (GPL), incorporated herein by reference. ++ Drivers based on this skeleton fall under the GPL and must retain ++ the authorship (implicit copyright) notice. ++ ++ 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. ++ ++ Modified from an incomplete driver for Interphase 5575 1KVC 1M card which ++ was originally written by Monalisa Agrawal at UNH. Now this driver ++ supports a variety of varients of Interphase ATM PCI (i)Chip adapter ++ card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) ++ in terms of PHY type, the size of control memory and the size of ++ packet memory. The followings are the change log and history: ++ ++ Bugfix the Mona's UBR driver. ++ Modify the basic memory allocation and dma logic. ++ Port the driver to the latest kernel from 2.0.46. ++ Complete the ABR logic of the driver, and added the ABR work- ++ around for the hardware anormalies. ++ Add the CBR support. ++ Add the flow control logic to the driver to allow rate-limit VC. ++ Add 4K VC support to the board with 512K control memory. ++ Add the support of all the variants of the Interphase ATM PCI ++ (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525 ++ (25M UTP25) and x531 (DS3 and E3). ++ Add SMP support. ++ ++ Support and updates available at: ftp://ftp.iphase.com/pub/atm ++ ++*******************************************************************************/ ++ ++#ifdef IA_MODULE ++#define MODULE ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for xtime */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iphase.h" ++#include "suni.h" ++#define swap(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) ++struct suni_priv { ++ struct sonet_stats sonet_stats; /* link diagnostics */ ++ unsigned char loop_mode; /* loopback mode */ ++ struct atm_dev *dev; /* device back-pointer */ ++ struct suni_priv *next; /* next SUNI */ ++}; ++#define PRIV(dev) ((struct suni_priv *) dev->phy_data) ++ ++static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr); ++ ++static IADEV *ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; ++static struct atm_dev *_ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; ++static int iadev_count = 0; ++static struct timer_list ia_timer; ++struct atm_vcc *vcc_close_que[100]; ++static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ; ++static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ; ++static u32 IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER ++ |IF_IADBG_ABR | IF_IADBG_EVENT*/ 0; ++ ++#ifdef MODULE ++MODULE_PARM(IA_TX_BUF, "i"); ++MODULE_PARM(IA_TX_BUF_SZ, "i"); ++MODULE_PARM(IA_RX_BUF, "i"); ++MODULE_PARM(IA_RX_BUF_SZ, "i"); ++MODULE_PARM(IADebugFlag, "i"); ++#endif ++ ++/**************************** IA_LIB **********************************/ ++ ++static void ia_init_rtn_q (IARTN_Q *que) ++{ ++ que->next = NULL; ++ que->tail = NULL; ++} ++ ++static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data) ++{ ++ data->next = NULL; ++ if (que->next == NULL) ++ que->next = que->tail = data; ++ else { ++ data->next = que->next; ++ que->next = data; ++ } ++ return; ++} ++ ++static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) { ++ IARTN_Q *entry; ++ entry = (IARTN_Q *)kmalloc(sizeof(IARTN_Q), GFP_KERNEL); ++ if (!entry) return -1; ++ entry->data = data; ++ entry->next = NULL; ++ if (que->next == NULL) ++ que->next = que->tail = entry; ++ else { ++ que->tail->next = entry; ++ que->tail = que->tail->next; ++ } ++ return 1; ++} ++ ++static IARTN_Q * ia_deque_rtn_q (IARTN_Q *que) { ++ IARTN_Q *tmpdata; ++ if (que->next == NULL) ++ return NULL; ++ tmpdata = que->next; ++ if ( que->next == que->tail) ++ que->next = que->tail = NULL; ++ else ++ que->next = que->next->next; ++ return tmpdata; ++} ++ ++static void ia_hack_tcq(IADEV *dev) { ++ ++ u_short desc1; ++ u_short tcq_wr; ++ struct ia_vcc *iavcc_r = NULL; ++ extern void desc_dbg(IADEV *iadev); ++ ++ tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff; ++ while (dev->host_tcq_wr != tcq_wr) { ++ desc1 = *(u_short *)(dev->seg_ram + dev->host_tcq_wr); ++ if (!desc1) ; ++ else if (!dev->desc_tbl[desc1 -1].timestamp) { ++ IF_ABR(printk(" Desc %d is reset at %ld\n", desc1 -1, jiffies);) ++ *(u_short *) (dev->seg_ram + dev->host_tcq_wr) = 0; ++ } ++ else if (dev->desc_tbl[desc1 -1].timestamp) { ++ if (!(iavcc_r = dev->desc_tbl[desc1 -1].iavcc)) { ++ printk("IA: Fatal err in get_desc\n"); ++ continue; ++ } ++ iavcc_r->vc_desc_cnt--; ++ dev->desc_tbl[desc1 -1].timestamp = 0; ++ IF_EVENT(printk("ia_hack: return_q skb = 0x%x desc = %d\n", ++ (u32)dev->desc_tbl[desc1 -1].txskb, desc1);) ++ if (iavcc_r->pcr < dev->rate_limit) { ++ IA_SKB_STATE (dev->desc_tbl[desc1-1].txskb) |= IA_TX_DONE; ++ if (ia_enque_rtn_q(&dev->tx_return_q, dev->desc_tbl[desc1 -1]) < 0) ++ printk("ia_hack_tcq: No memory available\n"); ++ } ++ dev->desc_tbl[desc1 -1].iavcc = NULL; ++ dev->desc_tbl[desc1 -1].txskb = NULL; ++ } ++ dev->host_tcq_wr += 2; ++ if (dev->host_tcq_wr > dev->ffL.tcq_ed) ++ dev->host_tcq_wr = dev->ffL.tcq_st; ++ } ++} /* ia_hack_tcq */ ++ ++static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) { ++ u_short desc_num, i; ++ struct sk_buff *skb; ++ struct ia_vcc *iavcc_r = NULL; ++ unsigned long delta; ++ static unsigned long timer = 0; ++ int ltimeout; ++ extern void desc_dbg(IADEV *iadev); ++ ++ ia_hack_tcq (dev); ++ if(((jiffies - timer)>50)||((dev->ffL.tcq_rd==dev->host_tcq_wr))){ ++ timer = jiffies; ++ i=0; ++ while (i < dev->num_tx_desc) { ++ if (!dev->desc_tbl[i].timestamp) { ++ i++; ++ continue; ++ } ++ ltimeout = dev->desc_tbl[i].iavcc->ltimeout; ++ delta = jiffies - dev->desc_tbl[i].timestamp; ++ if (delta >= ltimeout) { ++ IF_ABR(printk("RECOVER run!! desc_tbl %d = %d delta = %ld, ++ time = %ld\n", i,dev->desc_tbl[i].timestamp, delta, jiffies);) ++ if (dev->ffL.tcq_rd == dev->ffL.tcq_st) ++ dev->ffL.tcq_rd = dev->ffL.tcq_ed; ++ else ++ dev->ffL.tcq_rd -= 2; ++ *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1; ++ if (!(skb = dev->desc_tbl[i].txskb) || ++ !(iavcc_r = dev->desc_tbl[i].iavcc)) ++ printk("Fatal err, desc table vcc or skb is NULL\n"); ++ else ++ iavcc_r->vc_desc_cnt--; ++ dev->desc_tbl[i].timestamp = 0; ++ dev->desc_tbl[i].iavcc = NULL; ++ dev->desc_tbl[i].txskb = NULL; ++ } ++ i++; ++ } /* while */ ++ } ++ if (dev->ffL.tcq_rd == dev->host_tcq_wr) ++ return 0xFFFF; ++ ++ /* Get the next available descriptor number from TCQ */ ++ desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd); ++ ++ while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) { ++ dev->ffL.tcq_rd += 2; ++ if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) ++ dev->ffL.tcq_rd = dev->ffL.tcq_st; ++ if (dev->ffL.tcq_rd == dev->host_tcq_wr) ++ return 0xFFFF; ++ desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd); ++ } ++ ++ /* get system time */ ++ dev->desc_tbl[desc_num -1].timestamp = jiffies; ++ return desc_num; ++} ++ ++static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) { ++ u_char foundLockUp; ++ vcstatus_t *vcstatus; ++ u_short *shd_tbl; ++ u_short tempCellSlot, tempFract; ++ struct main_vc *abr_vc = (struct main_vc *)dev->MAIN_VC_TABLE_ADDR; ++ struct ext_vc *eabr_vc = (struct ext_vc *)dev->EXT_VC_TABLE_ADDR; ++ u_int i; ++ ++ if (vcc->qos.txtp.traffic_class == ATM_ABR) { ++ vcstatus = (vcstatus_t *) &(dev->testTable[vcc->vci]->vc_status); ++ vcstatus->cnt++; ++ foundLockUp = 0; ++ if( vcstatus->cnt == 0x05 ) { ++ abr_vc += vcc->vci; ++ eabr_vc += vcc->vci; ++ if( eabr_vc->last_desc ) { ++ if( (abr_vc->status & 0x07) == ABR_STATE /* 0x2 */ ) { ++ /* Wait for 10 Micro sec */ ++ udelay(10); ++ if ((eabr_vc->last_desc)&&((abr_vc->status & 0x07)==ABR_STATE)) ++ foundLockUp = 1; ++ } ++ else { ++ tempCellSlot = abr_vc->last_cell_slot; ++ tempFract = abr_vc->fraction; ++ if((tempCellSlot == dev->testTable[vcc->vci]->lastTime) ++ && (tempFract == dev->testTable[vcc->vci]->fract)) ++ foundLockUp = 1; ++ dev->testTable[vcc->vci]->lastTime = tempCellSlot; ++ dev->testTable[vcc->vci]->fract = tempFract; ++ } ++ } /* last descriptor */ ++ vcstatus->cnt = 0; ++ } /* vcstatus->cnt */ ++ ++ if (foundLockUp) { ++ IF_ABR(printk("LOCK UP found\n");) ++ writew(0xFFFD, dev->seg_reg+MODE_REG_0); ++ /* Wait for 10 Micro sec */ ++ udelay(10); ++ abr_vc->status &= 0xFFF8; ++ abr_vc->status |= 0x0001; /* state is idle */ ++ shd_tbl = (u_short *)dev->ABR_SCHED_TABLE_ADDR; ++ for( i = 0; ((i < dev->num_vc) && (shd_tbl[i])); i++ ); ++ if (i < dev->num_vc) ++ shd_tbl[i] = vcc->vci; ++ else ++ IF_ERR(printk("ABR Seg. may not continue on VC %x\n",vcc->vci);) ++ writew(T_ONLINE, dev->seg_reg+MODE_REG_0); ++ writew(~(TRANSMIT_DONE|TCQ_NOT_EMPTY), dev->seg_reg+SEG_MASK_REG); ++ writew(TRANSMIT_DONE, dev->seg_reg+SEG_INTR_STATUS_REG); ++ vcstatus->cnt = 0; ++ } /* foundLockUp */ ++ ++ } /* if an ABR VC */ ++ ++ ++} ++ ++/* ++** Conversion of 24-bit cellrate (cells/sec) to 16-bit floating point format. ++** ++** +----+----+------------------+-------------------------------+ ++** | R | NZ | 5-bit exponent | 9-bit mantissa | ++** +----+----+------------------+-------------------------------+ ++** ++** R = reserverd (written as 0) ++** NZ = 0 if 0 cells/sec; 1 otherwise ++** ++** if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec ++*/ ++static u16 ++cellrate_to_float(u32 cr) ++{ ++ ++#define NZ 0x4000 ++#define M_BITS 9 /* Number of bits in mantissa */ ++#define E_BITS 5 /* Number of bits in exponent */ ++#define M_MASK 0x1ff ++#define E_MASK 0x1f ++ u16 flot; ++ u32 tmp = cr & 0x00ffffff; ++ int i = 0; ++ if (cr == 0) ++ return 0; ++ while (tmp != 1) { ++ tmp >>= 1; ++ i++; ++ } ++ if (i == M_BITS) ++ flot = NZ | (i << M_BITS) | (cr & M_MASK); ++ else if (i < M_BITS) ++ flot = NZ | (i << M_BITS) | ((cr << (M_BITS - i)) & M_MASK); ++ else ++ flot = NZ | (i << M_BITS) | ((cr >> (i - M_BITS)) & M_MASK); ++ return flot; ++} ++ ++#if 0 ++/* ++** Conversion of 16-bit floating point format to 24-bit cellrate (cells/sec). ++*/ ++static u32 ++float_to_cellrate(u16 rate) ++{ ++ u32 exp, mantissa, cps; ++ if ((rate & NZ) == 0) ++ return 0; ++ exp = (rate >> M_BITS) & E_MASK; ++ mantissa = rate & M_MASK; ++ if (exp == 0) ++ return 1; ++ cps = (1 << M_BITS) | mantissa; ++ if (exp == M_BITS) ++ cps = cps; ++ else if (exp > M_BITS) ++ cps <<= (exp - M_BITS); ++ else ++ cps >>= (M_BITS - exp); ++ return cps; ++} ++#endif ++ ++static void init_abr_vc (IADEV *dev, srv_cls_param_t *srv_p) { ++ srv_p->class_type = ATM_ABR; ++ srv_p->pcr = dev->LineRate; ++ srv_p->mcr = 0; ++ srv_p->icr = 0x055cb7; ++ srv_p->tbe = 0xffffff; ++ srv_p->frtt = 0x3a; ++ srv_p->rif = 0xf; ++ srv_p->rdf = 0xb; ++ srv_p->nrm = 0x4; ++ srv_p->trm = 0x7; ++ srv_p->cdf = 0x3; ++ srv_p->adtf = 50; ++} ++ ++static int ++ia_open_abr_vc(IADEV *dev, srv_cls_param_t *srv_p, ++ struct atm_vcc *vcc, u8 flag) ++{ ++ f_vc_abr_entry *f_abr_vc; ++ r_vc_abr_entry *r_abr_vc; ++ u32 icr; ++ u8 trm, nrm, crm; ++ u16 adtf, air, *ptr16; ++ f_abr_vc =(f_vc_abr_entry *)dev->MAIN_VC_TABLE_ADDR; ++ f_abr_vc += vcc->vci; ++ switch (flag) { ++ case 1: /* FFRED initialization */ ++#if 0 /* sanity check */ ++ if (srv_p->pcr == 0) ++ return INVALID_PCR; ++ if (srv_p->pcr > dev->LineRate) ++ srv_p->pcr = dev->LineRate; ++ if ((srv_p->mcr + dev->sum_mcr) > dev->LineRate) ++ return MCR_UNAVAILABLE; ++ if (srv_p->mcr > srv_p->pcr) ++ return INVALID_MCR; ++ if (!(srv_p->icr)) ++ srv_p->icr = srv_p->pcr; ++ if ((srv_p->icr < srv_p->mcr) || (srv_p->icr > srv_p->pcr)) ++ return INVALID_ICR; ++ if ((srv_p->tbe < MIN_TBE) || (srv_p->tbe > MAX_TBE)) ++ return INVALID_TBE; ++ if ((srv_p->frtt < MIN_FRTT) || (srv_p->frtt > MAX_FRTT)) ++ return INVALID_FRTT; ++ if (srv_p->nrm > MAX_NRM) ++ return INVALID_NRM; ++ if (srv_p->trm > MAX_TRM) ++ return INVALID_TRM; ++ if (srv_p->adtf > MAX_ADTF) ++ return INVALID_ADTF; ++ else if (srv_p->adtf == 0) ++ srv_p->adtf = 1; ++ if (srv_p->cdf > MAX_CDF) ++ return INVALID_CDF; ++ if (srv_p->rif > MAX_RIF) ++ return INVALID_RIF; ++ if (srv_p->rdf > MAX_RDF) ++ return INVALID_RDF; ++#endif ++ memset ((caddr_t)f_abr_vc, 0, sizeof(f_vc_abr_entry)); ++ f_abr_vc->f_vc_type = ABR; ++ nrm = 2 << srv_p->nrm; /* (2 ** (srv_p->nrm +1)) */ ++ /* i.e 2**n = 2 << (n-1) */ ++ f_abr_vc->f_nrm = nrm << 8 | nrm; ++ trm = 100000/(2 << (16 - srv_p->trm)); ++ if ( trm == 0) trm = 1; ++ f_abr_vc->f_nrmexp =(((srv_p->nrm +1) & 0x0f) << 12)|(MRM << 8) | trm; ++ crm = srv_p->tbe / nrm; ++ if (crm == 0) crm = 1; ++ f_abr_vc->f_crm = crm & 0xff; ++ f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr); ++ icr = MIN( srv_p->icr, (srv_p->tbe > srv_p->frtt) ? ++ ((srv_p->tbe/srv_p->frtt)*1000000) : ++ (1000000/(srv_p->frtt/srv_p->tbe))); ++ f_abr_vc->f_icr = cellrate_to_float(icr); ++ adtf = (10000 * srv_p->adtf)/8192; ++ if (adtf == 0) adtf = 1; ++ f_abr_vc->f_cdf = ((7 - srv_p->cdf) << 12 | adtf) & 0xfff; ++ f_abr_vc->f_mcr = cellrate_to_float(srv_p->mcr); ++ f_abr_vc->f_acr = f_abr_vc->f_icr; ++ f_abr_vc->f_status = 0x0042; ++ break; ++ case 0: /* RFRED initialization */ ++ ptr16 = (u_short *)(dev->reass_ram + REASS_TABLE*dev->memSize); ++ *(ptr16 + vcc->vci) = NO_AAL5_PKT | REASS_ABR; ++ r_abr_vc = (r_vc_abr_entry*)(dev->reass_ram+ABR_VC_TABLE*dev->memSize); ++ r_abr_vc += vcc->vci; ++ r_abr_vc->r_status_rdf = (15 - srv_p->rdf) & 0x000f; ++ air = srv_p->pcr << (15 - srv_p->rif); ++ if (air == 0) air = 1; ++ r_abr_vc->r_air = cellrate_to_float(air); ++ dev->testTable[vcc->vci]->vc_status = VC_ACTIVE | VC_ABR; ++ dev->sum_mcr += srv_p->mcr; ++ dev->n_abr++; ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) { ++ u32 rateLow=0, rateHigh, rate; ++ int entries; ++ struct ia_vcc *ia_vcc; ++ ++ int idealSlot =0, testSlot, toBeAssigned, inc; ++ u32 spacing; ++ u16 *SchedTbl, *TstSchedTbl; ++ u16 cbrVC, vcIndex; ++ u32 fracSlot = 0; ++ u32 sp_mod = 0; ++ u32 sp_mod2 = 0; ++ ++ /* IpAdjustTrafficParams */ ++ if (vcc->qos.txtp.max_pcr <= 0) { ++ IF_ERR(printk("PCR for CBR not defined\n");) ++ return -1; ++ } ++ rate = vcc->qos.txtp.max_pcr; ++ entries = rate / dev->Granularity; ++ IF_CBR(printk("CBR: CBR entries=0x%x for rate=0x%x & Gran=0x%x\n", ++ entries, rate, dev->Granularity);) ++ if (entries < 1) ++ IF_CBR(printk("CBR: Bandwidth smaller than granularity of CBR table\n");) ++ rateLow = entries * dev->Granularity; ++ rateHigh = (entries + 1) * dev->Granularity; ++ if (3*(rate - rateLow) > (rateHigh - rate)) ++ entries++; ++ if (entries > dev->CbrRemEntries) { ++ IF_CBR(printk("CBR: Not enough bandwidth to support this PCR.\n");) ++ IF_CBR(printk("Entries = 0x%x, CbrRemEntries = 0x%x.\n", ++ entries, dev->CbrRemEntries);) ++ return -EBUSY; ++ } ++ ++ ia_vcc = INPH_IA_VCC(vcc); ++ ia_vcc->NumCbrEntry = entries; ++ dev->sum_mcr += entries * dev->Granularity; ++ /* IaFFrednInsertCbrSched */ ++ // Starting at an arbitrary location, place the entries into the table ++ // as smoothly as possible ++ cbrVC = 0; ++ spacing = dev->CbrTotEntries / entries; ++ sp_mod = dev->CbrTotEntries % entries; // get modulo ++ toBeAssigned = entries; ++ fracSlot = 0; ++ vcIndex = vcc->vci; ++ IF_CBR(printk("Vci=0x%x,Spacing=0x%x,Sp_mod=0x%x\n",vcIndex,spacing,sp_mod);) ++ while (toBeAssigned) ++ { ++ // If this is the first time, start the table loading for this connection ++ // as close to entryPoint as possible. ++ if (toBeAssigned == entries) ++ { ++ idealSlot = dev->CbrEntryPt; ++ dev->CbrEntryPt += 2; // Adding 2 helps to prevent clumping ++ if (dev->CbrEntryPt >= dev->CbrTotEntries) ++ dev->CbrEntryPt -= dev->CbrTotEntries;// Wrap if necessary ++ } else { ++ idealSlot += (u32)(spacing + fracSlot); // Point to the next location ++ // in the table that would be smoothest ++ fracSlot = ((sp_mod + sp_mod2) / entries); // get new integer part ++ sp_mod2 = ((sp_mod + sp_mod2) % entries); // calc new fractional part ++ } ++ if (idealSlot >= (int)dev->CbrTotEntries) ++ idealSlot -= dev->CbrTotEntries; ++ // Continuously check around this ideal value until a null ++ // location is encountered. ++ SchedTbl = (u16*)(dev->seg_ram+CBR_SCHED_TABLE*dev->memSize); ++ inc = 0; ++ testSlot = idealSlot; ++ TstSchedTbl = (u16*)(SchedTbl+testSlot); //set index and read in value ++ IF_CBR(printk("CBR Testslot 0x%x AT Location 0x%x, NumToAssign=%d\n", ++ testSlot, (u32)TstSchedTbl,toBeAssigned);) ++ memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(u16)); ++ while (cbrVC) // If another VC at this location, we have to keep looking ++ { ++ inc++; ++ testSlot = idealSlot - inc; ++ if (testSlot < 0) { // Wrap if necessary ++ testSlot += dev->CbrTotEntries; ++ IF_CBR(printk("Testslot Wrap. STable Start=0x%x,Testslot=%d\n", ++ (u32)SchedTbl,testSlot);) ++ } ++ TstSchedTbl = (u16 *)(SchedTbl + testSlot); // set table index ++ memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(u16)); ++ if (!cbrVC) ++ break; ++ testSlot = idealSlot + inc; ++ if (testSlot >= (int)dev->CbrTotEntries) { // Wrap if necessary ++ testSlot -= dev->CbrTotEntries; ++ IF_CBR(printk("TotCbrEntries=%d",dev->CbrTotEntries);) ++ IF_CBR(printk(" Testslot=0x%x ToBeAssgned=%d\n", ++ testSlot, toBeAssigned);) ++ } ++ // set table index and read in value ++ TstSchedTbl = (u16*)(SchedTbl + testSlot); ++ IF_CBR(printk("Reading CBR Tbl from 0x%x, CbrVal=0x%x Iteration %d\n", ++ (u32)TstSchedTbl,cbrVC,inc);) ++ memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(u16)); ++ } /* while */ ++ // Move this VCI number into this location of the CBR Sched table. ++ memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex,sizeof(u16)); ++ dev->CbrRemEntries--; ++ toBeAssigned--; ++ } /* while */ ++ ++ /* IaFFrednCbrEnable */ ++ dev->NumEnabledCBR++; ++ if (dev->NumEnabledCBR == 1) { ++ writew((CBR_EN | UBR_EN | ABR_EN | (0x23 << 2)), dev->seg_reg+STPARMS); ++ IF_CBR(printk("CBR is enabled\n");) ++ } ++ return 0; ++} ++static void ia_cbrVc_close (struct atm_vcc *vcc) { ++ IADEV *iadev; ++ u16 *SchedTbl, NullVci = 0; ++ u32 i, NumFound; ++ ++ iadev = INPH_IA_DEV(vcc->dev); ++ iadev->NumEnabledCBR--; ++ SchedTbl = (u16*)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize); ++ if (iadev->NumEnabledCBR == 0) { ++ writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS); ++ IF_CBR (printk("CBR support disabled\n");) ++ } ++ NumFound = 0; ++ for (i=0; i < iadev->CbrTotEntries; i++) ++ { ++ if (*SchedTbl == vcc->vci) { ++ iadev->CbrRemEntries++; ++ *SchedTbl = NullVci; ++ IF_CBR(NumFound++;) ++ } ++ SchedTbl++; ++ } ++ IF_CBR(printk("Exit ia_cbrVc_close, NumRemoved=%d\n",NumFound);) ++} ++ ++static int ia_avail_descs(IADEV *iadev) { ++ int tmp = 0; ++ ia_hack_tcq(iadev); ++ if (iadev->host_tcq_wr >= iadev->ffL.tcq_rd) ++ tmp = (iadev->host_tcq_wr - iadev->ffL.tcq_rd) / 2; ++ else ++ tmp = (iadev->ffL.tcq_ed - iadev->ffL.tcq_rd + 2 + iadev->host_tcq_wr - ++ iadev->ffL.tcq_st) / 2; ++ return tmp; ++} ++ ++static int ia_que_tx (IADEV *iadev) { ++ struct sk_buff *skb; ++ int num_desc; ++ struct atm_vcc *vcc; ++ struct ia_vcc *iavcc; ++ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb); ++ num_desc = ia_avail_descs(iadev); ++ while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) { ++ if (!(vcc = ATM_SKB(skb)->vcc)) { ++ dev_kfree_skb(skb); ++ printk("ia_que_tx: Null vcc\n"); ++ break; ++ } ++ if ((vcc->flags & ATM_VF_READY) == 0 ) { ++ dev_kfree_skb(skb); ++ printk("Free the SKB on closed vci %d \n", vcc->vci); ++ break; ++ } ++ iavcc = INPH_IA_VCC(vcc); ++ if (ia_pkt_tx (vcc, skb)) { ++ skb_queue_head(&iadev->tx_backlog, skb); ++ } ++ num_desc--; ++ } ++ return 0; ++} ++void ia_tx_poll (IADEV *iadev) { ++ struct atm_vcc *vcc = NULL; ++ struct sk_buff *skb = NULL, *skb1 = NULL; ++ struct ia_vcc *iavcc; ++ IARTN_Q * rtne; ++ ++ ia_hack_tcq(iadev); ++ while ( (rtne = ia_deque_rtn_q(&iadev->tx_return_q))) { ++ skb = rtne->data.txskb; ++ if (!skb) { ++ printk("ia_tx_poll: skb is null\n"); ++ return; ++ } ++ vcc = ATM_SKB(skb)->vcc; ++ if (!vcc) { ++ printk("ia_tx_poll: vcc is null\n"); ++ dev_kfree_skb(skb); ++ return; ++ } ++ ++ iavcc = INPH_IA_VCC(vcc); ++ if (!iavcc) { ++ printk("ia_tx_poll: iavcc is null\n"); ++ dev_kfree_skb(skb); ++ return; ++ } ++ ++ skb1 = skb_dequeue(&iavcc->txing_skb); ++ while (skb1 && (skb1 != skb)) { ++ if (!(IA_SKB_STATE(skb1) & IA_TX_DONE)) { ++ printk("IA_tx_intr: Vci %d lost pkt!!!\n", vcc->vci); ++ } ++ IF_ERR(printk("Release the SKB not match\n");) ++ if (vcc && (vcc->pop) && (skb1->len != 0)) ++ { ++ vcc->pop(vcc, skb1); ++ IF_EVENT(printk("Tansmit Done - skb 0x%lx return\n", ++ (long)skb1);) ++ } ++ else ++ dev_kfree_skb(skb1); ++ skb1 = skb_dequeue(&iavcc->txing_skb); ++ } ++ if (!skb1) { ++ IF_EVENT(printk("IA: Vci %d - skb not found requed\n",vcc->vci);) ++ ia_enque_head_rtn_q (&iadev->tx_return_q, rtne); ++ break; ++ } ++ if (vcc && (vcc->pop) && (skb->len != 0)) ++ { ++ vcc->pop(vcc, skb); ++ IF_EVENT(printk("Tx Done - skb 0x%lx return\n",(long)skb);) ++ } ++ else ++ dev_kfree_skb(skb); ++ kfree(rtne); ++ } ++ ia_que_tx(iadev); ++ return; ++} ++#if 0 ++static void ia_eeprom_put (IADEV *iadev, u32 addr, u_short val) ++{ ++ u32 t; ++ int i; ++ /* ++ * Issue a command to enable writes to the NOVRAM ++ */ ++ NVRAM_CMD (EXTEND + EWEN); ++ NVRAM_CLR_CE; ++ /* ++ * issue the write command ++ */ ++ NVRAM_CMD(IAWRITE + addr); ++ /* ++ * Send the data, starting with D15, then D14, and so on for 16 bits ++ */ ++ for (i=15; i>=0; i--) { ++ NVRAM_CLKOUT (val & 0x8000); ++ val <<= 1; ++ } ++ NVRAM_CLR_CE; ++ CFG_OR(NVCE); ++ t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); ++ while (!(t & NVDO)) ++ t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); ++ ++ NVRAM_CLR_CE; ++ /* ++ * disable writes again ++ */ ++ NVRAM_CMD(EXTEND + EWDS) ++ NVRAM_CLR_CE; ++ CFG_AND(~NVDI); +} ++#endif + ++static u16 ia_eeprom_get (IADEV *iadev, u32 addr) ++{ ++ u_short val; ++ u32 t; ++ int i; ++ /* ++ * Read the first bit that was clocked with the falling edge of the ++ * the last command data clock ++ */ ++ NVRAM_CMD(IAREAD + addr); ++ /* ++ * Now read the rest of the bits, the next bit read is D14, then D13, ++ * and so on. ++ */ ++ val = 0; ++ for (i=15; i>=0; i--) { ++ NVRAM_CLKIN(t); ++ val |= (t << i); ++ } ++ NVRAM_CLR_CE; ++ CFG_AND(~NVDI); ++ return val; ++} + -+static const struct atmphy_ops idt77105_ops = { -+ idt77105_start, -+ idt77105_ioctl, -+ idt77105_int -+}; ++static void ia_hw_type(IADEV *iadev) { ++ u_short memType = ia_eeprom_get(iadev, 25); ++ iadev->memType = memType; ++ if ((memType & MEM_SIZE_MASK) == MEM_SIZE_1M) { ++ iadev->num_tx_desc = IA_TX_BUF; ++ iadev->tx_buf_sz = IA_TX_BUF_SZ; ++ iadev->num_rx_desc = IA_RX_BUF; ++ iadev->rx_buf_sz = IA_RX_BUF_SZ; ++ } else if ((memType & MEM_SIZE_MASK) == MEM_SIZE_512K) { ++ if (IA_TX_BUF == DFL_TX_BUFFERS) ++ iadev->num_tx_desc = IA_TX_BUF / 2; ++ else ++ iadev->num_tx_desc = IA_TX_BUF; ++ iadev->tx_buf_sz = IA_TX_BUF_SZ; ++ if (IA_RX_BUF == DFL_RX_BUFFERS) ++ iadev->num_rx_desc = IA_RX_BUF / 2; ++ else ++ iadev->num_rx_desc = IA_RX_BUF; ++ iadev->rx_buf_sz = IA_RX_BUF_SZ; ++ } ++ else { ++ if (IA_TX_BUF == DFL_TX_BUFFERS) ++ iadev->num_tx_desc = IA_TX_BUF / 8; ++ else ++ iadev->num_tx_desc = IA_TX_BUF; ++ iadev->tx_buf_sz = IA_TX_BUF_SZ; ++ if (IA_RX_BUF == DFL_RX_BUFFERS) ++ iadev->num_rx_desc = IA_RX_BUF / 8; ++ else ++ iadev->num_rx_desc = IA_RX_BUF; ++ iadev->rx_buf_sz = IA_RX_BUF_SZ; ++ } ++ iadev->rx_pkt_ram = TX_PACKET_RAM + (iadev->num_tx_desc * iadev->tx_buf_sz); ++ IF_INIT(printk("BUF: tx=%d,sz=%d rx=%d sz= %d rx_pkt_ram=%d\n", ++ iadev->num_tx_desc, iadev->tx_buf_sz, iadev->num_rx_desc, ++ iadev->rx_buf_sz, iadev->rx_pkt_ram);) + ++#if 0 ++ if ((memType & FE_MASK) == FE_SINGLE_MODE) { ++ iadev->phy_type = PHY_OC3C_S; ++ else if ((memType & FE_MASK) == FE_UTP_OPTION) ++ iadev->phy_type = PHY_UTP155; ++ else ++ iadev->phy_type = PHY_OC3C_M; ++#endif ++ ++ iadev->phy_type = memType & FE_MASK; ++ IF_INIT(printk("memType = 0x%x iadev->phy_type = 0x%x\n", ++ memType,iadev->phy_type);) ++ if (iadev->phy_type == FE_25MBIT_PHY) ++ iadev->LineRate = (u32)(((25600000/8)*26)/(27*53)); ++ else if (iadev->phy_type == FE_DS3_PHY) ++ iadev->LineRate = (u32)(((44736000/8)*26)/(27*53)); ++ else if (iadev->phy_type == FE_E3_PHY) ++ iadev->LineRate = (u32)(((34368000/8)*26)/(27*53)); ++ else ++ iadev->LineRate = (u32)(ATM_OC3_PCR); ++ IF_INIT(printk("iadev->LineRate = %d \n", iadev->LineRate);) + -+int __init idt77105_init(struct atm_dev *dev) -+{ -+#ifdef MODULE -+ MOD_INC_USE_COUNT; -+#endif /* MODULE */ ++} + -+ dev->phy = &idt77105_ops; -+ return 0; ++static void IaFrontEndIntr(IADEV *iadev) { ++ volatile IA_SUNI *suni; ++ volatile ia_mb25_t *mb25; ++ volatile suni_pm7345_t *suni_pm7345; ++ u32 intr_status; ++ u_int frmr_intr; ++ ++ if(iadev->phy_type & FE_25MBIT_PHY) { ++ mb25 = (ia_mb25_t*)iadev->phy; ++ iadev->carrier_detect = Boolean(mb25->mb25_intr_status & MB25_IS_GSB); ++ } else if (iadev->phy_type & FE_DS3_PHY) { ++ suni_pm7345 = (suni_pm7345_t *)iadev->phy; ++ /* clear FRMR interrupts */ ++ frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat; ++ iadev->carrier_detect = ++ Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); ++ } else if (iadev->phy_type & FE_E3_PHY ) { ++ suni_pm7345 = (suni_pm7345_t *)iadev->phy; ++ frmr_intr = suni_pm7345->suni_e3_frm_maint_intr_ind; ++ iadev->carrier_detect = ++ Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS)); ++ } ++ else { ++ suni = (IA_SUNI *)iadev->phy; ++ intr_status = suni->suni_rsop_status & 0xff; ++ iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV)); ++ } ++ if (iadev->carrier_detect) ++ printk("IA: SUNI carrier detected\n"); ++ else ++ printk("IA: SUNI carrier lost signal\n"); ++ return; +} + ++void ia_mb25_init (IADEV *iadev) ++{ ++ volatile ia_mb25_t *mb25 = (ia_mb25_t*)iadev->phy; ++#if 0 ++ mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED; ++#endif ++ mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC; ++ mb25->mb25_diag_control = 0; ++ /* ++ * Initialize carrier detect state ++ */ ++ iadev->carrier_detect = Boolean(mb25->mb25_intr_status & MB25_IS_GSB); ++ return; ++} + -+/* -+ * TODO: this function should be called through phy_ops -+ * but that will not be possible for some time as there is -+ * currently a freeze on modifying that structure -+ * -- Greg Banks, 13 Sep 1999 -+ */ -+int idt77105_stop(struct atm_dev *dev) ++void ia_suni_pm7345_init (IADEV *iadev) +{ -+ struct idt77105_priv *walk, *prev; ++ volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy; ++ if (iadev->phy_type & FE_DS3_PHY) ++ { ++ iadev->carrier_detect = ++ Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); ++ suni_pm7345->suni_ds3_frm_intr_enbl = 0x17; ++ suni_pm7345->suni_ds3_frm_cfg = 1; ++ suni_pm7345->suni_ds3_tran_cfg = 1; ++ suni_pm7345->suni_config = 0; ++ suni_pm7345->suni_splr_cfg = 0; ++ suni_pm7345->suni_splt_cfg = 0; ++ } ++ else ++ { ++ iadev->carrier_detect = ++ Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS)); ++ suni_pm7345->suni_e3_frm_fram_options = 0x4; ++ suni_pm7345->suni_e3_frm_maint_options = 0x20; ++ suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d; ++ suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30; ++ suni_pm7345->suni_e3_tran_stat_diag_options = 0x0; ++ suni_pm7345->suni_e3_tran_fram_options = 0x1; ++ suni_pm7345->suni_config = SUNI_PM7345_E3ENBL; ++ suni_pm7345->suni_splr_cfg = 0x41; ++ suni_pm7345->suni_splt_cfg = 0x41; ++ } ++ /* ++ * Enable RSOP loss of signal interrupt. ++ */ ++ suni_pm7345->suni_intr_enbl = 0x28; ++ ++ /* ++ * Clear error counters ++ */ ++ suni_pm7345->suni_id_reset = 0; ++ ++ /* ++ * Clear "PMCTST" in master test register. ++ */ ++ suni_pm7345->suni_master_test = 0; + -+ DPRINTK("%s(itf %d): stopping IDT77105\n",dev->type,dev->number); ++ suni_pm7345->suni_rxcp_ctrl = 0x2c; ++ suni_pm7345->suni_rxcp_fctrl = 0x81; ++ ++ suni_pm7345->suni_rxcp_idle_pat_h1 = 0; ++ suni_pm7345->suni_rxcp_idle_pat_h2 = 0; ++ suni_pm7345->suni_rxcp_idle_pat_h3 = 0; ++ suni_pm7345->suni_rxcp_idle_pat_h4 = 1; ++ ++ suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff; ++ suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff; ++ suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff; ++ suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe; ++ ++ suni_pm7345->suni_rxcp_cell_pat_h1 = 0; ++ suni_pm7345->suni_rxcp_cell_pat_h2 = 0; ++ suni_pm7345->suni_rxcp_cell_pat_h3 = 0; ++ suni_pm7345->suni_rxcp_cell_pat_h4 = 1; ++ ++ suni_pm7345->suni_rxcp_cell_mask_h1 = 0xff; ++ suni_pm7345->suni_rxcp_cell_mask_h2 = 0xff; ++ suni_pm7345->suni_rxcp_cell_mask_h3 = 0xff; ++ suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff; ++ ++ suni_pm7345->suni_txcp_ctrl = 0xa4; ++ suni_pm7345->suni_txcp_intr_en_sts = 0x10; ++ suni_pm7345->suni_txcp_idle_pat_h5 = 0x55; ++ ++ suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB | ++ SUNI_PM7345_CLB | ++ SUNI_PM7345_DLB | ++ SUNI_PM7345_PLB); ++#ifdef __SNMP__ ++ suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE; ++#endif __SNMP__ ++ return; ++} ++ ++ ++/***************************** IA_LIB END *****************************/ ++ ++/* pwang_test debug utility */ ++int tcnter = 0, rcnter = 0; ++void xdump( u_char* cp, int length, char* prefix ) ++{ ++ int col, count; ++ u_char prntBuf[120]; ++ u_char* pBuf = prntBuf; ++ count = 0; ++ while(count < length){ ++ pBuf += sprintf( pBuf, "%s", prefix ); ++ for(col = 0;count + col < length && col < 16; col++){ ++ if (col != 0 && (col % 4) == 0) ++ pBuf += sprintf( pBuf, " " ); ++ pBuf += sprintf( pBuf, "%02X ", cp[count + col] ); ++ } ++ while(col++ < 16){ /* pad end of buffer with blanks */ ++ if ((col % 4) == 0) ++ sprintf( pBuf, " " ); ++ pBuf += sprintf( pBuf, " " ); ++ } ++ pBuf += sprintf( pBuf, " " ); ++ for(col = 0;count + col < length && col < 16; col++){ ++ if (isprint((int)cp[count + col])) ++ pBuf += sprintf( pBuf, "%c", cp[count + col] ); ++ else ++ pBuf += sprintf( pBuf, "." ); ++ } ++ sprintf( pBuf, "\n" ); ++ // SPrint(prntBuf); ++ printk(prntBuf); ++ count += col; ++ pBuf = prntBuf; ++ } ++ ++} /* close xdump(... */ ++ ++ ++static struct atm_dev *ia_boards = NULL; ++ ++#define ACTUAL_RAM_BASE \ ++ RAM_BASE*((iadev->mem)/(128 * 1024)) ++#define ACTUAL_SEG_RAM_BASE \ ++ IPHASE5575_FRAG_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024)) ++#define ACTUAL_REASS_RAM_BASE \ ++ IPHASE5575_REASS_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024)) ++ ++ ++/*-- some utilities and memory allocation stuff will come here -------------*/ ++ ++void desc_dbg(IADEV *iadev) { ++ ++ u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr; ++ u32 tmp, i; ++ // regval = readl((u32)ia_cmds->maddr); ++ tcq_wr_ptr = readw(iadev->seg_reg+TCQ_WR_PTR); ++ printk("B_tcq_wr = 0x%x desc = %d last desc = %d\n", ++ tcq_wr_ptr, readw(iadev->seg_ram+tcq_wr_ptr), ++ readw(iadev->seg_ram+tcq_wr_ptr-2)); ++ printk(" host_tcq_wr = 0x%x host_tcq_rd = 0x%x \n", iadev->host_tcq_wr, ++ iadev->ffL.tcq_rd); ++ tcq_st_ptr = readw(iadev->seg_reg+TCQ_ST_ADR); ++ tcq_ed_ptr = readw(iadev->seg_reg+TCQ_ED_ADR); ++ printk("tcq_st_ptr = 0x%x tcq_ed_ptr = 0x%x \n", tcq_st_ptr, tcq_ed_ptr); ++ i = 0; ++ while (tcq_st_ptr != tcq_ed_ptr) { ++ tmp = iadev->seg_ram+tcq_st_ptr; ++ printk("TCQ slot %d desc = %d Addr = 0x%x\n", i++, readw(tmp), tmp); ++ tcq_st_ptr += 2; ++ } ++ for(i=0; i num_tx_desc; i++) ++ printk("Desc_tbl[%d] = %d \n", i, iadev->desc_tbl[i].timestamp); ++} ++ ++ ++/*----------------------------- Recieving side stuff --------------------------*/ ++ ++static void rx_excp_rcvd(struct atm_dev *dev) ++{ ++#if 0 /* closing the receiving size will cause too many excp int */ ++ IADEV *iadev; ++ u_short state; ++ u_short excpq_rd_ptr; ++ //u_short *ptr; ++ int vci, error = 1; ++ iadev = INPH_IA_DEV(dev); ++ state = readl(iadev->reass_reg + STATE_REG) & 0xffff; ++ while((state & EXCPQ_EMPTY) != EXCPQ_EMPTY) ++ { printk("state = %x \n", state); ++ excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_RD_PTR) & 0xffff; ++ printk("state = %x excpq_rd_ptr = %x \n", state, excpq_rd_ptr); ++ if (excpq_rd_ptr == *(u16*)(iadev->reass_reg + EXCP_Q_WR_PTR)) ++ IF_ERR(printk("excpq_rd_ptr is wrong!!!\n");) ++ // TODO: update exception stat ++ vci = readw(iadev->reass_ram+excpq_rd_ptr); ++ error = readw(iadev->reass_ram+excpq_rd_ptr+2) & 0x0007; ++ // pwang_test ++ excpq_rd_ptr += 4; ++ if (excpq_rd_ptr > (readw(iadev->reass_reg + EXCP_Q_ED_ADR)& 0xffff)) ++ excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_ST_ADR)& 0xffff; ++ writew( excpq_rd_ptr, iadev->reass_reg + EXCP_Q_RD_PTR); ++ state = readl(iadev->reass_reg + STATE_REG) & 0xffff; ++ } ++#endif ++} ++ ++static void free_desc(struct atm_dev *dev, int desc) ++{ ++ IADEV *iadev; ++ iadev = INPH_IA_DEV(dev); ++ writew(desc, iadev->reass_ram+iadev->rfL.fdq_wr); ++ iadev->rfL.fdq_wr +=2; ++ if (iadev->rfL.fdq_wr > iadev->rfL.fdq_ed) ++ iadev->rfL.fdq_wr = iadev->rfL.fdq_st; ++ writew(iadev->rfL.fdq_wr, iadev->reass_reg+FREEQ_WR_PTR); ++} ++ ++ ++static int rx_pkt(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ struct atm_vcc *vcc; ++ unsigned short status; ++ struct rx_buf_desc *buf_desc_ptr; ++ int desc; ++ struct dle* wr_ptr; ++ int len; ++ struct sk_buff *skb; ++ u_int buf_addr, dma_addr; ++ iadev = INPH_IA_DEV(dev); ++ if (iadev->rfL.pcq_rd == (readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff)) ++ { ++ printk(KERN_ERR DEV_LABEL "(itf %d) Receive queue empty\n", dev->number); ++ return -EINVAL; ++ } ++ /* mask 1st 3 bits to get the actual descno. */ ++ desc = readw(iadev->reass_ram+iadev->rfL.pcq_rd) & 0x1fff; ++ IF_RX(printk("reass_ram = 0x%x iadev->rfL.pcq_rd = 0x%x desc = %d\n", ++ iadev->reass_ram, iadev->rfL.pcq_rd, desc); ++ printk(" pcq_wr_ptr = 0x%x\n", ++ readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff);) ++ /* update the read pointer - maybe we shud do this in the end*/ ++ if ( iadev->rfL.pcq_rd== iadev->rfL.pcq_ed) ++ iadev->rfL.pcq_rd = iadev->rfL.pcq_st; ++ else ++ iadev->rfL.pcq_rd += 2; ++ writew(iadev->rfL.pcq_rd, iadev->reass_reg+PCQ_RD_PTR); ++ ++ /* get the buffer desc entry. ++ update stuff. - doesn't seem to be any update necessary ++ */ ++ buf_desc_ptr = (struct rx_buf_desc *)iadev->RX_DESC_BASE_ADDR; ++ /* make the ptr point to the corresponding buffer desc entry */ ++ buf_desc_ptr += desc; ++ if (!desc || (desc > iadev->num_rx_desc) || ++ ((buf_desc_ptr->vc_index & 0xffff) > iadev->num_vc)) { ++ free_desc(dev, desc); ++ IF_ERR(printk("IA: bad descriptor desc = %d \n", desc);) ++ return -1; ++ } ++ vcc = iadev->rx_open[buf_desc_ptr->vc_index & 0xffff]; ++ if (!vcc) ++ { ++ free_desc(dev, desc); ++ printk("IA: null vcc, drop PDU\n"); ++ return -1; ++ } ++ ++ ++ /* might want to check the status bits for errors */ ++ status = (u_short) (buf_desc_ptr->desc_mode); ++ if (status & (RX_CER | RX_PTE | RX_OFL)) ++ { ++ vcc->stats->rx_err++; ++ IF_ERR(printk("IA: bad packet, dropping it");) ++ if (status & RX_CER) { ++ IF_ERR(printk(" cause: packet CRC error\n");) ++ } ++ else if (status & RX_PTE) { ++ IF_ERR(printk(" cause: packet time out\n");) ++ } ++ else { ++ IF_ERR(printk(" cause: buffer over flow\n");) ++ } ++ free_desc(dev, desc); ++ return 0; ++ } ++ ++ /* ++ build DLE. ++ */ ++ ++ buf_addr = (buf_desc_ptr->buf_start_hi << 16) | buf_desc_ptr->buf_start_lo; ++ dma_addr = (buf_desc_ptr->dma_start_hi << 16) | buf_desc_ptr->dma_start_lo; ++ len = dma_addr - buf_addr; ++ if (len > iadev->rx_buf_sz) { ++ printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz); ++ vcc->stats->rx_err++; ++ free_desc(dev, desc); ++ return 0; ++ } ++ ++#if LINUX_VERSION_CODE >= 0x20312 ++ if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) { ++#else ++ if (atm_charge(vcc, atm_pdu2truesize(len))) { ++ /* lets allocate an skb for now */ ++ skb = alloc_skb(len, GFP_ATOMIC); ++ if (!skb) ++ { ++ IF_ERR(printk("can't allocate memory for recv, drop pkt!\n");) ++ vcc->stats->rx_drop++; ++ atm_return(vcc, atm_pdu2truesize(len)); ++ free_desc(dev, desc); ++ return 0; ++ } ++ } ++ else { ++ IF_EVENT(printk("IA: Rx over the rx_quota %ld\n", vcc->rx_quota);) ++#endif ++ if (vcc->vci < 32) ++ printk("Drop control packets\n"); ++ free_desc(dev, desc); ++ return 0; ++ } ++ skb_put(skb,len); ++ // pwang_test ++ ATM_SKB(skb)->vcc = vcc; ++ ATM_SKB(skb)->iovcnt = 0; ++ ATM_DESC(skb) = desc; ++ skb_queue_tail(&iadev->rx_dma_q, skb); ++ ++ /* Build the DLE structure */ ++ wr_ptr = iadev->rx_dle_q.write; ++ wr_ptr->sys_pkt_addr = virt_to_bus(skb->data); ++ wr_ptr->local_pkt_addr = buf_addr; ++ wr_ptr->bytes = len; /* We don't know this do we ?? */ ++ wr_ptr->mode = DMA_INT_ENABLE; ++ ++ /* shud take care of wrap around here too. */ ++ if(++wr_ptr == iadev->rx_dle_q.end) ++ wr_ptr = iadev->rx_dle_q.start; ++ iadev->rx_dle_q.write = wr_ptr; ++ udelay(1); ++ /* Increment transaction counter */ ++ writel(1, iadev->dma+IPHASE5575_RX_COUNTER); ++ return 0; ++} ++ ++static void rx_intr(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ u_short status; ++ u_short state, i; ++ ++ iadev = INPH_IA_DEV(dev); ++ status = readl(iadev->reass_reg+REASS_INTR_STATUS_REG) & 0xffff; ++ IF_EVENT(printk("rx_intr: status = 0x%x\n", status);) ++ if (status & RX_PKT_RCVD) ++ { ++ /* do something */ ++ /* Basically recvd an interrupt for receving a packet. ++ A descriptor would have been written to the packet complete ++ queue. Get all the descriptors and set up dma to move the ++ packets till the packet complete queue is empty.. ++ */ ++ state = readl(iadev->reass_reg + STATE_REG) & 0xffff; ++ IF_EVENT(printk("Rx intr status: RX_PKT_RCVD %08x\n", status);) ++ while(!(state & PCQ_EMPTY)) ++ { ++ rx_pkt(dev); ++ state = readl(iadev->reass_reg + STATE_REG) & 0xffff; ++ } ++ iadev->rxing = 1; ++ } ++ if (status & RX_FREEQ_EMPT) ++ { ++ if (iadev->rxing) { ++ iadev->rx_tmp_cnt = iadev->rx_pkt_cnt; ++ iadev->rx_tmp_jif = jiffies; ++ iadev->rxing = 0; ++ } ++ else if (((jiffies - iadev->rx_tmp_jif) > 50) && ++ ((iadev->rx_pkt_cnt - iadev->rx_tmp_cnt) == 0)) { ++ for (i = 1; i <= iadev->num_rx_desc; i++) ++ free_desc(dev, i); ++printk("Test logic RUN!!!!\n"); ++ writew( ~(RX_FREEQ_EMPT|RX_EXCP_RCVD),iadev->reass_reg+REASS_MASK_REG); ++ iadev->rxing = 1; ++ } ++ IF_EVENT(printk("Rx intr status: RX_FREEQ_EMPT %08x\n", status);) ++ } ++ ++ if (status & RX_EXCP_RCVD) ++ { ++ /* probably need to handle the exception queue also. */ ++ IF_EVENT(printk("Rx intr status: RX_EXCP_RCVD %08x\n", status);) ++ rx_excp_rcvd(dev); ++ } ++ ++ ++ if (status & RX_RAW_RCVD) ++ { ++ /* need to handle the raw incoming cells. This deepnds on ++ whether we have programmed to receive the raw cells or not. ++ Else ignore. */ ++ IF_EVENT(printk("Rx intr status: RX_RAW_RCVD %08x\n", status);) ++ } ++} ++ ++ ++static void rx_dle_intr(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ struct atm_vcc *vcc; ++ struct sk_buff *skb; ++ int desc; ++ u_short state; ++ struct dle *dle, *cur_dle; ++ u_int dle_lp; ++ iadev = INPH_IA_DEV(dev); ++ ++ /* free all the dles done, that is just update our own dle read pointer ++ - do we really need to do this. Think not. */ ++ /* DMA is done, just get all the recevie buffers from the rx dma queue ++ and push them up to the higher layer protocol. Also free the desc ++ associated with the buffer. */ ++ dle = iadev->rx_dle_q.read; ++ dle_lp = readl(iadev->dma+IPHASE5575_RX_LIST_ADDR) & (sizeof(struct dle)*DLE_ENTRIES - 1); ++ cur_dle = (struct dle*)(iadev->rx_dle_q.start + (dle_lp >> 4)); ++ while(dle != cur_dle) ++ { ++ /* free the DMAed skb */ ++ skb = skb_dequeue(&iadev->rx_dma_q); ++ if (!skb) ++ goto INCR_DLE; ++ desc = ATM_DESC(skb); ++ free_desc(dev, desc); ++ ++ if (!skb->len) ++ { ++ printk("rx_dle_intr: skb len 0\n"); ++ dev_kfree_skb(skb); ++ } ++ else ++ { ++ struct cpcs_trailer *trailer; ++ u_short length; ++ struct ia_vcc *ia_vcc; ++ /* no VCC related housekeeping done as yet. lets see */ ++ vcc = ATM_SKB(skb)->vcc; ++ if (!vcc) { ++ printk("IA: null vcc\n"); ++ vcc->stats->rx_err++; ++ dev_kfree_skb(skb); ++ goto INCR_DLE; ++ } ++ ia_vcc = INPH_IA_VCC(vcc); ++ if (ia_vcc == NULL) ++ { ++ vcc->stats->rx_err++; ++ dev_kfree_skb(skb); ++#if LINUX_VERSION_CODE >= 0x20312 ++ atm_return(vcc, atm_guess_pdu2truesize(skb->len)); ++#else ++ atm_return(vcc, atm_pdu2truesize(skb->len)); ++#endif ++ goto INCR_DLE; ++ } ++ // get real pkt length pwang_test ++ trailer = (struct cpcs_trailer*)((u_char *)skb->data + ++ skb->len - sizeof(struct cpcs_trailer)); ++ length = swap(trailer->length); ++ if ((length > iadev->rx_buf_sz) || (length > ++ (skb->len - sizeof(struct cpcs_trailer)))) ++ { ++ vcc->stats->rx_err++; ++ dev_kfree_skb(skb); ++ IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)", ++ length, skb->len);) ++#if LINUX_VERSION_CODE >= 0x20312 ++ atm_return(vcc, atm_guess_pdu2truesize(skb->len)); ++#else ++ atm_return(vcc, atm_pdu2truesize(skb->len)); ++#endif ++ goto INCR_DLE; ++ } ++ skb_trim(skb, length); ++ ++ /* Display the packet */ ++ IF_RXPKT(printk("\nDmad Recvd data: len = %d \n", skb->len); ++ xdump(skb->data, skb->len, "RX: "); ++ printk("\n");) ++ ++ IF_RX(printk("rx_dle_intr: skb push");) ++ vcc->push(vcc,skb); ++ vcc->stats->rx++; ++ iadev->rx_pkt_cnt++; ++ } ++INCR_DLE: ++ if (++dle == iadev->rx_dle_q.end) ++ dle = iadev->rx_dle_q.start; ++ } ++ iadev->rx_dle_q.read = dle; ++ ++ /* if the interrupts are masked because there were no free desc available, ++ unmask them now. */ ++ if (!iadev->rxing) { ++ state = readl(iadev->reass_reg + STATE_REG) & 0xffff; ++ if (!(state & FREEQ_EMPTY)) { ++ state = readl(iadev->reass_reg + REASS_MASK_REG) & 0xffff; ++ writel(state & ~(RX_FREEQ_EMPT |/* RX_EXCP_RCVD |*/ RX_PKT_RCVD), ++ iadev->reass_reg+REASS_MASK_REG); ++ iadev->rxing++; ++ } ++ } ++} ++ ++ ++static int open_rx(struct atm_vcc *vcc) ++{ ++ IADEV *iadev; ++ u_short *vc_table; ++ u_short *reass_ptr; ++ IF_EVENT(printk("iadev: open_rx %d.%d\n", vcc->vpi, vcc->vci);) ++ ++ if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0; ++ iadev = INPH_IA_DEV(vcc->dev); ++ if (vcc->qos.rxtp.traffic_class == ATM_ABR) { ++ if (iadev->phy_type & FE_25MBIT_PHY) { ++ printk("IA: ABR not support\n"); ++ return -EINVAL; ++ } ++ } ++ /* Make only this VCI in the vc table valid and let all ++ others be invalid entries */ ++ vc_table = (u_short *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize); ++ vc_table += vcc->vci; ++ /* mask the last 6 bits and OR it with 3 for 1K VCs */ ++ ++ *vc_table = vcc->vci << 6; ++ /* Also keep a list of open rx vcs so that we can attach them with ++ incoming PDUs later. */ ++ if ((vcc->qos.rxtp.traffic_class == ATM_ABR) || ++ (vcc->qos.txtp.traffic_class == ATM_ABR)) ++ { ++ srv_cls_param_t srv_p; ++ init_abr_vc(iadev, &srv_p); ++ ia_open_abr_vc(iadev, &srv_p, vcc, 0); ++ } ++ else { /* for UBR later may need to add CBR logic */ ++ reass_ptr = (u_short *) ++ (iadev->reass_ram+REASS_TABLE*iadev->memSize); ++ reass_ptr += vcc->vci; ++ *reass_ptr = NO_AAL5_PKT; ++ } ++ ++ if (iadev->rx_open[vcc->vci]) ++ printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d already open\n", ++ vcc->dev->number, vcc->vci); ++ iadev->rx_open[vcc->vci] = vcc; ++ return 0; ++} ++ ++static int rx_init(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ struct rx_buf_desc *buf_desc_ptr; ++ unsigned long rx_pkt_start = 0; ++ u32 *dle_addr; ++ struct abr_vc_table *abr_vc_table; ++ u16 *vc_table; ++ u16 *reass_table; ++ u16 *ptr16; ++ int i,j, vcsize_sel; ++ u_short freeq_st_adr; ++ u_short *freeq_start; ++ ++ iadev = INPH_IA_DEV(dev); ++ // spin_lock_init(&iadev->rx_lock); ++ /* I need to initialize the DLEs somewhere. Lets see what I ++ need to do for this, hmmm... ++ - allocate memory for 256 DLEs. make sure that it starts ++ on a 4k byte address boundary. Program the start address ++ in Receive List address register. ..... to do for TX also ++ To make sure that it is a 4k byte boundary - allocate 8k and find ++ 4k byte boundary within. ++ ( (addr + (4k-1)) & ~(4k-1) ) ++ */ ++ ++ /* allocate 8k bytes */ ++ dle_addr = (u32*)kmalloc(2*sizeof(struct dle)*DLE_ENTRIES, GFP_KERNEL); ++ if (!dle_addr) ++ { ++ printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n"); ++ } ++ /* find 4k byte boundary within the 8k allocated */ ++ dle_addr = (u32*)( ((u32)dle_addr+(4096-1)) & ~(4096-1) ); ++ iadev->rx_dle_q.start = (struct dle*)dle_addr; ++ iadev->rx_dle_q.read = iadev->rx_dle_q.start; ++ iadev->rx_dle_q.write = iadev->rx_dle_q.start; ++ iadev->rx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES); ++ /* the end of the dle q points to the entry after the last ++ DLE that can be used. */ ++ ++ /* write the upper 20 bits of the start address to rx list address register */ ++ writel(virt_to_bus(dle_addr) & 0xfffff000, iadev->dma+IPHASE5575_RX_LIST_ADDR); ++ IF_INIT(printk("Tx Dle list addr: 0x%08x value: 0x%0x\n", ++ (u32)(iadev->dma+IPHASE5575_TX_LIST_ADDR), ++ *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR)); ++ printk("Rx Dle list addr: 0x%08x value: 0x%0x\n", ++ (u32)(iadev->dma+IPHASE5575_RX_LIST_ADDR), ++ *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));) ++ ++ writew(0xffff, iadev->reass_reg+REASS_MASK_REG); ++ writew(0, iadev->reass_reg+MODE_REG); ++ writew(RESET_REASS, iadev->reass_reg+REASS_COMMAND_REG); ++ ++ /* Receive side control memory map ++ ------------------------------- ++ ++ Buffer descr 0x0000 (736 - 23K) ++ VP Table 0x5c00 (256 - 512) ++ Except q 0x5e00 (128 - 512) ++ Free buffer q 0x6000 (1K - 2K) ++ Packet comp q 0x6800 (1K - 2K) ++ Reass Table 0x7000 (1K - 2K) ++ VC Table 0x7800 (1K - 2K) ++ ABR VC Table 0x8000 (1K - 32K) ++ */ ++ ++ /* Base address for Buffer Descriptor Table */ ++ writew(RX_DESC_BASE >> 16, iadev->reass_reg+REASS_DESC_BASE); ++ /* Set the buffer size register */ ++ writew(iadev->rx_buf_sz, iadev->reass_reg+BUF_SIZE); ++ ++ /* Initialize each entry in the Buffer Descriptor Table */ ++ iadev->RX_DESC_BASE_ADDR = iadev->reass_ram+RX_DESC_BASE*iadev->memSize; ++ buf_desc_ptr =(struct rx_buf_desc *)iadev->RX_DESC_BASE_ADDR; ++ memset((caddr_t)buf_desc_ptr, 0, sizeof(struct rx_buf_desc)); ++ buf_desc_ptr++; ++ rx_pkt_start = iadev->rx_pkt_ram; ++ for(i=1; i<=iadev->num_rx_desc; i++) ++ { ++ memset((caddr_t)buf_desc_ptr, 0, sizeof(struct rx_buf_desc)); ++ buf_desc_ptr->buf_start_hi = rx_pkt_start >> 16; ++ buf_desc_ptr->buf_start_lo = rx_pkt_start & 0x0000ffff; ++ buf_desc_ptr++; ++ rx_pkt_start += iadev->rx_buf_sz; ++ } ++ IF_INIT(printk("Rx Buffer desc ptr: 0x%0x\n", (u32)(buf_desc_ptr));) ++ i = FREE_BUF_DESC_Q*iadev->memSize; ++ writew(i >> 16, iadev->reass_reg+REASS_QUEUE_BASE); ++ writew(i, iadev->reass_reg+FREEQ_ST_ADR); ++ writew(i+iadev->num_rx_desc*sizeof(u_short), ++ iadev->reass_reg+FREEQ_ED_ADR); ++ writew(i, iadev->reass_reg+FREEQ_RD_PTR); ++ writew(i+iadev->num_rx_desc*sizeof(u_short), ++ iadev->reass_reg+FREEQ_WR_PTR); ++ /* Fill the FREEQ with all the free descriptors. */ ++ freeq_st_adr = readw(iadev->reass_reg+FREEQ_ST_ADR); ++ freeq_start = (u_short *)(iadev->reass_ram+freeq_st_adr); ++ for(i=1; i<=iadev->num_rx_desc; i++) ++ { ++ *freeq_start = (u_short)i; ++ freeq_start++; ++ } ++ IF_INIT(printk("freeq_start: 0x%0x\n", (u32)freeq_start);) ++ /* Packet Complete Queue */ ++ i = (PKT_COMP_Q * iadev->memSize) & 0xffff; ++ writew(i, iadev->reass_reg+PCQ_ST_ADR); ++ writew(i+iadev->num_vc*sizeof(u_short), iadev->reass_reg+PCQ_ED_ADR); ++ writew(i, iadev->reass_reg+PCQ_RD_PTR); ++ writew(i, iadev->reass_reg+PCQ_WR_PTR); ++ ++ /* Exception Queue */ ++ i = (EXCEPTION_Q * iadev->memSize) & 0xffff; ++ writew(i, iadev->reass_reg+EXCP_Q_ST_ADR); ++ writew(i + NUM_RX_EXCP * sizeof(RX_ERROR_Q), ++ iadev->reass_reg+EXCP_Q_ED_ADR); ++ writew(i, iadev->reass_reg+EXCP_Q_RD_PTR); ++ writew(i, iadev->reass_reg+EXCP_Q_WR_PTR); ++ ++ /* Load local copy of FREEQ and PCQ ptrs */ ++ iadev->rfL.fdq_st = readw(iadev->reass_reg+FREEQ_ST_ADR) & 0xffff; ++ iadev->rfL.fdq_ed = readw(iadev->reass_reg+FREEQ_ED_ADR) & 0xffff ; ++ iadev->rfL.fdq_rd = readw(iadev->reass_reg+FREEQ_RD_PTR) & 0xffff; ++ iadev->rfL.fdq_wr = readw(iadev->reass_reg+FREEQ_WR_PTR) & 0xffff; ++ iadev->rfL.pcq_st = readw(iadev->reass_reg+PCQ_ST_ADR) & 0xffff; ++ iadev->rfL.pcq_ed = readw(iadev->reass_reg+PCQ_ED_ADR) & 0xffff; ++ iadev->rfL.pcq_rd = readw(iadev->reass_reg+PCQ_RD_PTR) & 0xffff; ++ iadev->rfL.pcq_wr = readw(iadev->reass_reg+PCQ_WR_PTR) & 0xffff; ++ ++ IF_INIT(printk("INIT:pcq_st:0x%x pcq_ed:0x%x pcq_rd:0x%x pcq_wr:0x%x", ++ iadev->rfL.pcq_st, iadev->rfL.pcq_ed, iadev->rfL.pcq_rd, ++ iadev->rfL.pcq_wr);) ++ /* just for check - no VP TBL */ ++ /* VP Table */ ++ /* writew(0x0b80, iadev->reass_reg+VP_LKUP_BASE); */ ++ /* initialize VP Table for invalid VPIs ++ - I guess we can write all 1s or 0x000f in the entire memory ++ space or something similar. ++ */ ++ ++ /* This seems to work and looks right to me too !!! */ ++ i = REASS_TABLE * iadev->memSize; ++ writew((i >> 3), iadev->reass_reg+REASS_TABLE_BASE); ++ /* initialize Reassembly table to I don't know what ???? */ ++ reass_table = (u16 *)(iadev->reass_ram+i); ++ j = REASS_TABLE_SZ * iadev->memSize; ++ for(i=0; i < j; i++) ++ *reass_table++ = NO_AAL5_PKT; ++ i = 8*1024; ++ vcsize_sel = 0; ++ while (i != iadev->num_vc) { ++ i /= 2; ++ vcsize_sel++; ++ } ++ i = RX_VC_TABLE * iadev->memSize; ++ writew(((i>>3) & 0xfff8) | vcsize_sel, iadev->reass_reg+VC_LKUP_BASE); ++ vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize); ++ j = RX_VC_TABLE_SZ * iadev->memSize; ++ for(i = 0; i < j; i++) ++ { ++ /* shift the reassembly pointer by 3 + lower 3 bits of ++ vc_lkup_base register (=3 for 1K VCs) and the last byte ++ is those low 3 bits. ++ Shall program this later. ++ */ ++ *vc_table = (i << 6) | 15; /* for invalid VCI */ ++ vc_table++; ++ } ++ /* ABR VC table */ ++ i = ABR_VC_TABLE * iadev->memSize; ++ writew(i >> 3, iadev->reass_reg+ABR_LKUP_BASE); ++ ++ i = ABR_VC_TABLE * iadev->memSize; ++ abr_vc_table = (struct abr_vc_table *)(iadev->reass_ram+i); ++ j = REASS_TABLE_SZ * iadev->memSize; ++ memset ((char*)abr_vc_table, 0, j * sizeof(struct abr_vc_table ) ); ++ for(i = 0; i < j; i++) { ++ abr_vc_table->rdf = 0x0003; ++ abr_vc_table->air = 0x5eb1; ++ abr_vc_table++; ++ } ++ ++ /* Initialize other registers */ ++ ++ /* VP Filter Register set for VC Reassembly only */ ++ writew(0xff00, iadev->reass_reg+VP_FILTER); ++ writew(0, iadev->reass_reg+XTRA_RM_OFFSET); ++ writew(0x1, iadev->reass_reg+PROTOCOL_ID); ++ ++ /* Packet Timeout Count related Registers : ++ Set packet timeout to occur in about 3 seconds ++ Set Packet Aging Interval count register to overflow in about 4 us ++ */ ++ writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT ); ++ ptr16 = (u16*)j; ++ i = ((u32)ptr16 >> 6) & 0xff; ++ ptr16 += j - 1; ++ i |=(((u32)ptr16 << 2) & 0xff00); ++ writew(i, iadev->reass_reg+TMOUT_RANGE); ++ /* initiate the desc_tble */ ++ for(i=0; inum_tx_desc;i++) ++ iadev->desc_tbl[i].timestamp = 0; ++ ++ /* to clear the interrupt status register - read it */ ++ readw(iadev->reass_reg+REASS_INTR_STATUS_REG); ++ ++ /* Mask Register - clear it */ ++ writew(~(RX_FREEQ_EMPT|RX_PKT_RCVD), iadev->reass_reg+REASS_MASK_REG); ++ ++ skb_queue_head_init(&iadev->rx_dma_q); ++ iadev->rx_free_desc_qhead = NULL; ++ iadev->rx_open =(struct atm_vcc **)kmalloc(4*iadev->num_vc,GFP_KERNEL); ++ if (!iadev->rx_open) ++ { ++ printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n", ++ dev->number); ++ return -ENOMEM; ++ } ++ memset(iadev->rx_open, 0, 4*iadev->num_vc); ++ iadev->rxing = 1; ++ iadev->rx_pkt_cnt = 0; ++ /* Mode Register */ ++ writew(R_ONLINE, iadev->reass_reg+MODE_REG); ++ return 0; ++} ++ ++ ++/* ++ The memory map suggested in appendix A and the coding for it. ++ Keeping it around just in case we change our mind later. ++ ++ Buffer descr 0x0000 (128 - 4K) ++ UBR sched 0x1000 (1K - 4K) ++ UBR Wait q 0x2000 (1K - 4K) ++ Commn queues 0x3000 Packet Ready, Trasmit comp(0x3100) ++ (128 - 256) each ++ extended VC 0x4000 (1K - 8K) ++ ABR sched 0x6000 and ABR wait queue (1K - 2K) each ++ CBR sched 0x7000 (as needed) ++ VC table 0x8000 (1K - 32K) ++*/ ++ ++static void tx_intr(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ unsigned short status; ++ unsigned long flags; ++ ++ iadev = INPH_IA_DEV(dev); ++ ++ status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG); ++ if (status & TRANSMIT_DONE){ ++ ++ IF_EVENT(printk("Tansmit Done Intr logic run\n");) ++ spin_lock_irqsave(&iadev->tx_lock, flags); ++ ia_tx_poll(iadev); ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++ writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG); ++ if (iadev->close_pending) ++ wake_up(&iadev->close_wait); ++ } ++ if (status & TCQ_NOT_EMPTY) ++ { ++ IF_EVENT(printk("TCQ_NOT_EMPTY int received\n");) ++ } ++} ++ ++static void tx_dle_intr(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ struct dle *dle, *cur_dle; ++ struct sk_buff *skb; ++ struct atm_vcc *vcc; ++ struct ia_vcc *iavcc; ++ u_int dle_lp; ++ unsigned long flags; ++ ++ iadev = INPH_IA_DEV(dev); ++ spin_lock_irqsave(&iadev->tx_lock, flags); ++ dle = iadev->tx_dle_q.read; ++ dle_lp = readl(iadev->dma+IPHASE5575_TX_LIST_ADDR) & ++ (sizeof(struct dle)*DLE_ENTRIES - 1); ++ cur_dle = (struct dle*)(iadev->tx_dle_q.start + (dle_lp >> 4)); ++ while (dle != cur_dle) ++ { ++ /* free the DMAed skb */ ++ skb = skb_dequeue(&iadev->tx_dma_q); ++ if (!skb) break; ++ vcc = ATM_SKB(skb)->vcc; ++ if (!vcc) { ++ printk("tx_dle_intr: vcc is null\n"); ++ dev_kfree_skb(skb); ++ return; ++ } ++ iavcc = INPH_IA_VCC(vcc); ++ if (!iavcc) { ++ printk("tx_dle_intr: iavcc is null\n"); ++ dev_kfree_skb(skb); ++ return; ++ } ++ if (vcc->qos.txtp.pcr >= iadev->rate_limit) { ++ if ((vcc->pop) && (skb->len != 0)) ++ { ++ vcc->pop(vcc, skb); ++ } ++ else { ++ dev_kfree_skb(skb); ++ } ++ } ++ else { /* Hold the rate-limited skb for flow control */ ++ IA_SKB_STATE(skb) |= IA_DLED; ++ skb_queue_tail(&iavcc->txing_skb, skb); ++ } ++ IF_EVENT(printk("tx_dle_intr: enque skb = 0x%x \n", (u32)skb);) ++ if (++dle == iadev->tx_dle_q.end) ++ dle = iadev->tx_dle_q.start; ++ } ++ iadev->tx_dle_q.read = dle; ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++} ++ ++static int open_tx(struct atm_vcc *vcc) ++{ ++ struct ia_vcc *ia_vcc; ++ IADEV *iadev; ++ struct main_vc *vc; ++ struct ext_vc *evc; ++ int ret; ++ IF_EVENT(printk("iadev: open_tx entered vcc->vci = %d\n", vcc->vci);) ++ if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0; ++ iadev = INPH_IA_DEV(vcc->dev); + -+ /* disable interrupts */ -+ PUT( GET(MCR) & ~IDT77105_MCR_EIP, MCR ); ++ if (iadev->phy_type & FE_25MBIT_PHY) { ++ if (vcc->qos.txtp.traffic_class == ATM_ABR) { ++ printk("IA: ABR not support\n"); ++ return -EINVAL; ++ } ++ if (vcc->qos.txtp.traffic_class == ATM_CBR) { ++ printk("IA: CBR not support\n"); ++ return -EINVAL; ++ } ++ } ++ ia_vcc = INPH_IA_VCC(vcc); ++ memset((caddr_t)ia_vcc, 0, sizeof(struct ia_vcc)); ++ if (vcc->qos.txtp.max_sdu > ++ (iadev->tx_buf_sz - sizeof(struct cpcs_trailer))){ ++ printk("IA: SDU size over the configured SDU size %d\n", ++ iadev->tx_buf_sz); ++ kfree(ia_vcc); ++ return -EINVAL; ++ } ++ ia_vcc->vc_desc_cnt = 0; ++ ia_vcc->txing = 1; ++ ++ /* find pcr */ ++ if (vcc->qos.txtp.max_pcr == ATM_MAX_PCR) ++ vcc->qos.txtp.pcr = iadev->LineRate; ++ else if ((vcc->qos.txtp.max_pcr == 0)&&( vcc->qos.txtp.pcr <= 0)) ++ vcc->qos.txtp.pcr = iadev->LineRate; ++ else if ((vcc->qos.txtp.max_pcr > vcc->qos.txtp.pcr) && (vcc->qos.txtp.max_pcr> 0)) ++ vcc->qos.txtp.pcr = vcc->qos.txtp.max_pcr; ++ if (vcc->qos.txtp.pcr > iadev->LineRate) ++ vcc->qos.txtp.pcr = iadev->LineRate; ++ ia_vcc->pcr = vcc->qos.txtp.pcr; ++ ++ if (ia_vcc->pcr > (iadev->LineRate / 6) ) ia_vcc->ltimeout = HZ / 10; ++ else if (ia_vcc->pcr > (iadev->LineRate / 130)) ia_vcc->ltimeout = HZ; ++ else if (ia_vcc->pcr <= 170) ia_vcc->ltimeout = 16 * HZ; ++ else ia_vcc->ltimeout = 2700 * HZ / ia_vcc->pcr; ++ if (ia_vcc->pcr < iadev->rate_limit) ++ skb_queue_head_init (&ia_vcc->txing_skb); ++ if (ia_vcc->pcr < iadev->rate_limit) { ++ if (vcc->qos.txtp.max_sdu != 0) { ++ if (ia_vcc->pcr > 60000) ++ vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 5; ++ else if (ia_vcc->pcr > 2000) ++ vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 4; ++ else ++ vcc->sk->sndbuf = 3*vcc->qos.txtp.max_sdu; ++ } ++ else ++ vcc->sk->sndbuf = 24576; ++ } ++ ++ vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR; ++ evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR; ++ vc += vcc->vci; ++ evc += vcc->vci; ++ memset((caddr_t)vc, 0, sizeof(struct main_vc)); ++ memset((caddr_t)evc, 0, sizeof(struct ext_vc)); ++ ++ /* store the most significant 4 bits of vci as the last 4 bits ++ of first part of atm header. ++ store the last 12 bits of vci as first 12 bits of the second ++ part of the atm header. ++ */ ++ evc->atm_hdr1 = (vcc->vci >> 12) & 0x000f; ++ evc->atm_hdr2 = (vcc->vci & 0x0fff) << 4; ++ ++ /* check the following for different traffic classes */ ++ if (vcc->qos.txtp.traffic_class == ATM_UBR) ++ { ++ vc->type = UBR; ++ vc->status = CRC_APPEND; ++ vc->acr = cellrate_to_float(iadev->LineRate); ++ if (vcc->qos.txtp.pcr > 0) ++ vc->acr = cellrate_to_float(vcc->qos.txtp.pcr); ++ IF_UBR(printk("UBR: txtp.pcr = 0x%d f_rate = 0x%x\n", ++ vcc->qos.txtp.max_pcr,vc->acr);) ++ } ++ else if (vcc->qos.txtp.traffic_class == ATM_ABR) ++ { srv_cls_param_t srv_p; ++ IF_ABR(printk("Tx ABR VCC\n");) ++ init_abr_vc(iadev, &srv_p); ++ if (vcc->qos.txtp.pcr > 0) ++ srv_p.pcr = vcc->qos.txtp.pcr; ++ if (vcc->qos.txtp.min_pcr > 0) { ++ int tmpsum = iadev->sum_mcr+iadev->sum_cbr+vcc->qos.txtp.min_pcr; ++ if (tmpsum > iadev->LineRate) ++ return -EBUSY; ++ srv_p.mcr = vcc->qos.txtp.min_pcr; ++ iadev->sum_mcr += vcc->qos.txtp.min_pcr; ++ } ++ else srv_p.mcr = 0; ++ if (vcc->qos.txtp.icr) ++ srv_p.icr = vcc->qos.txtp.icr; ++ if (vcc->qos.txtp.tbe) ++ srv_p.tbe = vcc->qos.txtp.tbe; ++ if (vcc->qos.txtp.frtt) ++ srv_p.frtt = vcc->qos.txtp.frtt; ++ if (vcc->qos.txtp.rif) ++ srv_p.rif = vcc->qos.txtp.rif; ++ if (vcc->qos.txtp.rdf) ++ srv_p.rdf = vcc->qos.txtp.rdf; ++ if (vcc->qos.txtp.nrm_pres) ++ srv_p.nrm = vcc->qos.txtp.nrm; ++ if (vcc->qos.txtp.trm_pres) ++ srv_p.trm = vcc->qos.txtp.trm; ++ if (vcc->qos.txtp.adtf_pres) ++ srv_p.adtf = vcc->qos.txtp.adtf; ++ if (vcc->qos.txtp.cdf_pres) ++ srv_p.cdf = vcc->qos.txtp.cdf; ++ if (srv_p.icr > srv_p.pcr) ++ srv_p.icr = srv_p.pcr; ++ IF_ABR(printk("ABR:vcc->qos.txtp.max_pcr = %d mcr = %d\n", ++ srv_p.pcr, srv_p.mcr);) ++ ia_open_abr_vc(iadev, &srv_p, vcc, 1); ++ } else if (vcc->qos.txtp.traffic_class == ATM_CBR) { ++ if (iadev->phy_type & FE_25MBIT_PHY) { ++ printk("IA: CBR not support\n"); ++ return -EINVAL; ++ } ++ if (vcc->qos.txtp.max_pcr > iadev->LineRate) { ++ IF_CBR(printk("PCR is not availble\n");) ++ return -1; ++ } ++ vc->type = CBR; ++ vc->status = CRC_APPEND; ++ if ((ret = ia_cbr_setup (iadev, vcc)) < 0) { ++ return ret; ++ } ++ } ++ else ++ printk("iadev: Non UBR, ABR and CBR traffic not supportedn"); + -+ /* detach private struct from atm_dev & free */ -+ for (prev = NULL, walk = idt77105_all ; -+ walk != NULL; -+ prev = walk, walk = walk->next) { -+ if (walk->dev == dev) { -+ if (prev != NULL) -+ prev->next = walk->next; -+ else -+ idt77105_all = walk->next; -+ dev->phy = NULL; -+ PRIV(dev) = NULL; -+ kfree(walk); -+ break; ++ iadev->testTable[vcc->vci]->vc_status |= VC_ACTIVE; ++ IF_EVENT(printk("ia open_tx returning \n");) ++ return 0; ++} ++ ++ ++static int tx_init(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ struct tx_buf_desc *buf_desc_ptr; ++ unsigned int tx_pkt_start; ++ u32 *dle_addr; ++ int i; ++ u_short tcq_st_adr; ++ u_short *tcq_start; ++ u_short prq_st_adr; ++ u_short *prq_start; ++ struct main_vc *vc; ++ struct ext_vc *evc; ++ u_short tmp16; ++ u32 vcsize_sel; ++ ++ iadev = INPH_IA_DEV(dev); ++ spin_lock_init(&iadev->tx_lock); ++ ++ IF_INIT(printk("Tx MASK REG: 0x%0x\n", ++ readw(iadev->seg_reg+SEG_MASK_REG));) ++ /*---------- Initializing Transmit DLEs ----------*/ ++ /* allocating 8k memory for transmit DLEs */ ++ dle_addr = (u32*)kmalloc(2*sizeof(struct dle)*DLE_ENTRIES, GFP_KERNEL); ++ if (!dle_addr) ++ { ++ printk(KERN_ERR DEV_LABEL "can't allocate TX DLEs\n"); ++ } ++ ++ /* find 4k byte boundary within the 8k allocated */ ++ dle_addr = (u32*)(((u32)dle_addr+(4096-1)) & ~(4096-1)); ++ iadev->tx_dle_q.start = (struct dle*)dle_addr; ++ iadev->tx_dle_q.read = iadev->tx_dle_q.start; ++ iadev->tx_dle_q.write = iadev->tx_dle_q.start; ++ iadev->tx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES); ++ ++ /* write the upper 20 bits of the start address to tx list address register */ ++ writel(virt_to_bus(dle_addr) & 0xfffff000, iadev->dma+IPHASE5575_TX_LIST_ADDR); ++ writew(0xffff, iadev->seg_reg+SEG_MASK_REG); ++ writew(0, iadev->seg_reg+MODE_REG_0); ++ writew(RESET_SEG, iadev->seg_reg+SEG_COMMAND_REG); ++ iadev->MAIN_VC_TABLE_ADDR = iadev->seg_ram+MAIN_VC_TABLE*iadev->memSize; ++ iadev->EXT_VC_TABLE_ADDR = iadev->seg_ram+EXT_VC_TABLE*iadev->memSize; ++ iadev->ABR_SCHED_TABLE_ADDR=iadev->seg_ram+ABR_SCHED_TABLE*iadev->memSize; ++ ++ /* ++ Transmit side control memory map ++ -------------------------------- ++ Buffer descr 0x0000 (128 - 4K) ++ Commn queues 0x1000 Transmit comp, Packet ready(0x1400) ++ (512 - 1K) each ++ TCQ - 4K, PRQ - 5K ++ CBR Table 0x1800 (as needed) - 6K ++ UBR Table 0x3000 (1K - 4K) - 12K ++ UBR Wait queue 0x4000 (1K - 4K) - 16K ++ ABR sched 0x5000 and ABR wait queue (1K - 2K) each ++ ABR Tbl - 20K, ABR Wq - 22K ++ extended VC 0x6000 (1K - 8K) - 24K ++ VC Table 0x8000 (1K - 32K) - 32K ++ ++ Between 0x2000 (8K) and 0x3000 (12K) there is 4K space left for VBR Tbl ++ and Wait q, which can be allotted later. ++ */ ++ ++ /* Buffer Descriptor Table Base address */ ++ writew(TX_DESC_BASE, iadev->seg_reg+SEG_DESC_BASE); ++ ++ /* initialize each entry in the buffer descriptor table */ ++ buf_desc_ptr =(struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE); ++ memset((caddr_t)buf_desc_ptr, 0, sizeof(struct tx_buf_desc)); ++ buf_desc_ptr++; ++ tx_pkt_start = TX_PACKET_RAM; ++ for(i=1; i<=iadev->num_tx_desc; i++) ++ { ++ memset((caddr_t)buf_desc_ptr, 0, sizeof(struct tx_buf_desc)); ++ buf_desc_ptr->desc_mode = AAL5; ++ buf_desc_ptr->buf_start_hi = tx_pkt_start >> 16; ++ buf_desc_ptr->buf_start_lo = tx_pkt_start & 0x0000ffff; ++ buf_desc_ptr++; ++ tx_pkt_start += iadev->tx_buf_sz; ++ } ++ iadev->tx_buf= (caddr_t*)kmalloc(iadev->num_tx_desc*sizeof(caddr_t), ++ GFP_KERNEL); ++ if (!iadev->tx_buf) { ++ printk(KERN_ERR DEV_LABEL " couldn't get mem\n"); ++ return -EAGAIN; ++ } ++ for (i= 0; i< iadev->num_tx_desc; i++) ++ { ++ ++ iadev->tx_buf[i] =(caddr_t)kmalloc(sizeof(struct cpcs_trailer), ++ GFP_KERNEL|GFP_DMA); ++ if(!iadev->tx_buf[i]) { ++ printk(KERN_ERR DEV_LABEL " couldn't get freepage\n"); ++ return -EAGAIN; + } + } ++ iadev->desc_tbl = (struct desc_tbl_t *)kmalloc(iadev->num_tx_desc * ++ sizeof(struct desc_tbl_t), GFP_KERNEL); ++ ++ /* Communication Queues base address */ ++ i = TX_COMP_Q * iadev->memSize; ++ writew(i >> 16, iadev->seg_reg+SEG_QUEUE_BASE); ++ ++ /* Transmit Complete Queue */ ++ writew(i, iadev->seg_reg+TCQ_ST_ADR); ++ writew(i, iadev->seg_reg+TCQ_RD_PTR); ++ writew(i+iadev->num_tx_desc*sizeof(u_short),iadev->seg_reg+TCQ_WR_PTR); ++ iadev->host_tcq_wr = i + iadev->num_tx_desc*sizeof(u_short); ++ writew(i+2 * iadev->num_tx_desc * sizeof(u_short), ++ iadev->seg_reg+TCQ_ED_ADR); ++ /* Fill the TCQ with all the free descriptors. */ ++ tcq_st_adr = readw(iadev->seg_reg+TCQ_ST_ADR); ++ tcq_start = (u_short *)(iadev->seg_ram+tcq_st_adr); ++ for(i=1; i<=iadev->num_tx_desc; i++) ++ { ++ *tcq_start = (u_short)i; ++ tcq_start++; ++ } ++ ++ /* Packet Ready Queue */ ++ i = PKT_RDY_Q * iadev->memSize; ++ writew(i, iadev->seg_reg+PRQ_ST_ADR); ++ writew(i+2 * iadev->num_tx_desc * sizeof(u_short), ++ iadev->seg_reg+PRQ_ED_ADR); ++ writew(i, iadev->seg_reg+PRQ_RD_PTR); ++ writew(i, iadev->seg_reg+PRQ_WR_PTR); ++ ++ /* Load local copy of PRQ and TCQ ptrs */ ++ iadev->ffL.prq_st = readw(iadev->seg_reg+PRQ_ST_ADR) & 0xffff; ++ iadev->ffL.prq_ed = readw(iadev->seg_reg+PRQ_ED_ADR) & 0xffff; ++ iadev->ffL.prq_wr = readw(iadev->seg_reg+PRQ_WR_PTR) & 0xffff; ++ ++ iadev->ffL.tcq_st = readw(iadev->seg_reg+TCQ_ST_ADR) & 0xffff; ++ iadev->ffL.tcq_ed = readw(iadev->seg_reg+TCQ_ED_ADR) & 0xffff; ++ iadev->ffL.tcq_rd = readw(iadev->seg_reg+TCQ_RD_PTR) & 0xffff; ++ ++ /* Just for safety initializing the queue to have desc 1 always */ ++ /* Fill the PRQ with all the free descriptors. */ ++ prq_st_adr = readw(iadev->seg_reg+PRQ_ST_ADR); ++ prq_start = (u_short *)(iadev->seg_ram+prq_st_adr); ++ for(i=1; i<=iadev->num_tx_desc; i++) ++ { ++ *prq_start = (u_short)0; /* desc 1 in all entries */ ++ prq_start++; ++ } ++ /* CBR Table */ ++ IF_INIT(printk("Start CBR Init\n");) ++#if 1 /* for 1K VC board, CBR_PTR_BASE is 0 */ ++ writew(0,iadev->seg_reg+CBR_PTR_BASE); ++#else /* Charlie's logic is wrong ? */ ++ tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize)>>17; ++ IF_INIT(printk("cbr_ptr_base = 0x%x ", tmp16);) ++ writew(tmp16,iadev->seg_reg+CBR_PTR_BASE); ++#endif + -+#ifdef MODULE -+ MOD_DEC_USE_COUNT; -+#endif /* MODULE */ -+ return 0; ++ IF_INIT(printk("value in register = 0x%x\n", ++ readw(iadev->seg_reg+CBR_PTR_BASE));) ++ tmp16 = (CBR_SCHED_TABLE*iadev->memSize) >> 1; ++ writew(tmp16, iadev->seg_reg+CBR_TAB_BEG); ++ IF_INIT(printk("cbr_tab_beg = 0x%x in reg = 0x%x \n", tmp16, ++ readw(iadev->seg_reg+CBR_TAB_BEG));) ++ writew(tmp16, iadev->seg_reg+CBR_TAB_END+1); // CBR_PTR; ++ tmp16 = (CBR_SCHED_TABLE*iadev->memSize + iadev->num_vc*6 - 2) >> 1; ++ writew(tmp16, iadev->seg_reg+CBR_TAB_END); ++ IF_INIT(printk("iadev->seg_reg = 0x%x CBR_PTR_BASE = 0x%x\n", ++ (u32)iadev->seg_reg, readw(iadev->seg_reg+CBR_PTR_BASE));) ++ IF_INIT(printk("CBR_TAB_BEG = 0x%x, CBR_TAB_END = 0x%x, CBR_PTR = 0x%x\n", ++ readw(iadev->seg_reg+CBR_TAB_BEG), readw(iadev->seg_reg+CBR_TAB_END), ++ readw(iadev->seg_reg+CBR_TAB_END+1));) ++ tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize); ++ ++ /* Initialize the CBR Schedualing Table */ ++ memset((caddr_t)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize), ++ 0, iadev->num_vc*6); ++ iadev->CbrRemEntries = iadev->CbrTotEntries = iadev->num_vc*3; ++ iadev->CbrEntryPt = 0; ++ iadev->Granularity = MAX_ATM_155 / iadev->CbrTotEntries; ++ iadev->NumEnabledCBR = 0; ++ ++ /* UBR scheduling Table and wait queue */ ++ /* initialize all bytes of UBR scheduler table and wait queue to 0 ++ - SCHEDSZ is 1K (# of entries). ++ - UBR Table size is 4K ++ - UBR wait queue is 4K ++ since the table and wait queues are contiguous, all the bytes ++ can be intialized by one memeset. ++ */ ++ ++ vcsize_sel = 0; ++ i = 8*1024; ++ while (i != iadev->num_vc) { ++ i /= 2; ++ vcsize_sel++; ++ } ++ ++ i = MAIN_VC_TABLE * iadev->memSize; ++ writew(vcsize_sel | ((i >> 8) & 0xfff8),iadev->seg_reg+VCT_BASE); ++ i = EXT_VC_TABLE * iadev->memSize; ++ writew((i >> 8) & 0xfffe, iadev->seg_reg+VCTE_BASE); ++ i = UBR_SCHED_TABLE * iadev->memSize; ++ writew((i & 0xffff) >> 11, iadev->seg_reg+UBR_SBPTR_BASE); ++ i = UBR_WAIT_Q * iadev->memSize; ++ writew((i >> 7) & 0xffff, iadev->seg_reg+UBRWQ_BASE); ++ memset((caddr_t)(iadev->seg_ram+UBR_SCHED_TABLE*iadev->memSize), ++ 0, iadev->num_vc*8); ++ /* ABR scheduling Table(0x5000-0x57ff) and wait queue(0x5800-0x5fff)*/ ++ /* initialize all bytes of ABR scheduler table and wait queue to 0 ++ - SCHEDSZ is 1K (# of entries). ++ - ABR Table size is 2K ++ - ABR wait queue is 2K ++ since the table and wait queues are contiguous, all the bytes ++ can be intialized by one memeset. ++ */ ++ i = ABR_SCHED_TABLE * iadev->memSize; ++ writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE); ++ i = ABR_WAIT_Q * iadev->memSize; ++ writew((i >> 7) & 0xffff, iadev->seg_reg+ABRWQ_BASE); ++ ++ i = ABR_SCHED_TABLE*iadev->memSize; ++ memset((caddr_t)(iadev->seg_ram+i), 0, iadev->num_vc*4); ++ vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR; ++ evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR; ++ iadev->testTable = (struct testTable_t **) ++ kmalloc(sizeof(long)*iadev->num_vc, GFP_KERNEL); ++ if (!iadev->testTable) { ++ printk("Get freepage failed\n"); ++ return -EAGAIN; ++ } ++ for(i=0; inum_vc; i++) ++ { ++ memset((caddr_t)vc, 0, sizeof(struct main_vc)); ++ memset((caddr_t)evc, 0, sizeof(struct ext_vc)); ++ iadev->testTable[i] = (struct testTable_t *) ++ kmalloc(sizeof(struct testTable_t), GFP_KERNEL); ++ iadev->testTable[i]->lastTime = 0; ++ iadev->testTable[i]->fract = 0; ++ iadev->testTable[i]->vc_status = VC_UBR; ++ vc++; ++ evc++; ++ } ++ ++ /* Other Initialization */ ++ ++ /* Max Rate Register */ ++ if (iadev->phy_type & FE_25MBIT_PHY) { ++ writew(RATE25, iadev->seg_reg+MAXRATE); ++ writew((UBR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS); ++ } ++ else { ++ writew(cellrate_to_float(iadev->LineRate),iadev->seg_reg+MAXRATE); ++ writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS); ++ } ++ /* Set Idle Header Reigisters to be sure */ ++ writew(0, iadev->seg_reg+IDLEHEADHI); ++ writew(0, iadev->seg_reg+IDLEHEADLO); ++ ++ /* Program ABR UBR Priority Register as PRI_ABR_UBR_EQUAL */ ++ writew(0xaa00, iadev->seg_reg+ABRUBR_ARB); ++ ++ iadev->close_pending = 0; ++#if LINUX_VERSION_CODE >= 0x20303 ++ init_waitqueue_head(&iadev->close_wait); ++ init_waitqueue_head(&iadev->timeout_wait); ++#else ++ iadev->close_wait = NULL; ++ iadev->timeout_wait = NULL; ++#endif ++ skb_queue_head_init(&iadev->tx_dma_q); ++ ia_init_rtn_q(&iadev->tx_return_q); ++ ++ /* RM Cell Protocol ID and Message Type */ ++ writew(RM_TYPE_4_0, iadev->seg_reg+RM_TYPE); ++ skb_queue_head_init (&iadev->tx_backlog); ++ ++ /* Mode Register 1 */ ++ writew(MODE_REG_1_VAL, iadev->seg_reg+MODE_REG_1); ++ ++ /* Mode Register 0 */ ++ writew(T_ONLINE, iadev->seg_reg+MODE_REG_0); ++ ++ /* Interrupt Status Register - read to clear */ ++ readw(iadev->seg_reg+SEG_INTR_STATUS_REG); ++ ++ /* Interrupt Mask Reg- don't mask TCQ_NOT_EMPTY interrupt generation */ ++ writew(~(TRANSMIT_DONE | TCQ_NOT_EMPTY), iadev->seg_reg+SEG_MASK_REG); ++ writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG); ++ iadev->tx_pkt_cnt = 0; ++ iadev->rate_limit = iadev->LineRate / 3; ++ ++ return 0; ++} ++ ++static void ia_int(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct atm_dev *dev; ++ IADEV *iadev; ++ unsigned int status; ++ ++ dev = dev_id; ++ iadev = INPH_IA_DEV(dev); ++ while( (status = readl(iadev->reg+IPHASE5575_BUS_STATUS_REG) & 0x7f)) ++ { ++ IF_EVENT(printk("ia_int: status = 0x%x\n", status);) ++ if (status & STAT_REASSINT) ++ { ++ /* do something */ ++ IF_EVENT(printk("REASSINT Bus status reg: %08x\n", status);) ++ rx_intr(dev); ++ } ++ if (status & STAT_DLERINT) ++ { ++ /* Clear this bit by writing a 1 to it. */ ++ *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT; ++ rx_dle_intr(dev); ++ } ++ if (status & STAT_SEGINT) ++ { ++ /* do something */ ++ IF_EVENT(printk("IA: tx_intr \n");) ++ tx_intr(dev); ++ } ++ if (status & STAT_DLETINT) ++ { ++ *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT; ++ tx_dle_intr(dev); ++ } ++ if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT)) ++ { ++ if (status & STAT_FEINT) ++ IaFrontEndIntr(iadev); ++ } ++ } ++} ++ ++ ++ ++/*----------------------------- entries --------------------------------*/ ++static int get_esi(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ int i; ++ u32 mac1; ++ u16 mac2; ++ ++ iadev = INPH_IA_DEV(dev); ++ mac1 = cpu_to_be32(le32_to_cpu(readl( ++ iadev->reg+IPHASE5575_MAC1))); ++ mac2 = cpu_to_be16(le16_to_cpu(readl(iadev->reg+IPHASE5575_MAC2))); ++ IF_INIT(printk("ESI: 0x%08x%04x\n", mac1, mac2);) ++ for (i=0; iesi[i] = mac1 >>(8*(MAC1_LEN-1-i)); ++ ++ for (i=0; iesi[i+MAC1_LEN] = mac2 >>(8*(MAC2_LEN - 1 -i)); ++ return 0; ++} ++ ++static int reset_sar(struct atm_dev *dev) ++{ ++ IADEV *iadev; ++ int i, error = 1; ++ unsigned int pci[64]; ++ ++ iadev = INPH_IA_DEV(dev); ++ for(i=0; i<64; i++) ++ if ((error = pci_read_config_dword(iadev->pci, ++ i*4, &pci[i])) != PCIBIOS_SUCCESSFUL) ++ return error; ++ writel(0, iadev->reg+IPHASE5575_EXT_RESET); ++ for(i=0; i<64; i++) ++ if ((error = pci_write_config_dword(iadev->pci, ++ i*4, pci[i])) != PCIBIOS_SUCCESSFUL) ++ return error; ++ udelay(5); ++ return 0; ++} ++ ++ ++#if LINUX_VERSION_CODE >= 0x20312 ++static int __init ia_init(struct atm_dev *dev) ++#else ++__initfunc(static int ia_init(struct atm_dev *dev)) ++#endif ++{ ++ IADEV *iadev; ++ unsigned int real_base, base; ++ unsigned short command; ++ unsigned char revision; ++ int error, i; ++ ++ /* The device has been identified and registered. Now we read ++ necessary configuration info like memory base address, ++ interrupt number etc */ ++ ++ IF_INIT(printk(">ia_init\n");) ++ dev->ci_range.vpi_bits = 0; ++ dev->ci_range.vci_bits = NR_VCI_LD; ++ ++ iadev = INPH_IA_DEV(dev); ++ ++ if ((error = pci_read_config_word(iadev->pci, PCI_COMMAND,&command)) ++ || (error = pci_read_config_dword(iadev->pci, ++ PCI_BASE_ADDRESS_0,&real_base)) ++ || (error = pci_read_config_byte(iadev->pci, ++ PCI_INTERRUPT_LINE,&iadev->irq)) ++ || (error = pci_read_config_byte(iadev->pci, ++ PCI_REVISION_ID,&revision))) ++ { ++ printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%x\n", ++ dev->number,error); ++ return -EINVAL; ++ } ++ IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%x,irq=%d\n", ++ dev->number, revision, real_base, iadev->irq);) ++ ++ /* find mapping size of board */ ++ ++ /* write all 1's into the base address register. ++ read the register whic returns us 0's in the don't care bits. ++ size is calculated as ~(don't cre bits) + 1 */ ++ ++ if (pci_write_config_dword(iadev->pci, ++ PCI_BASE_ADDRESS_0, 0xffffffff)!=PCIBIOS_SUCCESSFUL) ++ { ++ printk(DEV_LABEL "(itf %d): init error 0x%x\n",dev->number, ++ error); ++ return -EINVAL; ++ } ++ if(pci_read_config_dword(iadev->pci, PCI_BASE_ADDRESS_0, ++ &(iadev->pci_map_size)) !=PCIBIOS_SUCCESSFUL) ++ { ++ printk(DEV_LABEL "(itf %d): init error 0x%x\n",dev->number, ++ error); ++ return -EINVAL; ++ } ++ iadev->pci_map_size &= PCI_BASE_ADDRESS_MEM_MASK; ++ iadev->pci_map_size = ~iadev->pci_map_size + 1; ++ if (iadev->pci_map_size == 0x100000){ ++ iadev->num_vc = 4096; ++ dev->ci_range.vci_bits = NR_VCI_4K_LD; ++ iadev->memSize = 4; ++ } ++ else if (iadev->pci_map_size == 0x40000) { ++ iadev->num_vc = 1024; ++ iadev->memSize = 1; ++ } ++ else { ++ printk("Unknown pci_map_size = 0x%x\n", iadev->pci_map_size); ++ return -EINVAL; ++ } ++ IF_INIT(printk (DEV_LABEL "map size: %i\n", iadev->pci_map_size);) ++ if(pci_write_config_dword(iadev->pci, PCI_BASE_ADDRESS_0, ++ real_base)!=PCIBIOS_SUCCESSFUL) ++ { ++ printk(DEV_LABEL "(itf %d): init error 0x%x\n",dev->number, ++ error); ++ return -EINVAL; ++ } ++ ++ /* strip flags (last 4 bits ) ---> mask with 0xfffffff0 */ ++ real_base &= MEM_VALID; ++ /* enabling the responses in memory space */ ++ command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ if ((error = pci_write_config_word(iadev->pci, ++ PCI_COMMAND, command))) ++ { ++ printk(DEV_LABEL "(itf %d): can't enable memory (0x%x)\n", ++ dev->number,error); ++ return error; ++ } ++ /* ++ * Delay at least 1us before doing any mem accesses (how 'bout 10?) ++ */ ++ udelay(10); ++ ++ /* mapping the physical address to a virtual address in address space */ ++ base=(unsigned long)ioremap((unsigned long)real_base,iadev->pci_map_size); /* ioremap is not resolved ??? */ ++ ++ if (!base) ++ { ++ printk(DEV_LABEL " (itf %d): can't set up page mapping\n", ++ dev->number); ++ return error; ++ } ++ IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=0x%x,irq=%d\n", ++ dev->number, revision, base, iadev->irq);) ++ ++ /* filling the iphase dev structure */ ++ iadev->mem = iadev->pci_map_size /2; ++ iadev->base_diff = real_base - base; ++ iadev->real_base = real_base; ++ iadev->base = base; ++ ++ /* Bus Interface Control Registers */ ++ iadev->reg = (u32 *) (base + REG_BASE); ++ /* Segmentation Control Registers */ ++ iadev->seg_reg = (u32 *) (base + SEG_BASE); ++ /* Reassembly Control Registers */ ++ iadev->reass_reg = (u32 *) (base + REASS_BASE); ++ /* Front end/ DMA control registers */ ++ iadev->phy = (u32 *) (base + PHY_BASE); ++ iadev->dma = (u32 *) (base + PHY_BASE); ++ /* RAM - Segmentation RAm and Reassembly RAM */ ++ iadev->ram = (u32 *) (base + ACTUAL_RAM_BASE); ++ iadev->seg_ram = (base + ACTUAL_SEG_RAM_BASE); ++ iadev->reass_ram = (base + ACTUAL_REASS_RAM_BASE); ++ ++ /* lets print out the above */ ++ IF_INIT(printk("Base addrs: %08x %08x %08x \n %08x %08x %08x %08x\n", ++ (u32)iadev->reg,(u32)iadev->seg_reg,(u32)iadev->reass_reg, ++ (u32)iadev->phy, (u32)iadev->ram, (u32)iadev->seg_ram, ++ (u32)iadev->reass_ram);) ++ ++ /* lets try reading the MAC address */ ++ error = get_esi(dev); ++ if (error) return error; ++ printk("IA: "); ++ for (i=0; i < ESI_LEN; i++) ++ printk("%s%02X",i ? "-" : "",dev->esi[i]); ++ printk("\n"); ++ ++ /* reset SAR */ ++ if (reset_sar(dev)) { ++ printk("IA: reset SAR fail, please try again\n"); ++ return 1; ++ } ++ return 0; ++} ++ ++static void ia_update_stats(IADEV *iadev) { ++ if (!iadev->carrier_detect) ++ return; ++ iadev->rx_cell_cnt += readw(iadev->reass_reg+CELL_CTR0)&0xffff; ++ iadev->rx_cell_cnt += (readw(iadev->reass_reg+CELL_CTR1) & 0xffff) << 16; ++ iadev->drop_rxpkt += readw(iadev->reass_reg + DRP_PKT_CNTR ) & 0xffff; ++ iadev->drop_rxcell += readw(iadev->reass_reg + ERR_CNTR) & 0xffff; ++ iadev->tx_cell_cnt += readw(iadev->seg_reg + CELL_CTR_LO_AUTO)&0xffff; ++ iadev->tx_cell_cnt += (readw(iadev->seg_reg+CELL_CTR_HIGH_AUTO)&0xffff)<<16; ++ return; ++} ++ ++static void ia_led_timer(unsigned long arg) { ++ unsigned long flags; ++ static u_char blinking[8] = {0, 0, 0, 0, 0, 0, 0, 0}; ++ u_char i; ++ static u32 ctrl_reg; ++ for (i = 0; i < iadev_count; i++) { ++ if (ia_dev[i]) { ++ ctrl_reg = readl(ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG); ++ if (blinking[i] == 0) { ++ blinking[i]++; ++ ctrl_reg &= (~CTRL_LED); ++ writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG); ++ ia_update_stats(ia_dev[i]); ++ } ++ else { ++ blinking[i] = 0; ++ ctrl_reg |= CTRL_LED; ++ writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG); ++ spin_lock_irqsave(&ia_dev[i]->tx_lock, flags); ++ if (ia_dev[i]->close_pending) ++ wake_up(&ia_dev[i]->close_wait); ++ ia_tx_poll(ia_dev[i]); ++ spin_unlock_irqrestore(&ia_dev[i]->tx_lock, flags); ++ } ++ } ++ } ++ mod_timer(&ia_timer, jiffies + HZ / 4); ++ return; +} + ++static void ia_phy_put(struct atm_dev *dev, unsigned char value, ++ unsigned long addr) ++{ ++ writel(value, INPH_IA_DEV(dev)->phy+addr); ++} ++ ++static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr) ++{ ++ return readl(INPH_IA_DEV(dev)->phy+addr); ++} + ++#if LINUX_VERSION_CODE >= 0x20312 ++static int __init ia_start(struct atm_dev *dev) ++#else ++__initfunc(static int ia_start(struct atm_dev *dev)) ++#endif ++{ ++ IADEV *iadev; ++ int error = 1; ++ unsigned char phy; ++ u32 ctrl_reg; ++ IF_EVENT(printk(">ia_start\n");) ++ iadev = INPH_IA_DEV(dev); ++ if (request_irq(iadev->irq, &ia_int, SA_SHIRQ, DEV_LABEL, dev)) { ++ printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n", ++ dev->number, iadev->irq); ++ return -EAGAIN; ++ } ++ /* @@@ should release IRQ on error */ ++ /* enabling memory + master */ ++ if ((error = pci_write_config_word(iadev->pci, ++ PCI_COMMAND, ++ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER ))) ++ { ++ printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+" ++ "master (0x%x)\n",dev->number, error); ++ free_irq(iadev->irq, dev); ++ return error; ++ } ++ udelay(10); ++ ++ /* Maybe we should reset the front end, initialize Bus Interface Control ++ Registers and see. */ ++ ++ IF_INIT(printk("Bus ctrl reg: %08x\n", ++ readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));) ++ ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG); ++ ctrl_reg = (ctrl_reg & (CTRL_LED | CTRL_FE_RST)) ++ | CTRL_B8 ++ | CTRL_B16 ++ | CTRL_B32 ++ | CTRL_B48 ++ | CTRL_B64 ++ | CTRL_B128 ++ | CTRL_ERRMASK ++ | CTRL_DLETMASK /* shud be removed l8r */ ++ | CTRL_DLERMASK ++ | CTRL_SEGMASK ++ | CTRL_REASSMASK ++ | CTRL_FEMASK ++ | CTRL_CSPREEMPT; ++ ++ writel(ctrl_reg, iadev->reg+IPHASE5575_BUS_CONTROL_REG); ++ ++ IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", ++ readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG)); ++ printk("Bus status reg after init: %08x\n", ++ readl(iadev->reg+IPHASE5575_BUS_STATUS_REG));) ++ ++ ia_hw_type(iadev); ++ error = tx_init(dev); ++ if (error) { ++ free_irq(iadev->irq, dev); ++ return error; ++ } ++ error = rx_init(dev); ++ if (error) { ++ free_irq(iadev->irq, dev); ++ return error; ++ } ++ ++ ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG); ++ writel(ctrl_reg | CTRL_FE_RST, iadev->reg+IPHASE5575_BUS_CONTROL_REG); ++ IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", ++ readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));) ++ phy = 0; /* resolve compiler complaint */ ++ IF_INIT ( ++ if ((phy=ia_phy_get(dev,0)) == 0x30) ++ printk("IA: pm5346,rev.%d\n",phy&0x0f); ++ else ++ printk("IA: utopia,rev.%0x\n",phy);) ++ ++ if (iadev->phy_type & FE_25MBIT_PHY) { ++ ia_mb25_init(iadev); ++ return 0; ++ } ++ if (iadev->phy_type & (FE_DS3_PHY | FE_E3_PHY)) { ++ ia_suni_pm7345_init(iadev); ++ return 0; ++ } + -+EXPORT_SYMBOL(idt77105_init); -+EXPORT_SYMBOL(idt77105_stop); ++ error = suni_init(dev); ++ if (error) { ++ free_irq(iadev->irq, dev); ++ return error; ++ } + -+#ifdef MODULE ++ /* Enable interrupt on loss of signal SUNI_RSOP_CIE 0x10 ++ SUNI_RSOP_CIE_LOSE - 0x04 ++ */ ++ ia_phy_put(dev, ia_phy_get(dev,0x10) | 0x04, 0x10); ++#ifndef MODULE ++ error = dev->phy->start(dev); ++ if (error) { ++ free_irq(iadev->irq, dev); ++ return error; ++ } ++#endif ++ /* Get iadev->carrier_detect status */ ++ IaFrontEndIntr(iadev); ++ return 0; ++} ++ ++static void ia_close(struct atm_vcc *vcc) ++{ ++ u16 *vc_table; ++ IADEV *iadev; ++ struct ia_vcc *ia_vcc; ++ struct sk_buff *skb = NULL; ++ struct sk_buff_head tmp_tx_backlog, tmp_vcc_backlog; ++ unsigned long closetime, flags; ++ int ctimeout; ++ ++ iadev = INPH_IA_DEV(vcc->dev); ++ ia_vcc = INPH_IA_VCC(vcc); ++ if (!ia_vcc) return; ++ ++ IF_EVENT(printk("ia_close: ia_vcc->vc_desc_cnt = %d vci = %d\n", ++ ia_vcc->vc_desc_cnt,vcc->vci);) ++ vcc->flags &= ~ATM_VF_READY; ++ skb_queue_head_init (&tmp_tx_backlog); ++ skb_queue_head_init (&tmp_vcc_backlog); ++ if (vcc->qos.txtp.traffic_class != ATM_NONE) { ++ iadev->close_pending++; ++ sleep_on_timeout(&iadev->timeout_wait, 50); ++ spin_lock_irqsave(&iadev->tx_lock, flags); ++ while((skb = skb_dequeue(&iadev->tx_backlog))) { ++ if (ATM_SKB(skb)->vcc == vcc){ ++ if (vcc->pop) vcc->pop(vcc, skb); ++ else dev_kfree_skb(skb); ++ } ++ else ++ skb_queue_tail(&tmp_tx_backlog, skb); ++ } ++ while((skb = skb_dequeue(&tmp_tx_backlog))) ++ skb_queue_tail(&iadev->tx_backlog, skb); ++ IF_EVENT(printk("IA TX Done decs_cnt = %d\n", ia_vcc->vc_desc_cnt);) ++ closetime = jiffies; ++ ctimeout = 300000 / ia_vcc->pcr; ++ if (ctimeout == 0) ++ ctimeout = 1; ++ while (ia_vcc->vc_desc_cnt > 0){ ++ if ((jiffies - closetime) >= ctimeout) ++ break; ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++ sleep_on(&iadev->close_wait); ++ spin_lock_irqsave(&iadev->tx_lock, flags); ++ } ++ iadev->close_pending--; ++ iadev->testTable[vcc->vci]->lastTime = 0; ++ iadev->testTable[vcc->vci]->fract = 0; ++ iadev->testTable[vcc->vci]->vc_status = VC_UBR; ++ if (vcc->qos.txtp.traffic_class == ATM_ABR) { ++ if (vcc->qos.txtp.min_pcr > 0) ++ iadev->sum_mcr -= vcc->qos.txtp.min_pcr; ++ } ++ if (vcc->qos.txtp.traffic_class == ATM_CBR) { ++ ia_vcc = INPH_IA_VCC(vcc); ++ iadev->sum_mcr -= ia_vcc->NumCbrEntry*iadev->Granularity; ++ ia_cbrVc_close (vcc); ++ } ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++ } ++ ++ if (vcc->qos.rxtp.traffic_class != ATM_NONE) { ++ // reset reass table ++ vc_table = (u16 *)(iadev->reass_ram+REASS_TABLE*iadev->memSize); ++ vc_table += vcc->vci; ++ *vc_table = NO_AAL5_PKT; ++ // reset vc table ++ vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize); ++ vc_table += vcc->vci; ++ *vc_table = (vcc->vci << 6) | 15; ++ if (vcc->qos.rxtp.traffic_class == ATM_ABR) { ++ struct abr_vc_table *abr_vc_table = (struct abr_vc_table *) ++ (iadev->reass_ram+ABR_VC_TABLE*iadev->memSize); ++ abr_vc_table += vcc->vci; ++ abr_vc_table->rdf = 0x0003; ++ abr_vc_table->air = 0x5eb1; ++ } ++ // Drain the packets ++ rx_dle_intr(vcc->dev); ++ iadev->rx_open[vcc->vci] = 0; ++ } ++ kfree(INPH_IA_VCC(vcc)); ++ ia_vcc = NULL; ++ INPH_IA_VCC(vcc) = NULL; ++ vcc->flags &= ~ATM_VF_ADDR; ++ return; ++} ++ ++static int ia_open(struct atm_vcc *vcc, short vpi, int vci) ++{ ++ IADEV *iadev; ++ struct ia_vcc *ia_vcc; ++ int error; ++ if (!(vcc->flags & ATM_VF_PARTIAL)) ++ { ++ IF_EVENT(printk("ia: not partially allocated resources\n");) ++ INPH_IA_VCC(vcc) = NULL; ++ } ++ iadev = INPH_IA_DEV(vcc->dev); ++ error = atm_find_ci(vcc, &vpi, &vci); ++ if (error) ++ { ++ printk("iadev: atm_find_ci returned error %d\n", error); ++ return error; ++ } ++ vcc->vpi = vpi; ++ vcc->vci = vci; ++ if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) ++ { ++ IF_EVENT(printk("iphase open: unspec part\n");) ++ vcc->flags |= ATM_VF_ADDR; ++ } ++ if (vcc->qos.aal != ATM_AAL5) ++ return -EINVAL; ++ IF_EVENT(printk(DEV_LABEL "(itf %d): open %d.%d\n", ++ vcc->dev->number, vcc->vpi, vcc->vci);) ++ ++ /* Device dependent initialization */ ++ ia_vcc = kmalloc(sizeof(struct ia_vcc), GFP_KERNEL); ++ if (!ia_vcc) return -ENOMEM; ++ INPH_IA_VCC(vcc) = ia_vcc; ++ ++ if ((error = open_rx(vcc))) ++ { ++ IF_EVENT(printk("iadev: error in open_rx, closing\n");) ++ ia_close(vcc); ++ return error; ++ } ++ ++ if ((error = open_tx(vcc))) ++ { ++ IF_EVENT(printk("iadev: error in open_tx, closing\n");) ++ ia_close(vcc); ++ return error; ++ } ++ ++ vcc->flags |= ATM_VF_READY; ++ ++#ifndef MODULE ++ { ++ static u8 first = 1; ++ if (first) { ++ ia_timer.next = NULL; ++ ia_timer.prev = NULL; ++ ia_timer.expires = jiffies + 3*HZ; ++ ia_timer.data = 0UL; ++ ia_timer.function = ia_led_timer; ++ add_timer(&ia_timer); ++ first = 0; ++ } ++ } ++#endif ++ IF_EVENT(printk("ia open returning\n");) ++ return 0; ++} ++ ++static int ia_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags) ++{ ++ IF_EVENT(printk(">ia_change_qos\n");) ++ return 0; ++} ++ ++static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg) ++{ ++ PIA_CMDBUF ia_cmds; ++ IADEV *iadev; ++ int i, board; ++ u16 *tmps; ++ IF_EVENT(printk(">ia_ioctl\n");) ++ if (cmd != IA_CMD) { ++ if (!dev->phy->ioctl) return -EINVAL; ++ return dev->phy->ioctl(dev,cmd,arg); ++ } ++ ia_cmds = (PIA_CMDBUF)arg; ++ board = ia_cmds->status; ++ if ((board < 0) || (board > iadev_count)) ++ board = 0; ++ iadev = ia_dev[board]; ++ switch (ia_cmds->cmd) { ++ case MEMDUMP: ++ { ++ switch (ia_cmds->sub_cmd) { ++ case MEMDUMP_DEV: ++ memcpy((char*)ia_cmds->buf, (char*)iadev, ++ sizeof(IADEV)); ++ ia_cmds->status = 0; ++ break; ++ case MEMDUMP_SEGREG: ++ tmps = (u16 *)ia_cmds->buf; ++ for(i=0; i<0x80; i+=2, tmps++) ++ *tmps = *(u16*)(iadev->seg_reg+i); ++ ia_cmds->status = 0; ++ ia_cmds->len = 0x80; ++ break; ++ case MEMDUMP_REASSREG: ++ tmps = (u16 *)ia_cmds->buf; ++ for(i=0; i<0x80; i+=2, tmps++) ++ *tmps = *(u16*)(iadev->reass_reg+i); ++ ia_cmds->status = 0; ++ ia_cmds->len = 0x80; ++ break; ++ case MEMDUMP_FFL: ++ { ++ ia_regs_t regs_local; ++ ffredn_t *ffL = ®s_local.ffredn; ++ rfredn_t *rfL = ®s_local.rfredn; ++ ++ /* Copy real rfred registers into the local copy */ ++ for (i=0; i<(sizeof (rfredn_t))/4; i++) ++ ((u_int *)rfL)[i] = ((u_int *)iadev->reass_reg)[i] & 0xffff; ++ /* Copy real ffred registers into the local copy */ ++ for (i=0; i<(sizeof (ffredn_t))/4; i++) ++ ((u_int *)ffL)[i] = ((u_int *)iadev->seg_reg)[i] & 0xffff; ++ ++ memcpy((char*)ia_cmds->buf,(char*)®s_local,sizeof(ia_regs_t)); ++ printk("Board %d registers dumped\n", board); ++ ia_cmds->status = 0; ++ } ++ break; ++ case READ_REG: ++ { ++ desc_dbg(iadev); ++ ia_cmds->status = 0; ++ } ++ break; ++ case 0x6: ++ { ++ ia_cmds->status = 0; ++ printk("skb = 0x%lx\n", (long)skb_peek(&iadev->tx_backlog)); ++ printk("rtn_q: 0x%lx\n",(long)ia_deque_rtn_q(&iadev->tx_return_q)); ++ } ++ break; ++ case 0x8: ++ { ++ struct sonet_stats *stats; ++ stats = &PRIV(_ia_dev[board])->sonet_stats; ++ printk("section_bip: %d\n", stats->section_bip); ++ printk("line_bip : %d\n", stats->line_bip); ++ printk("path_bip : %d\n", stats->path_bip); ++ printk("line_febe : %d\n", stats->line_febe); ++ printk("path_febe : %d\n", stats->path_febe); ++ printk("corr_hcs : %d\n", stats->corr_hcs); ++ printk("uncorr_hcs : %d\n", stats->uncorr_hcs); ++ printk("tx_cells : %d\n", stats->tx_cells); ++ printk("rx_cells : %d\n", stats->rx_cells); ++ } ++ ia_cmds->status = 0; ++ break; ++ case 0x9: ++ for (i = 1; i <= iadev->num_rx_desc; i++) ++ free_desc(_ia_dev[board], i); ++ writew( ~(RX_FREEQ_EMPT | RX_EXCP_RCVD), ++ iadev->reass_reg+REASS_MASK_REG); ++ iadev->rxing = 1; ++ ++ ia_cmds->status = 0; ++ break; + -+int init_module(void) -+{ -+ return 0; -+} ++ case 0xb: ++ IaFrontEndIntr(iadev); ++ break; ++ case 0xa: ++ { ++ ia_cmds->status = 0; ++ IADebugFlag = ia_cmds->maddr; ++ printk("New debug option loaded\n"); ++ } ++ break; ++ default: ++ memcpy((char*)ia_cmds->buf, (char*)ia_cmds->maddr, ia_cmds->len); ++ ia_cmds->status = 0; ++ break; ++ } ++ } ++ break; ++ default: ++ break; ++ ++ } ++ return 0; ++} ++ ++static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname, ++ void *optval, int optlen) ++{ ++ IF_EVENT(printk(">ia_getsockopt\n");) ++ return -EINVAL; ++} ++ ++static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname, ++ void *optval, int optlen) ++{ ++ IF_EVENT(printk(">ia_setsockopt\n");) ++ return -EINVAL; ++} ++ ++static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) { ++ IADEV *iadev; ++ struct dle *wr_ptr; ++ struct tx_buf_desc *buf_desc_ptr; ++ int desc; ++ int comp_code; ++ unsigned int addr; ++ int total_len, pad, last; ++ struct cpcs_trailer *trailer; ++ struct ia_vcc *iavcc; ++ iadev = INPH_IA_DEV(vcc->dev); ++ iavcc = INPH_IA_VCC(vcc); ++ if (!iavcc->txing) { ++ printk("discard packet on closed VC\n"); ++ if (vcc->pop) vcc->pop(vcc, skb); ++ else dev_kfree_skb(skb); ++ } + ++ if (skb->len > iadev->tx_buf_sz - 8) { ++ printk("Transmit size over tx buffer size\n"); ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); ++ return 0; ++ } ++ if ((u32)skb->data & 3) { ++ printk("Misaligned SKB\n"); ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); ++ return 0; ++ } ++ /* Get a descriptor number from our free descriptor queue ++ We get the descr number from the TCQ now, since I am using ++ the TCQ as a free buffer queue. Initially TCQ will be ++ initialized with all the descriptors and is hence, full. ++ */ ++ desc = get_desc (iadev, iavcc); ++ if (desc == 0xffff) ++ return 1; ++ comp_code = desc >> 13; ++ desc &= 0x1fff; ++ ++ if ((desc == 0) || (desc > iadev->num_tx_desc)) ++ { ++ IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) ++ vcc->stats->tx++; ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); ++ return 0; /* return SUCCESS */ ++ } ++ ++ if (comp_code) ++ { ++ IF_ERR(printk(DEV_LABEL "send desc:%d completion code %d error\n", ++ desc, comp_code);) ++ } ++ ++ /* remember the desc and vcc mapping */ ++ iavcc->vc_desc_cnt++; ++ iadev->desc_tbl[desc-1].iavcc = iavcc; ++ iadev->desc_tbl[desc-1].txskb = skb; ++ IA_SKB_STATE(skb) = 0; ++ ++ iadev->ffL.tcq_rd += 2; ++ if (iadev->ffL.tcq_rd > iadev->ffL.tcq_ed) ++ iadev->ffL.tcq_rd = iadev->ffL.tcq_st; ++ writew(iadev->ffL.tcq_rd, iadev->seg_reg+TCQ_RD_PTR); ++ ++ /* Put the descriptor number in the packet ready queue ++ and put the updated write pointer in the DLE field ++ */ ++ *(u16*)(iadev->seg_ram+iadev->ffL.prq_wr) = desc; ++ ++ iadev->ffL.prq_wr += 2; ++ if (iadev->ffL.prq_wr > iadev->ffL.prq_ed) ++ iadev->ffL.prq_wr = iadev->ffL.prq_st; ++ ++ /* Figure out the exact length of the packet and padding required to ++ make it aligned on a 48 byte boundary. */ ++ total_len = skb->len + sizeof(struct cpcs_trailer); ++ last = total_len - (total_len/48)*48; ++ pad = 48 - last; ++ total_len = pad + total_len; ++ IF_TX(printk("ia packet len:%d padding:%d\n", total_len, pad);) ++ ++ /* Put the packet in a tx buffer */ ++ if (!iadev->tx_buf[desc-1]) ++ printk("couldn't get free page\n"); ++ ++ IF_TX(printk("Sent: skb = 0x%x skb->data: 0x%x len: %d, desc: %d\n", ++ (u32)skb, (u32)skb->data, skb->len, desc);) ++ addr = virt_to_bus(skb->data); ++ trailer = (struct cpcs_trailer*)iadev->tx_buf[desc-1]; ++ trailer->control = 0; ++ /*big endian*/ ++ trailer->length = ((skb->len & 0xff) << 8) | ((skb->len & 0xff00) >> 8); ++ trailer->crc32 = 0; /* not needed - dummy bytes */ ++ ++ /* Display the packet */ ++ IF_TXPKT(printk("Sent data: len = %d MsgNum = %d\n", ++ skb->len, tcnter++); ++ xdump(skb->data, skb->len, "TX: "); ++ printk("\n");) ++ ++ /* Build the buffer descriptor */ ++ buf_desc_ptr = (struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE); ++ buf_desc_ptr += desc; /* points to the corresponding entry */ ++ buf_desc_ptr->desc_mode = AAL5 | EOM_EN | APP_CRC32 | CMPL_INT; ++ writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG); ++ buf_desc_ptr->vc_index = vcc->vci; ++ buf_desc_ptr->bytes = total_len; ++ ++ if (vcc->qos.txtp.traffic_class == ATM_ABR) ++ clear_lockup (vcc, iadev); ++ ++ /* Build the DLE structure */ ++ wr_ptr = iadev->tx_dle_q.write; ++ memset((caddr_t)wr_ptr, 0, sizeof(struct dle)); ++ wr_ptr->sys_pkt_addr = addr; ++ wr_ptr->local_pkt_addr = (buf_desc_ptr->buf_start_hi << 16) | ++ buf_desc_ptr->buf_start_lo; ++ /* wr_ptr->bytes = swap(total_len); didn't seem to affect ?? */ ++ wr_ptr->bytes = skb->len; ++ ++ /* hw bug - DLEs of 0x2d, 0x2e, 0x2f cause DMA lockup */ ++ if ((wr_ptr->bytes >> 2) == 0xb) ++ wr_ptr->bytes = 0x30; ++ ++ wr_ptr->mode = TX_DLE_PSI; ++ wr_ptr->prq_wr_ptr_data = 0; ++ ++ /* end is not to be used for the DLE q */ ++ if (++wr_ptr == iadev->tx_dle_q.end) ++ wr_ptr = iadev->tx_dle_q.start; ++ ++ /* Build trailer dle */ ++ wr_ptr->sys_pkt_addr = virt_to_bus(iadev->tx_buf[desc-1]); ++ wr_ptr->local_pkt_addr = ((buf_desc_ptr->buf_start_hi << 16) | ++ buf_desc_ptr->buf_start_lo) + total_len - sizeof(struct cpcs_trailer); ++ ++ wr_ptr->bytes = sizeof(struct cpcs_trailer); ++ wr_ptr->mode = DMA_INT_ENABLE; ++ wr_ptr->prq_wr_ptr_data = iadev->ffL.prq_wr; ++ ++ /* end is not to be used for the DLE q */ ++ if (++wr_ptr == iadev->tx_dle_q.end) ++ wr_ptr = iadev->tx_dle_q.start; ++ ++ iadev->tx_dle_q.write = wr_ptr; ++ ATM_DESC(skb) = vcc->vci; ++ skb_queue_tail(&iadev->tx_dma_q, skb); ++ ++ vcc->stats->tx++; ++ iadev->tx_pkt_cnt++; ++ /* Increment transaction counter */ ++ writel(2, iadev->dma+IPHASE5575_TX_COUNTER); ++ ++#if 0 ++ /* add flow control logic */ ++ if (vcc->stats->tx % 20 == 0) { ++ if (iavcc->vc_desc_cnt > 10) { ++ vcc->tx_quota = vcc->tx_quota * 3 / 4; ++ printk("Tx1: vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); ++ iavcc->flow_inc = -1; ++ iavcc->saved_tx_quota = vcc->tx_quota; ++ } else if ((iavcc->flow_inc < 0) && (iavcc->vc_desc_cnt < 3)) { ++ // vcc->tx_quota = 3 * iavcc->saved_tx_quota / 4; ++ printk("Tx2: vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); ++ iavcc->flow_inc = 0; ++ } ++ } ++#endif ++ IF_TX(printk("ia send done\n");) ++ return 0; ++} + -+void cleanup_module(void) ++static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb) +{ -+ /* turn off timers */ -+ del_timer(&stats_timer); -+ del_timer(&restart_timer); ++ IADEV *iadev; ++ struct ia_vcc *iavcc; ++ unsigned long flags; ++ ++ iadev = INPH_IA_DEV(vcc->dev); ++ iavcc = INPH_IA_VCC(vcc); ++ if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer)))) ++ { ++ if (!skb) ++ printk(KERN_CRIT "null skb in ia_send\n"); ++ dev_kfree_skb(skb); ++ return -EINVAL; ++ } ++ spin_lock_irqsave(&iadev->tx_lock, flags); ++ if ((vcc->flags & ATM_VF_READY) == 0){ ++ dev_kfree_skb(skb); ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++ return -EINVAL; ++ } ++ ATM_SKB(skb)->vcc = vcc; ++ ++ if (skb_peek(&iadev->tx_backlog)) { ++ skb_queue_tail(&iadev->tx_backlog, skb); ++ } ++ else { ++ if (ia_pkt_tx (vcc, skb)) { ++ skb_queue_tail(&iadev->tx_backlog, skb); ++ } ++ } ++ spin_unlock_irqrestore(&iadev->tx_lock, flags); ++ return 0; ++ +} + -+#endif ---- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/drivers/atm/idt77105.h Wed Dec 1 03:15:17 1999 -@@ -0,0 +1,92 @@ -+/* drivers/atm/idt77105.h - IDT77105 (PHY) declarations */ ++static int ia_sg_send(struct atm_vcc *vcc, unsigned long start, ++ unsigned long size) ++{ ++ IF_EVENT(printk(">ia_sg_send\n");) ++ return 0; ++} ++ ++ ++static int ia_proc_read(struct atm_dev *dev,loff_t *pos,char *page) ++{ ++ int left = *pos, n; ++ char *tmpPtr; ++ IADEV *iadev = INPH_IA_DEV(dev); ++ if(!left--) { ++ if (iadev->phy_type == FE_25MBIT_PHY) { ++ n = sprintf(page, " Board Type : Iphase5525-1KVC-128K\n"); ++ return n; ++ } ++ if (iadev->phy_type == FE_DS3_PHY) ++ n = sprintf(page, " Board Type : Iphase-ATM-DS3"); ++ else if (iadev->phy_type == FE_E3_PHY) ++ n = sprintf(page, " Board Type : Iphase-ATM-E3"); ++ else if (iadev->phy_type == FE_UTP_OPTION) ++ n = sprintf(page, " Board Type : Iphase-ATM-UTP155"); ++ else ++ n = sprintf(page, " Board Type : Iphase-ATM-OC3"); ++ tmpPtr = page + n; ++ if (iadev->pci_map_size == 0x40000) ++ n += sprintf(tmpPtr, "-1KVC-"); ++ else ++ n += sprintf(tmpPtr, "-4KVC-"); ++ tmpPtr = page + n; ++ if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_1M) ++ n += sprintf(tmpPtr, "1M \n"); ++ else if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_512K) ++ n += sprintf(tmpPtr, "512K\n"); ++ else ++ n += sprintf(tmpPtr, "128K\n"); ++ return n; ++ } ++ if (!left) { ++ return sprintf(page, " Number of Tx Buffer: %u\n" ++ " Size of Tx Buffer : %u\n" ++ " Number of Rx Buffer: %u\n" ++ " Size of Rx Buffer : %u\n" ++ " Packets Receiverd : %u\n" ++ " Packets Transmitted: %u\n" ++ " Cells Received : %u\n" ++ " Cells Transmitted : %u\n" ++ " Board Dropped Cells: %u\n" ++ " Board Dropped Pkts : %u\n", ++ iadev->num_tx_desc, iadev->tx_buf_sz, ++ iadev->num_rx_desc, iadev->rx_buf_sz, ++ iadev->rx_pkt_cnt, iadev->tx_pkt_cnt, ++ iadev->rx_cell_cnt, iadev->tx_cell_cnt, ++ iadev->drop_rxcell, iadev->drop_rxpkt); ++ } ++ return 0; ++} ++ ++static const struct atmdev_ops ops = { ++ open: ia_open, ++ close: ia_close, ++ ioctl: ia_ioctl, ++ getsockopt: ia_getsockopt, ++ setsockopt: ia_setsockopt, ++ send: ia_send, ++ sg_send: ia_sg_send, ++ phy_put: ia_phy_put, ++ phy_get: ia_phy_get, ++ change_qos: ia_change_qos, ++ proc_read: ia_proc_read ++}; ++ ++ ++#if LINUX_VERSION_CODE >= 0x20312 ++int __init ia_detect(void) ++#else ++__initfunc(int ia_detect(void)) ++#endif ++{ ++ struct atm_dev *dev; ++ IADEV *iadev; ++ unsigned long flags; ++ int index = 0; ++ struct pci_dev *prev_dev; ++ if (!pci_present()) { ++ printk(KERN_ERR DEV_LABEL " driver but no PCI BIOS ?\n"); ++ return 0; ++ } ++ iadev = (IADEV *)kmalloc(sizeof(IADEV), GFP_KERNEL); ++ if (!iadev) return -ENOMEM; ++ memset((char*)iadev, 0, sizeof(IADEV)); ++ prev_dev = NULL; ++ while((iadev->pci = pci_find_device(PCI_VENDOR_ID_IPHASE, ++ PCI_DEVICE_ID_IPHASE_5575, prev_dev))) { ++ IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n", ++ iadev->pci->bus->number, PCI_SLOT(iadev->pci->devfn), ++ PCI_FUNC(iadev->pci->devfn));) ++ dev = atm_dev_register(DEV_LABEL, &ops, -1, 0); ++ if (!dev) break; ++ IF_INIT(printk(DEV_LABEL "registered at (itf :%d)\n", ++ dev->number);) ++ INPH_IA_DEV(dev) = iadev; ++ // TODO: multi_board using ia_boards logic in cleanup_module ++ ia_dev[index] = iadev; ++ _ia_dev[index] = dev; ++ IF_INIT(printk("dev_id = 0x%x iadev->LineRate = %d \n", ++ (u32)dev, iadev->LineRate);) ++ iadev_count++; ++ spin_lock_init(&iadev->misc_lock); ++ spin_lock_irqsave(&iadev->misc_lock, flags); ++ if (ia_init(dev) || ia_start(dev)) { ++ atm_dev_deregister(dev); ++ IF_INIT(printk("IA register failed!\n");) ++ ia_dev[index] = NULL; ++ _ia_dev[index] = NULL; ++ iadev_count--; ++ spin_unlock_irqrestore(&iadev->misc_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&iadev->misc_lock, flags); ++ IF_EVENT(printk("iadev_count = %d\n", iadev_count);) ++ prev_dev = iadev->pci; ++ iadev->next_board = ia_boards; ++ ia_boards = dev; ++ iadev = (IADEV *)kmalloc( ++ sizeof(IADEV), GFP_KERNEL); ++ if (!iadev) break; ++ memset((char*)iadev, 0, sizeof(IADEV)); ++ index++; ++ dev = NULL; ++ } ++ return index; ++} ++ ++ ++#ifdef MODULE ++ ++int init_module(void) ++{ ++ IF_EVENT(printk(">ia init_module\n");) ++ if (!ia_detect()) { ++ printk(KERN_ERR DEV_LABEL ": no adapter found\n"); ++ return -ENXIO; ++ } ++ // MOD_INC_USE_COUNT; ++ ia_timer.next = NULL; ++ ia_timer.prev = NULL; ++ ia_timer.expires = jiffies + 3*HZ; ++ ia_timer.data = 0UL; ++ ia_timer.function = ia_led_timer; ++ add_timer(&ia_timer); ++ ++ return 0; ++} ++ ++ ++void cleanup_module(void) ++{ ++ struct atm_dev *dev; ++ IADEV *iadev; ++ unsigned short command; ++ int i, j= 0; + -+/* Written 1999 by Greg Banks, NEC Australia . Based on suni.h */ ++ IF_EVENT(printk(">ia cleanup_module\n");) ++ // MOD_DEC_USE_COUNT; ++ if (MOD_IN_USE) ++ printk("ia: module in use\n"); ++ del_timer(&ia_timer); ++ while(ia_dev[j]) ++ { ++ dev = ia_boards; ++ iadev = INPH_IA_DEV(dev); ++ ia_boards = iadev->next_board; ++ ++ /* disable interrupt of lost signal */ ++ ia_phy_put(dev, ia_phy_get(dev,0x10) & ~(0x4), 0x10); ++ udelay(1); ++ ++ /* De-register device */ ++ atm_dev_deregister(dev); ++ IF_EVENT(printk("iav deregistered at (itf:%d)\n", dev->number);) ++ for (i= 0; i< iadev->num_tx_desc; i++) ++ kfree(iadev->tx_buf[i]); ++ kfree(iadev->tx_buf); ++ /* Disable memory mapping and busmastering */ ++ if (pci_read_config_word(iadev->pci, ++ PCI_COMMAND, &command) != 0) ++ { ++ printk("ia: can't read PCI_COMMAND.\n"); ++ } ++ command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ if (pci_write_config_word(iadev->pci, ++ PCI_COMMAND, command) != 0) ++ { ++ printk("ia: can't write PCI_COMMAND.\n"); ++ } ++ free_irq(iadev->irq, dev); ++ iounmap((void *) iadev->base); ++ kfree(iadev); ++ j++; ++ } ++ /* and voila whatever we tried seems to work. I don't know if it will ++ fix suni errors though. Really doubt that. */ ++ for (i = 0; i<8; i++) { ++ ia_dev[i] = NULL; ++ _ia_dev[i] = NULL; ++ } ++} ++ ++#endif ++ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/iphase.h Fri Jan 21 16:48:16 2000 +@@ -0,0 +1,1465 @@ ++/****************************************************************************** ++ Device driver for Interphase ATM PCI adapter cards ++ Author: Peter Wang ++ Interphase Corporation ++ Version: 1.0 ++ iphase.h: This is the header file for iphase.c. ++******************************************************************************* ++ ++ This software may be used and distributed according to the terms ++ of the GNU Public License (GPL), incorporated herein by reference. ++ Drivers based on this skeleton fall under the GPL and must retain ++ the authorship (implicit copyright) notice. ++ ++ 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. ++ ++ Modified from an incomplete driver for Interphase 5575 1KVC 1M card which ++ was originally written by Monalisa Agrawal at UNH. Now this driver ++ supports a variety of varients of Interphase ATM PCI (i)Chip adapter ++ card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) ++ in terms of PHY type, the size of control memory and the size of ++ packet memory. The followings are the change log and history: ++ ++ Bugfix the Mona's UBR driver. ++ Modify the basic memory allocation and dma logic. ++ Port the driver to the latest kernel from 2.0.46. ++ Complete the ABR logic of the driver, and added the ABR work- ++ around for the hardware anormalies. ++ Add the CBR support. ++ Add the flow control logic to the driver to allow rate-limit VC. ++ Add 4K VC support to the board with 512K control memory. ++ Add the support of all the variants of the Interphase ATM PCI ++ (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525 ++ (25M UTP25) and x531 (DS3 and E3). ++ Add SMP support. ++ ++ Support and updates available at: ftp://ftp.iphase.com/pub/atm ++ ++*******************************************************************************/ ++ ++#ifndef IPHASE_H ++#define IPHASE_H ++ ++/************************ IADBG DEFINE *********************************/ ++/* IADebugFlag Bit Map */ ++#define IF_IADBG_INIT_ADAPTER 0x00000001 // init adapter info ++#define IF_IADBG_TX 0x00000002 // debug TX ++#define IF_IADBG_RX 0x00000004 // debug RX ++#define IF_IADBG_QUERY_INFO 0x00000008 // debug Request call ++#define IF_IADBG_SHUTDOWN 0x00000010 // debug shutdown event ++#define IF_IADBG_INTR 0x00000020 // debug interrupt DPC ++#define IF_IADBG_TXPKT 0x00000040 // debug TX PKT ++#define IF_IADBG_RXPKT 0x00000080 // debug RX PKT ++#define IF_IADBG_ERR 0x00000100 // debug system error ++#define IF_IADBG_EVENT 0x00000200 // debug event ++#define IF_IADBG_DIS_INTR 0x00001000 // debug disable interrupt ++#define IF_IADBG_EN_INTR 0x00002000 // debug enable interrupt ++#define IF_IADBG_LOUD 0x00004000 // debugging info ++#define IF_IADBG_VERY_LOUD 0x00008000 // excessive debugging info ++#define IF_IADBG_CBR 0x00100000 // ++#define IF_IADBG_UBR 0x00200000 // ++#define IF_IADBG_ABR 0x00400000 // ++#define IF_IADBG_DESC 0x01000000 // ++#define IF_IADBG_SUNI_STAT 0x02000000 // suni statistics ++#define IF_IADBG_RESET 0x04000000 ++ ++extern unsigned int IADebugFlag; ++ ++#define IF_IADBG(f) if (IADebugFlag & (f)) ++ ++#ifdef CONFIG_ATM_IA_DEBUG /* Debug build */ ++ ++#define IF_LOUD(A) IF_IADBG(IF_IADBG_LOUD) { A } ++#define IF_ERR(A) IF_IADBG(IF_IADBG_ERR) { A } ++#define IF_VERY_LOUD(A) IF_IADBG( IF_IADBG_VERY_LOUD ) { A } ++ ++#define IF_INIT_ADAPTER(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A } ++#define IF_INIT(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A } ++#define IF_SUNI_STAT(A) IF_IADBG( IF_IADBG_SUNI_STAT ) { A } ++#define IF_QUERY_INFO(A) IF_IADBG( IF_IADBG_QUERY_INFO ) { A } ++#define IF_COPY_OVER(A) IF_IADBG( IF_IADBG_COPY_OVER ) { A } ++ ++#define IF_INTR(A) IF_IADBG( IF_IADBG_INTR ) { A } ++#define IF_DIS_INTR(A) IF_IADBG( IF_IADBG_DIS_INTR ) { A } ++#define IF_EN_INTR(A) IF_IADBG( IF_IADBG_EN_INTR ) { A } ++ ++#define IF_TX(A) IF_IADBG( IF_IADBG_TX ) { A } ++#define IF_RX(A) IF_IADBG( IF_IADBG_RX ) { A } ++#define IF_TXPKT(A) IF_IADBG( IF_IADBG_TXPKT ) { A } ++#define IF_RXPKT(A) IF_IADBG( IF_IADBG_RXPKT ) { A } ++ ++#define IF_SHUTDOWN(A) IF_IADBG(IF_IADBG_SHUTDOWN) { A } ++#define IF_CBR(A) IF_IADBG( IF_IADBG_CBR ) { A } ++#define IF_UBR(A) IF_IADBG( IF_IADBG_UBR ) { A } ++#define IF_ABR(A) IF_IADBG( IF_IADBG_ABR ) { A } ++#define IF_EVENT(A) IF_IADBG( IF_IADBG_EVENT) { A } ++ ++#else /* free build */ ++#define IF_LOUD(A) ++#define IF_VERY_LOUD(A) ++#define IF_INIT_ADAPTER(A) ++#define IF_INIT(A) ++#define IF_SUNI_STAT(A) ++#define IF_PVC_CHKPKT(A) ++#define IF_QUERY_INFO(A) ++#define IF_COPY_OVER(A) ++#define IF_HANG(A) ++#define IF_INTR(A) ++#define IF_DIS_INTR(A) ++#define IF_EN_INTR(A) ++#define IF_TX(A) ++#define IF_RX(A) ++#define IF_TXDEBUG(A) ++#define IF_VC(A) ++#define IF_ERR(A) ++#define IF_CBR(A) ++#define IF_UBR(A) ++#define IF_ABR(A) ++#define IF_SHUTDOWN(A) ++#define DbgPrint(A) ++#define IF_EVENT(A) ++#define IF_TXPKT(A) ++#define IF_RXPKT(A) ++#endif /* CONFIG_ATM_IA_DEBUG */ ++ ++#define isprint(a) ((a >=' ')&&(a <= '~')) ++#define ATM_DESC(skb) (skb->protocol) ++#define IA_SKB_STATE(skb) (skb->protocol) ++#define IA_DLED 1 ++#define IA_TX_DONE 2 ++ ++/* iadbg defines */ ++#define IA_CMD 0x7749 ++typedef struct { ++ int cmd; ++ int sub_cmd; ++ int len; ++ u32 maddr; ++ int status; ++ void *buf; ++} IA_CMDBUF, *PIA_CMDBUF; ++ ++/* cmds */ ++#define MEMDUMP 0x01 ++ ++/* sub_cmds */ ++#define MEMDUMP_SEGREG 0x2 ++#define MEMDUMP_DEV 0x1 ++#define MEMDUMP_REASSREG 0x3 ++#define MEMDUMP_FFL 0x4 ++#define READ_REG 0x5 ++#define WAKE_DBG_WAIT 0x6 ++ ++/************************ IADBG DEFINE END ***************************/ ++ ++#define Boolean(x) ((x) ? 1 : 0) ++#define NR_VCI 1024 /* number of VCIs */ ++#define NR_VCI_LD 10 /* log2(NR_VCI) */ ++#define NR_VCI_4K 4096 /* number of VCIs */ ++#define NR_VCI_4K_LD 12 /* log2(NR_VCI) */ ++#define MEM_VALID 0xfffffff0 /* mask base address with this */ ++ ++#ifndef PCI_VENDOR_ID_IPHASE ++#define PCI_VENDOR_ID_IPHASE 0x107e ++#endif ++#ifndef PCI_DEVICE_ID_IPHASE_5575 ++#define PCI_DEVICE_ID_IPHASE_5575 0x0008 ++#endif ++#define DEV_LABEL "ia" ++#define PCR 207692 ++#define ICR 100000 ++#define MCR 0 ++#define TBE 1000 ++#define FRTT 1 ++#define RIF 2 ++#define RDF 4 ++#define NRMCODE 5 /* 0 - 7 */ ++#define TRMCODE 3 /* 0 - 7 */ ++#define CDFCODE 6 ++#define ATDFCODE 2 /* 0 - 15 */ ++ ++/*---------------------- Packet/Cell Memory ------------------------*/ ++#define TX_PACKET_RAM 0x00000 /* start of Trasnmit Packet memory - 0 */ ++#define DFL_TX_BUF_SZ 10240 /* 10 K buffers */ ++#define DFL_TX_BUFFERS 50 /* number of packet buffers for Tx ++ - descriptor 0 unused */ ++#define REASS_RAM_SIZE 0x10000 /* for 64K 1K VC board */ ++#define RX_PACKET_RAM 0x80000 /* start of Receive Packet memory - 512K */ ++#define DFL_RX_BUF_SZ 10240 /* 10k buffers */ ++#define DFL_RX_BUFFERS 50 /* number of packet buffers for Rx ++ - descriptor 0 unused */ ++ ++struct cpcs_trailer ++{ ++ u_short control; ++ u_short length; ++ u_int crc32; ++}; ++ ++struct ia_vcc ++{ ++ int rxing; ++ int txing; ++ int NumCbrEntry; ++ u32 pcr; ++ u32 saved_tx_quota; ++ int flow_inc; ++ struct sk_buff_head txing_skb; ++ int ltimeout; ++ u8 vc_desc_cnt; ++ ++}; ++ ++struct abr_vc_table ++{ ++ u_char status; ++ u_char rdf; ++ u_short air; ++ u_int res[3]; ++ u_int req_rm_cell_data1; ++ u_int req_rm_cell_data2; ++ u_int add_rm_cell_data1; ++ u_int add_rm_cell_data2; ++}; ++ ++/* 32 byte entries */ ++struct main_vc ++{ ++ u_short type; ++#define ABR 0x8000 ++#define UBR 0xc000 ++#define CBR 0x0000 ++ /* ABR fields */ ++ u_short nrm; ++ u_short trm; ++ u_short rm_timestamp_hi; ++ u_short rm_timestamp_lo:8, ++ crm:8; ++ u_short remainder; /* ABR and UBR fields - last 10 bits*/ ++ u_short next_vc_sched; ++ u_short present_desc; /* all classes */ ++ u_short last_cell_slot; /* ABR and UBR */ ++ u_short pcr; ++ u_short fraction; ++ u_short icr; ++ u_short atdf; ++ u_short mcr; ++ u_short acr; ++ u_short unack:8, ++ status:8; /* all classes */ ++#define UIOLI 0x80 ++#define CRC_APPEND 0x40 /* for status field - CRC-32 append */ ++#define ABR_STATE 0x02 ++ ++}; ++ ++ ++/* 8 byte entries */ ++struct ext_vc ++{ ++ u_short atm_hdr1; ++ u_short atm_hdr2; ++ u_short last_desc; ++ u_short out_of_rate_link; /* reserved for UBR and CBR */ ++}; ++ ++ ++#define DLE_ENTRIES 256 ++#define DMA_INT_ENABLE 0x0002 /* use for both Tx and Rx */ ++#define TX_DLE_PSI 0x0001 ++ ++/* Descriptor List Entries (DLE) */ ++struct dle ++{ ++ u32 sys_pkt_addr; ++ u32 local_pkt_addr; ++ u32 bytes; ++ u16 prq_wr_ptr_data; ++ u16 mode; ++}; ++ ++struct dle_q ++{ ++ struct dle *start; ++ struct dle *end; ++ struct dle *read; ++ struct dle *write; ++}; ++ ++struct free_desc_q ++{ ++ int desc; /* Descriptor number */ ++ struct free_desc_q *next; ++}; ++ ++struct tx_buf_desc { ++ unsigned short desc_mode; ++ unsigned short vc_index; ++ unsigned short res1; /* reserved field */ ++ unsigned short bytes; ++ unsigned short buf_start_hi; ++ unsigned short buf_start_lo; ++ unsigned short res2[10]; /* reserved field */ ++}; ++ ++ ++struct rx_buf_desc { ++ unsigned short desc_mode; ++ unsigned short vc_index; ++ unsigned short vpi; ++ unsigned short bytes; ++ unsigned short buf_start_hi; ++ unsigned short buf_start_lo; ++ unsigned short dma_start_hi; ++ unsigned short dma_start_lo; ++ unsigned short crc_upper; ++ unsigned short crc_lower; ++ unsigned short res:8, timeout:8; ++ unsigned short res2[5]; /* reserved field */ ++}; ++ ++/*--------SAR stuff ---------------------*/ ++ ++#define EPROM_SIZE 0x40000 /* says 64K in the docs ??? */ ++#define MAC1_LEN 4 ++#define MAC2_LEN 2 ++ ++/*------------ PCI Memory Space Map, 128K SAR memory ----------------*/ ++#define IPHASE5575_PCI_CONFIG_REG_BASE 0x0000 ++#define IPHASE5575_BUS_CONTROL_REG_BASE 0x1000 /* offsets 0x00 - 0x3c */ ++#define IPHASE5575_FRAG_CONTROL_REG_BASE 0x2000 ++#define IPHASE5575_REASS_CONTROL_REG_BASE 0x3000 ++#define IPHASE5575_DMA_CONTROL_REG_BASE 0x4000 ++#define IPHASE5575_FRONT_END_REG_BASE IPHASE5575_DMA_CONTROL_REG_BASE ++#define IPHASE5575_FRAG_CONTROL_RAM_BASE 0x10000 ++#define IPHASE5575_REASS_CONTROL_RAM_BASE 0x20000 ++ ++/*------------ Bus interface control registers -----------------*/ ++#define IPHASE5575_BUS_CONTROL_REG 0x00 ++#define IPHASE5575_BUS_STATUS_REG 0x01 /* actual offset 0x04 */ ++#define IPHASE5575_MAC1 0x02 ++#define IPHASE5575_REV 0x03 ++#define IPHASE5575_MAC2 0x03 /*actual offset 0x0e-reg 0x0c*/ ++#define IPHASE5575_EXT_RESET 0x04 ++#define IPHASE5575_INT_RESET 0x05 /* addr 1c ?? reg 0x06 */ ++#define IPHASE5575_PCI_ADDR_PAGE 0x07 /* reg 0x08, 0x09 ?? */ ++#define IPHASE5575_EEPROM_ACCESS 0x0a /* actual offset 0x28 */ ++#define IPHASE5575_CELL_FIFO_QUEUE_SZ 0x0b ++#define IPHASE5575_CELL_FIFO_MARK_STATE 0x0c ++#define IPHASE5575_CELL_FIFO_READ_PTR 0x0d ++#define IPHASE5575_CELL_FIFO_WRITE_PTR 0x0e ++#define IPHASE5575_CELL_FIFO_CELLS_AVL 0x0f /* actual offset 0x3c */ ++ ++/* Bus Interface Control Register bits */ ++#define CTRL_FE_RST 0x80000000 ++#define CTRL_LED 0x40000000 ++#define CTRL_25MBPHY 0x10000000 ++#define CTRL_ENCMBMEM 0x08000000 ++#define CTRL_ENOFFSEG 0x01000000 ++#define CTRL_ERRMASK 0x00400000 ++#define CTRL_DLETMASK 0x00100000 ++#define CTRL_DLERMASK 0x00080000 ++#define CTRL_FEMASK 0x00040000 ++#define CTRL_SEGMASK 0x00020000 ++#define CTRL_REASSMASK 0x00010000 ++#define CTRL_CSPREEMPT 0x00002000 ++#define CTRL_B128 0x00000200 ++#define CTRL_B64 0x00000100 ++#define CTRL_B48 0x00000080 ++#define CTRL_B32 0x00000040 ++#define CTRL_B16 0x00000020 ++#define CTRL_B8 0x00000010 ++ ++/* Bus Interface Status Register bits */ ++#define STAT_CMEMSIZ 0xc0000000 ++#define STAT_ADPARCK 0x20000000 ++#define STAT_RESVD 0x1fffff80 ++#define STAT_ERRINT 0x00000040 ++#define STAT_MARKINT 0x00000020 ++#define STAT_DLETINT 0x00000010 ++#define STAT_DLERINT 0x00000008 ++#define STAT_FEINT 0x00000004 ++#define STAT_SEGINT 0x00000002 ++#define STAT_REASSINT 0x00000001 ++ ++ ++/*--------------- Segmentation control registers -----------------*/ ++/* The segmentation registers are 16 bits access and the addresses ++ are defined as such so the addresses are the actual "offsets" */ ++#define IDLEHEADHI 0x00 ++#define IDLEHEADLO 0x01 ++#define MAXRATE 0x02 ++/* Values for MAXRATE register for 155Mbps and 25.6 Mbps operation */ ++#define RATE155 0x64b1 // 16 bits float format ++#define MAX_ATM_155 352768 // Cells/second p.118 ++#define RATE25 0x5f9d ++ ++#define STPARMS 0x03 ++#define STPARMS_1K 0x008c ++#define STPARMS_2K 0x0049 ++#define STPARMS_4K 0x0026 ++#define COMP_EN 0x4000 ++#define CBR_EN 0x2000 ++#define ABR_EN 0x0800 ++#define UBR_EN 0x0400 ++ ++#define ABRUBR_ARB 0x04 ++#define RM_TYPE 0x05 ++/*Value for RM_TYPE register for ATM Forum Traffic Mangement4.0 support*/ ++#define RM_TYPE_4_0 0x0100 ++ ++#define SEG_COMMAND_REG 0x17 ++/* Values for the command register */ ++#define RESET_SEG 0x0055 ++#define RESET_SEG_STATE 0x00aa ++#define RESET_TX_CELL_CTR 0x00cc ++ ++#define CBR_PTR_BASE 0x20 ++#define ABR_SBPTR_BASE 0x22 ++#define UBR_SBPTR_BASE 0x23 ++#define ABRWQ_BASE 0x26 ++#define UBRWQ_BASE 0x27 ++#define VCT_BASE 0x28 ++#define VCTE_BASE 0x29 ++#define CBR_TAB_BEG 0x2c ++#define CBR_TAB_END 0x2d ++#define PRQ_ST_ADR 0x30 ++#define PRQ_ED_ADR 0x31 ++#define PRQ_RD_PTR 0x32 ++#define PRQ_WR_PTR 0x33 ++#define TCQ_ST_ADR 0x34 ++#define TCQ_ED_ADR 0x35 ++#define TCQ_RD_PTR 0x36 ++#define TCQ_WR_PTR 0x37 ++#define SEG_QUEUE_BASE 0x40 ++#define SEG_DESC_BASE 0x41 ++#define MODE_REG_0 0x45 ++#define T_ONLINE 0x0002 /* (i)chipSAR is online */ ++ ++#define MODE_REG_1 0x46 ++#define MODE_REG_1_VAL 0x0400 /*for propoer device operation*/ ++ ++#define SEG_INTR_STATUS_REG 0x47 ++#define SEG_MASK_REG 0x48 ++#define TRANSMIT_DONE 0x0200 ++#define TCQ_NOT_EMPTY 0x1000 /* this can be used for both the interrupt ++ status registers as well as the mask register */ ++ ++#define CELL_CTR_HIGH_AUTO 0x49 ++#define CELL_CTR_HIGH_NOAUTO 0xc9 ++#define CELL_CTR_LO_AUTO 0x4a ++#define CELL_CTR_LO_NOAUTO 0xca ++ ++/* Diagnostic registers */ ++#define NEXTDESC 0x59 ++#define NEXTVC 0x5a ++#define PSLOTCNT 0x5d ++#define NEWDN 0x6a ++#define NEWVC 0x6b ++#define SBPTR 0x6c ++#define ABRWQ_WRPTR 0x6f ++#define ABRWQ_RDPTR 0x70 ++#define UBRWQ_WRPTR 0x71 ++#define UBRWQ_RDPTR 0x72 ++#define CBR_VC 0x73 ++#define ABR_SBVC 0x75 ++#define UBR_SBVC 0x76 ++#define ABRNEXTLINK 0x78 ++#define UBRNEXTLINK 0x79 ++ ++ ++/*----------------- Reassembly control registers ---------------------*/ ++/* The reassembly registers are 16 bits access and the addresses ++ are defined as such so the addresses are the actual "offsets" */ ++#define MODE_REG 0x00 ++#define R_ONLINE 0x0002 /* (i)chip is online */ ++#define IGN_RAW_FL 0x0004 ++ ++#define PROTOCOL_ID 0x01 ++#define REASS_MASK_REG 0x02 ++#define REASS_INTR_STATUS_REG 0x03 ++/* Interrupt Status register bits */ ++#define RX_PKT_CTR_OF 0x8000 ++#define RX_ERR_CTR_OF 0x4000 ++#define RX_CELL_CTR_OF 0x1000 ++#define RX_FREEQ_EMPT 0x0200 ++#define RX_EXCPQ_FL 0x0080 ++#define RX_RAWQ_FL 0x0010 ++#define RX_EXCP_RCVD 0x0008 ++#define RX_PKT_RCVD 0x0004 ++#define RX_RAW_RCVD 0x0001 ++ ++#define DRP_PKT_CNTR 0x04 ++#define ERR_CNTR 0x05 ++#define RAW_BASE_ADR 0x08 ++#define CELL_CTR0 0x0c ++#define CELL_CTR1 0x0d ++#define REASS_COMMAND_REG 0x0f ++/* Values for command register */ ++#define RESET_REASS 0x0055 ++#define RESET_REASS_STATE 0x00aa ++#define RESET_DRP_PKT_CNTR 0x00f1 ++#define RESET_ERR_CNTR 0x00f2 ++#define RESET_CELL_CNTR 0x00f8 ++#define RESET_REASS_ALL_REGS 0x00ff ++ ++#define REASS_DESC_BASE 0x10 ++#define VC_LKUP_BASE 0x11 ++#define REASS_TABLE_BASE 0x12 ++#define REASS_QUEUE_BASE 0x13 ++#define PKT_TM_CNT 0x16 ++#define TMOUT_RANGE 0x17 ++#define INTRVL_CNTR 0x18 ++#define TMOUT_INDX 0x19 ++#define VP_LKUP_BASE 0x1c ++#define VP_FILTER 0x1d ++#define ABR_LKUP_BASE 0x1e ++#define FREEQ_ST_ADR 0x24 ++#define FREEQ_ED_ADR 0x25 ++#define FREEQ_RD_PTR 0x26 ++#define FREEQ_WR_PTR 0x27 ++#define PCQ_ST_ADR 0x28 ++#define PCQ_ED_ADR 0x29 ++#define PCQ_RD_PTR 0x2a ++#define PCQ_WR_PTR 0x2b ++#define EXCP_Q_ST_ADR 0x2c ++#define EXCP_Q_ED_ADR 0x2d ++#define EXCP_Q_RD_PTR 0x2e ++#define EXCP_Q_WR_PTR 0x2f ++#define CC_FIFO_ST_ADR 0x34 ++#define CC_FIFO_ED_ADR 0x35 ++#define CC_FIFO_RD_PTR 0x36 ++#define CC_FIFO_WR_PTR 0x37 ++#define STATE_REG 0x38 ++#define BUF_SIZE 0x42 ++#define XTRA_RM_OFFSET 0x44 ++#define DRP_PKT_CNTR_NC 0x84 ++#define ERR_CNTR_NC 0x85 ++#define CELL_CNTR0_NC 0x8c ++#define CELL_CNTR1_NC 0x8d ++ ++/* State Register bits */ ++#define EXCPQ_EMPTY 0x0040 ++#define PCQ_EMPTY 0x0010 ++#define FREEQ_EMPTY 0x0004 ++ ++ ++/*----------------- Front End registers/ DMA control --------------*/ ++/* There is a lot of documentation error regarding these offsets ??? ++ eg:- 2 offsets given 800, a00 for rx counter ++ similarly many others ++ Remember again that the offsets are to be 4*register number, so ++ correct the #defines here ++*/ ++#define IPHASE5575_TX_COUNTER 0x200 /* offset - 0x800 */ ++#define IPHASE5575_RX_COUNTER 0x280 /* offset - 0xa00 */ ++#define IPHASE5575_TX_LIST_ADDR 0x300 /* offset - 0xc00 */ ++#define IPHASE5575_RX_LIST_ADDR 0x380 /* offset - 0xe00 */ ++ ++/*--------------------------- RAM ---------------------------*/ ++/* These memory maps are actually offsets from the segmentation and reassembly RAM base addresses */ ++ ++/* Segmentation Control Memory map */ ++#define TX_DESC_BASE 0x0000 /* Buffer Decriptor Table */ ++#define TX_COMP_Q 0x1000 /* Transmit Complete Queue */ ++#define PKT_RDY_Q 0x1400 /* Packet Ready Queue */ ++#define CBR_SCHED_TABLE 0x1800 /* CBR Table */ ++#define UBR_SCHED_TABLE 0x3000 /* UBR Table */ ++#define UBR_WAIT_Q 0x4000 /* UBR Wait Queue */ ++#define ABR_SCHED_TABLE 0x5000 /* ABR Table */ ++#define ABR_WAIT_Q 0x5800 /* ABR Wait Queue */ ++#define EXT_VC_TABLE 0x6000 /* Extended VC Table */ ++#define MAIN_VC_TABLE 0x8000 /* Main VC Table */ ++#define SCHEDSZ 1024 /* ABR and UBR Scheduling Table size */ ++#define TX_DESC_TABLE_SZ 128 /* Number of entries in the Transmit ++ Buffer Descriptor Table */ ++ ++/* These are used as table offsets in Descriptor Table address generation */ ++#define DESC_MODE 0x0 ++#define VC_INDEX 0x1 ++#define BYTE_CNT 0x3 ++#define PKT_START_HI 0x4 ++#define PKT_START_LO 0x5 ++ ++/* Descriptor Mode Word Bits */ ++#define EOM_EN 0x0800 ++#define AAL5 0x0100 ++#define APP_CRC32 0x0400 ++#define CMPL_INT 0x1000 ++ ++#define TABLE_ADDRESS(db, dn, to) \ ++ (((unsigned long)(db & 0x04)) << 16) | (dn << 5) | (to << 1) ++ ++/* Reassembly Control Memory Map */ ++#define RX_DESC_BASE 0x0000 /* Buffer Descriptor Table */ ++#define VP_TABLE 0x5c00 /* VP Table */ ++#define EXCEPTION_Q 0x5e00 /* Exception Queue */ ++#define FREE_BUF_DESC_Q 0x6000 /* Free Buffer Descriptor Queue */ ++#define PKT_COMP_Q 0x6800 /* Packet Complete Queue */ ++#define REASS_TABLE 0x7000 /* Reassembly Table */ ++#define RX_VC_TABLE 0x7800 /* VC Table */ ++#define ABR_VC_TABLE 0x8000 /* ABR VC Table */ ++#define RX_DESC_TABLE_SZ 736 /* Number of entries in the Receive ++ Buffer Descriptor Table */ ++#define VP_TABLE_SZ 256 /* Number of entries in VPTable */ ++#define RX_VC_TABLE_SZ 1024 /* Number of entries in VC Table */ ++#define REASS_TABLE_SZ 1024 /* Number of entries in Reassembly Table */ ++ /* Buffer Descriptor Table */ ++#define RX_ACT 0x8000 ++#define RX_VPVC 0x4000 ++#define RX_CNG 0x0040 ++#define RX_CER 0x0008 ++#define RX_PTE 0x0004 ++#define RX_OFL 0x0002 ++#define NUM_RX_EXCP 32 ++ ++/* Reassembly Table */ ++#define NO_AAL5_PKT 0x0000 ++#define AAL5_PKT_REASSEMBLED 0x4000 ++#define AAL5_PKT_TERMINATED 0x8000 ++#define RAW_PKT 0xc000 ++#define REASS_ABR 0x2000 ++ ++/*-------------------- Base Registers --------------------*/ ++#define REG_BASE IPHASE5575_BUS_CONTROL_REG_BASE ++#define RAM_BASE IPHASE5575_FRAG_CONTROL_RAM_BASE ++#define PHY_BASE IPHASE5575_FRONT_END_REG_BASE ++#define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE ++#define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE ++ ++typedef volatile u_int freg_t; ++typedef u_int rreg_t; ++ ++typedef struct _ffredn_t { ++ freg_t idlehead_high; /* Idle cell header (high) */ ++ freg_t idlehead_low; /* Idle cell header (low) */ ++ freg_t maxrate; /* Maximum rate */ ++ freg_t stparms; /* Traffic Management Parameters */ ++ freg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ ++ freg_t rm_type; /* */ ++ u_int filler5[0x17 - 0x06]; ++ freg_t cmd_reg; /* Command register */ ++ u_int filler18[0x20 - 0x18]; ++ freg_t cbr_base; /* CBR Pointer Base */ ++ freg_t vbr_base; /* VBR Pointer Base */ ++ freg_t abr_base; /* ABR Pointer Base */ ++ freg_t ubr_base; /* UBR Pointer Base */ ++ u_int filler24; ++ freg_t vbrwq_base; /* VBR Wait Queue Base */ ++ freg_t abrwq_base; /* ABR Wait Queue Base */ ++ freg_t ubrwq_base; /* UBR Wait Queue Base */ ++ freg_t vct_base; /* Main VC Table Base */ ++ freg_t vcte_base; /* Extended Main VC Table Base */ ++ u_int filler2a[0x2C - 0x2A]; ++ freg_t cbr_tab_beg; /* CBR Table Begin */ ++ freg_t cbr_tab_end; /* CBR Table End */ ++ freg_t cbr_pointer; /* CBR Pointer */ ++ u_int filler2f[0x30 - 0x2F]; ++ freg_t prq_st_adr; /* Packet Ready Queue Start Address */ ++ freg_t prq_ed_adr; /* Packet Ready Queue End Address */ ++ freg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ ++ freg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ ++ freg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ ++ freg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ ++ freg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ ++ freg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ ++ u_int filler38[0x40 - 0x38]; ++ freg_t queue_base; /* Base address for PRQ and TCQ */ ++ freg_t desc_base; /* Base address of descriptor table */ ++ u_int filler42[0x45 - 0x42]; ++ freg_t mode_reg_0; /* Mode register 0 */ ++ freg_t mode_reg_1; /* Mode register 1 */ ++ freg_t intr_status_reg;/* Interrupt Status register */ ++ freg_t mask_reg; /* Mask Register */ ++ freg_t cell_ctr_high1; /* Total cell transfer count (high) */ ++ freg_t cell_ctr_lo1; /* Total cell transfer count (low) */ ++ freg_t state_reg; /* Status register */ ++ u_int filler4c[0x58 - 0x4c]; ++ freg_t curr_desc_num; /* Contains the current descriptor num */ ++ freg_t next_desc; /* Next descriptor */ ++ freg_t next_vc; /* Next VC */ ++ u_int filler5b[0x5d - 0x5b]; ++ freg_t present_slot_cnt;/* Present slot count */ ++ u_int filler5e[0x6a - 0x5e]; ++ freg_t new_desc_num; /* New descriptor number */ ++ freg_t new_vc; /* New VC */ ++ freg_t sched_tbl_ptr; /* Schedule table pointer */ ++ freg_t vbrwq_wptr; /* VBR wait queue write pointer */ ++ freg_t vbrwq_rptr; /* VBR wait queue read pointer */ ++ freg_t abrwq_wptr; /* ABR wait queue write pointer */ ++ freg_t abrwq_rptr; /* ABR wait queue read pointer */ ++ freg_t ubrwq_wptr; /* UBR wait queue write pointer */ ++ freg_t ubrwq_rptr; /* UBR wait queue read pointer */ ++ freg_t cbr_vc; /* CBR VC */ ++ freg_t vbr_sb_vc; /* VBR SB VC */ ++ freg_t abr_sb_vc; /* ABR SB VC */ ++ freg_t ubr_sb_vc; /* UBR SB VC */ ++ freg_t vbr_next_link; /* VBR next link */ ++ freg_t abr_next_link; /* ABR next link */ ++ freg_t ubr_next_link; /* UBR next link */ ++ u_int filler7a[0x7c-0x7a]; ++ freg_t out_rate_head; /* Out of rate head */ ++ u_int filler7d[0xca-0x7d]; /* pad out to full address space */ ++ freg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ ++ freg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ ++ u_int fillercc[0x100-0xcc]; /* pad out to full address space */ ++} ffredn_t; ++ ++typedef struct _rfredn_t { ++ rreg_t mode_reg_0; /* Mode register 0 */ ++ rreg_t protocol_id; /* Protocol ID */ ++ rreg_t mask_reg; /* Mask Register */ ++ rreg_t intr_status_reg;/* Interrupt status register */ ++ rreg_t drp_pkt_cntr; /* Dropped packet cntr (clear on read) */ ++ rreg_t err_cntr; /* Error Counter (cleared on read) */ ++ u_int filler6[0x08 - 0x06]; ++ rreg_t raw_base_adr; /* Base addr for raw cell Q */ ++ u_int filler2[0x0c - 0x09]; ++ rreg_t cell_ctr0; /* Cell Counter 0 (cleared when read) */ ++ rreg_t cell_ctr1; /* Cell Counter 1 (cleared when read) */ ++ u_int filler3[0x0f - 0x0e]; ++ rreg_t cmd_reg; /* Command register */ ++ rreg_t desc_base; /* Base address for description table */ ++ rreg_t vc_lkup_base; /* Base address for VC lookup table */ ++ rreg_t reass_base; /* Base address for reassembler table */ ++ rreg_t queue_base; /* Base address for Communication queue */ ++ u_int filler14[0x16 - 0x14]; ++ rreg_t pkt_tm_cnt; /* Packet Timeout and count register */ ++ rreg_t tmout_range; /* Range of reassembley IDs for timeout */ ++ rreg_t intrvl_cntr; /* Packet aging interval counter */ ++ rreg_t tmout_indx; /* index of pkt being tested for aging */ ++ u_int filler1a[0x1c - 0x1a]; ++ rreg_t vp_lkup_base; /* Base address for VP lookup table */ ++ rreg_t vp_filter; /* VP filter register */ ++ rreg_t abr_lkup_base; /* Base address of ABR VC Table */ ++ u_int filler1f[0x24 - 0x1f]; ++ rreg_t fdq_st_adr; /* Free desc queue start address */ ++ rreg_t fdq_ed_adr; /* Free desc queue end address */ ++ rreg_t fdq_rd_ptr; /* Free desc queue read pointer */ ++ rreg_t fdq_wr_ptr; /* Free desc queue write pointer */ ++ rreg_t pcq_st_adr; /* Packet Complete queue start address */ ++ rreg_t pcq_ed_adr; /* Packet Complete queue end address */ ++ rreg_t pcq_rd_ptr; /* Packet Complete queue read pointer */ ++ rreg_t pcq_wr_ptr; /* Packet Complete queue write pointer */ ++ rreg_t excp_st_adr; /* Exception queue start address */ ++ rreg_t excp_ed_adr; /* Exception queue end address */ ++ rreg_t excp_rd_ptr; /* Exception queue read pointer */ ++ rreg_t excp_wr_ptr; /* Exception queue write pointer */ ++ u_int filler30[0x34 - 0x30]; ++ rreg_t raw_st_adr; /* Raw Cell start address */ ++ rreg_t raw_ed_adr; /* Raw Cell end address */ ++ rreg_t raw_rd_ptr; /* Raw Cell read pointer */ ++ rreg_t raw_wr_ptr; /* Raw Cell write pointer */ ++ rreg_t state_reg; /* State Register */ ++ u_int filler39[0x42 - 0x39]; ++ rreg_t buf_size; /* Buffer size */ ++ u_int filler43; ++ rreg_t xtra_rm_offset; /* Offset of the additional turnaround RM */ ++ u_int filler45[0x84 - 0x45]; ++ rreg_t drp_pkt_cntr_nc;/* Dropped Packet cntr, Not clear on rd */ ++ rreg_t err_cntr_nc; /* Error Counter, Not clear on read */ ++ u_int filler86[0x8c - 0x86]; ++ rreg_t cell_ctr0_nc; /* Cell Counter 0, Not clear on read */ ++ rreg_t cell_ctr1_nc; /* Cell Counter 1, Not clear on read */ ++ u_int filler8e[0x100-0x8e]; /* pad out to full address space */ ++} rfredn_t; ++ ++typedef struct { ++ /* Atlantic */ ++ ffredn_t ffredn; /* F FRED */ ++ rfredn_t rfredn; /* R FRED */ ++} ia_regs_t; ++ ++typedef struct { ++ u_short f_vc_type; /* VC type */ ++ u_short f_nrm; /* Nrm */ ++ u_short f_nrmexp; /* Nrm Exp */ ++ u_short reserved6; /* */ ++ u_short f_crm; /* Crm */ ++ u_short reserved10; /* Reserved */ ++ u_short reserved12; /* Reserved */ ++ u_short reserved14; /* Reserved */ ++ u_short last_cell_slot; /* last_cell_slot_count */ ++ u_short f_pcr; /* Peak Cell Rate */ ++ u_short fraction; /* fraction */ ++ u_short f_icr; /* Initial Cell Rate */ ++ u_short f_cdf; /* */ ++ u_short f_mcr; /* Minimum Cell Rate */ ++ u_short f_acr; /* Allowed Cell Rate */ ++ u_short f_status; /* */ ++} f_vc_abr_entry; ++ ++typedef struct { ++ u_short r_status_rdf; /* status + RDF */ ++ u_short r_air; /* AIR */ ++ u_short reserved4[14]; /* Reserved */ ++} r_vc_abr_entry; ++ ++#define MRM 3 ++#define MIN(x,y) ((x) < (y)) ? (x) : (y) ++ ++typedef struct srv_cls_param { ++ u32 class_type; /* CBR/VBR/ABR/UBR; use the enum above */ ++ u32 pcr; /* Peak Cell Rate (24-bit) */ ++ /* VBR parameters */ ++ u32 scr; /* sustainable cell rate */ ++ u32 max_burst_size; /* ?? cell rate or data rate */ ++ ++ /* ABR only UNI 4.0 Parameters */ ++ u32 mcr; /* Min Cell Rate (24-bit) */ ++ u32 icr; /* Initial Cell Rate (24-bit) */ ++ u32 tbe; /* Transient Buffer Exposure (24-bit) */ ++ u32 frtt; /* Fixed Round Trip Time (24-bit) */ + ++#if 0 /* Additional Parameters of TM 4.0 */ ++bits 31 30 29 28 27-25 24-22 21-19 18-9 ++----------------------------------------------------------------------------- ++| NRM present | TRM prsnt | CDF prsnt | ADTF prsnt | NRM | TRM | CDF | ADTF | ++----------------------------------------------------------------------------- ++#endif /* 0 */ ++ ++ u8 nrm; /* Max # of Cells for each forward RM ++ cell (3-bit) */ ++ u8 trm; /* Time between forward RM cells (3-bit) */ ++ u16 adtf; /* ACR Decrease Time Factor (10-bit) */ ++ u8 cdf; /* Cutoff Decrease Factor (3-bit) */ ++ u8 rif; /* Rate Increment Factor (4-bit) */ ++ u8 rdf; /* Rate Decrease Factor (4-bit) */ ++ u8 reserved; /* 8 bits to keep structure word aligned */ ++} srv_cls_param_t; ++ ++struct testTable_t { ++ u16 lastTime; ++ u16 fract; ++ u8 vc_status; ++}; ++ ++typedef struct { ++ u16 vci; ++ u16 error; ++} RX_ERROR_Q; ++ ++typedef struct { ++ u8 active: 1; ++ u8 abr: 1; ++ u8 ubr: 1; ++ u8 cnt: 5; ++#define VC_ACTIVE 0x01 ++#define VC_ABR 0x02 ++#define VC_UBR 0x04 ++} vcstatus_t; ++ ++struct ia_rfL_t { ++ u32 fdq_st; /* Free desc queue start address */ ++ u32 fdq_ed; /* Free desc queue end address */ ++ u32 fdq_rd; /* Free desc queue read pointer */ ++ u32 fdq_wr; /* Free desc queue write pointer */ ++ u32 pcq_st; /* Packet Complete queue start address */ ++ u32 pcq_ed; /* Packet Complete queue end address */ ++ u32 pcq_rd; /* Packet Complete queue read pointer */ ++ u32 pcq_wr; /* Packet Complete queue write pointer */ ++}; + -+#ifndef DRIVER_ATM_IDT77105_H -+#define DRIVER_ATM_IDT77105_H ++struct ia_ffL_t { ++ u32 prq_st; /* Packet Ready Queue Start Address */ ++ u32 prq_ed; /* Packet Ready Queue End Address */ ++ u32 prq_wr; /* Packet Ready Queue write pointer */ ++ u32 tcq_st; /* Transmit Complete Queue Start Address*/ ++ u32 tcq_ed; /* Transmit Complete Queue End Address */ ++ u32 tcq_rd; /* Transmit Complete Queue read pointer */ ++}; + -+#include -+#include ++struct desc_tbl_t { ++ u32 timestamp; ++ struct ia_vcc *iavcc; ++ struct sk_buff *txskb; ++}; ++ ++typedef struct ia_rtn_q { ++ struct desc_tbl_t data; ++ struct ia_rtn_q *next, *tail; ++} IARTN_Q; ++ ++#define SUNI_LOSV 0x04 ++typedef struct { ++ u32 suni_master_reset; /* SUNI Master Reset and Identity */ ++ u32 suni_master_config; /* SUNI Master Configuration */ ++ u32 suni_master_intr_stat; /* SUNI Master Interrupt Status */ ++ u32 suni_reserved1; /* Reserved */ ++ u32 suni_master_clk_monitor;/* SUNI Master Clock Monitor */ ++ u32 suni_master_control; /* SUNI Master Clock Monitor */ ++ u32 suni_reserved2[10]; /* Reserved */ ++ ++ u32 suni_rsop_control; /* RSOP Control/Interrupt Enable */ ++ u32 suni_rsop_status; /* RSOP Status/Interrupt States */ ++ u32 suni_rsop_section_bip8l;/* RSOP Section BIP-8 LSB */ ++ u32 suni_rsop_section_bip8m;/* RSOP Section BIP-8 MSB */ ++ ++ u32 suni_tsop_control; /* TSOP Control */ ++ u32 suni_tsop_diag; /* TSOP Disgnostics */ ++ u32 suni_tsop_reserved[2]; /* TSOP Reserved */ ++ ++ u32 suni_rlop_cs; /* RLOP Control/Status */ ++ u32 suni_rlop_intr; /* RLOP Interrupt Enable/Status */ ++ u32 suni_rlop_line_bip24l; /* RLOP Line BIP-24 LSB */ ++ u32 suni_rlop_line_bip24; /* RLOP Line BIP-24 */ ++ u32 suni_rlop_line_bip24m; /* RLOP Line BIP-24 MSB */ ++ u32 suni_rlop_line_febel; /* RLOP Line FEBE LSB */ ++ u32 suni_rlop_line_febe; /* RLOP Line FEBE */ ++ u32 suni_rlop_line_febem; /* RLOP Line FEBE MSB */ ++ ++ u32 suni_tlop_control; /* TLOP Control */ ++ u32 suni_tlop_disg; /* TLOP Disgnostics */ ++ u32 suni_tlop_reserved[14]; /* TLOP Reserved */ ++ ++ u32 suni_rpop_cs; /* RPOP Status/Control */ ++ u32 suni_rpop_intr; /* RPOP Interrupt/Status */ ++ u32 suni_rpop_reserved; /* RPOP Reserved */ ++ u32 suni_rpop_intr_ena; /* RPOP Interrupt Enable */ ++ u32 suni_rpop_reserved1[3]; /* RPOP Reserved */ ++ u32 suni_rpop_path_sig; /* RPOP Path Signal Label */ ++ u32 suni_rpop_bip8l; /* RPOP Path BIP-8 LSB */ ++ u32 suni_rpop_bip8m; /* RPOP Path BIP-8 MSB */ ++ u32 suni_rpop_febel; /* RPOP Path FEBE LSB */ ++ u32 suni_rpop_febem; /* RPOP Path FEBE MSB */ ++ u32 suni_rpop_reserved2[4]; /* RPOP Reserved */ ++ ++ u32 suni_tpop_cntrl_daig; /* TPOP Control/Disgnostics */ ++ u32 suni_tpop_pointer_ctrl; /* TPOP Pointer Control */ ++ u32 suni_tpop_sourcer_ctrl; /* TPOP Source Control */ ++ u32 suni_tpop_reserved1[2]; /* TPOP Reserved */ ++ u32 suni_tpop_arb_prtl; /* TPOP Arbitrary Pointer LSB */ ++ u32 suni_tpop_arb_prtm; /* TPOP Arbitrary Pointer MSB */ ++ u32 suni_tpop_reserved2; /* TPOP Reserved */ ++ u32 suni_tpop_path_sig; /* TPOP Path Signal Lable */ ++ u32 suni_tpop_path_status; /* TPOP Path Status */ ++ u32 suni_tpop_reserved3[6]; /* TPOP Reserved */ ++ ++ u32 suni_racp_cs; /* RACP Control/Status */ ++ u32 suni_racp_intr; /* RACP Interrupt Enable/Status */ ++ u32 suni_racp_hdr_pattern; /* RACP Match Header Pattern */ ++ u32 suni_racp_hdr_mask; /* RACP Match Header Mask */ ++ u32 suni_racp_corr_hcs; /* RACP Correctable HCS Error Count */ ++ u32 suni_racp_uncorr_hcs; /* RACP Uncorrectable HCS Error Count */ ++ u32 suni_racp_reserved[10]; /* RACP Reserved */ ++ ++ u32 suni_tacp_control; /* TACP Control */ ++ u32 suni_tacp_idle_hdr_pat; /* TACP Idle Cell Header Pattern */ ++ u32 suni_tacp_idle_pay_pay; /* TACP Idle Cell Payld Octet Pattern */ ++ u32 suni_tacp_reserved[5]; /* TACP Reserved */ ++ ++ u32 suni_reserved3[24]; /* Reserved */ ++ ++ u32 suni_master_test; /* SUNI Master Test */ ++ u32 suni_reserved_test; /* SUNI Reserved for Test */ ++} IA_SUNI; + + -+/* IDT77105 registers */ ++typedef struct _SUNI_STATS_ ++{ ++ u32 valid; // 1 = oc3 PHY card ++ u32 carrier_detect; // GPIN input ++ // RSOP: receive section overhead processor ++ u16 rsop_oof_state; // 1 = out of frame ++ u16 rsop_lof_state; // 1 = loss of frame ++ u16 rsop_los_state; // 1 = loss of signal ++ u32 rsop_los_count; // loss of signal count ++ u32 rsop_bse_count; // section BIP-8 error count ++ // RLOP: receive line overhead processor ++ u16 rlop_ferf_state; // 1 = far end receive failure ++ u16 rlop_lais_state; // 1 = line AIS ++ u32 rlop_lbe_count; // BIP-24 count ++ u32 rlop_febe_count; // FEBE count; ++ // RPOP: receive path overhead processor ++ u16 rpop_lop_state; // 1 = LOP ++ u16 rpop_pais_state; // 1 = path AIS ++ u16 rpop_pyel_state; // 1 = path yellow alert ++ u32 rpop_bip_count; // path BIP-8 error count ++ u32 rpop_febe_count; // path FEBE error count ++ u16 rpop_psig; // path signal label value ++ // RACP: receive ATM cell processor ++ u16 racp_hp_state; // hunt/presync state ++ u32 racp_fu_count; // FIFO underrun count ++ u32 racp_fo_count; // FIFO overrun count ++ u32 racp_chcs_count; // correctable HCS error count ++ u32 racp_uchcs_count; // uncorrectable HCS error count ++} IA_SUNI_STATS; ++ ++typedef struct iadev_t { ++ /*-----base pointers into (i)chipSAR+ address space */ ++ u32 *phy; /* base pointer into phy(SUNI) */ ++ u32 *dma; /* base pointer into DMA control ++ registers */ ++ u32 *reg; /* base pointer to SAR registers ++ - Bus Interface Control Regs */ ++ u32 *seg_reg; /* base pointer to segmentation engine ++ internal registers */ ++ u32 *reass_reg; /* base pointer to reassemble engine ++ internal registers */ ++ u32 *ram; /* base pointer to SAR RAM */ ++ unsigned int seg_ram; ++ unsigned int reass_ram; ++ struct dle_q tx_dle_q; ++ struct free_desc_q *tx_free_desc_qhead; ++ struct sk_buff_head tx_dma_q, tx_backlog; ++ spinlock_t tx_lock; ++ IARTN_Q tx_return_q; ++ u32 close_pending; ++#if LINUX_VERSION_CODE >= 0x20303 ++ wait_queue_head_t close_wait; ++ wait_queue_head_t timeout_wait; ++#else ++ struct wait_queue *close_wait; ++ struct wait_queue *timeout_wait; ++#endif ++ caddr_t *tx_buf; ++ u16 num_tx_desc, tx_buf_sz, rate_limit; ++ u32 tx_cell_cnt, tx_pkt_cnt; ++ u32 MAIN_VC_TABLE_ADDR, EXT_VC_TABLE_ADDR, ABR_SCHED_TABLE_ADDR; ++ struct dle_q rx_dle_q; ++ struct free_desc_q *rx_free_desc_qhead; ++ struct sk_buff_head rx_dma_q; ++ spinlock_t rx_lock, misc_lock; ++ struct atm_vcc **rx_open; /* list of all open VCs */ ++ u16 num_rx_desc, rx_buf_sz, rxing; ++ u32 rx_pkt_ram, rx_tmp_cnt, rx_tmp_jif; ++ u32 RX_DESC_BASE_ADDR; ++ u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt; ++ struct atm_dev *next_board; /* other iphase devices */ ++ struct pci_dev *pci; ++ int mem; ++ unsigned long base_diff; /* virtual - real base address */ ++ unsigned int real_base, base; /* real and virtual base address */ ++ unsigned int pci_map_size; /*pci map size of board */ ++ unsigned char irq; ++ unsigned char bus; ++ unsigned char dev_fn; ++ u_short phy_type; ++ u_short num_vc, memSize, memType; ++ struct ia_ffL_t ffL; ++ struct ia_rfL_t rfL; ++ /* Suni stat */ ++ // IA_SUNI_STATS suni_stats; ++ unsigned char carrier_detect; ++ /* CBR related */ ++ // transmit DMA & Receive ++ unsigned int tx_dma_cnt; // number of elements on dma queue ++ unsigned int rx_dma_cnt; // number of elements on rx dma queue ++ unsigned int NumEnabledCBR; // number of CBR VCI's enabled. CBR ++ // receive MARK for Cell FIFO ++ unsigned int rx_mark_cnt; // number of elements on mark queue ++ unsigned int CbrTotEntries; // Total CBR Entries in Scheduling Table. ++ unsigned int CbrRemEntries; // Remaining CBR Entries in Scheduling Table. ++ unsigned int CbrEntryPt; // CBR Sched Table Entry Point. ++ unsigned int Granularity; // CBR Granularity given Table Size. ++ /* ABR related */ ++ unsigned int sum_mcr, sum_cbr, LineRate; ++ unsigned int n_abr; ++ struct desc_tbl_t *desc_tbl; ++ u_short host_tcq_wr; ++ struct testTable_t **testTable; ++} IADEV; ++ ++ ++#define INPH_IA_DEV(d) ((IADEV *) (d)->dev_data) ++#define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data) ++ ++/******************* IDT77105 25MB/s PHY DEFINE *****************************/ ++typedef struct { ++ u_int mb25_master_ctrl; /* Master control */ ++ u_int mb25_intr_status; /* Interrupt status */ ++ u_int mb25_diag_control; /* Diagnostic control */ ++ u_int mb25_led_hec; /* LED driver and HEC status/control */ ++ u_int mb25_low_byte_counter; /* Low byte counter */ ++ u_int mb25_high_byte_counter; /* High byte counter */ ++} ia_mb25_t; + -+#define IDT77105_MCR 0x0 /* Master Control Register */ -+#define IDT77105_ISTAT 0x1 /* Interrupt Status */ -+#define IDT77105_DIAG 0x2 /* Diagnostic Control */ -+#define IDT77105_LEDHEC 0x3 /* LED Driver & HEC Status/Control */ -+#define IDT77105_CTRLO 0x4 /* Low Byte Counter Register */ -+#define IDT77105_CTRHI 0x5 /* High Byte Counter Register */ -+#define IDT77105_CTRSEL 0x6 /* Counter Register Read Select */ ++/* ++ * Master Control ++ */ ++#define MB25_MC_UPLO 0x80 /* UPLO */ ++#define MB25_MC_DREC 0x40 /* Discard receive cell errors */ ++#define MB25_MC_ECEIO 0x20 /* Enable Cell Error Interrupts Only */ ++#define MB25_MC_TDPC 0x10 /* Transmit data parity check */ ++#define MB25_MC_DRIC 0x08 /* Discard receive idle cells */ ++#define MB25_MC_HALTTX 0x04 /* Halt Tx */ ++#define MB25_MC_UMS 0x02 /* UTOPIA mode select */ ++#define MB25_MC_ENABLED 0x01 /* Enable interrupt */ + -+/* IDT77105 register values */ ++/* ++ * Interrupt Status ++ */ ++#define MB25_IS_GSB 0x40 /* GOOD Symbol Bit */ ++#define MB25_IS_HECECR 0x20 /* HEC error cell received */ ++#define MB25_IS_SCR 0x10 /* "Short Cell" Received */ ++#define MB25_IS_TPE 0x08 /* Trnamsit Parity Error */ ++#define MB25_IS_RSCC 0x04 /* Receive Signal Condition change */ ++#define MB25_IS_RCSE 0x02 /* Received Cell Symbol Error */ ++#define MB25_IS_RFIFOO 0x01 /* Received FIFO Overrun */ + -+/* MCR */ -+#define IDT77105_MCR_UPLO 0x80 /* R/W, User Prog'le Output Latch */ -+#define IDT77105_MCR_DREC 0x40 /* R/W, Discard Receive Error Cells */ -+#define IDT77105_MCR_ECEIO 0x20 /* R/W, Enable Cell Error Interrupts -+ * Only */ -+#define IDT77105_MCR_TDPC 0x10 /* R/W, Transmit Data Parity Check */ -+#define IDT77105_MCR_DRIC 0x08 /* R/W, Discard Received Idle Cells */ -+#define IDT77105_MCR_HALTTX 0x04 /* R/W, Halt Tx */ -+#define IDT77105_MCR_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */ -+#define IDT77105_MCR_EIP 0x01 /* R/W, Enable Interrupt Pin */ ++/* ++ * Diagnostic Control ++ */ ++#define MB25_DC_FTXCD 0x80 /* Force TxClav deassert */ ++#define MB25_DC_RXCOS 0x40 /* RxClav operation select */ ++#define MB25_DC_ECEIO 0x20 /* Single/Multi-PHY config select */ ++#define MB25_DC_RLFLUSH 0x10 /* Clear receive FIFO */ ++#define MB25_DC_IXPE 0x08 /* Insert xmit payload error */ ++#define MB25_DC_IXHECE 0x04 /* Insert Xmit HEC Error */ ++#define MB25_DC_LB_MASK 0x03 /* Loopback control mask */ ++ ++#define MB25_DC_LL 0x03 /* Line Loopback */ ++#define MB25_DC_PL 0x02 /* PHY Loopback */ ++#define MB25_DC_NM 0x00 ++ ++#define FE_MASK 0x00F0 ++#define FE_MULTI_MODE 0x0000 ++#define FE_SINGLE_MODE 0x0010 ++#define FE_UTP_OPTION 0x0020 ++#define FE_25MBIT_PHY 0x0040 ++#define FE_DS3_PHY 0x0080 /* DS3 */ ++#define FE_E3_PHY 0x0090 /* E3 */ ++ ++extern void ia_mb25_init (IADEV *); + -+/* ISTAT */ -+#define IDT77105_ISTAT_GOODSIG 0x40 /* R, Good Signal Bit */ -+#define IDT77105_ISTAT_HECERR 0x20 /* sticky, HEC Error*/ -+#define IDT77105_ISTAT_SCR 0x10 /* sticky, Short Cell Received */ -+#define IDT77105_ISTAT_TPE 0x08 /* sticky, Transmit Parity Error */ -+#define IDT77105_ISTAT_RSCC 0x04 /* sticky, Rx Signal Condition Change */ -+#define IDT77105_ISTAT_RSE 0x02 /* sticky, Rx Symbol Error */ -+#define IDT77105_ISTAT_RFO 0x01 /* sticky, Rx FIFO Overrun */ ++/*********************** SUNI_PM7345 PHY DEFINE HERE *********************/ ++typedef struct _suni_pm7345_t ++{ ++ u_int suni_config; /* SUNI Configuration */ ++ u_int suni_intr_enbl; /* SUNI Interrupt Enable */ ++ u_int suni_intr_stat; /* SUNI Interrupt Status */ ++ u_int suni_control; /* SUNI Control */ ++ u_int suni_id_reset; /* SUNI Reset and Identity */ ++ u_int suni_data_link_ctrl; ++ u_int suni_rboc_conf_intr_enbl; ++ u_int suni_rboc_stat; ++ u_int suni_ds3_frm_cfg; ++ u_int suni_ds3_frm_intr_enbl; ++ u_int suni_ds3_frm_intr_stat; ++ u_int suni_ds3_frm_stat; ++ u_int suni_rfdl_cfg; ++ u_int suni_rfdl_enbl_stat; ++ u_int suni_rfdl_stat; ++ u_int suni_rfdl_data; ++ u_int suni_pmon_chng; ++ u_int suni_pmon_intr_enbl_stat; ++ u_int suni_reserved1[0x13-0x11]; ++ u_int suni_pmon_lcv_evt_cnt_lsb; ++ u_int suni_pmon_lcv_evt_cnt_msb; ++ u_int suni_pmon_fbe_evt_cnt_lsb; ++ u_int suni_pmon_fbe_evt_cnt_msb; ++ u_int suni_pmon_sez_det_cnt_lsb; ++ u_int suni_pmon_sez_det_cnt_msb; ++ u_int suni_pmon_pe_evt_cnt_lsb; ++ u_int suni_pmon_pe_evt_cnt_msb; ++ u_int suni_pmon_ppe_evt_cnt_lsb; ++ u_int suni_pmon_ppe_evt_cnt_msb; ++ u_int suni_pmon_febe_evt_cnt_lsb; ++ u_int suni_pmon_febe_evt_cnt_msb; ++ u_int suni_ds3_tran_cfg; ++ u_int suni_ds3_tran_diag; ++ u_int suni_reserved2[0x23-0x21]; ++ u_int suni_xfdl_cfg; ++ u_int suni_xfdl_intr_st; ++ u_int suni_xfdl_xmit_data; ++ u_int suni_xboc_code; ++ u_int suni_splr_cfg; ++ u_int suni_splr_intr_en; ++ u_int suni_splr_intr_st; ++ u_int suni_splr_status; ++ u_int suni_splt_cfg; ++ u_int suni_splt_cntl; ++ u_int suni_splt_diag_g1; ++ u_int suni_splt_f1; ++ u_int suni_cppm_loc_meters; ++ u_int suni_cppm_chng_of_cppm_perf_meter; ++ u_int suni_cppm_b1_err_cnt_lsb; ++ u_int suni_cppm_b1_err_cnt_msb; ++ u_int suni_cppm_framing_err_cnt_lsb; ++ u_int suni_cppm_framing_err_cnt_msb; ++ u_int suni_cppm_febe_cnt_lsb; ++ u_int suni_cppm_febe_cnt_msb; ++ u_int suni_cppm_hcs_err_cnt_lsb; ++ u_int suni_cppm_hcs_err_cnt_msb; ++ u_int suni_cppm_idle_un_cell_cnt_lsb; ++ u_int suni_cppm_idle_un_cell_cnt_msb; ++ u_int suni_cppm_rcv_cell_cnt_lsb; ++ u_int suni_cppm_rcv_cell_cnt_msb; ++ u_int suni_cppm_xmit_cell_cnt_lsb; ++ u_int suni_cppm_xmit_cell_cnt_msb; ++ u_int suni_rxcp_ctrl; ++ u_int suni_rxcp_fctrl; ++ u_int suni_rxcp_intr_en_sts; ++ u_int suni_rxcp_idle_pat_h1; ++ u_int suni_rxcp_idle_pat_h2; ++ u_int suni_rxcp_idle_pat_h3; ++ u_int suni_rxcp_idle_pat_h4; ++ u_int suni_rxcp_idle_mask_h1; ++ u_int suni_rxcp_idle_mask_h2; ++ u_int suni_rxcp_idle_mask_h3; ++ u_int suni_rxcp_idle_mask_h4; ++ u_int suni_rxcp_cell_pat_h1; ++ u_int suni_rxcp_cell_pat_h2; ++ u_int suni_rxcp_cell_pat_h3; ++ u_int suni_rxcp_cell_pat_h4; ++ u_int suni_rxcp_cell_mask_h1; ++ u_int suni_rxcp_cell_mask_h2; ++ u_int suni_rxcp_cell_mask_h3; ++ u_int suni_rxcp_cell_mask_h4; ++ u_int suni_rxcp_hcs_cs; ++ u_int suni_rxcp_lcd_cnt_threshold; ++ u_int suni_reserved3[0x57-0x54]; ++ u_int suni_txcp_ctrl; ++ u_int suni_txcp_intr_en_sts; ++ u_int suni_txcp_idle_pat_h1; ++ u_int suni_txcp_idle_pat_h2; ++ u_int suni_txcp_idle_pat_h3; ++ u_int suni_txcp_idle_pat_h4; ++ u_int suni_txcp_idle_pat_h5; ++ u_int suni_txcp_idle_payload; ++ u_int suni_e3_frm_fram_options; ++ u_int suni_e3_frm_maint_options; ++ u_int suni_e3_frm_fram_intr_enbl; ++ u_int suni_e3_frm_fram_intr_ind_stat; ++ u_int suni_e3_frm_maint_intr_enbl; ++ u_int suni_e3_frm_maint_intr_ind; ++ u_int suni_e3_frm_maint_stat; ++ u_int suni_reserved4; ++ u_int suni_e3_tran_fram_options; ++ u_int suni_e3_tran_stat_diag_options; ++ u_int suni_e3_tran_bip_8_err_mask; ++ u_int suni_e3_tran_maint_adapt_options; ++ u_int suni_ttb_ctrl; ++ u_int suni_ttb_trail_trace_id_stat; ++ u_int suni_ttb_ind_addr; ++ u_int suni_ttb_ind_data; ++ u_int suni_ttb_exp_payload_type; ++ u_int suni_ttb_payload_type_ctrl_stat; ++ u_int suni_pad5[0x7f-0x71]; ++ u_int suni_master_test; ++ u_int suni_pad6[0xff-0x80]; ++}suni_pm7345_t; ++ ++#define SUNI_PM7345_T suni_pm7345_t ++#define SUNI_PM7345 0x20 /* Suni chip type */ ++#define SUNI_PM5346 0x30 /* Suni chip type */ ++/* ++ * SUNI_PM7345 Configuration ++ */ ++#define SUNI_PM7345_CLB 0x01 /* Cell loopback */ ++#define SUNI_PM7345_PLB 0x02 /* Payload loopback */ ++#define SUNI_PM7345_DLB 0x04 /* Diagnostic loopback */ ++#define SUNI_PM7345_LLB 0x80 /* Line loopback */ ++#define SUNI_PM7345_E3ENBL 0x40 /* E3 enable bit */ ++#define SUNI_PM7345_LOOPT 0x10 /* LOOPT enable bit */ ++#define SUNI_PM7345_FIFOBP 0x20 /* FIFO bypass */ ++#define SUNI_PM7345_FRMRBP 0x08 /* Framer bypass */ ++/* ++ * DS3 FRMR Interrupt Enable ++ */ ++#define SUNI_DS3_COFAE 0x80 /* Enable change of frame align */ ++#define SUNI_DS3_REDE 0x40 /* Enable DS3 RED state intr */ ++#define SUNI_DS3_CBITE 0x20 /* Enable Appl ID channel intr */ ++#define SUNI_DS3_FERFE 0x10 /* Enable Far End Receive Failure intr*/ ++#define SUNI_DS3_IDLE 0x08 /* Enable Idle signal intr */ ++#define SUNI_DS3_AISE 0x04 /* Enable Alarm Indication signal intr*/ ++#define SUNI_DS3_OOFE 0x02 /* Enable Out of frame intr */ ++#define SUNI_DS3_LOSE 0x01 /* Enable Loss of signal intr */ ++ ++/* ++ * DS3 FRMR Status ++ */ ++#define SUNI_DS3_ACE 0x80 /* Additional Configuration Reg */ ++#define SUNI_DS3_REDV 0x40 /* DS3 RED state */ ++#define SUNI_DS3_CBITV 0x20 /* Application ID channel state */ ++#define SUNI_DS3_FERFV 0x10 /* Far End Receive Failure state*/ ++#define SUNI_DS3_IDLV 0x08 /* Idle signal state */ ++#define SUNI_DS3_AISV 0x04 /* Alarm Indication signal state*/ ++#define SUNI_DS3_OOFV 0x02 /* Out of frame state */ ++#define SUNI_DS3_LOSV 0x01 /* Loss of signal state */ + -+/* DIAG */ -+#define IDT77105_DIAG_FTD 0x80 /* R/W, Force TxClav deassert */ -+#define IDT77105_DIAG_ROS 0x40 /* R/W, RxClav operation select */ -+#define IDT77105_DIAG_MPCS 0x20 /* R/W, Multi-PHY config'n select */ -+#define IDT77105_DIAG_RFLUSH 0x10 /* R/W, clear receive FIFO */ -+#define IDT77105_DIAG_ITPE 0x08 /* R/W, Insert Tx payload error */ -+#define IDT77105_DIAG_ITHE 0x04 /* R/W, Insert Tx HEC error */ -+#define IDT77105_DIAG_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */ -+#define IDT77105_DIAG_LCMASK 0x03 /* R/W, Loopback Control */ ++/* ++ * E3 FRMR Interrupt/Status ++ */ ++#define SUNI_E3_CZDI 0x40 /* Consecutive Zeros indicator */ ++#define SUNI_E3_LOSI 0x20 /* Loss of signal intr status */ ++#define SUNI_E3_LCVI 0x10 /* Line code violation intr */ ++#define SUNI_E3_COFAI 0x08 /* Change of frame align intr */ ++#define SUNI_E3_OOFI 0x04 /* Out of frame intr status */ ++#define SUNI_E3_LOS 0x02 /* Loss of signal state */ ++#define SUNI_E3_OOF 0x01 /* Out of frame state */ + -+#define IDT77105_DIAG_LC_NORMAL 0x00 /* Receive from network */ -+#define IDT77105_DIAG_LC_PHY_LOOPBACK 0x02 -+#define IDT77105_DIAG_LC_LINE_LOOPBACK 0x03 ++/* ++ * E3 FRMR Maintenance Status ++ */ ++#define SUNI_E3_AISD 0x80 /* Alarm Indication signal state*/ ++#define SUNI_E3_FERF_RAI 0x40 /* FERF/RAI indicator */ ++#define SUNI_E3_FEBE 0x20 /* Far End Block Error indicator*/ + -+/* LEDHEC */ -+#define IDT77105_LEDHEC_DRHC 0x40 /* R/W, Disable Rx HEC check */ -+#define IDT77105_LEDHEC_DTHC 0x20 /* R/W, Disable Tx HEC calculation */ -+#define IDT77105_LEDHEC_RPWMASK 0x18 /* R/W, RxRef pulse width select */ -+#define IDT77105_LEDHEC_TFS 0x04 /* R, Tx FIFO Status (1=empty) */ -+#define IDT77105_LEDHEC_TLS 0x02 /* R, Tx LED Status (1=lit) */ -+#define IDT77105_LEDHEC_RLS 0x01 /* R, Rx LED Status (1=lit) */ ++/* ++ * RXCP Control/Status ++ */ ++#define SUNI_DS3_HCSPASS 0x80 /* Pass cell with HEC errors */ ++#define SUNI_DS3_HCSDQDB 0x40 /* Control octets in HCS calc */ ++#define SUNI_DS3_HCSADD 0x20 /* Add coset poly */ ++#define SUNI_DS3_HCK 0x10 /* Control FIFO data path integ chk*/ ++#define SUNI_DS3_BLOCK 0x08 /* Enable cell filtering */ ++#define SUNI_DS3_DSCR 0x04 /* Disable payload descrambling */ ++#define SUNI_DS3_OOCDV 0x02 /* Cell delineation state */ ++#define SUNI_DS3_FIFORST 0x01 /* Cell FIFO reset */ + -+#define IDT77105_LEDHEC_RPW_1 0x00 /* RxRef active for 1 RxClk cycle */ -+#define IDT77105_LEDHEC_RPW_2 0x08 /* RxRef active for 2 RxClk cycle */ -+#define IDT77105_LEDHEC_RPW_4 0x10 /* RxRef active for 4 RxClk cycle */ -+#define IDT77105_LEDHEC_RPW_8 0x18 /* RxRef active for 8 RxClk cycle */ ++/* ++ * RXCP Interrupt Enable/Status ++ */ ++#define SUNI_DS3_OOCDE 0x80 /* Intr enable, change in CDS */ ++#define SUNI_DS3_HCSE 0x40 /* Intr enable, corr HCS errors */ ++#define SUNI_DS3_FIFOE 0x20 /* Intr enable, unco HCS errors */ ++#define SUNI_DS3_OOCDI 0x10 /* SYNC state */ ++#define SUNI_DS3_UHCSI 0x08 /* Uncorr. HCS errors detected */ ++#define SUNI_DS3_COCAI 0x04 /* Corr. HCS errors detected */ ++#define SUNI_DS3_FOVRI 0x02 /* FIFO overrun */ ++#define SUNI_DS3_FUDRI 0x01 /* FIFO underrun */ ++ ++extern void ia_suni_pm7345_init (IADEV *iadev); ++ ++///////////////////SUNI_PM7345 PHY DEFINE END ///////////////////////////// ++ ++/* ia_eeprom define*/ ++#define MEM_SIZE_MASK 0x000F /* mask of 4 bits defining memory size*/ ++#define MEM_SIZE_128K 0x0000 /* board has 128k buffer */ ++#define MEM_SIZE_512K 0x0001 /* board has 512K of buffer */ ++#define MEM_SIZE_1M 0x0002 /* board has 1M of buffer */ ++ /* 0x3 to 0xF are reserved for future */ ++ ++#define FE_MASK 0x00F0 /* mask of 4 bits defining FE type */ ++#define FE_MULTI_MODE 0x0000 /* 155 MBit multimode fiber */ ++#define FE_SINGLE_MODE 0x0010 /* 155 MBit single mode laser */ ++#define FE_UTP_OPTION 0x0020 /* 155 MBit UTP front end */ ++ ++#define NOVRAM_SIZE 64 ++#define CMD_LEN 10 ++ ++/*********** ++ * ++ * Switches and defines for header files. ++ * ++ * The following defines are used to turn on and off ++ * various options in the header files. Primarily useful ++ * for debugging. ++ * ++ ***********/ + -+/* CTRSEL */ -+#define IDT77105_CTRSEL_SEC 0x08 /* W, Symbol Error Counter */ -+#define IDT77105_CTRSEL_TCC 0x04 /* W, Tx Cell Counter */ -+#define IDT77105_CTRSEL_RCC 0x02 /* W, Rx Cell Counter */ -+#define IDT77105_CTRSEL_RHEC 0x01 /* W, Rx HEC Error Counter */ ++/* ++ * a list of the commands that can be sent to the NOVRAM ++ */ + -+#ifdef __KERNEL__ -+int idt77105_init(struct atm_dev *dev) __init; -+int idt77105_stop(struct atm_dev *dev); -+#endif ++#define EXTEND 0x100 ++#define IAWRITE 0x140 ++#define IAREAD 0x180 ++#define ERASE 0x1c0 ++ ++#define EWDS 0x00 ++#define WRAL 0x10 ++#define ERAL 0x20 ++#define EWEN 0x30 + +/* -+ * Tunable parameters ++ * these bits duplicate the hw_flip.h register settings ++ * note: how the data in / out bits are defined in the flipper specification + */ -+ -+/* Time between samples of the hardware cell counters. Should be <= 1 sec */ -+#define IDT77105_STATS_TIMER_PERIOD (HZ) -+/* Time between checks to see if the signal has been found again */ -+#define IDT77105_RESTART_TIMER_PERIOD (5 * HZ) + -+#endif ---- ref/drivers/atm/nicstar.c Wed Sep 8 20:14:31 1999 -+++ work/drivers/atm/nicstar.c Mon Nov 22 14:10:24 1999 ++#define NVCE 0x02 ++#define NVSK 0x01 ++#define NVDO 0x08 ++#define NVDI 0x04 ++/*********************** ++ * ++ * This define ands the value and the current config register and puts ++ * the result in the config register ++ * ++ ***********************/ ++ ++#define CFG_AND(val) { \ ++ u32 t; \ ++ t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \ ++ t &= (val); \ ++ writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \ ++ } ++ ++/*********************** ++ * ++ * This define ors the value and the current config register and puts ++ * the result in the config register ++ * ++ ***********************/ ++ ++#define CFG_OR(val) { \ ++ u32 t; \ ++ t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \ ++ t |= (val); \ ++ writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \ ++ } ++ ++/*********************** ++ * ++ * Send a command to the NOVRAM, the command is in cmd. ++ * ++ * clear CE and SK. Then assert CE. ++ * Clock each of the command bits out in the correct order with SK ++ * exit with CE still asserted ++ * ++ ***********************/ ++ ++#define NVRAM_CMD(cmd) { \ ++ int i; \ ++ u_short c = cmd; \ ++ CFG_AND(~(NVCE|NVSK)); \ ++ CFG_OR(NVCE); \ ++ for (i=0; ireg+IPHASE5575_EEPROM_ACCESS); \ ++ value = (_t & NVDO) ? 1 : 0; \ ++ } ++ ++ ++#endif /* IPHASE_H */ +--- ref/drivers/atm/nicstar.c Mon Jan 10 23:05:32 2000 ++++ work/drivers/atm/nicstar.c Fri Jan 21 16:01:05 2000 @@ -44,6 +44,9 @@ #ifdef CONFIG_ATM_NICSTAR_USE_SUNI #include "suni.h" @@ -1008,7 +10804,36 @@ #undef CEIL(d) -@@ -286,6 +291,12 @@ +@@ -164,21 +169,13 @@ + static unsigned num_cards = 0; + static struct atmdev_ops atm_ops = + { +- NULL, /* dev_close */ +- ns_open, /* open */ +- ns_close, /* close */ +- ns_ioctl, /* ioctl */ +- NULL, /* getsockopt */ +- NULL, /* setsockopt */ +- ns_send, /* send */ +- NULL, /* sg_send */ +- NULL, /* send_oam */ +- ns_phy_put, /* phy_put */ +- ns_phy_get, /* phy_get */ +- NULL, /* feedback */ +- NULL, /* change_qos */ +- NULL, /* free_rx_skb */ +- ns_proc_read /* proc_read */ ++ open: ns_open, ++ close: ns_close, ++ ioctl: ns_ioctl, ++ send: ns_send, ++ phy_put: ns_phy_put, ++ phy_get: ns_phy_get, ++ proc_read: ns_proc_read + }; + static struct timer_list ns_timer; + static char *mac[NS_MAX_CARDS] = { NULL +@@ -286,6 +283,12 @@ card = cards[i]; @@ -1021,7 +10846,7 @@ /* Stop everything */ writel(0x00000000, card->membase + CFG); -@@ -457,15 +468,16 @@ +@@ -457,15 +460,16 @@ cards[i] = card; card->index = i; @@ -1036,12 +10861,28 @@ #endif /* __powerpc__ */ - card->membase = (u32) ioremap(card->membase, NS_IOREMAP_SIZE); - if (card->membase == (u32) (NULL)) -+ card->membase = ioremap(card->membase, NS_IOREMAP_SIZE); ++ card->membase = (unsigned long) ioremap(card->membase, NS_IOREMAP_SIZE); + if (card->membase == 0) { printk("nicstar%d: can't ioremap() membase.\n",i); error = 3; -@@ -872,8 +884,8 @@ +@@ -497,6 +501,7 @@ + ns_init_card_error(card, error); + return error; + } ++#ifdef NS_PCI_LATENCY + if (pci_latency < NS_PCI_LATENCY) + { + PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i, NS_PCI_LATENCY); +@@ -513,6 +518,7 @@ + return error; + } + } ++#endif /* NS_PCI_LATENCY */ + + /* Clear timer overflow */ + data = readl(card->membase + STAT); +@@ -872,8 +878,8 @@ card->atmdev->ci_range.vpi_bits = card->vpibits; card->atmdev->ci_range.vci_bits = card->vcibits; card->atmdev->link_rate = card->max_pcr; @@ -1051,7 +10892,7 @@ #ifdef CONFIG_ATM_NICSTAR_USE_SUNI if (card->max_pcr == ATM_OC3_PCR) { suni_init(card->atmdev); -@@ -883,6 +895,17 @@ +@@ -883,6 +889,17 @@ #endif /* MODULE */ } #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ @@ -1069,7 +10910,27 @@ if (card->atmdev->phy && card->atmdev->phy->start) card->atmdev->phy->start(card->atmdev); -@@ -2679,7 +2702,10 @@ +@@ -1798,8 +1815,8 @@ + flags = NS_TBD_AAL5; + scqe.word_2 = cpu_to_le32((u32) virt_to_bus(skb->data)); + scqe.word_3 = cpu_to_le32((u32) skb->len); +- scqe.word_4 = cpu_to_le32(((u32) vcc->vpi) << NS_TBD_VPI_SHIFT | +- ((u32) vcc->vci) << NS_TBD_VCI_SHIFT); ++ scqe.word_4 = ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0, ++ ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? 1 : 0); + flags |= NS_TBD_EOPDU; + } + else /* (vcc->qos.aal == ATM_AAL0) */ +@@ -1950,7 +1967,7 @@ + { + u32 scdi; + scq_info *scq; +- ns_tsi *previous, *one_ahead, *two_ahead; ++ ns_tsi *previous = NULL, *one_ahead, *two_ahead; + int serviced_entries; /* flag indicating at least on entry was serviced */ + + serviced_entries = 0; +@@ -2679,7 +2696,10 @@ card->intcnt = 0; return retval; } @@ -1080,7 +10941,7 @@ if (card->max_pcr == IDT_25_PCR && !left--) { u32 phy_regs[4]; -@@ -2696,6 +2722,7 @@ +@@ -2696,6 +2716,7 @@ return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n", phy_regs[0], phy_regs[1], phy_regs[2], phy_regs[3]); } @@ -1088,8 +10949,53 @@ #if 0 /* Dump TST */ if (left-- < NS_TST_NUM_ENTRIES) +@@ -2757,7 +2778,7 @@ + break; + + default: +- return -EINVAL; ++ return -ENOIOCTLCMD; + + } + if (!copy_to_user((pool_levels *) arg, &pl, sizeof(pl))) +@@ -2921,7 +2942,7 @@ + else { + printk("nicstar%d: %s == NULL \n", card->index, + dev->phy ? "dev->phy->ioctl" : "dev->phy"); +- return -EINVAL; ++ return -ENOIOCTLCMD; + } + } + } --- ref/drivers/atm/nicstar.h Mon Aug 23 18:56:31 1999 -+++ work/drivers/atm/nicstar.h Wed Dec 1 03:16:50 1999 ++++ work/drivers/atm/nicstar.h Fri Jan 21 16:47:47 2000 +@@ -51,7 +51,7 @@ + 128K x 32bit SRAM will limit the maximum + VCI. */ + +-#define NS_PCI_LATENCY 64 /* Must be a multiple of 32 */ ++/*#define NS_PCI_LATENCY 64*/ /* Must be a multiple of 32 */ + + /* Number of buffers initially allocated */ + #define NUM_SB 32 /* Must be even */ +@@ -240,13 +240,13 @@ + #define NS_TBD_VCI_SHIFT 4 + + #define ns_tbd_mkword_1(flags, m, n, buflen) \ +- (cpu_to_le32(flags | m << 23 | n << 16 | buflen)) ++ (cpu_to_le32((flags) | (m) << 23 | (n) << 16 | (buflen))) + #define ns_tbd_mkword_1_novbr(flags, buflen) \ +- (cpu_to_le32(flags | buflen | 0x00810000)) ++ (cpu_to_le32((flags) | (buflen) | 0x00810000)) + #define ns_tbd_mkword_3(control, pdulen) \ +- (cpu_to_le32(control << 16 | pdulen)) ++ (cpu_to_le32((control) << 16 | (pdulen))) + #define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \ +- (cpu_to_le32(gfc << 28 | vpi << 20 | vci << 4 | pt << 1 | clp))) ++ (cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp))) + + + #define NS_TSR_INTENABLE 0x20000000 @@ -455,41 +455,59 @@ /* NISCtAR operation registers ************************************************/ @@ -1277,9 +11183,2710 @@ unsigned long max_pcr; int rct_size; /* Number of entries */ int vpibits; +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/pca200e.data Fri Jan 21 16:01:05 2000 +@@ -0,0 +1,850 @@ ++:150000001F8B0808AB5A10380203706361323030652E62696E4D ++:150015007D00E43A0D7014D7796FA5BDE84EC86211A7333020EE ++:15002A00AD89C00A23EA83AA589C7E7C38D8152EB887477677D3 ++:15003F0095C39C3DB2AB388CA324C4A509352BFBB085BBD0C73F ++:150054007210B903C92991CCD1B1C242255BCCD81EA5C34C6826 ++:1500690006271AC6D36A3A31B976D4A9A683DB4B07BB38265C56 ++:15007E00BFEFBDB7777BA7030B2733994C35737AFBBEF7BDEFE7 ++:15009300EF7DDFF7BEF7769FFEEAD79F221221E1ED844C3E4677 ++:1500A8007EA3BFF036F827CF8597C3AF0C7E920B16595BCE5AA8 ++:1500BD00296B6483D83E9F7DBE8FF50BE74A0B45FB1F274FAA79 ++:1500D200D82E2867139DF637FD937EF1D55FB0769FE8678BDAFB ++:1500E7007D9BD8885451515172FE27E4138E9FC9949CBFF026BC ++:1500FC00741DF83ECE59823FF23BF89346493F6B4F17C1B3A7CE ++:15011100B3B79C97D3275B5ABFEC3CF9579457703B3CBFEFD600 ++:15012600FC38236CA91B5E347EDBFA67F7ED4397956EA4D3C5F4 ++:15013B007CE6A567799EFFF5CFC4FF7BDF938BF83E83EDE59F02 ++:15015000FEAC24BF8A3C3F2FF9FDFF933CF51EF2FFEC2FEBFA11 ++:150165002341C38CBC5F4EAA265F5EAF04BC51F0059FD1419ED8 ++:15017A00063493D465A2384E66A0171C30231F40AB5CB5646FC8 ++:15018F005CBFB633DECCC614D2DAF622F15D3189EFEA3EE28B83 ++:1501A4007D99F8DABE4D7C2418A438AF3129015D7507F1032EBA ++:1501B900E174827F46C82229AE2BC63A9D50E9253960EC005FCA ++:1501CE00F2EDFE0AF12A9D5EBD6A35F1B5AC441A49BAD94F22C6 ++:1501E300DECB544F180D1A51FACD8C4A7C034B93DAFD6455A8F9 ++:1501F8009AAC5AB74C9542EF11E23DB0946A0F1B0DA10BF0CC0C ++:15020D00F9A4A8097BCA1D751474A02FEC02593C75C9E870D176 ++:15022200B8CF352EC3783C379E1C2893C98017C6A57B3CDD0E4D ++:15023700CE32426A9CB99F03FC2E81BF46AD0D06544FD0190B08 ++:15024C00C0580B8E897EFDF490DE08FD652E9CFAE911DD5F24FE ++:15026100CF832469DAB1116BE0F3C437B686F8D275C437AC9220 ++:150276000542BFF6CC0320B22AB7237E1F5B97A4E927A397490C ++:15028B0064C43AFF0CD8ACCE8886D37F632A7F4C16005E289CAF ++:1502A0003E491DDAFB083513C6B0A6B8E4929626F531E0877479 ++:1502B50082E58C9E2503DDD45DC4777E3BF1051F253E09684E42 ++:1502CA00C3BAC26825AC39F5225F6598EE23B366227C52ABFC3A ++:1502DF00BC2754E61BD1FFEBAE6DCDFE8D49AAEA38EE89A35A1B ++:1502F4009DF0DCF4254234681BBB09E98536033F2F3C5F835F24 ++:15030900107E147E1AE8AA0406A36989DB63C95ADE9F9272EBA7 ++:15031E00C17C6131AC4519193457028723BE118D0433D6F063E5 ++:150333005C6E1C77EC2981FD118663B2FA3A455F8D11A2D66BC0 ++:15034800AFE9B096E6D4A38454D70D004ECA8235541117C7A5F2 ++:15035D002D26F8E4B07D3848BA956402FC7BF8EC956CB6B6D35F ++:1503720091EB21B280C218CAB04122B5957583D126189B7D88FF ++:15038700FB2BDA46560F52056C867C6CE85FF1135F19E0C948D1 ++:15039C0023873342916798F3A6E45FA58C9021887DB9A8DF9307 ++:1503B1002EECF7421F693AB054DE6F73F4FDF414E83A6B66B2C0 ++:1503C6000B11C3BA0E45D0D1074E3318C92C24FE074FF267E847 ++:1503DB00E03AE67193D635C40D9FD66A65B471CABA5AC66D9C17 ++:1503F00081B68DE4F5200AEA316B3E3EF5F8D4CAF0C902BFBC6E ++:1504050003FD12ED00BE39F8E7C4E765F2A6F8BCC8083DA6B648 ++:15041A00335DAAA0AFC4DEA66A6CDC8418EA26910FAD6A0821BE ++:15042F0012B4A9C269D1DDAC9DB05A98BD06B91D807702D6021B ++:15044400F02CA479BF88CD3D82BE3F92D49137C262E0EB5969BB ++:15045900D6AC8DA4F4A3A0EB808FEB8570E6F34897F9F77CE4C2 ++:15046E0071E4E07C73F2C0FC256AC3208B2D5C834D43BA3F060F ++:15048300F39566B386103FC611E321E23D02F1168A79426C3DFD ++:15049800E159DA32AAA34C083FBA62DC2474847A94BF031D86A2 ++:1504AD00ACE5EAEB969CDC4FF3F3216F03DE5414FD8ED3DA3050 ++:1504C2005F5AC953795A804F2146D05612811C0DB6A0BC0E67DE ++:1504D7007C6E471FC3A5CFA04B06639EFA201E11FA182E7D3E53 ++:1504EC009556913E89227D129F511FDBA5CF05970CF63CF54199 ++:15050100BCE097B83EB64B9F4FA555A4CF60913E839F511F752A ++:1505160026AF4FCB4C5E0684CF471FC48B75737DF079C37C69B3 ++:15052B0015E973BC489FE32E7DC231AFD997FEF15925301975DC ++:150540007CBC5E33F5D918F2E53E82FD69D1B745FF82E8237F22 ++:15055500EC4FB07ED2A4626FD8C3F7363321FA29D11F14FD6938 ++:15056A00D13F2EFA9D40678FFA1ACBD131181B507F88FBA8451E ++:15057F00E179507D8362EC4FC2734A7D8786D5D526CF431356CC ++:1505940010E6D51152BB2CE6690F243DED35694FBB17D6017487 ++:1505A900B251C766F514A3D3037337AB67189D043C77A9E728AB ++:1505BE00CE3FCFE5A0C8B347ED17F9CDB09A812EE4A09AFBC861 ++:1505D30005F3ECCE1F76B0B8059C6AD51342D87777BEC16093F7 ++:1505E8002ED82B3BDF613094C9813DB7F3A50E87FE6A95AF1F58 ++:1505FD00D259C69E53B447F047991EAA1FDDE8D0747091968332 ++:15061200EBC88AB2D5095CA4FB07AA87ED030961D37494DB348F ++:15062700C27225D77D497EBF32958271CE6F8DA0D12CF612E37F ++:15063C00718ED32568206F3FDF874C7B477EAC4DD8310AE35B40 ++:15065100C17E683B139EA3EA6178A6D65B4CA65926E72EF555F4 ++:150666007A82D977D06A9A610E58F3D80D4F6BFDF4DDFAC37506 ++:15067B00E7D67D672AA93DD881720C301B55C6E4D0860EB97506 ++:150690007D5DFF3A0A636BD898CDE4AD4C7A42CBDE915B037587 ++:1506A50087D7593056DDC1E5477B55429CDCF8B5DCFAAB15AFBD ++:1506BA00AE3B0263FFD3EE69AF8C5584FEF3FD0FDA90E6BFADE7 ++:1506CF0030DB70FEBF9C186B43DC4BEFBFDE4682BD8C27C86F5A ++:1506E400B3BC185CC264063DED086BF730DA2418B655D6F63110 ++:1506F900394850B53126EEFCD1AC2EBD1B83F83B6D56056C5662 ++:15070E0027F079B3565739DFC3A2AC8D591AB48B37FD4097B6BD ++:150723007D4527CA41F38E00D6C48665887A30CEDA5E6BA09CE8 ++:15073800EF7568CF8A7EC03FF80DC05F6B56078280AFB25C86D9 ++:15074D00F863ACEDB32658DBC26CBEE04780FFEEB7017F9BB98C ++:15076200301001FCB0C5E54E5A0DD0BEC8D6618FD53893DFDBC0 ++:15077700489D0A781A5B9B27616DFAD4435409C08E179C365B01 ++:15078C00B86D2C5EB34E5BCDD0CEC0B98106CBBA25A29A87AEC7 ++:1507A100676BD0977601BC4A7DCDC2BA15ED575E1DD7B78610CF ++:1507B6008FC715EE954F0A5CB4B78837139F9F079E8AEFA21E32 ++:1507CB00DF9814679714AB9163E99F59FEBDE3263A704FFA4DF8 ++:1507E0000BFAD400D9FCE1115DF1C541C7772D591DB7BA1C7929 ++:1507F500D4BBCC1B9F701EC761BE22E4A1429EB736E6E5C1BDA9 ++:15080A00EE92C09D74C933790B79222E79BA401EE8535A429E39 ++:15081F00F3ABF2F23C2B785CC43812F24C0A799A5CF2E05E759D ++:15083400BFC0457F73E4C1E79BC91376C9B319E4813E4D9690D5 ++:15084900A7D925CFE55F711E6D33B8A771799007CA73BC252F86 ++:15085E000FEE3567392EE35506B935DE3E625D87B3AC9363DDC5 ++:15087300675D387B325FEEC53DCA370CF1D064D2707F1F9E1BAD ++:15088800BCCC7732962CFCB60AF76B17AFD80C1694A4D6EBDAB7 ++:15089D0047E58DFC1CEB75E1E10563311E21B6794C95704FA00C ++:1508B20031EEBF8BC93DD0270326EC0F8A54674771FCCEF0B040 ++:1508C7007E67F81CD864D8EA401CC819480FE1811DBC76E5FDFE ++:1508DC00733A83FDD508D6AA24406D9DCF3FA75FCC66FD65D592 ++:1508F100FDFAEE7BF332F5F0FDC225936D769033AD01550A3A24 ++:15090600BCF12CBF86F184F305E007567C68E59EDB3FCCF1498D ++:15091B00D79F692B73E8803CC25E4CAEDA152370463A4A2DE42F ++:15093000AB34998BC0DE1BD01C0AA7C5715314ED0FC74F4B510E ++:150945005ED2BDC9319893001F18B3A2AE734B17D4E2CFA89EB1 ++:15095A00D6B7245E6394E2F350520E95A6DD6079943780F65B70 ++:15096F00507B1C857AE36D0B6B12491D8133EA88E6D41A72B92A ++:15098400A835607E52D421448C255D7548EE0F723FD656E84744 ++:15099900CA3D28974DE33C4751AF90CFEB9603D61BE545BA8197 ++:1509AE00906D2A44D446CA190BE550DE5F85B273DF637264CCC1 ++:1509C300C15E487501388B928C8974B4ED9C4E8FD80F395D9B32 ++:1509D800D9A7F6FDFD5482B3B6141B358F92514D3A30CEEA2EE8 ++:1509ED003EC7B6108744E478BE6ECB98555F46FA54D0E77A23D8 ++:150A0200FDE876AE1FE7932AE0C3EC226CC2EC98E676BC7347DE ++:150A1700DC0A446C361675F3A48267306C72595A4C85D9A5D310 ++:150A2C006467AB60D0E4761AA00C1E19A6CFDE057584F27DAC4C ++:150A4100810A64F09F5845DD6B073896ACC05936324E1D3FC1D0 ++:150A56001C843796C7485C2391FD168998CC2EAC0E807119F419 ++:150A6B00A52D86899716E555719D1E5CABF77860FDA686D87D2E ++:150A8000881FD74839ABCBEADB34C06AE6FC196F49F9DC3367A7 ++:150A9500FF9653FCBCE83E774E9DC198FD9433E7203F734E0EF2 ++:150AAA00E7CE9BECEC19F9BEE5F8961C30A2634DFCFEA0D0B70D ++:150ABF00B82FA14CBDC23E6C6D4249E6574419B2081DA247F1E2 ++:150AD400AE02FC0A7D81D9CC00FA74C84ADCC82E72F9336B3524 ++:150AE90075186487D8A757CCC5B06FE37D56B5BAAAF912D674D6 ++:150AFE0012F13EA3AE0D5D83985C9FF6B7B3DAEE31CEB713DA06 ++:150B130045E420F33B90DB12700BE117C47D4058E0468A700568 ++:150B2800DC42F87111EF0EFD1E316777D11C01B710DE2BE8F75C ++:150B3D000A5CA30857C02D84B709FA2B05FD06818B78F8BCDCC9 ++:150B5200956F1A5D63F88C67293C4379C18FCAAB46C037862CF0 ++:150B6700B497ACBCA2E37A07D5613B00F6AA091FED901553AFF3 ++:150B7C00EDBFA257A9A7AC65C6076D814DFFADCBB131EB44D2FC ++:150B9100D3ED8D9966269B5D0C355EAB1CBB62393E5B09B92DA1 ++:150BA6007D3DEB73C7C0B7A0CE95599D4AE7C4A388AF5C5E4121 ++:150BBB001ACAA1213D513EACA16C353B1A2C279ED9DA634E30EB ++:150BD0002027A4DFC63C22E273C22A8E67F405C61362C61D27AE ++:150BE5002FDE11D7C365DC0F1591D33E2D4E5E82FD3B17230768 ++:150BFA008634CC078AD84F31565642CAC2B3E0D3AC9E17310500 ++:150C0F00F1F318F89BA8DF73B0FBC5B9E2E6B1D4226269A8F448 ++:150C2400FD8D2B9E7ABEF0DBCFD57473E2296C3D2DEC7EBCF2E1 ++:150C3900AE00DF13950DDEA802CFB7FA713CC25A35E0ECA52AC3 ++:150C4E00D412F544A96ED2E3655F78CA23E0B4C678CA19C73BC6 ++:150C63007A25DCF084ECD008279EA8719E37E5E1B9FD8ADDB182 ++:150C78000DC0764CD423AADC4D73B519BFDF7C84EDF7B3589BA5 ++:150C8D002978178F2324729206D4F666ACDF181C6C7FFDBEF62F ++:150CA2003F04FFB4091D3E8BEDE2C8A08EF7A1481361354A427E ++:150CB700BF0075C79CFD52F0EFBA09FFF58CFF80C9F2281DB6EB ++:150CCC00918E943ECEE946809780E173BA047D6A637DC3E9E326 ++:150CE100FD30D41426ABD5A0BF066353F5B7AD57AB426111E732 ++:150CF6002175793BD0A435CA01DD9101E36E51513FF72CF85916 ++:150D0B00533FD0D6AB0F846AD4079A03EAAAD056276FA94F71C2 ++:150D2000DA82A6E43B3E87AEF48FB786AD4E2F6F75EEA36584E2 ++:150D3500837D8F64208743DE10F7CD8B56A7E5565C0F7627CD82 ++:150D4A0071E811C84132E2404C200ECA9A85BA8E1AFB35425244 ++:150D5F00980BCDECDF9F97C1AF71CF55D02E2C2EA660BF823D2D ++:150D74006135190E61FC6476BEDEE1BEA7FD9C787F107F84E908 ++:150D89005860EF2C9930495D2A9AA76D08DAB6C1624F81FD644F ++:150D9E0072445B638C94A45D2168373E42BCEE7D285F5F65CC2D ++:150DB300E4D7B03E3172F5C9FCF381CDF301E856321F28AE3A51 ++:150DC80028771E688C4A5BD641CD07B107B58A72379C210E6DFD ++:150DDD00D477415EF648712D0AAD1C4846132A3F977C1772DDE5 ++:150DF200B1E4C7CDE4EA10BDF6B5FC7B8D3D5FFFDDFEA623C476 ++:150E070037F149D60767196DF37D72BB73D787F76764B77176CD ++:150E1C0012DFEDED4E9E9D62ED24C612B4E9B319F6CE0FCEC553 ++:150E310060A795E28EC5592B49ACD55EA03DFBA77C1F408D2F19 ++:150E4600C19925111ED61AB1FD22D431CC768DCC76686BC46913 ++:150E5B00025948755C5BFE89B05F4C62F603E3079A805E15C03F ++:150E70007F7E9F7C2F5BCFEDA2BE82166B17AC59900EF6BB59E8 ++:150E85003D95F781473ED50706C49DFE70491F5072FB7DC6422E ++:150E9A009DC136B6B08D2D6C630BDBD8689B72C8E56E9F99AF8B ++:150EAF003DF1DD13D451C14A757F10CEF8BE3C6C2DC00E06535C ++:150EC40005B03F02D8D1E09803AB42582DC056042711C6EE3D4A ++:150ED900B87DDFFB18EC09763DFFF15CBBBEF730F18D7D8C764C ++:150EEE006DB877BE7ACD579F7809FF2813FE1105BE17B615CA1F ++:150F0300D922135F23C8E20159979490B511E67899AC4DF7DEFF ++:150F1800CE1ACC57DEDE12F2960B795F0759976C9BEBCF06FAC8 ++:150F2D004B095F8E5DCBFACA408FC8B5B97AC4804EF81AEAE194 ++:150F4200BFF7767DE976F4E929A18F2CF4F9F956E2EB84DF675D ++:150F5700E1BFF97F4127B5812A6A1365EFE620074AB029B701EC ++:150F6C001CFB32E934357C0E6AA60AD659AEEA96A26EFA5B76F9 ++:150F8100970E79676B6C88BD2B8E7D53DCF73CC76A5433FD0D60 ++:150F9600A89D643847E33B55DC9401EF62EC9455F5C419EBC295 ++:150FAB00479C3601BAD9858639057D89F7BD631F15CA33267057 ++:150FC000DF83B68B244DBFCAF9118DF3433EC8CFDE5DC86F3932 ++:150FD500E0553D71CADA0AFC3441837EC4F9C5043FE87BDDF609 ++:150FEA0054843DCD3FE1EFB8AF3E440AC61789F15D62FCBDA29D ++:150FFF00F11A31BE558C8F158D2F16E34D623CC1C63366D79E29 ++:15101400FC793F0B3A5202FB37ECD5DEE52452707687BF81A5FC ++:15102900B646E14C41EA923BF0AC5963EC5F87EFF53591D70ED8 ++:15103E002C9DD53AC22F873A5DF7E92F4C3CF113B4D573BB2F35 ++:1510530075045DF0CBAFFEF57584B7EEF84987FBFE7DFA8D6F83 ++:151068009D40F893FFF0E30EC2BE871834E3FFFC179BFC0163E8 ++:15107D0047B297F8269F24BE3972BAEE17827F59B87FCB380E23 ++:15109200F9167388548D39197231C24AECC74EAE81B351FBEE40 ++:1510A7002DE2DE07700F6C19D52A638F065F811671F66EE7672C ++:1510BC003C1C73CE320C5644AF8EDFF7F1EF332E0FE8F683F8F2 ++:1510D1001D01FB1640C47E8ADD2918BE51B6571056CB2419BE69 ++:1510E6005F39CDEE52768B7B1784A9EA283B4BED71C18202D67F ++:1510FB00E7823509D8DE99FCB707866B1CED4B26086954472D8C ++:15111000370CBF436C2882554932692E84518A67BFD838550E10 ++:151125008DEA2D3826F4C6EF6508BD9BD99D8AF91FDC58F453B2 ++:15113A002F9B9FF345D18A7E649C4A07F09C0338ECFD3DE713EE ++:15114F005647E93EA827B19EC2F3EE65F0B7441FE9C6F74ED3D0 ++:15116400397FE1B66DACE2760DA74FE6E40CA74FD3FE2DE3DA2C ++:151179006675DC72D37C79E98086FB33D28C15ECEFA3ECEE6226 ++:15118E00AB80ED1132EE113206605F6732E27B2576864DE1DED8 ++:1511A300CF6A05B6F78BB51C106B298B6F2998CDA06605DE16C5 ++:1511B8007EFF9280338317CFA17866127A7845AB14B5176F64D1 ++:1511CD000BEA546EDF93EC5E0EF76903F4C3332E3E3B30F2F086 ++:1511E2005C58991BC6EAE794D509272B493C6F56381C6C66A124 ++:1511F700DD6A33CCCE0143C8C160013B1AD89812E727389FC223 ++:15120C009C5A03D60DD688B591717321D2A3A356297C52029F42 ++:15122100E4F0DFE4F605183C5B7B9DCFF944FCBD20F4E4B19C55 ++:1512360062758BE4E804CF57A514F3F7A03F3FFEF296FCB8034D ++:15124B007BA9044C7E782ECCE386B9623AE7DF22A69C7875C78E ++:15126000727F512C633B25C66E36C72831C7196BC4F68BF9B97C ++:151275009590BB8DBBC902278FA04D5E747C0E9EEBA7E37AAC39 ++:15128A00687CC1E594CE69A4CC1648B68998A71B7CAC06F7016D ++:15129F0073733E27A17F605C38637DEE31F6ED1BA7C35A178D76 ++:1512B400CE221A8E0DB80F7298510C037A2F38307F1E66948027 ++:1512C900555617C250A7FD2E9D1D58BC04ACBCDA0D334CBB4EC1 ++:1512DE0026E1D5C23EB08F60CEC0B8F483CF634D85DFE4B17ECD ++:1512F3002015AD75BD4B225584BD3342FFF533FF1D311D3FAFDB ++:151308003C84DF1BD87400BFB50BF35C568A8672DB34600CF7B2 ++:15131D00176514F12C2D1717498AF91CF3E12ECC25D0C77907C1 ++:1513320097A634461F7DC54F6829B8E2829B6EFC25A5E10AC018 ++:151347007B9DEFDEEA788E75DB6BAB74137BF94BEBBAE0B20DCC ++:15135C0067E4D1BE83504BB03C301FBBFD1669A19EB75A03F3CC ++:1513710076E4FACCB40AD7D51679DED9AB793E2EB475613E2E11 ++:15138600210BCCE1B2A44CD602ED85480F6ABE927628814F729C ++:15139B00F885F2ED75F91DC6AF543D37BE49F5DCF82EAB9E1BB7 ++:1513B000CBA404EC15DFDCF8F654CF8D65B90886F847DC73F32E ++:1513C500EF3C2B79FD8531CEF706B469BD6BEF83D6D825BEDF9F ++:1513DA0020AEBD50291A935D63FEA231AF6B6C49D158956B6C58 ++:1513EF00B922F611E52D4A1493CAEA307BCFC4BF63A4F41A6BD3 ++:1514040007E9F532BEE765581B34A1A82072F5889E30C635FCEE ++:151419005676B13CA21F2B1FD78E854735AC55BE639CD3BC1730 ++:15142E003FD0192E201F360E68CA5653AF81BC5CE97AFF8BDFE1 ++:151443008FCAE638833F17AB0ACDB8D613DFFBFFD37DFC7B9AE7 ++:1514580058EEDB1B80CFF0335F65F2D7CDCB92DFC4EF4EC4B7BF ++:15146D003313ECBB277E5F3EC1BF8D080E50FEBD0C1538830C25 ++:15148200A7D7F57E03DF9F3F2BF84CCEE17347011FFE7DCD0460 ++:15149700FB7ECAE1630B3E5D820FC719345551A725A13D119479 ++:1514AC00BA2B0E8DE8FEF02AFD353C9FC4EE6E0BC42A425745A7 ++:1514C1007C5D8ADD139A85672FD8BF5E8BEBD433DA5719F3B4AB ++:1514D600E33A292ABE8B033BBE097935297577A9A72C388AD66C ++:1514EB00C8CA5A88EB03B42E7CB0ED30665CA5DFC46F5D37FF53 ++:151500003B9CEB22BFB41AD45F5ACEFBE836F58015560F5BFEA9 ++:15151500F408FDBFF6BE3E3A8AEBCAF355AB5A6A498DA816ADA6 ++:15152A0046C2209588708447715A422648964C43182F78306934 ++:15153F00639CAD12C26EDB644C1C26A3DD61E7704E58BB255AC4 ++:1515540020E10729D548462638B4B064E30938322B123C47248E ++:1515690062E275F02C61B48CC390C4269D19C626332456BC4A65 ++:15157E0086CD38F4DEDFABAAEE9210FE9839B367FF58D5D1A9A8 ++:15159300EA57EFE3BE7BEFBBEFDEF7EEBB657887B6D5087BF17D ++:1515A800081FA63A83A941B22B5F3491CE945E0EDF6E779BEBA1 ++:1515BD00BF3ED0EC2E5FA1FD996EDA75A02C9E5157FCDBF00DF9 ++:1515D200AF6E8D4C2B5F4CE523EA336693FA8A5DBE77C6F2D17B ++:1515E700E31818D5AD80254CEF6AD47623AC7673ACFB9A2CD1D0 ++:1515FC00A6A93F37BD12FC228E7293F5B5C9B184594CF2CC8307 ++:151611007DE9E8A0E98BF59AFED8A869EDDBB8F9F8A4CDC7F152 ++:15162600297C9CE1DFB1214D71F16F51CCDB98E151EC1B61AFE5 ++:15163B008478348FE466095BA45B7DABB6FA16196876F3735093 ++:15165000ED364231F94E6BBFC1E0F0E51DF97BAC8FC45BA1DF9D ++:15166500AF6E60F987CA929AA22E16B459053AC0F5491D31629D ++:15167A00EA5123A26EE04A68756B1FE9A75864EF1B7F41737C57 ++:15168F00777BEDF1DB6FF95B14BBFD285AA9BF3945A7743575DF ++:1516A4008C67CB1C31B9ED0FE7E415FB9AE349AD9878DC5D3E9C ++:1516B900AAF61A1BA87D8DE0D0D483F47FD56853AB8CED6A8D70 ++:1516CE001157EB8D2EB5C930D45544BB477493FD595B754AEC79 ++:1516E3009FB6F553FEA43A6A1C51B9D1F7EC515EC28EE97336A4 ++:1516F8003DCB17BC759527367D92772E58CC776DAAE5BB9F6D89 ++:15170D00E05D6FADE04F2F38CEB166F2B91FC0892426ECBAFDF3 ++:15172200CF9EE2FED387F59EB7F6F262B677A91B2E3205F38BA3 ++:15173700D455CD99B46807AF92587EB13B4D74A083F39BA4BF13 ++:15174C0071217D43BA16EB3032FB606FDDF89E191DFCFD821912 ++:15176100EA235E1B79279D5F953C6C88B1053FE0CB37DAD7F014 ++:151776008388129F788B3A85AE7290F2BC1FCCFA9DF8A6FB9DCA ++:15178B0010AF1E14B65E3B7C7A4CE13F4D63DF4B32A32F49FA86 ++:1517A0006CD3104F596B5EA6DF3A5F31A744D87D9326DEAB6A39 ++:1517B500027BA94167BC63FD5E8B55124FE0EC483B8FBBDA56CD ++:1517CA0066F0C3F1C5A85D3127C44DEC57F6A9528B323AC0AF33 ++:1517DF00D96D627F734A9BF4DE37ADCDE9FB071B5CED3357FB1F ++:1517F400EA0CEDCBAEF6E7CFD07ED5C76C1FFE3589863077601A ++:15180900010C3BE65830CCA7B6A6B7AF8CBE28DA526303A46BCC ++:15181E000CB732A5D384EF8F4CB67188DA9D1F1B309E5EF06B13 ++:15183300E1D331E9F6F371EDCFAC7D2AEB3F22E52774A9ECA464 ++:15184800BE7EACB3D1B78E0B5D46B92FA995EC18E1511F8B60C6 ++:15185D007C96EC18E4317A866F01F21B296F0B337E6D62EF18A4 ++:15187200699E6969D4D712C77F24188AB5865929DFD939B88DCC ++:15188700190F70F08FFA790234A4B5FACEEDA1F64EF292D096AF ++:15189C00D6B93B8EF208B5118C5B3A33F2083F10E3707FF1B807 ++:1518B10021F67738C13277473D27B9DDD6B177ADF0F3098696FE ++:1518C600B576DCFB29FD3CE1E9B598E74ECFA5FF20CE4084AD8B ++:1518DB00730562BF0D739DBD9F2CF6434331A9B94059AFA36E52 ++:1518F00094654A3397A5C37AA7381BF0B258170EC2C732BA3C2A ++:15190500B35621C717E9589F484C785A426F35F0D08A7B74362A ++:15191A003E6286562CB6FD5AC4BA96B557611C3597624F3D3A72 ++:15192F0018BF4DDDB4043693D88735068633FFCA603C4875F9B3 ++:15194400F32BF52BE974E08DE57AD3E34F7A9A1C5A5DA0BEB02D ++:15195900F0761BEEB69BC2EDB954A1CBA79337C21E5E6686ED09 ++:15196E00F593E9F04346032FE883D59719FA30FE0D731DFA6039 ++:151983003C175F29FA10113028D1B80EF80D35A70577C08F3B83 ++:15199800F15EC92CCC25E37BF8E0EFD285428F540EC7C7976FC2 ++:1519AD00AA1FA5BEADA2BE39EF77FCCE75D410FE24048BAFE8E2 ++:1519C200A8E085B93B4EF00999C598B16838A00CEA993335F4F6 ++:1519D7005B8D25E8FD31FE3EDEC37710FB414A3B6C06E386DFF9 ++:1519EC006E7FA97D597EF71525048FB3FA041F233316FB9D6202 ++:151A0100BF69D883FD6A137BBB57D3E950D6FF89C6CBBFB17C5F ++:151A1600625F767D5894CF961DB6FF8DCCFFB4F5E2B6988F27FD ++:151A2B0053DF3715E2733535305C1CDA4EF56CE1C154A5312B41 ++:151A400095D3B22AB5D80884DA88DE63A2CE10CDC92CFAFBFC5E ++:151A55003519FBF21A87AF8EFCFA2384C752BE16FABD021FF809 ++:151A6A00A8F0B5EA8DD7697F1EA96DBE47F5349FF75EE1A1C844 ++:151A7F002797826E1BD2E9C249C9B193BA8D3CD02D2AEF32DA11 ++:151A9400E013B89683D6C85743F9CEDAF9C2A91554EF6A739572 ++:151AA900C573C38286F6BD26760FEF16FB8295246F5682A68619 ++:151ABE0045C3A9F70E09EB8657787A391C7107881F3FAD4DE607 ++:151AD30058F517F101FD41755663B13AABF6A5CA924673E18293 ++:151AE800C657F18EE018BC9E2E5CA84A8D024E85F4B072A3D58F ++:151AFD00C7FAF9E51FA7F333E7F1C60F5B7B8DE387CD4365D585 ++:151B12001AF58C63BFABD7AE9FCA37A32E8DEA72F23AF9B6524A ++:151B27009E7D6B06B45D34C6D0875B49E64D6F6BFB8FAD3D8A0C ++:151B3C00522AFFAA64C185737B5D180BE37163BE7F500FFE6E98 ++:151B5100BF8101BE3AF5A2619DD34A3333F282D647F5CEF3D710 ++:151B6600E8A42B97C0D7BC865DE189C837DB70F62E89B1BB66B3 ++:151B7B00B16E12AD72D990EE25FEC7DE506364A89129CF59B491 ++:151B9000B1F5378C6159F0994A70455A05FCCA73E69B3F4AE70C ++:151BA5001FF558FD5C49B46E9A81A6B751DBD3FB34F8A3B4D82E ++:151BBA0013443D5BEDF2F36252A3779C6440740FF7F8137A2424 ++:151BCF00B59F375D4AE73B6573699CE02CDDA88D779CE714B2F2 ++:151BE40080F0E0E4E9A777E2D9788AC77F98B6CE3F529E37DF4D ++:151BF9009F8A7BF0E04CB012FE4B4A53ED46FD050BE783D3CA28 ++:151C0E008D02FFE07371566D0F77708D3371AB530326C73E7BDE ++:151C2300785ABF5957A6DF472F5AFD06ED515F1BD55763D34CAD ++:151C3800F0E6A0C59BF04B97D6FCBE1EA5F7B73AFC67D3C2C2FA ++:151C4D0063B60EEDA2056B1BF1C4C8BF583C31CF5FAF8706A432 ++:151C6200468737B662BC5BE73B6DDE209D3F32A42D64279AC1E8 ++:151C770017C18661C10F667CA1E6EB7E519769AE5C68F381E5DB ++:151C8C00F73A95EEA493FA42CA61E2F9765E447C116CAFD595EC ++:151CA100376C7C3BE3C15506F6D44CF8BE1DE39DF203E737B4A5 ++:151CB60043E3E928D5E9F8D3E4BA78631BF186FAA6C51B12E1DB ++:151CCB0057B67963EDDF5AF8157B568493CBBFCDD20FF5CD8A7C ++:151CE0006ED1B59F7CA99E649C599D5A6356A5569824E74C9214 ++:151CF50083C60CFB4DE21C33F4143FD901C2276E063F6FD2937B ++:151D0A00785E51B7DE06BF4CD2DFA09749F9033AF6B5BAEC73CC ++:151D1F000BF02D7B50F8330D0B5B4AF877E34C34D94F87CA4E3B ++:151D34006ACC1812BEDE4AB2D384BDBB2A794AE877F1E410782A ++:151D4900728EA2769AABD453A641F712E388FEAA6ABD67954398 ++:151D5E00FCF24DF43FD8438150B4750FE66FA58A17939CAF263F ++:151D73003BE676F8E23B7633D96915DA55BD27B2BF0DF8F35FD4 ++:151D8800C8DACDADEA7DE6DB3F93EE94957BF52A7505AF225DD7 ++:151D9D00FE92EA6D0ED2FD5BF04514E36C0F2F3D9FCE7FAD5214 ++:151DB2006E249BDC207BD698C78EDD15211B50B6694D76AC01A8 ++:151DC70059D9E44A433E25146EA53ACD2ED5DFECF8589692BDD0 ++:151DDC009BC72C3D0DBF8F52DDBB95A7DAA08F55CF618580CB48 ++:151DF1006D67BA6DCCE80FAD71D029F257F36BC5AC9029EF99AF ++:151E0600412A0399E186C9E2BF7A7E3BCD0B800F7004D5970D68 ++:151E1B00F4218F781FEBE76C7C31749E6068C5A774F41D7A90B7 ++:151E3000F774834E6085AAA82E21038C1E1E559FE1AFCE26DABE ++:151E45002BC46754DE6907766090F41F4A33DD6DDE934E8B36D0 ++:151E5A00855EA51C364748472B8FD9B22C6AC939D4D9361BEBFD ++:151E6F00F6614A3B2CE0F2B2BD7A0FE08AEE3121A71CBA396BC1 ++:151E84001ED13740BBF704ED707E5C55498F573A877DEA1DA687 ++:151E99007705E940D1BDA26EE8F5D0E9FDEAB366CD75A929AB9C ++:151EAE00CF583470F0EDA6C360C0F2BFBCD97B1E60856E7A0042 ++:151EC3009EB1BFA139D2A117E495526526D6701D7AD4E49355C5 ++:151ED800774DE7D7A87D9E2F9E7AC72C095D6CCD49922D7DFE54 ++:151EED000A8D8D2FF00AED4FF425B16FF37D9D27DAC43E90ED91 ++:151F0200971EA6BBB087B08608C28CC1C77DD80C8BB3DCDF30DF ++:151F1700E684CE50BB3F249952DAEA8B3D493AED72CC2B66C792 ++:151F2C00BD0F918E7BBFD171EFBD7A774A024E857E9B87392E76 ++:151F41001CB5F5DB2ECB2F8FC66CCCF6B31F16F76ADB0638627B ++:151F56008CDC073B2B4265B6087D3A2D7C44525C444EC819E394 ++:151F6B00E1582D9F9DCC69093CBB9E074EB7E852F2040F40BFA2 ++:151F8000879E7C1F7CD25F163EB87DEC9B1ACABD4FCA53DF677C ++:151F9500BF69EDA7517DFBD97734B6ED1847F4903EF66D0DBA40 ++:151FAA0018E4771F7B4D832F2DE089920E87FC80E55689059E76 ++:151FBF00227915185BA9DF4DFDF12B8FE8B2FA9C81BE3A7E50F6 ++:151FD4002C7A9FD931EB5EE1039C4F3031638DD9C70632FE501A ++:151FE90028CFA2CF99AF125FFACE8DE86CA4D384FD04FA0FDB39 ++:151FFE007BCC68ABE8524AEFCD7941E8F56BB1AE3C72CC1C63DA ++:15201300225F1CFA3CFCE2B0B78867D80758AF213917C7BC7364 ++:15202800ADE27073B9EA69F49D233DBCFE18A7726DED852B5BE4 ++:15203D00A05F930D5A124DBD635468DFD3674BCF0B9DD8E33F85 ++:15205200A1236F09FC1BEA87903F7270672FCD457DC236050FD3 ++:15206700887764234E923CF49D3BA8CF3BF79CCE2607054C382D ++:15207C00EF437C2564FC1FC6D6365978F986E13BFD72960F9219 ++:15209100DE0C1F84C007842787F6BEC82ABDABCD63D111F4336D ++:1520A600BA4D879E4FB31735879E2CFA0D73103ABACD2B53F1A0 ++:1520BB0067E1EDABAFFF9186337253717644E0ACA44DF848DBB0 ++:1520D000381B06CE026CFC581CBEDAD79EBC7789A80FB6CCA84C ++:1520E5008533165D346CFD77F65B733B1B9E3B7A42E047AC7FA6 ++:1520FA0019C7CC02E8C5935FE16F104B127F9414A53CCDC0ED45 ++:15210F00E39E2796FE69CA736728E66976F30978C373E91DDDF8 ++:1521240027BDA077AB599C04A78C0DCBF6035D2D7EB6C60AF085 ++:1521390094E1F5E9769FBDEF6EAAEBEFF49DBBAAC367D9EAA701 ++:15214E00C1710644E83FE1301778D9F669AB7FCA401C6BEB2D2E ++:15216300EA034BB0FFE1659D7A70C75745FFD8E6E778EFD81756 ++:15217800493E7CD174D93BFDC2D6C19E36E18245474CA78E203C ++:15218D00D951852E5C8C117F2797AF6FBA7EDDC2C76FCA9FA8EE ++:1521A200DD40FA96859FBFD7EBA4273F003FDF27FC3CFFEF82DF ++:1521B7009F97809F7577E98E6D9E6661CE267F6EE1836CE6DE14 ++:1521CC0038EC050B1F0BD8223DF8FE62818F9C68A95E1E2F6F3A ++:1521E100BE45CC71FB782CF5AEB9ED97B0974B5BE9D9807CB1CE ++:1521F600EC1FC21BFBE32C0F2A583310FF84BB0117EE5E369D99 ++:15220B00F6A6E3AE9770B78D70F77736EE2E12EED07EC8D5FE2D ++:15222000B55F586D4F6DF7056D5FFE505666DC5C56CC71C98A24 ++:15223500A64C3EEBEC74667C2CC4BAEEBAE7333244D8E7E3545F ++:15224A002E3EA44D2EF70AD8204B204722A4E3418E604D0A67B3 ++:15225F002050EEE9944B9EE4BCA461FF0FE736F05EBCB3E449EC ++:15227400896FDD4BFA016A5BC8946D4362CC627D0A7D2E76F53C ++:1522890059A63EBB65CD74FFA551F8E6285C2FBA64E801D20F34 ++:15229E00FA9232F547354EDE27F4CA906B8F8C063EE99034B72D ++:1522B3000357276DFE4079DF42962F8FEFD495F33BB5A9FEFC1E ++:1522C80086B0357697F56B42B7945917703526D65C86E20BB10B ++:1522DD00A743632327752C2EA74EC47D7ED27308BF05F1A1C669 ++:1522F200E2A841F301E73D29B94556137CAEF217382B182AC2CA ++:1523070019BA0C4C5161776CC799BBF2D5ADD0B1587958D821CF ++:15231C00D095271EB07C67AFE15EBE8CE6DDDF3F207CF7C2EA17 ++:15233100F1D40333FB731B87B07ED12FD62F76931E5C34D629A3 ++:15234600D609D8B89C301A8E58B04787E245F06FB4D33DB1A12D ++:15235B00B8D2302CFAD7C3F66A384FE85B47F3883104BD08739A ++:152370008C41735BA67FC591C146A7ACB58F9B79BE019E6B8741 ++:15238500B2EB31BBCB86B5A2B80D8F711378285D215B1AB0B83F ++:15239A00DB94ACFD988ECC5A8DBD3F8FBD68567ED2DAF7B4FD65 ++:1523AF00110977167EACB5F4A978543A0F4CF12FA27110BF1F74 ++:1523C4007D305A31164897E928B77CA2E21D94DE1B4D6ABE22CE ++:1523D9004B2F4B114C5772E258F32AC4FBE87ACB96C1DAC1428D ++:1523EE00DB8F6AB5E09123F1FBE89D03BB809BF26BEBC51EA3A5 ++:15240300D8075C6BE7D35DF956A45EE8A0FF38D28DF558CFF983 ++:15241800761CF31EFA82FD4FC0D1BB73480B8ED9F050BAD3EE10 ++:15242D0016BBBE9E19DAED77B5BBD5CEF78C2BDF4A6A17F99220 ++:15244200AE7C6D76BE8119E05B99FA661C67108E0818BF1BC70A ++:152457001ED815824521F89E16BC734CF8CDF47E8F6065D6BA3B ++:15246C00E01517ACDBECBA5F9C01D661170CDBED7C2FCF00EB9F ++:152481004957BE1D76BE573E0056D0D881F5EA87C07AD5056B9E ++:15249600CAAEBBFDFE1B61EDBA3F0BC3653B5FF7FD37A1E7FD24 ++:1524AB00597A5EBE093D2FBBDABDE2D0738676FB5DED5E75E845 ++:1524C000799376B76CC0F81A050E8C0977BBE8AFBD7E8F74875A ++:1524D500E71FA7FCFBD95086E737782D9E7F5FB2783EB621DB46 ++:1524EA0076D46BB5FDF0860F681BFBA576BB4E7B93AE7E6EB0F7 ++:1524FF00EBF8E2CC751818B38E6FCEB5E9328FE4CBE5C1ACBCF8 ++:1525140013E359ACCD22E69421FC099832624057F1F93BF5DD6E ++:152529006586A6D0FCA0AC3DA597F213FA3E9A12DC32E809EAA9 ++:15253E00D74CB2C729179286B4FDA437825F2CFFC7BD644B24A5 ++:152553003BE0EFBD52D4959D1BEAA82E0FCD0B19B94A7A896F04 ++:15256800DD9090A9429E3AF3451CF27448C853650DC14F725439 ++:15257D00723D4F9D8FB0DFDBAF4965869EC61A18F6DAADB37498 ++:15259200F6DC346CB56FD8F234DA678A35D5F121C3EACBA0069B ++:1525A7007F17EC0B189897C85E99ABBCA2FB48E7C6DC34E37C24 ++:1525BC0032945D0FC73A1CF6944270D7856FBEFD9BE6F339D379 ++:1525D100D7C2AD75DCA3864CF348A0419C756301E917FA933497 ++:1525E600B72D10BAC911331264D1D7688EF6150D0A9F0E2B1601 ++:1525FB0058B5D807DA5DA66AAC7E2F6F13FB0B3D64EF579AE254 ++:152610004CDCFFEDFFC3BD1C30B36DEFF238D159C0EE7ABF99F3 ++:15262500F4B6E5F4FECBEC1F9722C609FAB0ABEC88735E5915B9 ++:15263A007D237D48F44321BBE2E3FE0FF4F29215EFEAD9B4A1AD ++:15264F00E175B1F412A7AD0ACDB2D53F4A5BF1E48D7535C6BE43 ++:152664002BEA8A7E40F918952B5D33B5DCEDB18796587433CC8C ++:15267900D5A09B5D2E4C79FDD3F2D6C52AECBC2A17FB43365DAB ++:15268E006591AFC75C3061C77B237CE26C5D5D2CAF51ECBDC060 ++:1526A3007F53E44F7092F13109F989A7113746B6E2C319880F2E ++:1526B80027CE3F132F89B399E383A67B3FA9F5886B3F087BA603 ++:1526CD00DB388F603F272A6C1B71BE5251E0FF613FAB3807990B ++:1526E200DD0FEA75955F18931B9D3D21D421AFE17A8F589B1E44 ++:1526F7001C9E74EDA33AECEF63A3F96FC977E57CD9F39EF47519 ++:15270C00E951E9335250BAC6FE8EFD35FB2E7B990DB1AF319314 ++:1527210075B30EB683FD2929DA5F628FB147D9436C23D3D8036A ++:152736006C3DFB1CBB97FD015BCDEE66ABD84AB6822D67CDACF0 ++:15274B008935B206B68C2D6577B07AB684D5B15A16669F66B73C ++:15276000B34FB11ABA7E8FDDC616D355CD3E49D7AD6C115D55E8 ++:15277500747D82AE857455D2A5D25521AE72BA16886BBEB86E5A ++:15278A0011D73CFB2A1357A97DCDCD5C21FB2AC95C41D735C7EC ++:15279F0075154FB902D32EE5866BF60D57D18CD7AC9B5EFE0F7A ++:1527B400BC0A3FF42AF8C857FE875E3E26CE181FB7D6B754E111 ++:1527C9008B4EBA3DE9F151A61E475A15A519F673353D8FDBCFB4 ++:1527DE0035F4AC48F48C35BEF26ACA1FE1065BCDC7C95E5024A0 ++:1527F3008D2BEAC2E34A8CFE93F49F5A785C8C2BB11E522DF667 ++:15280800DB55D54ECBB7D3244A8BD96905769A87D292765AA167 ++:15281D009D964369A88FDA14B02B2C1AB6EB825F60D8AE037E98 ++:152832008061BB2CFCFEC254262AC16651F9F04B5828BD8D33C0 ++:1528470075E1016F6899A8272AE2EED41AC549A9CE776631CD9E ++:15285C006B95077C671A843C887FC0BBE10F78073F38BC2BA2B2 ++:1528710077946E225D7EBD41176D8F2F361DDC3938473FC66D43 ++:15288600189561411343153E7661037E200CFD1465C2ADC02FED ++:15289B0070A878ACFCA96FDBEF99CA9BD485A661D7C35EB1D235 ++:1528B000A3942F8A754A65A129FBC8A6BFC93D2A65F38CBB9EA0 ++:1528C500154FF6D9B0D345FD63E9D988ED64F947AA7C42ACE7CD ++:1528DA00A8563C48B12EAA8A5891B9F6B3F043F310AF617D2323 ++:1528EF00BC8C477FE16109CF32332FA4B6CA91067DA2B241C487 ++:15290400A998F8AEF70EE004BFE12B3046E5FC6C19CEE49A35C6 ++:15291900840B529EB84FAD33F3D86D04FB6DA63714691D9F2168 ++:15292E004D91AC34A6BE67C2BEAACE99AE9FA98648037FD3FD64 ++:152943004155AA9389664ABCBD4E86FF8C5209F9ED634A2D354B ++:15295800B9CCA81171196A4DA6002E55C012F594521B8B0DB4AE ++:15296D002F9F29D595F8E27ADC7DF1C575B847D1D7F1B090F94B ++:15298200C82BF818F29DF489B81813CB7844F8D946901E4BCFE8 ++:152997005E4D79A2464CAC776BF659FC188F88B5932DD699FCEB ++:1529AC00709B75469E6DB7E3F076D9677810F764360195205DD9 ++:1529C1002461182CA141FFC1EFF796CB77B0F10EC3AFCA752C4C ++:1529D600BAD39844BFC655C35A07B2CE2DD7A472EA449D549F2D ++:1529EB00386783E768AFD15516D72431FFF59A9973E3D1FFDE24 ++:152A00008FFECD579F3664F575D21913464495EF78E9A197A820 ++:152A1500FED7FA918EB41A4A3B302DAD94D2764D4BDBB69CE0E0 ++:152A2A0052DEEEFFF243EFD49262C6FDEA25633B3BC3E7AF7812 ++:152A3F00476FA9F869EDD7965DB17DA5E362BD6D41FC027C739B ++:152A5400845EB160C5395D4E0E1A9EF223ADAAFAAD7E664C9A2E ++:152A6900BEAE5EA193637EF68DF52D0D618EA47698F10DF3161F ++:152A7E00E91D1D7828603FAD1D7EE8974B0906A2E92582EB9C07 ++:152A930021F17DFAD736BDCD6F89D05CACEC330967F1EBCB57B1 ++:152AA800D5FABAA9BDE8CE617624176BE5C33E1F7483DD077C9B ++:152ABD00ABDFA1F4FD07ACDF2FD8BFBF7DE00CCDB7C9EBD3C29B ++:152AD20060477FD89FF09C3180B7ED6C8CC7BF935BF7C413B97E ++:152AE70075581F3830FE356DDEF9FD5ACEB937F4BBD985DA799A ++:152AFC0063A774C41685FE62AD2F8E8BBE96287FAE4F3E7CC918 ++:152B11009C27BD46EF2F98BEF8B1A5D88342DD130F9F337CC974 ++:152B2600DCBA912773EF10671887451C98E3090FD90CCA090325 ++:152B3B007DF9EDA1CEFAD069AA5BF9078EFE28803BFABD611FD5 ++:152B5000620529BB8F2B02FEEF1F7F9BC66081BAB70B6BB57987 ++:152B65006A67BC27CE3589F49389CA1F1AD05192A4777CD58762 ++:152B7A00F83ABC6BA2F2D726E5DDF34BB5E68E28E5DF115B5586 ++:152B8F0007BB4A8C2DE59821279F2519E9AD8B8D1DAD63C60920 ++:152BA4006302BC47EF317ED653BA9C3C46FCD3297C13ABEDD81E ++:152BB9006D62AC197BC53E47B5186706F725F7D2388B73996858 ++:152BCE00AB305E8FBB8FF13ADC113FCA97ECA33AC68C36EC2BC0 ++:152BE300261386E4231C85C74CFC061F627C9CF92EDE0D923EE6 ++:152BF800493A7F3261DE16E7227D8CD2F11BFBC81395DCF0C751 ++:152C0D00E4BA00E96B1827139583E63CB22746AF7BEF205C9AE6 ++:152C220067DE4FFB1482A789DAB8807115EEE71324839BA85E80 ++:152C3700963C68BE91F1E7EE32FC8481300177A193D733E374C9 ++:152C4C00BFF0632179D61D39A7FDE51772EBFA59A7D61FEFD3ED ++:152C61007E5925DFD14FF6DADC44AFDEB3936B3D0D17C55EB4FD ++:152C7600927ABAFFB645E59F11BA5B383E8C9824810509C4C806 ++:152C8B0032E627459FAC182F3EE8A37111C3A55AC6DEFBDB8611 ++:152CA000B41AF18A5F357BC6B806FF415FF22095DB0D3C8B58F6 ++:152CB50057A5A9A7CDF9A9AF9BD5849BF9D4D7642EF634778BAF ++:152CCA00F159ADEE16BEF1A20E85236E9FAF54FDAA217CF63673 ++:152CDF00714EE50CC806393662D4A7BE437977D358E9A579EE05 ++:152CF400A08E3A3D6787442CE5B6BF60AC0CF62FD980885722D7 ++:152D0900AFDBA5539F0E78D6EDD3B7E4B1A9E3631CB16EBAF850 ++:152D1E0057DE92BFFFB424E82262000553F033EA177E46C029AE ++:152D3300E2FE045942AC5F8A78669FB77CBF906E8EF56AA5A9CF ++:152D48005DFDE1D4F3496505D77DA403E7ACE5BAAC72D3EF4371 ++:152D5D008CB783BC3AD2B714EBBE25EDC43FEA102F8DE3F709B1 ++:152D72003364FF464C0D4BEE937D9AF2D7210DEBC2BE8CFF7CCB ++:152D8700BF8881E3016EC67B8D2A4107EB8CA2447637CEE55AC6 ++:152D9C006713AD3DBD37A92E896000ED413FA9EB981E5AD069C0 ++:152DB100EE8F58E7DA104346FA032EF47445D0D1107E6A8AE003 ++:152DC600EBE78E5F1636449788B723A748868D4F0A3C07C84604 ++:152DDB00F60B1F837E116FC72362565BBE6BCC78CA443C46C088 ++:152DF00029A5BEC2AB539FA875CB76C874D04FC8F58C4C27F975 ++:152E0500BE25B72598FA8D29E22C1E07FFED32F7FC2E5D520F81 ++:152E1A003F3B9B06C07130B5CFF0F05E3DD068C5BCF3906C4040 ++:152E2F00DC763FEB5DE2271E99C77A6B41BFAD2EDEDC6AD1C9B0 ++:152E4400D88E7BF99556C15B4437FC96C5B982B888E3047A8367 ++:152E5900BE22361FC632D1733A2D6551D6A2C387E1F623D3083F ++:152E6E003470E3DEA1C7C7A04181A041BF1DE7284B8B0FA58182 ++:152E83006B6E75F03FF62DC4A72C0ABB69511CFB64ADB04BA3BE ++:152E9800EDC3D79EFCE452259647F368BB01DB13B28A7F25B730 ++:152EAD00EEE2BF38F2C79217A544ABE205DC94A84FA01DFA68E6 ++:152EC200C53AB2DA407BA83B130F23A31F59F42873D1628780A9 ++:152ED700A7CB3AB740EF11574B49ED33253521F808BF35D77979 ++:152EEC00E0A0AB7CF0F399F8E022AE783F1B12FB163ED0BC7DCA ++:152F010048F3AB5E218B15F007C99EB288257B32E38EFA2C6D48 ++:152F1600C1FC4BF735E7040E689C06FB7F6BF53735EDB313D89E ++:152F2B00A3290D75B596D1DCAFB2E4F1301B3B1E61A9E3D72E7F ++:152F4000A4F3E93E4CBF87297D58B3CBDF2CFF9137A7E6AFB6EC ++:152F5500F3631E1FFD8DDBFF14F32C8BBACB8AB8C362CF8D1B4F ++:152F6A00D79F94EF6882BF8B3A1AFFEA99535A2E9917B2DADB5D ++:152F7F0085B84805EAAB5D38FF68F9838F8933508A3A42764A45 ++:152F9400C2F0A716D5C97F93CE071ECE5E4AE74FAFD30D9B3808 ++:152FA9003B48659BD4678CC99F71D2890C1173C9E2C33F330520 ++:152FBE00EF5AB19D267A483FAC233DE8E3F0E6C4CF7A8D84A7CE ++:152FD300CB6047E496899F7133E1E9379BD41EF337D7313EE251 ++:152FE800B62DD26E5E86EE13361CBDD48AEB6E1C34A0034B3494 ++:152FFD006E003BFD3677FC17D2FBC25113FAAE83B39387B2F8C4 ++:153012006EFD7516BFF3110B22544A7A79BB7196E0DECE629CE6 ++:15302700A5C2FDD88FF2A7AA8DDCD3B5FAB7E28B6B3B972D9B72 ++:15303C00A22BE631F8892E13FA539EF428C98F35869A8AF63372 ++:15305100E557A6CF57A9C3D7D4D213172E2D205BC453AE8936F5 ++:15306600105F167AB6B7BD562F8AD4D617509B472BEE5C3A3F3C ++:15307B00A5D25C576D94A6C286E46FD43B9FADE5DE31B2FBC612 ++:153090009799CE1E37621B0A5D5D6927FDB1AA56C65E6AF49146 ++:1530A50061663C7CC0D785F301FF49DC53CB3D7764D7834AED9C ++:1530BA00B882D5B69C0A939C5AA6414F9FA74A61118F54C869C1 ++:1530CF00B241A83FB22B2695357F3E3F5C3676502FB3D7338382 ++:1530E400340F63BE65E3AF9801E9B25E5759F419567EA695B16D ++:1530F9002B5C61FFB03428BDABEF53BD75D005C32413E74B43AF ++:15310E007A49E864AB2FF20F4BE6D3DD73AE4FF8AD601D6FEEF2 ++:153123000AC4C23B69FBC7C4F9159AD78BE327F4C07CD24B94E8 ++:153138008EE18FFA3F97746FDCFB97E7D517C7F2C82679C5604B ++:15314D00A9E78FBF41E3687EEA6903B24AC411A0FE07683EBE55 ++:153162005AD6BB2442BA0CE69B07BC86D05F7EFC0CAF75749694 ++:15317700ABBF4BDF546719FEDFE99BEA2CCB6EA6B344DFE129A5 ++:15318C00E7FC27640CE1CA57F985A505620F0F783BB53478FAFC ++:1531A1001754FF29BE9E70B77F99E19CA917780AC54732780A6C ++:1531B600A516D5FAAE604FB963587EFD14E473685E6A562DFD13 ++:1531CB00368A5325E25E905A20EE06C9F199FA4FF369BD67F568 ++:1531E000BBFAE56B691FF080BED6D87D9F78DFEAFBFC19FA8E7C ++:1531F50032C3D73E7EFF1710DD4B2147A33DFD6DBF9966BF5070 ++:15320A001FC55AAA8B9E6BDD79A27DC63DAC9F6F201D3DF78709 ++:15321F00BD4B54F5345920295E2C91DEA55C3083365FCA381F10 ++:15323400A4FCC4DCCE2EF280745587DCBB65C5BB7A78EC3BF5FD ++:15324900B73458F8BC85BD63F975517BB7C05E095F143805CF3D ++:15325E00C1BF133EA2E5296F9D9367EEE94B19BCCFA5B28ADA53 ++:15327300DE1F2F4CB420EF56ECE54447FA117B31E7CC29BC3BCF ++:15328800E0397B4A37D26427D1FB6AF50B4B71073C93CBF3EE4B ++:15329D00D8F6D04F491FFC89E1535F3E50A3FEC85C3669F73195 ++:1532B200BA6BD88FF8AAC9F5DC7A86ADB46BF8CA72ABFC49C28D ++:1532C7005BD0AEEBDAF2C796DECE5EA813B68E2B2FCAA20E77B1 ++:1532DC00B9B394A7E3A90B5A58FD8F4B908EF99154E5CFE1F98C ++:1532F10019CC91D15D49E89F285B803D65C225BE1F33BFE7B062 ++:15330600C0EB3C957402BBFEA229CF736B3DD6737F813ABB967E ++:15331B00EE86A7C8D2CB51BFE7EB7B74A1037C876405E9576696 ++:15333000E4794D8924F4529A3B443C16C53A83F361FF34A7745C ++:15334500495DEB75F8193265A7987794129A3FEC7947CC41785F ++:15335A00F731E61F67EEB1E7A119E71FCC3D9883EAC599FBCC51 ++:15336F005CC3D5316BAEB1DA5159A9FA2B730E74099A977C6AF3 ++:15338400B7B9E5BDB4AF20C9BB0A08EEFA48A2CEB1FF4A691EE8 ++:15339900439ED5EF39F4EE349AEA2CBB716254BC37F03E4CF834 ++:1533AE00417996BC6C486557881F39D98D5D3C37998817533BB2 ++:1533C3004A72A41F632E27758AA34EF01A78AE5AFDD901F0D4A9 ++:1533D800C5F71DFDCC8699607DA3E7591AC3EDC6D65F58F3BB94 ++:1533ED005897A5B6467F951D5F8190E5EFE1B3CF1924432C9F18 ++:1534020074CFFC2B01EB77DCCBF23748AC707B0ECBC77986F8A2 ++:15341700D8D46F3B4DFC2D4D4C1711129DBA46FF6DF46FD0FFC6 ++:15342C0030FD8FD3FF04FD2B3FA2F73FB2F28ABD83A0EAC46896 ++:15344100E467C7F0E1884A1DB1F06F555B97B0FA5F755EA47C51 ++:1534560015FDCF100EAE926CBE6AB2FA761EFB4B7B9DAD7E8045 ++:15346B0027E9B947F5B62834AEC7DE465F470DC4BC14E73EEA46 ++:15348000BB39DAA977F43BCA1FA7FCB7B2BDCDE299DA539A5FFA ++:15349500340CF4433961C0BF36B4E298CE627B39DEA3EC7EF867 ++:1534AA0063217634D5592CEA7C45B429621B7D601DC77851E412 ++:1534BF005433F2A3CDB9A11BFDA9597082F7B2ECFEADF0DF0892 ++:1534D40066CFECBF799A1AA43993D59FE216AEE1DB316CF5B34B ++:1534E9007E888B36C73B0DAC81948C1DD3156AB7247E54878F79 ++:1534FE009EAC4E4DC31A888FD202E35D7ACF84A7C5FDCE47EF92 ++:1535130042CA7FD3FD64878E601FD4D97725F8FCCC155F697AF0 ++:153528000CA57FE37B9C131A0922364775EB55BA7B953A1D3188 ++:15353D0072FDB14A3397CA5C0BB142F9BFB61B56BC617917D2C3 ++:153552000629CD1F1BA03967917E71B9749757E9D0C7290DF1AC ++:153567004BBB903F5669E07C8D8A73A29426C706CC61A4D3B355 ++:15357C00417C7B9164217CFC6BE63271C68307B23609CE1C5FF6 ++:15359100F558F1B2B6219DE007C079471077F45DAE9C7F464330 ++:1535A6003F4AE11BA48C709FFF98BE8E6CB339AADC92973A2800 ++:1535BB00E2B610FCC5A114F2EFED90BA7B853F27CE18DE966C99 ++:1535D0005AA2F82D5F0BC466982DEA1C3AE0A33C3E2B4FB034D1 ++:1535E500292F918EDC589645F304DE0C9AF7AAE658DF8082FF11 ++:1535FA00BDC3E7E373E0979EC8F887C9EAA4D95A427822B92460 ++:15360F00137EA2F4CC66F0E72F25BC5BDF3CF96B737BEA6F0F36 ++:15362400C897DAF5CBC553EBC7F744DAECFABDA1B156CA6B50E9 ++:15363900DE7ED4B58764E75A196B3AED343E2254FF6AEE53F13D ++:15364E001C6D853FB7447A2EE9C2A65FD5CDB504838C33722494 ++:15366300A7F17D95F96A3B87DCDC537646C37AECAAD43F13CFF4 ++:15367800FEC05C4DF724F1C25ABAAF4E7DA61FB410FEE76AEDB5 ++:15368D00011FD5514FF59706587E581DE0169C5FE8079C388F73 ++:1536A200BD92F475D8309EF258EB9EB2360DF23E42EDC4A82EF4 ++:1536B700CA773C4AF7CDF41FA1FA733167184D7C436AB919A3B7 ++:1536CC0076A2A9FDFD38F3B09ADA89AA3D070E521E8DDA3AAA9F ++:1536E100D8676C4987403B84C0923D6549AD551D306304D7662A ++:1536F600AA7F82F07335C00A7D54E632DD714E9EF8CFBC46CFF7 ++:15370B00ABA88E8900CE1924F8167A7E35007E575BDFA4FB6AE1 ++:153720004A93296D989EFD418B46D371ECA697F7525CDF4C7926 ++:153735008B55B939C745CFB03A48B8867F31F68427699C0F9A63 ++:15374A008A4A73DA349A875F9B2AAFE12FA284734806776564EA ++:15375F00301C123057DF4DD38107E71CB78D7051CE386594ECF6 ++:1537740018B4E4DCB663960C8AEE35E0D33217320A6B58888D3C ++:1537890019957765DADD3669CBEF1E9249581B3C684A65713D24 ++:15379E00E37F4678A0692F9FE62E23389BE5E3AC06D9408DFDF8 ++:1537B30012CB273E32A89F8D7E1AC705EA82CFACCA63F9F3E96C ++:1537C80019DF929195DDFA28F169BFC20ABFCCAA1A494008FC7C ++:1537DD003E42CF09C5C26B39AB6A8EDA721FB240C04675602E4B ++:1537F20088501E12E685CBE8AE282FEA997874341F5FA8686FF7 ++:1538070084CFA788BD46F7ABCBBDCD0AE5DB5A7CE31872C60954 ++:15381C00F6CC300E2798F50D3C278F9FF860A7FD9DBA72D5DBD0 ++:153831005C4DF5E4975F213A1D9A820B85FA73167CA3DC26CE74 ++:15384600D0EC8AE13B033DC613915ED1FFFC4FD3FC46F800FFDC ++:15385B002D25B4416F7FB508E30EFD7AD1C01CD1C83A455EA932 ++:153870002CAC77E663AD63C0AC72FAA5741B32E916D5E0BD40AC ++:1538850017740503FE7E0AD581323EF5457AFF2B33BFC82AC7C6 ++:15389A0094174DE0783BE5CF75CD5B6AD1D4F59B6B45AC3048CA ++:1538AF0079268AC0F35546428C936A314EE0DF0499FBE6F5749D ++:1538C4003EFC750AE289466FB45A57D54AE3CA72A97994CAD023 ++:1538D900382EF4BAEA2FB6CFD665ED55D598781B01B576EAA8ED ++:1538EE005B39FF7B22D6307CB5B09624931C95A9BE2292F7E8B6 ++:15390300C7C44303F50FD2337CAD64711EC8D603E0E3F536F634 ++:15391800F82CF8E5D810C9A4170D712EDDD255D3C53407E3FBCC ++:15392D0055B2FA8C69CB9300BE0D09F926C33FC2FEFEC424D5C1 ++:15394200F3E318F1606CC85E334EA7FF6A6CB0D14FBF713687E5 ++:1539570045DBF9F642969F5B4934B4EBFE2DF5DDE90BD67050D7 ++:15396C008785AB230257F0FB0DB1458D4E7F0AA80F93158B9A3D ++:1539810071CE7372162BACB8981D3F326414D96517C986FC2802 ++:15399600FDC4FE9B809FF409C0E21D233B3B3A4A750D4057248D ++:1539AB003C7467FC45BC946FB480E5DFA30276AB6F778D250892 ++:1539C000B735A60337F611FFC7B19F1CC5FA83A82F84B58C55BA ++:1539D50007A03FE3BD903D36BEEAA7ED4F59E36515B7F15B828E ++:1539EA00FD0F3FE5298EC9CD9B73B26347C9AFC1B7BB047ED1E3 ++:1539FF00D6BCB141D2A306B1A79816E71AE9AF3CF242E3453F3E ++:153A140070F373DD194F23F6F95EE80781F1A7F4C0F9255AB02E ++:153A2900BD419F97929A049F19DD7C07CDEFBE50360E0960AEE7 ++:153A3E00639F6A862E3096EFD0CDEAFB6FD177AA0BF97136C947 ++:153A53001FB3E28A20CDDBB448C46C9745DC120BA6BF2298E058 ++:153A6800DF081AECC7593A9A0333F44D791BA103CAA9534601AC ++:153A7D007BA57132ED6D9E97F23607A7F58164880F78925343FB ++:153A920037A72BE1183038FCE84F9D30FA52DE9650D3908009B9 ++:153AA7007066F4D570B5A08B22F42AC0FD29EC41091CCD8B0F3C ++:153ABC00D43B78D94C32D76BD3CD473A5451A5D468F5CDC2C5E5 ++:153AD10075C1E30306C64D89DDCE3F52F98FD3DF85D4DFAA4288 ++:153AE600F437ABCF839FB723662FF1815F75F529F6B2D117930E ++:153AFB00B27D52AD3E59F850459F9CF3D2363D44BF0CD798284B ++:153B100076E10E7A01F0E6F4674EE84A2BC9419A7F7F6EE6B539 ++:153B2500D3F852F6F0373C969E087C6C60D9710F19B839730EAD ++:153B3A00D7D28BC4B96ABBDC412A071E49A28C4B9E857F379504 ++:153B4F00FFFDEA51923983FC4F2343B5CA8E11D12F5FB2D374B5 ++:153B6400FA0C79017E2F16B1E59F35DDB20973899C7CD6EC230E ++:153B79005D5321FB3E4032DF9F841CE3A6D5CFE12C9D934346AA ++:153B8E00A8E984C04788FA60AF6F171440BE8AF1C5752BEEFC13 ++:153BA30015D1DEC2152FB8C697859FA2D38322FE2F70F7C8C3D1 ++:153BB80096BF2BEAFF0EDB4B7C3068049A3A6DFE1FCCF0FF61C9 ++:153BCD00E27FC0073B05EB7C820F62E003C3E683D10CDFCFCFB8 ++:153BE2009FCAF747057F0E66E9AF8E18A82BCBD3832EFA774D11 ++:153BF700A33FE0D96BF537293763ECB8C70C7ECB49C4324A1863 ++:153C0C004F936CB360B6FAB98BF8DAE1E110C1574C7CEBC07AA5 ++:153C21008D602D2758DB7C37F2ECABBF01BFBAE08D11BC311723 ++:153C3600BCAA1B5E4B36BAF502A5A953C0EBC8216B6EE8123030 ++:153C4B00CB31CB87CF8824DA8A5C7362EADA541EC4B91256DF0C ++:153C60006BE0FB53B01DB5FF952ECCF01FD92E6F2256C061F98F ++:153C75004E2566D92FC591A33AA972C52595724BE07CBFE6913D ++:153C8A0058600EDE8D8F18CAF9A426930D739CE055C8E6958910 ++:153C9F00C7B0AEE5F321561CE721A2A74AB64FFCA9DE960EA415 ++:153CB40077FD33E6910EDFD953629FF44AC5DE3BD8F8A8618648 ++:153CC900A516D4539ED88B98C1C1B988EF41E9896EEC77ED3513 ++:153CDE0065AA0F7B61E237B52B8BB5FABDA62887B68CBD387FDC ++:153CF3003CA73C2937B65B653AE26413E16C936F2DD785BF237A ++:153D08007C526C9B08B0A2FE9DABB996B36E528FD370E9FD2C8B ++:153D1D00D7D06799CA94278E6D02FC98CF010B60036F2E2318BE ++:153D32004ACE9FD4E662CE7FFD59BD98719A2F92DAB7302FD91C ++:153D470075E2FB086DD4579473FABE8BEAEFDA7742F851827F75 ++:153D5C0044DEE84887AFFB9FF51460A33EA12F6CF220CE5EA6C6 ++:153D71008107D29D39F0B9142C4BEF1D5C5CCCE0C16A2B830789 ++:153D8600ACDF8D5B78087D576EEC5A873DC921DE4EE9BD185FB6 ++:153D9B008413A4C13644AC330BDE538483631AEACF59F76B7D0D ++:153DB00087C0C3312D40FD030E149C3BC6DA3BF4326A0B310BAB ++:153DC500C3D47E39C941271EA1751E24CED93B8CED29EBD2DED5 ++:153DDA0023DD754198FD61952ADFE5C45B1FFEBC88472874DE64 ++:153DEF00D5C2AE5A7420286268EE16DF804059E2EB7CFA3D8C92 ++:153E04007DC0F17F72C5B3251B113184845E087F7AF8A685976F ++:153E190071863C4ADD01D249C6E2D5DE16C957A3CB91C5FA20AF ++:153E2E00C18AF80B48AFD0FA750573907A6FA34FFDA346457D70 ++:153E4300A0598EAA3ADEA54847C77DB3388FF4E722966149836F ++:153E58006A5AF51E860E34B68CDE5568861E8E0F36D6501DD54A ++:153E6D00544795FA40A35347A9783FB58DCBCB1F10F5FA45BD41 ++:153E8200BFEA70F25ABF0F1B89E57D778A33DA0D13565B510BB7 ++:153E97007EE0EAACF0EFAF36A3948E39F62A6385D2EAC5BA120B ++:153EAC00818E68F793F20D8A7C61BE01E58DC526F28ECD90178A ++:153EC1006D6F07ED92569E8337C9B30163D3CEB3FD2679C294B6 ++:153ED600C76FE7D9302D4FAE522FBE37847CE095ADCB7F762708 ++:153EEB006425FA21533F719F43F2DCA79AE64CEB596166FBCB27 ++:153F0000638C2A8363D86F147A0B3DE34CAD88371B8D0BDE2D37 ++:153F1500B1CECE67D68424C9E2B74CBD549FEAAC1F093F34B224 ++:153F2A004F7F90C3B07E029FEF94A06FB6BC150BEB8881746A9C ++:153F3F00D3AA9FDE958C3FA707CF3FA7C1462DA1B1126C1A1181 ++:153F54006397F836A0B013F598673FF7560E53E3234B133497BD ++:153F6900FBC9362A461F146E5A3E6FC233A400318BFDF1634B40 ++:153F7E00A04B237F10F53B700839DE65C11749D48BEFFDD9F533 ++:153F9300CE8F0F2EAD99566FC60EA6B941949F617DE61FEDF10C ++:153FA800877EC15626788B2F63DC2855D9F2EE785B347E71160F ++:153FBD00EB9F662877745A391A9F379C27B4CA1FE23F9FA1FCAC ++:153FD200D68F50FEDD19CAD57F28BC87F89519CABDCF3EBCBDF5 ++:153FE700D434FD0AFC1274F31FD6D5FFC9F54DBA19DEC7AF7EC8 ++:153FFC00F0FB890F7BFFEF5DFFB4F77EF778F8A0F5D6FFFFFE71 ++:154011005FF55E71E1BF789A7CFA7F077E9B3FA69D399A78FFE4 ++:15402600C6F1F061F5B9F94D2A3BA2F779129B3F2ABF61BCCE52 ++:15403B009155FE79711EAABAB553896D5E49C3DA1FF8828EF8BF ++:1540500077F80EB8FFEE6E1D631E3A823FB0459FB5AA5B57D5B8 ++:154065002FF15977B7EBC1755CF34B957AB0A8524F90CE66CB4D ++:15407A00874DD7482F5102D53AEAFBD7D675680DD786E173B5CB ++:15408F00AE4A877F33BC776435A7E57192F925FE4ABD605D8D23 ++:1540A400FEF5358BB58A758BB5907FB3DE99F37B1AF6A316C828 ++:1540B90031C4C70922AF2C7D4217EB40ABDA850C822CAA284A4F ++:1540CE0068F08372DE178BF78B756F202EF4DA8A07E3BAF0CFA1 ++:1540E3002438CFCED0FE4ABBFD426AFF10B55FE26A1BED9653F3 ++:1540F800FBC827EAA5FADD6D5FB3EB9D70D59B4EFF34ED474C7B ++:15410D00C55AD6B29E4C18D41DCF8971E022CDACBA6EA7297B4C ++:154122002EE1C54F6DE6AF5D4CF8A9D416F86BF4F99F965BBC93 ++:15413700AC7D63C51FCB2D87662704FEB12E457378106BA2B712 ++:15414C0009DD240BBB881D01FD90C59F147D2398CEDA308DA2A4 ++:15416100EFFE0D7AC5BEF5BA54E4C096BEEEC0D648B095FA2B21 ++:15417600457A9C14638756F94535BA5FC0D4AD2D284AE83D3BB9 ++:15418B00F764F80078FE6D3A6DC3C0443F71F6CEDA779D78128F ++:1541A000ED8EDB7048655DF8269C6F36B76008ECABD203D41E5E ++:1541B500FAD662FBB8C3394CE0252F8B970AE29BC2B54D7AC9E4 ++:1541CA00BA7A01CFEE9C6EAD80F052E84FE8B92CB1718FCD975C ++:1541DF000B45DFB3ED5EA1B60C7A17207C11DD8B1D1840FB8A9B ++:1541F400D51B34D8DC15EB3668D3E94F83275020CE13B2828A7C ++:154209003307C57BE95C8D5EF2604C97D997F45994E780C44203 ++:15421E005EFB791F3D17AE23F8884F0A8BEA75FEBD06EDD0EB49 ++:154233000D5AE1B9B57A09A7B47DAB74FED97B88DFEFD140FB92 ++:1542480012C265C55A0B07724C6A51D9165E4F38F34A0FEBFE75 ++:15425D00580E62F807F3B15753BEBA7596F4A8EE9757EAFE153F ++:15427200D4D6DD8FEBFE55F7E87B73566A5823975764F3E7852A ++:15428700AC3324227FA2D6CAFFDA1775FFAB0DFADE9DB59A97C5 ++:15429C00E6ECC0F7366B159FCE69C177627CF1DA8DF9630D1B06 ++:1542B1009FC6B78679AD5E71EE615D3ADBA073CA2BF9B2F8DF16 ++:1542C60086311D12674E362176B4AF9DCA9D6ED828ECDA65ACCF ++:1542DB00253710DE981758B6B1A26BBDB69B6401E982C5BBE8C3 ++:1542F000FE879031FFF331DDBFAB41870DA1AA8F72B16F98F838 ++:15430500A22EADFD922EDEBDD640EF6BF5BD842FD01C7C0DFB89 ++:15431A00ABE09B524BC539C21F6FD74BCE7D512F3CDB2DE8DE86 ++:15432F0043749F45F42E88F08D6E39045A835EC25FD7A623F818 ++:15434400F06E82A505F0138E11377A1D3D2772B66AB3A81DC03C ++:15435900DFB9D37ABEFB7ABA0472C8F98DBC34AF6C3A4869289B ++:15436E000B7E36C98C04FE20E7C8BE9CE3F0D276CA237CAB09C3 ++:1543830086ADF41CF8DE7CADE26C29E1B3549F896F7EC9B27C78 ++:15439800F377CCE21BE0BD80F826E4DF2A70F1759B77C03725B1 ++:1543AD009CD2A6F14E77FCBEC70A425B8826B1D66EF6E863B372 ++:1543C20042D156C9FFB8EEFC2E8C3CFA186833AB7DFD46F67A95 ++:1543D700CB46E75EF1AE477C1FA220BE7E63E158CB46299FE89F ++:1543EC00FC894AEE25DC5F277A0367B70BFC7B5A0A7907E1FE98 ++:1544010071C2FD1E21B7DDF8CFB1F19FB0BE4B11947C9FA0B6CC ++:15441600A39BCE085A8057A29B46A7D102DF6D7BD0A605C9D76D ++:15442B00E2F52E5ADCEAA2C57BC287303B8677D2F8ED75D106C1 ++:15444000EB55A03BD277D8F4394FB471E8B1659AFFE787D1E3D1 ++:15445500828B1E7F65D30363B8C4A6C50D7420DAB86991177966 ++:15446A00E4B1DCC8FAC7D876D6E21F7B64E32C65CBC63CF69F69 ++:15447F001F2B88FFC946FFD8A3E277C51F8B315AEC67F43BF207 ++:15449400258177794725F7908CBD9E17E5050EDE696C16FA775A ++:1544A900929CBB5F2F5CFBD414BC17CC84F7AE85A0B90BEF3177 ++:1544BE008177A7BF6EFC936C2FBEDBC63FD67C30361CFC17BBB3 ++:1544D300F0EF116B37167E7B6DFC164136D13BEC33BBF9DE2957 ++:1544E800FF4B21FF2D9AA19C887B69D3C1C279FD14589E408C43 ++:1544FD00AAA4D48273D5099237B954C72304C3A17B37EB15EBF0 ++:154512009A34256789969773A7061EF693BC61AF376C3CF4031B ++:154527007A776EAD569CF3592D3FE70FAC77D2CA8D6CCD3D1BF6 ++:15453C0077C73C2D806B2170522ED6B603B9AA47CC8548473C72 ++:1545510037C7A641FBD89BCA71E6687B9E403EF80E03AEB7C9AB ++:15456600ECA43C99F1FE1A8D77CC5117D26905EB41D003684EA5 ++:15457B000BBE6AE7FF163D57BC2BE35E7CD2EA77C1FF01EF9849 ++:06459000C0E6B892000035 ++:00000001FF +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/pca200e_ecd.data Fri Jan 21 16:01:05 2000 +@@ -0,0 +1,906 @@ ++:150000001F8B0808AC5A10380203706361323030655F65636428 ++:150015002E62696E327D00DC3A0D7054459AFD261333136278A4 ++:15002A00192663E02479728060A10E9063213F64F0700F3DE05E ++:15003F009E6CDC7B2F3514B35EF0A28B9A5A731E554B91474C5C ++:1500540034E11AB6692618B7609D8404A2121CA8648D7551435D ++:150069009DA578A56C8AF276A9AB829DF3AC92DD52CC5EB177A0 ++:15007E00D4CA32F77DDD6F665E263FA25B775B7753D5E9F7BEA8 ++:15009300FEFAFBEBEFFBFAEB7E79F4A91F6C270A21A1870849C1 ++:1500A8007C974CFA8536C11F37B9A99FFEAD9C49302569258321 ++:1500BD00D8EF4EEE6E14EF59E3B3EDFED3E3C735EC67E50822CC ++:1500D200A9FE0FFD29BF7CEA97A26F4EC993D537AF13234A5E2D ++:1500E7005EDE94F3BF245F4AFCF1F129E7CF9E866E0ADE2C3919 ++:1500FC002BF0237F849F3240F688FEB5EC75792D39E3BCB43E9B ++:15011100C9A9F54BDE24FFBC9C3C6987DDCD33F3938CB0674E4E ++:1501260078D6F8D7D63FD9DC8CEEABDC4824B2F9DC949E391965 ++:15013B00FED7BF11FF975E7267F17D1CFB4BE77E3625BFBC0C26 ++:150150003F0FF9BFFF5372CB72671A1F3D3EF99DF51312ECCF0D ++:15016500C070095C0E5FF8FFFE4B3A7E246851FDD31C5230FA46 ++:15017A00FC0A35E009832F79ADB5E45140A3A4743C8CE3E39F62 ++:15018F00C35BB09DEAFF05BD7A95BB3DADE6B56DADE538465425 ++:1501A40052C90E11EF08B4773A8857FB013CB7112F090619CEAC ++:1501B9005B125380AEB695F80197D874FE9A9022A5D554ADE572 ++:1501CE002661CA73EE80B5F5F26AE22D7F9A78FC814838484AB5 ++:1501E300E8B36DBD4D843D4C4930CE42B06FCC091861CFB9BDAD ++:1501F8002621C3B438D010BE6DD7091AF29090DFEA334930C6AA ++:15020D001187E86D9CB09E2EDF18033C8DD220A9BB6D57390DB4 ++:1502220011D2D8B26F23C02CEA0FAC0EB76CBADB3C4F48F1BBF2 ++:150237001157A5EBD25FC0FCCB804A3412ECA211D133EA167DD2 ++:15024C003B8518510311A53A5FDD62226D9C4BD46AEA567ACCA9 ++:15026100362DB78EE8A7683E21017F201E4E927EEAB6169944DB ++:15027600AFE1ADE3AEBAC0C53534B0EE4194CF8AC2FE47C6065E ++:15028B007960DD5253D1FA6834346000BC45C0D909BE0A681025 ++:1502A000BDD7BA4BDBBA12ED8A7C09EB8EA79BDA6BF9816681AC ++:1502B500F70EF3723259F4518D59F578B3AB0A66E7A3597F0E69 ++:1502CA00BA90E04E5BEEC669E5765D2A33DD6762936427C1D5C0 ++:1502DF005CDA40CA8A7AA03EA807AC0147BBA02E52A72974180E ++:1502F4007B956F461DD851EB3EA14348C8A0EA9689F2332DA72B ++:150309000E7B941FFB00D8FFD6801526637B69AB8FCC22A5F03C ++:15031E00ACF65863355BCB4740B7F5A05B6A3CEC239954156CC1 ++:15033300E7B09E9AA7F084F085DB760DD171378910B6285EA406 ++:15034800F64A5F403DE05D8BB4C2F800BD8EE3418BAF06B8AA3D ++:15035D00EE81F5E96393DE6D3B92E0385D564748698085091946 ++:15037200A79EC256E0D34F49792B1D759310AC032BD6FBCDCEAF ++:1503870038D845EFE5456A87F95932097ABB5B050D98BFE30F8A ++:15039C009CDF2BE6B767E667E6C6EDC6D24DB7E7A56AA4888777 ++:1503B1003626DE3B6D253EE5C5810BE19CD8095A7CFEB241D8BF ++:1503C600765A663C6DAE8CBC4EF7B70D35420264F51833C16105 ++:1503DB00A6438F32018C232C303A64E29A23DCADBDCAE604CE52 ++:1503F000C2DAFC0BE48392B027D20C3E546386122FF0964DDB3D ++:15040500C0A7BEC35A366D323B120AE8B357F8531ECA1ED46DF0 ++:15041A007F6AE732A6800FFA49302E6321B8C48EB97E560BEFE0 ++:15042F00458110CC6910FE9B84D825C10415992A67940623CBF7 ++:15044400E9EC584E5DD1912DB4E84C9DA9C486689188ABB8F0F0 ++:15045900BD43E494A124DEA49DE43503E75D87B4D6F9E7F81CCD ++:15046E00E748EF05F296419A062866F84EF23AC04791363CBF24 ++:150483000BCFC31CE5D213EF71C44759162BA4E81F2077148DF9 ++:15049800DE677E1BF429501F117ABAB5A3E037FD527EFD21DE68 ++:1504AD0072EB2653890C502FC844D803BC937403BD7E2113CE66 ++:1504C20027FA51FE0EC4AAE7DCA04906DB38E62BF04FDB0E52E9 ++:1504D700EFC24B09339A731CE3886F2C203A191CE0A344E0591A ++:1504EC00183F514DC49F88258C471F213EC2FAAC68A8CFB85650 ++:15050100D6535DAAB92A3CE7C0EFCB0728CC6BDC33EBBE3AF4E9 ++:15051600E76BC964B19EF8949519FF64CE568E091F74150C995D ++:15052B00885B1C83D82FEF43FCD0E167A306513B39C4E31CF4C7 ++:150540000131A6FE965F4D26FD9E7387CD79E78E9AE46AAF90F1 ++:1505550009FC2A0E7E2562E5D1C8C62AB40BFA87E7CCA98C1F9A ++:15056A00E07CDB0F02E0079ED07A136DD5DEE892EB27D74DDAA8 ++:15057F009075F0D47A1E222F1BA9F524FAABBC1763C2F6998923 ++:15059400F69376FBD1FB4F007E4396CDFA85CD8A1BD166C3B678 ++:1505A900CDE268B322323660755A03C6B5E64D2B053DCC1D2390 ++:1505BE00D266445F1497ADAD0B68E03E15BF6D6448D8278AEB56 ++:1505D300C80678BEF73EB0C30FE947E092E01FC585095735DAFE ++:1505E800F671D7EE55CF245C958188AB5ADA037C046D01BEE121 ++:1505FD00BAF4A9E9518E9B1D5AC626FE09B121732DAEABB48BBB ++:150612008C15B459DAD7B3F32CC428FA34D7B6547ACE7D067369 ++:15062700345B4F0631B39A266B102748855D9AEE95FAA9DD5677 ++:15063C00D4EA35EAB4875792D2583897B499FE5D3F12FA91FA31 ++:15065100A3343AFA18E487C7B823BF7489DC027E87B620FA20D5 ++:150666004FD1F043DE9AE5B0C528F877AC664BD58D1BD21EFFFA ++:15067B0059BA7B79AD423CD23EFF6EAE509A67B0CF7B609F6360 ++:15069000FF23F63989F6D9BCD64CED8550E85072F557D21EB076 ++:1506A5004745AD6EE339DB1EF3C922D37F7DA9B0478E5E629653 ++:1506BA005AA5D57F827B8FBE9F46125FF04F66E1FE5412866761 ++:1506CF0086F945D818ED469ECAF8A08A7BB46860BB6E87ED4EC3 ++:1506E400F114BF6CDB45C1764D60BB8F6DDB5D00DB21FF8083E0 ++:1506F9007F83CD7B22DFE3C67E6F5F26674C9F2BE638724555DF ++:15070E001A0F7DDA111F0B20A778361F4BE710B11F8EC13CAB3F ++:15072300CFB85A932B64C35C82792494788F611E51E60E9B4A3C ++:1507380007E413987728E1C8273927219F0C603EF1E1B81893A8 ++:15074D00F9A4D8B3F9A4F963E02D724A539F88D97980873AFBA5 ++:150762001C3A37E59359CE5C33A1781D3BC1DC9B7BCDA235ED12 ++:15077700A29E2C523E379B4988CE17BAF7F3909FE8EF821F7925 ++:15078C000AB11608D25AE1474B445DF7FC5CCD20E5FB68A3A870 ++:1507A100170E70A2DF010DFCFD7FBBF54429CA4C9ABEA016F86E ++:1507B6008190DD315E0F7E5103E34F925FAF825A94A30ECFCD41 ++:1507CB00EDC7BD45FA3FEA06F6167AA890B7BE6EEB8ED2E275F7 ++:1507E0005F9819585F7C7324B932C5ABCC90B5C0CDF0B262939A ++:1507F500695544DE16B4F419E647605EC90313E7DD13D9B652B6 ++:15080A00AE1BE31B70DDEC7941C02DC8C25D1129B371352AEAA4 ++:15081F003D7B5DDD02EF009F3F4EEA549887F684FAAA68452469 ++:15083400AF42D45290DF570BFC56BA0BF015C4D73BF911F04B90 ++:1508490037E243DE03FC62DCA7D1977CA206EDE5CEFA7063BDC6 ++:15085E00A3BEDB4CC197290D617DA68BDC791A7B55055EA967AE ++:150873000D7A477DD7EA98BF20E2AE48D57848C3FD00350F601C ++:150888007C421EC69849CFB37FEA060FC6604F20B001CE496318 ++:15089D00F45BB141FAE3B6A126DC2B99A8E7346641AFCCBD0C5D ++:1508B200FC9F80B3D24E383761AD1C83FDE1320F41BEF0EFBA70 ++:1508C7005F9C89FC501BE39EAAC2D98AE8F5D48775DE582DD4FD ++:1508DC0079C130D653FB649EE04837404E899AD0B2CF592B7220 ++:1508F10048F13F47DC707EFA7B13EB3699AF0DFBFCA4DB755C24 ++:150906003B75477AA046AD605EF541B3E5D6BBCD36A0A978FFF8 ++:15091B00C6DC8B750C9CBB3007DDB2E7553337827B40B7D80387 ++:150930008A033190A792DF42FECCF4C379E3167106B1EBAEB1A5 ++:150945001EEEC7F307D45D9DA1DE74BD05671CBE429CA18E43BC ++:15095A00BE5B682CD0CC95E2ACA1F6C4DD381FFA828EE5E21D9F ++:15096F00CF4F17DE36CBDB9B95EA476A72D279D11F53A6CF9FA5 ++:150984002F7597077ACCF25BD6C49886A7633517D785EC80E7CC ++:15099900C4DF12320AAD0BDA4E683AB425D008B40B301E87C6CB ++:1509AE00A0E9625E4FDC6EB04FF43059BBFD16CF2CA13DDE56FB ++:1509C30043BEDBB50EF83FC2317F3629F20C3409C7410F71268F ++:1509D8008F2F88CBF60A4BF1D9381D5E9ADF82B8362D3FA475C3 ++:1509ED00BA4BD293F8E3643ABE8067E39C2533D1CBD03A3C13A1 ++:150A02009E8DD33425BF89326D9C964E46A68553D2C9D040BBF7 ++:150A17007F55C31A995C3D2CF1C7A25CE40D8CB1E29881790360 ++:150A2C00623586F12B629A58F412FA289C3F647C34424C9608E5 ++:150A41007F9B2E4E5E8138715DFA8579CB9E939363247D66979D ++:150A5600B181F1823501C620C60CC64E3A56ACA39958518FC96B ++:150A6B00B3FA18D457D69F1A6B2156F09CCE223913E224153FF3 ++:150A80001F431E9A8D7990EDA5175CF2ACFE817D7D38027114D6 ++:150A950081380A7D8D38DA6CC751C3639938FA009E23DF07232E ++:150AAA004223D0128F43850E8D416B8016825602ED1AE0753D49 ++:150ABF0036318EC41D03C412CAEFD9DF938E27E09B965B03B992 ++:150AD400F7BCFF8A21C70726C557AA05537E9F8DEBE047317E33 ++:150AE900DEEF81F157441D23C75BE2B2C13A3649FEF5022F9BEF ++:150AFE004E8B23CE5AE21F91E9F8B54C8AB35E320D3D874FEF6F ++:150B13009A915E86969EC69B420F382B230E9D92DF4499668A69 ++:150B28008D7A32959D60BE4D7FE194E3683F394E74A0F3154D74 ++:150B3D00CE4DE17F988EBFD4BA8B38D4FBB846C8AC542C4EA83B ++:150B520027713FDF91D98F156FABA86DB78CB65588BD1DFC5798 ++:150B67007D286614EF1AA4BA479E078B77F5D28847D6AE88CF94 ++:150B7C00B0C665526784B9B260E38E7DBC445B88674CB6E10A5C ++:150B910021EE75DDA61F635A2DC718F12B780796AE33FA999E1D ++:150BA60043484524B702756A8067E58101519721BC73FE108595 ++:150BBB009862B92AE8AF77F3DBB513DC1D6B73DC635914F1AC84 ++:150BD00087F12E56D25A75B3B4622F6768017E1CF67CBF1E338F ++:150BE50015C85F985FE2F23B9EE0F375F4B11CFA743964B06EE9 ++:150BFA00521FC48BD74A7D2C873E5F492B4B9FC12C7D06BFA10A ++:150C0F003E71873E671D32C46F521FC44B7C47EA1377E8F3954C ++:150C2400B4B2F419CED267F81BEAA35EC9E8B3E44A460684DF02 ++:150C39008C3E88A7DAFAE0F3AA9BA595A5CF48963E230E7D4207 ++:150C4E00F6FDA61A180DA77CBCCCA066BB897CA58FE0FB4EFBF0 ++:150C63003D6EBF37D8EFC81FDF0DF11EA3C29781C7CE1CD1D360 ++:150C780041FBBDDF7E1FB6DF2FD8EF23F6FB6AA0B3533BC6C47E ++:150C8D007E0B63EDDA49BC1BE40C9EBBB49FE2F99F8FC273BFE6 ++:150CA200F6160B698BA97DE6E61ACC2B857D695E24B73A10CB76 ++:150CB700ADF62572AB3DB00E78DE451DCBB597059D7A98BB5EAC ++:150CCC003B25E844E1B9567B83E1FC77A41C0C79D66B7B98A408 ++:150CE1006BF18540B710724F0D394B4F6F3BB916715096422D36 ++:150CF600B702613FD9F653011B75C0F66E7B4BC050A614EC99A4 ++:150D0B006DCFAD4DD15FACC9F5433AF3C4733FABB7F9A34C0FC4 ++:150D2000960DAC49D14CE122AD146E4A5694ADD4C645BAF768FE ++:150D3500B9D5381EB56DAA3D216D1ABA22EF6F904789BD3FE19D ++:150D4A00B8BEC3392EF9DD65D358286174F44989B3DEA681BC57 ++:150D5F00FD4803C6C69FC88C55D9760CC3F846B01FDA8EC2739B ++:150D7400583BC0F0DC392264BA2CE4DCA1BDC88E08FB76F1DBED ++:150D8900AF0807F47DF7466E65D9853BCDCDA56F2C7F612C6631 ++:150D9E007C7B2DCAD12E6C940F67B9556BDD952B4AF72C6730C3 ++:150DB3007697188B0B79F363B915F3DE7257064A0F2CE7305641 ++:150DC800B856CA8FF6CA8738B9F17B77E5EFE6BFB8FC208CFDBE ++:150DDD0047756E753E9C577F7DF1F32AA4F9F17C5A85F3FFF557 ++:150DF200C86015E29EBF78026AAD06C113E48F5BA22F113283A0 ++:150E07009E715DF43B056D120CC555D1370A39E07C18C798B8BB ++:150E1C00EDCC6553F93002F1F71A2D10DF7F625CCEBBCC6B45C5 ++:150E31002F6D4482116E403F67DD5153D9F47DA8B3F6D15B712C ++:150E4600AF04BB49BE31DE2AFA06DE2EFA2E61CFBC3D80BFEF5E ++:150E5B0069C0BF9B16068280AF895C26F2ADE81BF9B0E8570B92 ++:150E70009BCF3A03F81FFE10F037D1D9011DF0435CCA1DE37EDB ++:150E8500E89F15EBB093975CC9EC6DA454033C43ACCD23B0367D ++:150E9A008DDA7EA606C6007681AE96B6E141D15FE0E5D037AD30 ++:150EAF00245E1674D52944A3FBAF277DE84B3B005EA01D83BA29 ++:150EC400C112F6CB81B3F8ED77209E8C2BDC2B1FB171D1DE7613 ++:150ED900BC517CDE0D3C55EF0766EB9A98FD6DB39F22BF48E2BF ++:150EEE0067DCBF6B08EB5F529F789DC33BB340367FA8CF54BDFC ++:150F0300782FF021776B43FC9315B63CDA1DF4C69792C76198CC ++:150F1800AFDAF2305B1EAA65E4C1BDEEBC8D3BEA9067740679E9 ++:150F2D0074873CB5200FBC3336853CB50E799EB4797C807164D6 ++:150F4200CB336ACB73BD2C230FEE55F7D9B8E86F2979F0793A72 ++:150F570079420E79D6833CF0CE6253C8F3CEF28C3C977E277943 ++:150F6C002CBB827B9A940779A03C3B1CF2E05E735AE20A5E2E36 ++:150F8100C8ADADD57DFC7A32994CE55867F917D10659443B01F6 ++:150F960039BA96AA810DE1CE35FD14FF4FA873ECB821758973F1 ++:150FAB00DDCE291BAFE0A505F1791CFB6658EB6539856F9A5A59 ++:150FC00002CE58E939FD7C839D8F53B806E04521B67D901B9DD8 ++:150FD500F3752DCA6A81BF017218DA61689FB1466D21DBA92DFB ++:150FEA00039F2967ED5A15ACD57A56663C627272B07149A28F90 ++:150FFF0046ADBEC62EC08F6923AC5FA3ACF3C8095A4C06CC398E ++:151014005B8FD0F9173FA3AD5BEFA46DF397D2E7B62EA7CF1F57 ++:151029005943DB2FAEA387E69FA6783FF357BFC8C198A6F8BFCB ++:15103E00542F1C7993169CE9310F5CDC07F5C0BE554EB9CEDE5D ++:1510530043BC85DAFAEA344C6FA1E5F712AFCF09130AB4D0C3DD ++:15106800D3C06BAF2527C18D480BC37C89F6F12F9E621E6BA1D1 ++:15107D00CBD64C01875AE093F9C4BB30D6C3704D312FD45EC9C3 ++:15109200D405E99F3AC2884A995B13DF2FD855FCC78E2063D72D ++:1510A70044DFC5AEBB64AD33EE92DF494812EAA2C23E336A0D67 ++:1510BC0019F87D638EBBCF3C9433641C0A0D189DB0962F586F8B ++:1510D100189E0F3E1777C9F825E280D561A81BA9897E90EF9079 ++:1510E6000FCFF76E3A24E0CF440A2A3E49FD7B8D9D377E5E23CE ++:1510FB00F7C7487A2F8D31947F01EC63F9B1DF97CF8BFD1DEE8E ++:1511100023F65E382CEA18B97F0DCB5C073693FB1FB371BA04B5 ++:151125004E43669F14F1F0A4CD6774129F5B27F091FBE5B0A8F2 ++:15113A0087527CE2369FF5361F89D345651EEE67B171428E04DB ++:15114F0095BABCFD7DA63FB4C83C06BAFA2277560560AFBA7A78 ++:1511640043EA7B3E726FC56578F680FDCB0C3807E50E34C29EFD ++:1511790055AD94F687550DBF8B04E9D8DB9027624A5DADF6326D ++:15118E00DED9F9DCEADDB00F75B0D2D0BEAA0324DA48D43DD4DD ++:1511A30055DA15762F851A4DFF0D5FA8FD86BB6C5B57691D3C31 ++:1511B800A41DE0FE441F63B97D4DCBB46E8E79C51A053D12BD56 ++:1511CD004C059A08276A94C281CBE3E4B9E527DDD5CEF965C6B7 ++:1511E2004193DB34702E3E232D1D68B94B97844359F37D303FCA ++:1511F700A4BDC8A186B0E747A79CAFFE23EE4D4BC2284B10C611 ++:15120C0096419D11D43AC45D3427AD8D86F62B9EAB609E3B411A ++:1512210039E96C74475AB90FF66017D6BB7A2FF744A2BC2032BB ++:1512360022EE9C27FAF1B0EDC7D6043F4EFBEF689FA13AFCB79B ++:15124B00106A85B48F821FE0FAA18FE6ED1F308BC92253EAB616 ++:1512600044EA16EAAE76FAB35FEB608188BBD28DE768C2A807ED ++:15127500D6A3E94EE2C5F7E7E7B61B259B89F7A5B93143D596FA ++:15128A008AB5598FEB0073D9FAE876EC73578BFF21CABF23206C ++:15129F0069AAAB3C61159E676A128F885E0BA4E4D620EECA880B ++:1512B4005AB8CC6C752DDD9E6BC399CFDA9E1AC7FF6352430BCD ++:1512C900BFE74ED10845BFE74B3DAFCBC0459C801EF81D11EF02 ++:1512DE00CD0E6AEE3A96DE9BE4BDD916BCABB2EFA5314E08DEDD ++:1512F300AFE9C75940AB2EC7B51570BD8F5DAFA95E29EEFB990A ++:15130800BCE39FA37799F8BD016922CCA746CDB3C9A47F527EA9 ++:15131D00B2F9D74EE2DF6EDF9D4B39EE127766BD71A4A3240E38 ++:151332004BBA3A7E4790307C4E4C419FC571FF91F4D500F0620B ++:1513470094E2BE68D3F4F9347FD50AADA02264E78D0AEDF66A05 ++:15135C00A0C97C6A47FAEE1068B3A2ACF7F4B3CD8F8F1D355654 ++:1513710068F757F8B4FBCB03DAA28AD47DEB0A6DBBA46DD35490 ++:15138600BC8727D155DE9F19B638717B25D610F8EC4638D8F716 ++:15139B00207ECF8950FC3E731ABFE72C4EB82B713D104791385F ++:1513B000EC20E660C4D1FB38E2A0ACA501AC11A1B67B88903162 ++:1513C5000236FE4BE255C5DD690CCF9BEA79D24FF15ED2F20E35 ++:1513DA0088EF6B44AC7B4CE0FBD5D7E47730FBDC81304D1BA0C3 ++:1513EF00E28CE280056D58A303B6CC8635E0D9B754F0E33B1C7E ++:15140400E3E2FF0C865D648936C09D30DC971766C188CB4DCA55 ++:1514190027C2583DF46A6488A910CBABB3C712CAF87016AC0146 ++:15142E0060235930F7BF29E3A3593002B0771066AFF37F13F3E9 ++:1514430084C1511569F6242F3203617CC0644C280C0F0C1AF656 ++:15145800229960D0640871E2A297502C37025AEFB141264ADC60 ++:15146D00E0A1CC4156D92DEE7CC144126CB07926122DDD9DB8D3 ++:1514820099327844070F14B7425DEE8E73BD2D6A2B6559B7D497 ++:151497009D52B355DE15578538BAE8B2559C73DFD7DD6FE6CDD5 ++:1514AC006450F1F6EA7E4CBD37DDFDBEEFEBAFBFFEBEAFFBFBA7 ++:1514C100BA31DE44D82DB80EE738919E4FBE9AF31B37FF6E8C0B ++:1514D600D97D8E4A1BC19FE113CC3500EB7D15DAA8986B25E05C ++:1514EB0087B471F62449D02133CEFDA473208FA0ED37A19F74B0 ++:151500003663C7C458757D99E6E3144ABE9AA12F947C9BF50CD4 ++:151515008CEBAB1D34234CD447180B4298111E57823AA4431D81 ++:15152A006768C3D7CAB2AD92C6AD92463FE63CA91C16DF3FF7EC ++:15153F00E1FF709CDAB90469291BFD5236446E9DE415D833C0CF ++:151554000DBEEBAB6C10E61C105FC6F58DEC875B3ED5BCE799CF ++:15156900AF3269B70EFEBE8AB2C2569792B0D97682E72DADE6FD ++:15157E00717D5146D64D2F2B7296012DDCE704CDE492EFAB5527 ++:15159300511E4ABE0134BEC1CA529CCF7E53D2C1CBC0E6F81BA9 ++:1515A800C7A4FE495015BE293361DC608CF8337C825E8FF0D8F6 ++:1515BD00B855A83D29D09E64DABF2DF80B65F06EEDC9F843208F ++:1515D200770BC03B94FDC477DE271FD06EF709DE2FB9C6F8FCD9 ++:1515E70009F8B2F5FBDAB2F576D9D305CA9475D3CB4A9C65796F ++:1515FC00F1542EDF728EDAF3DFA91B7AF274033EA764DDD5BE7C ++:15161100310B7C63D755E3F3FBD96FD1EE4ECD27B36CBD843CC7 ++:1516260079CA9639785F78B6D748E4D5CF3A3766081863B4A142 ++:15163B001CFCA948C92615F7A301D6853FCFEA38940F9C17769B ++:15165000DD94B30E78E19670F8D301632C0F86CD032183A2CC22 ++:15166500CC2F03787BED325FB6CC2C5036D39B5B867DEA73F4B0 ++:15167A00D92EEB2D5056EC7596993451A9105621F9436214752A ++:15168F0006CE4B1FC83CC6CA306EC2FFFBC7DACB1C6B51524A3A ++:1516A400F89A13E5D7C7E5374E6D399F7910F72B13AC1DE6BA33 ++:1516B9003F2474592118EA35C380BA700CDFB19DA53BD60968C7 ++:1516CE001F501F6E475D02FFF1BB0315633A878FB2E223AC503C ++:1516E300B9EA28A7CEF6E585CB5528EF92712E94FB7C7E617C84 ++:1516F800B820BF7C85FB3AEB5CC21832C7A3072A123AD703DF1D ++:15170D00866F7F4258D8CFAF1B037A2D747D6758B9E39A907AAE ++:15172200DEB6FD421FE7F23A571F17A005BE11B48C51FE04D841 ++:15173700D7233CF06F0AF2A1407B92699F4BDF1E87DCE1FC7519 ++:15174C0079A7CF6FE29D3EBF8BBCD3E7322950B6DF337D7E97A8 ++:1517610078A7CF6525AF0CDB3FE7FC36BB26E13ABB92CF716123 ++:151776001B90A70B1DB60FE3E0DD72AF86386CA19A57A738EAD9 ++:15178B007C79756E475D795E5DA9A36E812AED48204577F72309 ++:1517A0005D268F1F667D8F380BDA7BE6DCDF88338C69E058640C ++:1517B500FD8D98217C8BDCDC45A266737E547F75BBABAD8E9F57 ++:1517CA0067C09C7AF516428A0E361AC9CFD31E5843EA53F054F3 ++:1517DF00802798FB87FB643F03997A3EF6C77A726984BDD79F79 ++:1517F4008DAFB70EFCFFFECEB7104F0DD0CA423DFAEA3B9555D3 ++:1518090076EC09E339A4DB7C7312CFA274C7DE9CE2CF495CDB6C ++:15181E00C033F9668A9F5101FFF25EB157E2F039A98B8C9F43E4 ++:151833007E52807D39C4E339D2CEF6839D1D053B0BCFEF8FEA65 ++:151848008277D59C77B6CD8D7D96F6106FAFCE3E93FC8BB8384D ++:15185D00FF50FF35013C13CA3FBC53B903F1EDB957CC93DDF0B5 ++:15187200447F12734E79CC08FEAFCFF137E36CCD771C7335E3A0 ++:15188700FFA62CEC2BF024217992903C49489E249027C5B09E3B ++:15189C00BE16FEE15CF26A4B0233B5BEC04BC58257A2EC562824 ++:1518B1003B1018CB295B01654381E3765929969541D98D8149CF ++:1518C6002CE3FBEE829F7A0AF8077C6C4D4DE7E3A53B89A721F4 ++:1518DB00857CACBAE34FDD9FFE02F25024E5610FE03DDF9C4B45 ++:1518F0006783423C473F853903B4BEF4E9745A5BE11BFA29D2CB ++:151905005AF3AD69B5E391DF86DEED05E82D96F49E015A1B9ABF ++:15191A00A7CBAF8939BE0564F7E38B694F11F4E3838BD3FB616C ++:15192F00029CD317B11FBE6BEA47E63CEEB7EC4F5781FE28B23F ++:151944003F5756114F17FCBE0BFEF73E813E69554CD56A18D73C ++:15195900FDA0F35CCB09998472FCAF9056FA21BE0774AA017723 ++:15196E00166886A56A2D2F22FE08E899B511DC0F8C51DC35426B ++:151983009B98A262AD12DB0FB65831C11EF6F3FD2C0AEDCE4436 ++:151998008E58A51DC7ACB512762F3CD3D79B74233C5DE2BFBBA6 ++:1519AD00218F9E06D95687E746F0357D9AC04774810FF120BED8 ++:1519C200E833B9F81640BBD28E23D65AC0F7E10501C327F17D8A ++:1519D7007C41E083FF6E273F55C9CFA34D44D437919CFA39B6C6 ++:1519EC00FE93F59756E6D6CF95F5DB65FD0779F5F364FD5A59A5 ++:151A01007F9CD7A7A8EFD9ECF9A334F491913E1DF790DC68A32C ++:151A1600F3CE1BF5833FC4F0CC47656C7333EE2F997D75959A13 ++:151A2B0012D4A53E1BA838AF3787F6055B1DF1DCBD273B7E8D0B ++:151A4000BC7ABCFBFDE680A3FCDC0BCF5CC1F2959B7FDDEC8CD9 ++:151A5500FF9E7DEBA72F63F983FFF8AB665289B1C761DAFBDB56 ++:151A6A00275A7C7E7373EC87C433761FF14CA3D391AF9B7A36C9 ++:151A7F00D73E0B5F2365A10E7179C53A8C97A9B97DB3FD236C72 ++:151A94003713647D3028721BB0ED40DBB83E33725F607F1BD7AA ++:151AA900E5CCB47539D4719D0F3079591E3C5C6F52B02D5D5C15 ++:151ABE0086ED35183306CD2A1DF7BDC16FF4F457C4F4BBC89216 ++:151AD300A0972CA99BAFB98298233650C1F4756655F0BD0C5F2F ++:151AE800C6F83EC46CCE0FB6177D9412F0F546F3EA3D8E7A059E ++:151AFD00EA7BB37CED2F5248BF1BEA5DB5307EB2CD7C6ECFC40A ++:151B1200B7D741FB8DB2FDF740FFFBB592805DE787BA0622E42F ++:151B270009FF2F3C3B6254C3FFF98E360BCFC60D5F1E3DF7C0A8 ++:151B3C0038252271CB0DBAB6FECBB4277625EDD9FA557A96EC0C ++:151B5100DFAA49D0D3203F397AC527E574B491F079134A3E4B1F ++:151B660093256416CA19FAC136EC27619E610C4775D0E5AA8842 ++:151B7B0019C723DCFED2808C3FEF01B8D5C0FFDE45C493AA12E9 ++:151B9000B27FB20160CB7D72226DF99364980E4E8EEA336F4273 ++:151BA5009B1EA0C297D5E43E6D35C576459EB8F1AF8B7E50EF22 ++:151BBA006B8CB1062BEB6F45E0BD669090283C1B9E23C484E70C ++:151BCF0065F895C3FB65F885E0C79E13FB5D08A7F53FD29ED399 ++:151BE400B82693FFDDE7D39EE3F89F8DB079303E181BA8E47B6F ++:151BF9000929EBF4FD843C87B6818D58367FED75C669919FC22E ++:151C0E0061281AC6285EC77C7A9ABA8F102FEA228C9B711FF33D ++:151C230088E56AA306EE2763EC8AE7CAAB23B8B75AD6E4A0E3B9 ++:151C3800AC9BCCC2D82AE2C7734FB857B100EAC73CD25E713CCB ++:151C4D000798CA7535A326FC5FF05F609F501F89FC8B0C2D99AC ++:151C6200B39958F63B570AF0F17D3CC5F18E7B97F63BEE59F2DD ++:151C7700B80FFC1F73C4B96C783E76C4405D904A5FCFE71EC6BA ++:151C8C004486FEF9282F23A9EB89EFDD51F10E7F701CB36D6341 ++:151CA10016C65186268FEA650ADF43B1447C2566613CA5C94103 ++:151CB600B7D8BF1CA60F4C3D30B5787234472E67A35C227D20D4 ++:151CCB009BBB6F271E1EAF0C1F61E8F7EDD7560510861B73A2DD ++:151CE00022A798163941FDFC9CD3179697E700279862EF075FF5 ++:151CF50014F916FC5C82DAC3F74C791C397CCC7A5CCEC76BF51C ++:151D0A00279B1CFCFA661A246E3CAB84F80BCC81F25560EBE5AC ++:151D1F00FC60B8F7AC522E5764B288801D328662CA263C7B40E5 ++:151D3400EFE5716FBFBD6E9B43460CD46BC85B2AE9C3EFCFDEF8 ++:151D4900463CCAD45386FAFE53BA5347E2792466821EE76BBC5A ++:151D5E007E9AFEBBD30AC626152EFBA6581F4D017FCCB87E3379 ++:151D7300190DE299C5D496A3CDCE71B94EEA8BEE159C0779F150 ++:151D8800175CBFD9704D0E374D4ED2CC99447594611CED7B66CF ++:151D9D00BC20EC191276F90A92B38F9B858F79A4FD745FC5B0E0 ++:151DB200CECFC7838E45FA63FCEC42DC5C8CEB03C0519C1C3729 ++:151DC70095E409D35D1A37704F7026E09B1B66862B42E9A1A492 ++:151DDC00B249D17AE90DEA2F8D33E9B4DF1B5382D9757098A279 ++:151DF1005FBBDB85BAB015CAAAF9790D9EAE8B3EC3FD620D515C ++:151E06008ECFCA06983B77BFC8D75A01ED4D727F017AC13E46AC ++:151E1B000EA37D1CE6F6715FC549DD3BD9773BC737A5F4B2C6FC ++:151E300031417B386E7AD1DF93E54591B8A9362678FF0E9103BC ++:151E4500BA05F2EA5E07F38DC5AD9BC51955E68A8C67FA3737FD ++:151E5A00341AB4BF15FA2AF33E8D9EF70E67F371F7817FE13540 ++:151E6F00253DEC2AF440B90AFA176971E2748978EADE9C3334E2 ++:151E8400A82741C648E549B18F20FD33E09DE08FC82DC8E5A33C ++:151E9900DAF762CE7E3DCCBDC806EC036BC7791A4A1EDE5B29A3 ++:151EAE00D681E683503E188EE96EAFD86B4B024DE78B4D3CA3AA ++:151EC3003E0BEB03EB458E0CDAB0C572EDD8CA6564CCAC833ABB ++:151ED8009B764E37B46F58CFFD6C1EC75F2BDB353ADAB5245FE1 ++:151EED00DD0B3F13CBA3EB798CC4C43831F605D7AA48C7E05399 ++:151F020071DD3729F704A1DCC6DB25E1FD5501BCBB1D78B7CB1C ++:151F1700763F71B4BB0BF0623BD3D12E2ADBF514A0EFAEE41B6C ++:151F2C0026CEB17E4EE3DF9B685FDC408B0AF43DCF65679CEF03 ++:151F4100430FFE13D04AC4397EB783D66E097BA000ADCC41C374 ++:151F56006ED9EE50015A871DEDF6C8762F7C0DAD38C636ADA5E6 ++:151F6B00DF406BA983D6A484DDB1613AAD5D1BB2347C2CDB6D89 ++:151F8000DB7095F1DC901D4FE52AE3A938F09EB7C7B300DEDD56 ++:151F95000EBC17ECF1BC0ADED68D38BF2690074C75E2C5FECA8E ++:151FAA00FB36B0DC96F935D0FE308967647E638990F92B2E21E2 ++:151FBF00F3A18D59DCE11281BB65E3D7E006BC3E89D7C6E77309 ++:151FD400F473A384D1561806C3396BEF7597E7EB3CD02FC75F90 ++:151FE900CAEA3B3E9FF95D0A4719B767784F8E7A9CA11FE92EF7 ++:151FFE00ED33F6815FAA826D53D79E32CAE909E32021739C3A1C ++:15201300E86FA05F85748FFD9DDF15D70F9BE33ACA8B88271E8C ++:15202800D0613DBC17D7BF77715859DBB01C6015815DC8E8D5B4 ++:15203D00D0B8EE5E17E73A95EB53DB5E98A84FE35C9FAA6D40B2 ++:152052003FE85197E33DA7BF9598AF31ACBB2A9881E7F178AE2F ++:152067008CB0F9D23625047E26F5697848F8946063455F46F90A ++:15207C00F9097E3E08ED52641CECD23B863B7682A26D2A684F28 ++:152091005ECEAE1F193FC7D46BF8319C8E7B15F2FFA5747A5E1E ++:1520A600FE5A52EC77F278BD359C02FDEA81B915AEA12CD41386 ++:1520BB00455DEC2E163A59917E7C293CA37F486772FF588AE7B0 ++:1520D000E79539F3C6944671EF4CABA31D5EF893DF0E6DC2F3A4 ++:1520E5001A9E5B3AC910CE83987F510BFF8167E877BB2A13EDD1 ++:1520FA00587F4368D4B821F40ECA8CD5CC7345C618C2C372FF1D ++:15210F00E6B895FDFF8EC1CBFE3A8E3E0BF1B38421BE7F076D69 ++:15212400BAAFC8DB631CFF324BD3608AFB4D0E9A12B4991C5B1C ++:15213900E9D75C011B37DEBDC3F34230FF1ADAFB6FFCC2CABCBE ++:15214E00AFFA228327B9F058535126EF07D6AB320F1BE92ABB9B ++:15216300310E7EFE10B3F819D31A3A07F87D3BB24315B044DB21 ++:152178003186FC07B368A9EAD330D6C7E19B414BD18E5BED0E8D ++:15218D00BF12D6DDE411AD64E5844BAE8B0BE05983BE4B41D8DD ++:1521A200555689FA16C09EA0840D594AEC94856704C4797E691E ++:1521B700BB51BF15CBF98B396DF25C0091759305FD19915B88C8 ++:1521CC0072746106D29560ED226798B9257D6E271D682B8B05AC ++:1521E1005C7F30415522CF2AA8C72CA443FD6889C56D51868E26 ++:1521F60014ED8A65E51BE11CBD4FC0194C09F8026E82F3A7EC3D ++:15220B00A33EE68235223F8347C6753C138F3EB0F82661619B93 ++:152220009C7900F03F8C65FD1FBBDF083F719FE89FC0339683D4 ++:15223500C7DE73C0B69C8F49C1C71B36F75AFE7082D7259C38A8 ++:15224A0033E7914354D0D24055CE975679875080BA653E202FCF ++:15225F000F8FB28717A1EFFA0ACF4773D2E07B7909738E1DB4DE ++:15227400B114F508C6FE992D27E80BE30D65CF935E9DDFD31477 ++:15228900A69C2FFCAC05D42BD05FD660525C841797F61AECC022 ++:15229E00ADC607FF96F690A911BEBEF7E118A96F1A8A768AF9BB ++:1522B30023E24E017B0D535E3C7D1DD5D37624735E3EB39E9A77 ++:1522C8003A66DD7EADEBA9F06B962D539847365C22D6BDB93243 ++:1522DD002564086919967CE163128C7179E2EB5958C7A33D4393 ++:1522F200794219E0BC32C51AFEA5AF44AE52A1F504CF1B0EC06E ++:15230700DC6717E83C7FA01DF767BCDA92FAF7D19EC23AFC1118 ++:15231C00EDD6E0659893CB93BE55DC36DE2FF37DEEC74B4F0E1C ++:1523310070B9E3F960A2DCC2F2F7E4FA3622DB46F3DACA720B9E ++:15234600CBEDF3B836FC5EF9CD60DE37B2DCC2F22E09BF5FB607 ++:15235B008DE5B595E51696DBEBD4C512FE6AD916DBE1FB028718 ++:15237000BE6975D4E13B9E6DC2334D6E90A362B0558A36622134 ++:15238500BF1475BF81E31DD046F19EA9B9734343CD0AAC57CB16 ++:15239A007A2E18A5DA116BBEF94993BFE55343891CB75E8E95C9 ++:1523AF006C72C39A0BECF1BC9991192B95C805CB96D999A0DB1C ++:1523C4009257709F2E3B077E0A3652E1E746D8B4F928E757464D ++:1523D900AF200CF5E08831583CAA236D73375759F67CE632C014 ++:1523EE00CFE58EF3BB8BF8592FA147ACFCF92CF2400127CC19EB ++:15240300E73C796A76AF91F8ADD84754A54EFBA679F27480DF1E ++:152418008D23E6C8C008CF89518BB3F98F8B31F7007C8D07F85F ++:15242D00DE7E36AEB50EE4CD67CBCDFF36BEE9984FAD45FF072C ++:152442003A3ACF9F086B23ACC4DBC7F9F912C06BFAD4E10B5CB6 ++:15245700CCB3BB400BB611FB20A6C5F7472AC7DA4B0EC68D21C8 ++:15246C009015B5294E93220662B9C57E29BF37096D33D66BB0B8 ++:152481006E4FA17D97F0307EAB4716B1622FDE75D743272F66C3 ++:1524960071AB05FC107704F0F23D0AD3C2F11A02BBAF4E8CD0AA ++:1524AB00CB12278E6F0E4EA877E7E1CCED7F75FB4607FE900352 ++:1524C000BF5600BFE2C0BFA000FEAA6BC48FFE456F6380DAB4A9 ++:1524D500200D139F081A1600AE7CFCEAC4118E4B8B8CC0DA3C30 ++:1524EA00D10E6B6F0B7D1F45E377CACC5B101961CF83DF833679 ++:1524FF00ED92D3CFC1589F5A65F5B65103EF74BBF46455338FA4 ++:152514002756DFB4B4AA6D6B50FB6143E366ED9EBF587FB7B6A6 ++:15252900E127BBBA3B1FDDA5ADEFDCDED9B1AB33A8B56CB9679D ++:15253E00C7CECE8D5D3B7EFCA3AEEE2DF5CB6E5B16D0AA1FD909 ++:15255300D5B56DE7CE1D8F6DE978BC235457D75877DBD23F5BD6 ++:15256800AE3DBC6D7BE72E2DD0585BD750DB7807BC04EB03C11A ++:15257D00FADBB4AA4CFCCCC6575BBBB533BAA3BBF6A11D8F4646 ++:152592006B3BB67644773D51FB68C7B6C76A77ED7CA8B6735700 ++:1525A700B4F6E1276A3B3AB6F3B2ED3B764497EDBAA96E857601 ++:1525BC00ABD6B9755BB7B6B5F3E18E1F6FEFD61EEAEA78EC478C ++:1525D1009D5AF5EEEECEDDDD4B11CBB783BF75E7B6C73B77D624 ++:1525E6003E0CDDDAD2D1FDE896AD3B1F5FF6D04D2B1AAE063F10 ++:1525FB00039E9F6799E30FB7EFC77D42B58ACEF537B4576BF5C9 ++:152610006C199EE5B1F3F423CACA85FA05E350E870B4880CD334 ++:15262500F63FA63379FAEDDABDD67FFECEB552517F6054692D59 ++:15263A00B40AE6DE39D0253E78BE85BA539ECBEEFA22ED797785 ++:15264F009112DCA81D613550379F8C3787B401C6EBC3CAD30165 ++:1526640028437DD3E428C3762AD8408069F56BA5AB6C9B500E21 ++:15267900BA710611BE04FEBF02B0F7A9CF44D14F1CFE657A16F7 ++:15268E00D2E5CC6B77E6B4C72E8B585C1F6F5F4DBBA03D513FA2 ++:1526A300B77CF0CD04E68D39F0B328E1676797B9C85CA40FE9F8 ++:1526B800F069C718F66106AC53317F8E4C2DC538ACCFDF72AB4E ++:1526CD00817DC77B164BFEA1D1C02B54AA0096D8AF3A44C3DAC6 ++:1526E2000BB4FE6DC00DFE940FBEB7F1E0391EBCB301CA2C2721 ++:1526F700CE35E934C7C9EF6D04FFEA783A3DA732E2127B6AE153 ++:15270C00017A1DD80584997C0BF3660350F60AA7AB04ECE521AB ++:152721007E6FC47EDC972BB3C7CD3E6311FB038EDDE77CEC30F5 ++:152736007EA36930EFD4BE845B5B6195B41C85F13EC061E33C5F ++:15274B00C43958AABD6CD57CE56ACAFAAB620C6C7E3BC7C1F730 ++:152760004EDAFD75F5574EA66739C703E951811E9F63BCA211D6 ++:15277500378D257F65A920875A722431D7BF1BDA76515F7211DD ++:15278A009B9D2CDEB43AB914E435DA8E776AE01D89782F0E0997 ++:15279F00DF4DDF55709DA453F465947F79D0C07B36D662FC4621 ++:1527B400C533BB61EE8B0E9ACBF5D74275ABD66845ABDE2F396E ++:1527C9004FFDA15BF83E63EFEBE959975C765ED6009B9133FE04 ++:1527DE006B29DE5D89EDDAA1DD19D92E906C01B8ADD66A11DF97 ++:1527F30048F03B29E5B326B2860EF0BC9145D485F77F014FC4CC ++:152808009D94B9CFBD2E71278EB8E76B047CE95AFD52B180EFB5 ++:15281D00A523C603DAECE05C6D76DDEB8BCA82D6E21B83A7B1E3 ++:152832000EE3BAE3E9598B355790D3A90E50DC8376C3BC3C0DA3 ++:15284700F320137F9B7A45D8E7A957AC9F5754EB7CBF1874E630 ++:15285C00A0840FDFF3BDD47E8065B7B5DB6D873607DBF0BEB4B9 ++:1528710012DE07DCDFCDC7A57F21E6512B7CCFE358324E77F2F6 ++:1528860028C233D982D251C3F7DF87190A4E6B12CF389FE7E720 ++:15289B00A9ACD0ABFA10C09D5F5A632C07BEE2D9D81A729EF631 ++:1528B00086DE88624C2D896B83B6A5860563751DC84EC99E710C ++:1528C5008AB90441DCFF507F21C646CE65F4A915BE2ED380AECD ++:1528DA00503BA75FFD85357129ED395A24FA79178C75538131D3 ++:1528EF00857575597E9F7A2FA5790E09C2D92EBF9F0F73AE6456 ++:15290400CA34F0BEBA2258A784928729FD4DDA637F8B730575F3 ++:15291900E284E43BC66F911701E083DD6618EAF83B7B864652D2 ++:15292E006911EF8436A54773798F325888569CC7E5C91EE6FB92 ++:152943004CF0FC83BFCDFD6E02F98F72CE75C37E6AF37A1078EE ++:15295800DD9A1CB1265E933E80B3DFB83724FB4D7F2FFA8D63CC ++:15296D008FF0A200AF468E1997CD51219B788ED6D576B71186B2 ++:15298200FA9B6DF9936321F89885D1F07B416B1464E2E3D78499 ++:152997004CCC2FAD37FC23AEA02D1B78CC3B2AE2B952364EE849 ++:1529AC00E8DF2D262756A15CF81A135C1E2C73B1EE1E386228C5 ++:1529C100A073174B3910FB02B9E37E12F8EC575F0199EFA15EF8 ++:1529D600900B5F4F9D91BA28F96DCF07C737181B2FC4EF6538A7 ++:1529EB00DFA13DE7793E1E984F9837649F7FB9CE211BDD201B4B ++:152A0000D13342365C781796940DCC8343DEF01C07CCEB782D44 ++:152A15003B7E086F76B8CBD0FFFD2FEB41C759D5C936AB2AD9BA ++:152A2A0062819EB3400FB202F909FC5E665CEF946A553CC61AE4 ++:152A3F002BB00F06FA9BCEF00E1891728C1B8DB5A3DFE6F28C47 ++:152A540018B89FA6CB73D6E8833FC0F79712FCAC18DFFF8275A5 ++:152A69003B9E0FFB79C54958ABC6F95E981AEBB3300F7275EC6C ++:152A7E0014F7FFCC581C65729EAAF559ABB553168367191B3372 ++:152A93004E6BA29E2C8AD38FAFE21FBAC984E723A5B9F8B1A2B3 ++:152AA800CF5D3F73FD4F7B4F1B1DC575DD9BD5AC342B0D627676 ++:152ABD00D95D495848232C12C9519C5DB1C8922CC242A88FEC13 ++:152AD20010654B9D744612F63AB603B19D84B634C7E784C42B00 ++:152AE7005889058FF03015F65A266695480E6E209539909014D9 ++:152AFC0092A5761C9152B2E1381C9AA4F638716C9AB8B6EC6293 ++:152B110087A436DB7BEFCCAC56027F25ED39FDD13367CECCFB72 ++:152B2600BEEFDEF7EEBBEFBDFBEEBB95BB86F37317D82FD98F5D ++:152B3B00D9F7D9636C823DC40CB69D6D619BD917D84676275BBC ++:152B5000CF6E6537B33EA6B04FB0B5ECE3EC63ECA3AC9B5DC784 ++:152B650056B3556C255BC196C38CB29375B076D6C696B1085B45 ++:152B7A00CA5A599885D887D8D5EC83AC059E0FB0AB58333C4D64 ++:152B8F00ECFDF0BC8F2D81A7119E2BE1590C4F033C323CF5F4B3 ++:152BA400D4C1B3889E5A7AAEA067A1FDD4D0536D3F558527687B ++:152BB9003F81C2E32F7A16143DBE598F77CE235DF2CCBFE4A91D ++:152BCE00BCEC33EF2D1FF16D9F8A777CCADFF5E379C747C0C3D7 ++:152BE300535AF6BB963D6099CEB280EC52D7DE1F63F241F46BAC ++:152BF800043FDDFE6F82FF9CFDDF02FF1207FFC863EA9A207EDC ++:152C0D0054D359B7968349B2C4299A242F3E28C5E1CDC06B2E5B ++:152C22003E487602C97E6C13D9BE9365DBCF63FB71E017B7FD26 ++:152C3700CA6D3F17F8656CBF0ADBAF04FC303F2893CE264A2C4B ++:152C4C0016B2F342BDE2909D07EA1187ECB4A8371C8234310E91 ++:152C6100F768656DE3B751D0BA4A83D9F6A81BE41AF48BD1B952 ++:152C7600FFB0EECB70ADC25433F081865161AA83EC1B26DE2674 ++:152C8B006CF26DC2C81E0B84554218F81BE8CF9FE850A9EC5CF1 ++:152CA000B3E1E0CEC139D62367C3983B4234D1659A8787749C89 ++:152CB500F731AC27A509F5237E118792CB8A3F99B5C3813776CE ++:152CCA00C98B0DDDC9E7B8E51F837831E49BD262831740067A12 ++:152CDF008B6F8C9B89932BFA975C33FFBAED4FF8CFE6E7A36DBF ++:152CF40009EB3CB7AC4D93FD5BD9D2E720DD4999743D4AED7F28 ++:152D09003A37EB82B686F66043EDC03B5D2CE96A37CA609ECA75 ++:152D1E00473BD4E9860E5A9F9BFEBE7B19E204DDB8469A857495 ++:152D3300226B471D6CA30570018C5613E456A38C5D05B05F65E1 ++:152D4800B883D1FEDC65FC24CEF263F2AB06F2DAA6B96B14217A ++:152D5D0059273F6CDFF0BD49E65A79A099941868E571BE2C35E6 ++:152D7200A03D4A18CFC35064BBDE42EB5061834908974CB0C425 ++:152D87005CD55046B38EE5F353D5AA94688EE0574834B7E23778 ++:152D9C008675CD8548A6C6B8D48ED15E6528A425A84FB46B511B ++:152DB100D26D8AA27F3C3FBF1BE2C4C88E24CAD0D659D8B8163F ++:152DC600A573001BAC33B1A18D961E14BBDBBE272065EB48E02C ++:152DDB003AEF7C002A09F397A4AEB3A482FB3DE87E7505BF8CF3 ++:152DF000E5B6E8A2CCB7B2D856FD3CD62B27EB96DD5C4B6FAAC7 ++:152E0500C52C69A53C213F5A57C2FFD8889EAA49281CD9F31C8E ++:152E1A00310A7A20B11FA4B17EB5F2FD3A2F9F30989E84791408 ++:152E2F00BFEC9B377F13F27F328DFEE8D7027EA373FCAAC16F26 ++:152E4400688EDFA6150097F47CFA7337BF1006815913E5A7F5FB ++:152E5900BBD99456BBF205B5B7FE99F043EDE7ECB316093A3FF3 ++:152E6E00BC287106EF0EA075B3452B4FA97C665C77C1B828CBA6 ++:152E8300DF4A33FDBC21A44668AE836B6D4276775B10E7515087 ++:152E98000ED3BF615CC1BDA0221ECAD933E1C99B5F6A031880EB ++:152EAD00A64F035CA7744EDBA93EB4EE79ED8AA806ED68A70154 ++:152EC200384B5C5CB13A2C6C87F2625B27D9BE52B42D3E2908A7 ++:152ED70068EB74DBA8D0FD02F83F306AB9BF6EBBBF3D3A95CFC1 ++:152EEC00073217E75CF311FB693AE99AD2116F77B3AC96F85E05 ++:152F010069EB97BF5CDA8AFA10A3B9879485A71F504A4E3DA5BB ++:152F16005EC7CE8417668FA964672DA4DB76067354D780F4F77E ++:152F2B00EAF95B9E3616724F42F81943481C68C3392CE63D7D7E ++:152F4000CB295DC894B61EBAA77419CA26C447A4B18349570694 ++:152F5500E87C58C7BAFC61EF6024781CF2967EAD617D24843B52 ++:152F6A00F6F8A4807B23D2B68312C1FFC383CF431F2C978753B1 ++:152F7F0068DBBA4C1E4CEC4A680AD7A3411FFDA98E3657E38FD5 ++:152F940031769F80FB095A6ABAE13503E2EE78496E591683F8DE ++:152FA9009BE3AB5B518EA1BE251DD0F9CC578047BA5BE3D9FD8E ++:152FBE00AD4C3FAC4F63DB8370EC3F6BC19FCF1C80F63348B612 ++:152FD300299A6CDB31D4D7F461B20BDF44FD0C64DBCC30F4B3E3 ++:152FE80084C6036D25A645F02B30AD15BFB85F266476431E596D ++:152FFD00B2C55A9D49EA9C00380A65C9862AB643EC1FFBA6308D ++:153012006CDC88A1CC9D491A572534F2CF803FBA512E9C6ED029 ++:153027007431CEB77A4176C47E32DD306E2C0C66FA8F5E742F22 ++:15303C00035C1A536FE40509E0E98232CE60BF0AA5B52CF0E088 ++:153051002EC89765F6184F15CEF7A47411301002E09E1FD42243 ++:153066004C3F9EA67929F0B3EDD153CAE9DB4B5BD36C504927FD ++:15307B00762B171BF965E9E8B052951C51776DD5945D1D6749C3 ++:15309000B694CCFBD39D4BEAAEA13DA3506212D762BD8B92B8B7 ++:1530A50027A8D766A84ED69AB680F67513B466DDCEA32CFDBCA3 ++:1530BA00CE75A38EE113C6AEACA6E07AA190D903E9B6219E69A5 ++:1530CF006FAFDABCDFA8351F369A0037B550D75C298805108ECA ++:1530E400FDB349DE46B63C280F49439B4E42B57C9F4E36F7D6B9 ++:1530F900691AA4D39137F0F1437AC4FC1EC4DD66A00D4E616AB7 ++:15310E008F8A79BA4E4E908E5AEC71C66A70BF3F74846C05F0F8 ++:153123003D432AD469D4D5B3534D95B1D9FD23876BFB29ED8BE7 ++:15313800FFC6FFF0618EE8427B1E7EF311D203A45B7670CD1FF4 ++:15314D00FD5892F4B5B0CED6FE478AF63F8CEC88526D0EA543D0 ++:15316200E6231969A5A60AD76B6AC91A4DE565CD1005DCD3DEE3 ++:15317700A3354577B7E1B9B1C000B41F98B75627D07DD808DA47 ++:15318C006E3CD36EF1FDDD86DF145BD18FEC8D16F643D2B4E610 ++:1531A100EF42DCE446F446A28375C69963FB34D4CBB6CE365B69 ++:1531B6007720FC02F2E2D6A0CE5E86E8C7A50EA8C14583C60317 ++:1531CB0051EB5C2CAE9DBB7A2CDBCB3716D921E03EAA912D62AA ++:1531E0000969AB7FED20D93284FAE33A346F022FCB9D277C7B31 ++:1531F5004DBE57A4B9439AF6195CA46B6ADDB101F35C03ED4235 ++:15320A0021BC9CF945ADC95C102EE6F1C8DB918EC4DF0BBC1DC8 ++:15321F00F8FC86D25EBFF9BA4176DBFE11DBE190B1E5CD7CA012 ++:15323400E54DECBB162D10D77E73A7EED246546FA7B5D7EF02FD ++:153249001E81F7CB886C64A9086D65211B09231DB5A236AA591F ++:15325E00F4D2D3A4F375AE9FDA18D00FDD3CB3F45F5336DD9182 ++:15327300CE9806DD48D7B934251AD8F478271CBF5B5AFD4FD299 ++:15328800A29C6891B6F7796668F28EB4281A6B1D3AE8DF477B45 ++:15329D005995A1629AF8E2EF0F93DDEDD8C0E4857BDEDF26C538 ++:1532B200CB605C1DD0D1B636F2AECD5F2C6D9DFA2F871F59FCB0 ++:1532C700A31A68E65BA4191CF04DA421D6D5DAF3B1CAC0F230DC ++:1532DC00EFC2B9A882BC64D1A5A688269B099E94657705C27175 ++:1532F1005F5132771A9C9CA4F6846EA5C8BE40A4287DE4930561 ++:153306007D5FD2134EB309D2DB6C42DA0F4C28A2EC26DE1C225F ++:15331B003D404DAF895ABCA8D00FA1CEDC061C8FE17BFD29C2BE ++:1533300001F45B7FEA0F567DCD39D76CA18DFBEA60AABF06645E ++:153345000199650E8658F660949907AB7F9BF7C07712DC93E0AA ++:15335A003FD96DA77FABF8CAB9D9F1ABEDF838AEEF7FBDA84C2E ++:15336F00D4C780F947715AB2CF45771668FAC57BF8655DB87E3E ++:153384002E1F4DDC37754C2985E9062F8FA4D04E49B9FC448ADD ++:15339900EC86D37E5096CE544AF22198B72475D15CD27AE3FDB6 ++:1533AE00790FE2417B30EF999B67316CA4770869BBE407F5F373 ++:1533C300CF6A2023E96403C56A877F6750DBB56CAD4CEF0279DE ++:1533D800B115E4A2F7D236A79F1DD193AE94CEF6F1BDD3CF6A0E ++:1533ED0046D29536BAE45DC6EB17B17F24ECB9C980F11CCA42CA ++:15340200407FDC5F95A18C629C5C787A363E717FD796672D5DEB ++:15341700687D8F8EB23307FD0BEB086E63F5DF82BC188A914D54 ++:15342C0074279FEC8F67F2697C2D2FD4E2D9A16035C8F103FAC1 ++:153441004928F36E16D798194AE3BA986836E9A5C7C3EAB7121E ++:15345600CDE1C1F6F659B26519C375E276EAF765DCADC067AE49 ++:15346B00D765339666D22B862034A8B8D66CC9958BDBCA61EE8B ++:15348000E2AA53A80CB4878769DC0361B5321A8E944399FBEB54 ++:15349500AF6DAB3565181B9BF46A33A47362A73AF895B0E6CE17 ++:1534AA00C23C31D76E387788A0EE07B374D041DE6C0CF3B8563E ++:1534BF001DFBD424D36F191552B87FF857F43557B896CDACFF5A ++:1534D40057DB7A174D363F0B013F6B5750AEF7C95C88E62A504F ++:1534E9000FDEB11D937B64B226BB47ADB1EF6FF0C3388DE3317F ++:1534FE00CB7DC7F072CFA9AD0D95D7B0BAA97EC6CE6912FB759A ++:153513009B9F7B59DD29BB5B51560C01AFACE526D440F048BF54 ++:1535280010FDF5D25AF8BA4EED26BBF4C827AB56A26EC011FBD2 ++:15353D00BEA1843605E3BE2F7158F5D682DC52B0CFFCCE6F157A ++:15355200C8E6F84DAF288BF8E2653067F98ECECC470E8E83CCE6 ++:15356700556BDEAF23EFC276817BD85E18AF9FAA19591A05598C ++:15357C0007C7A14FB875926FFEE9412DECC8346FBC997F4B99EA ++:1535910026FDFBFC5BCA34ED6F25D3C45ED04CE77C39F21CC0B6 ++:1535A60095D0707B5B39E93423DE8EB5F98FFF07E47F4C5B0B28 ++:1535BB00B87BA05D776C76109E828943053C05CD2561E11CEEF2 ++:1535D000296D99E44F1C437E1D5C68CE0B835BF79901FA969B53 ++:1535E5008BE8AB035FBF5CFD619C8DB8BA5F564F5EC80B880779 ++:1535FA00AC6B8B5D7766D7BDF63275C734E90BEFBDFE8B80EE1D ++:15360F00D5C85763BBD2B1D7E7CC6FA08E747744113D5B8AE3A5 ++:15362400C476EB37B0B47623C8F0CF3F35B254968F4F0297D654 ++:153639007C1C8CB7D219C36FB74B1EF505A49F1B77B3B39A97FE ++:15364E007B91EE4FB862E5CB6A28FBBDC8151D163EAF602F502E ++:15366300DBC3FE7A05CE67426709A7D8E6703D17D784EB4C771E ++:15367800AB13A7EAF8D305BC57415A491E48272A92BD18F72EE4 ++:15368D005CB28D1D4AA32E4AC9D4310C1B759D3CA6EA799847E0 ++:1536A2004178937C7B1B7E119EF32BCA966DBAF91990177FAEFD ++:1536B7000BF263A32DF2BF1AD5E7ED3AC6862645D437CBACD512 ++:1536CC00AC7F9C4B0D4D9E5B61A53F0278F3DB795D58B1BEED6D ++:1536E1006AF6F5569A0B15C5C5B49847713AB4F7BEE5DE334AFE ++:1536F60048FECBA5E88FE32588D21FC7FF0771CC8C0D65503E7B ++:15370B00C5B4E5A8630FB8C4F361B5BBBE4A785D28838C60E796 ++:153720005F39EBBF2AECB2FED3E5F2FC307C7557A525B763FE8C ++:15373500AE8777A83437FA21F00A90BB8CE8238A144DAAD5302F ++:15374A0096D079BD7761A31F5F1863525C6AAD8AFB984CDA4A08 ++:15375F00E3901480F1C41E87684CC2B0F7301E3963913D2E5D94 ++:15377400763CC2B108C7A408D9F4288C291A3B618D29563932C9 ++:15378900AB965F3116A06C01E394206F37BA5FCD0BE5192D5589 ++:15379E000E7047A2C956677E580DE31AC6697AD5A1F7A05EDB5A ++:1537B3006ACD2B733FA0701DC343801F4CCF32CFE97417484EF5 ++:1537C8008379654A2BCD24133E2847CA1C4A639F2B318F699847 ++:1537DD0027B6356C734DF2B3A3D8A6CEBEE1C86B36CC00EBA1A5 ++:1537F2005D5F813E3CA0D37959B439FA5D6B5CDDF3CA4CFFF2E4 ++:1538070006ADF32F82BD5F3659C53C208B7AF62DB0DC719E794D ++:15381C0036BB98670A5E4BCE6EB27993A523E2C6BB03FCCE58AA ++:1538310098D136039EFCC73BD45520CFBA07C6D491DC98522753 ++:15384600BB3B17CA1FFC30AE9D511AA9592D9C178D3540BBE016 ++:15385B0086F87883EE96701D8E1B7A716F73849D1FD0CC1378F1 ++:15387000B9D15C797276F9AB12CD4BFFA4722ED1BF09F53756D0 ++:15388500B10A495AACA2BE2DEE75476A58855BFA06E9475E9528 ++:15389A0079B30B75A7825F0AA3AC4B3A51645F00CFE5423CA71A ++:1538AF003CF4EF02F78CCD6E9AEB94E3BEF81341B47DD3D4FF48 ++:1538C4004610F36D253D9F5C35AB10E363C05797A8EF93B98E87 ++:1538D90052482FC61B8C0BE0CF7F6940B7F412F921679DC02DFA ++:1538EE006D517F0161685F6F04E340BD704F4F46DD29F0E3E3FC ++:1539030063C651F487FF17618E7ED64E877B5BCF813F7EC78161 ++:15391800C6783EF0A8CB3A53398234F74FA31D4656B60FEDE209 ++:15392D00BDAC49A71F5450AFB51AE737D2214D100FA83D40DB6E ++:153942000532DF5B66EE21BB48B5C00B8326C61FDEC26D1FA1AC ++:15395700FBE170AE7355A66BA9245A672FD0F6C97CCA736254CD ++:15396C0080388215C75F9DE19772FB2E4DCB6265A4EFAA03DE24 ++:153981002201EB4C23EAB7A0DD41DCCF37C18F49C9C2FE1A2F08 ++:153996009F37EE02BAF1801711FA66BCCABEA3720E7D437141CA ++:1539AB008B9B3F3CC83F3DA0BEE177F2AD2DE49BB2F38DDBB65E ++:1539C000677700AF385A86B695E47E964B18B4FE2E4534AEAEF2 ++:1539D500BD9F379B0CC1443FA095D94EE5579BD306CA4392991B ++:1539EA00813CE3FDB82EB9A3668342BCAA6E637FAD8967CCCFD0 ++:1539FF00F6F3F2678DA341AB7D34429A263337DA02E923905F61 ++:153A1400D702E609417A0BB63F4B236C68A77415CAA076FB725B ++:153A2900D545FBA3E6EF8C1D3531254A792AFD317043FC83ABCF ++:153A3E00E11B87BC4B614E70A3B9D7889A0FA4BB4D7D34065FA4 ++:153A5300DCD38BC17F16C215282BE7B36DF1B20CE1009015D890 ++:153A6800519351FACD8C711BE41B07D8FCD85E01572DF015E0BB ++:153A7D008B362E6508AF85FFD590871FBE8D3077DB00FFE716D1 ++:153A920060DB065C815F37F8F1C06F9E02BF50D0A2477C8E4D94 ++:153AA7005FF7D30915DA5D854FE6979714D18B4378E47103D74A ++:153ABC00A042F2B826E0FFE5F4E5E83C48448BB958C5D5995BCC ++:153AD10022D86F4A3B642D4B3A81CD7A359E6991068C52DA2366 ++:153AE600E6869C3C3250667D7A8CCE0570350975C67E4B14E2A1 ++:153AFB00453406F90D215EFC4D05DEA69CC231AD5945BBE28BDE ++:153B1000E5DEA56CD32B8353CF32E6E4C3360D68999FD8FB05AF ++:153B25009BC63413FE51074328C0D3A12FC47105C39EB5F48CEF ++:153B3A005B1CFE047ED99FA0AEDEB2E502C00A3207C1EDD09B26 ++:153B4F00492097DBE9826CF972B6A983F277F46D310DE45551D0 ++:153B6400C9BA280CF32A0B5E8A2FECDF7E6E461F5EC2BB96FCCD ++:153B7900FB0A75ECFA31D6F1807A030C0DD29726F4F88F11604E ++:153B8E00B44D64ADF7EBE0CEC03B096F16DE1CBC26BCD3787B99 ++:153BA300758E0CAD3119DE50CE8ACB360D5A75B574E6C9CD7E81 ++:153BB80039DB2DCF7147E7B8E373DC8939EECC1C77768EDB9CD5 ++:153BCD00E366BF9A53FEAF8A74FA013FDDDC6CFB0393483BFFD1 ++:153BE20064C16E531CEA161838AC56D2D9503B1F9873E3DCFA61 ++:153BF70086F8BA48E0D8849ECE219D66F03605EEB3F09E83F799 ++:153C0C0002BC02D0A71ADE2678DBE1ED86578177C34FACB8ECF6 ++:153C2100D004E12DE3D01FDC8837BDC88D784B14B9116F1B8B77 ++:153C3600DC88B778911BF1162B7223DEA2456EC45BA8C88D78AC ++:153C4B00938BCBFFD58C5D442A1FDC818E8C816D1BF54BF97BFD ++:153C6000D65DEB9C6B279C5DCE3E03E0576445F89D1BE74F0C29 ++:153C750047DE7314E417908DF427E6310FEA1AC29CBA33CD31E8 ++:153C8A008F00FFC0673A451823CBE545D73C05E3622DFC231DFB ++:153C9F0079699B7A971778D67C5671076BEC8CCEB778DA4DF0DC ++:153CB4001F996FF1B23AD6B8DCD11B91D1CE2F8CF93AE48138E6 ++:153CC9009BAE84F11BD29FAB44D9E1D1193B0A20EF9DA91F80D0 ++:153CDE0071793FCA08FAF40AF7F227208EECBDFCF8E48C73B8E8 ++:153CF3009789E311A0D1531C4F8472B7DA67BC41DE597E16F2D1 ++:153D0800F290FC3E9B8FD502BC9B251C0F51BED8AEEF88E3B99A ++:153D1D009E47F52DD1FD547FCF87DCBD92DCAC23CF6F03B4794F ++:153D320057EEC6B5306DE33C5CCF1FD399FEA81E80B97B271B90 ++:153D4700A4F8839E0985AB6987B175CCC07B8078905BC9B66F83 ++:153D5C006C587B6A3E8E637ABFE44D511E47459021218D203F57 ++:153D7100AAF330167B2A715D6ECC401B0688E746C9923F10D617 ++:153D86009C385BBEDB378F553C01F965E6E138D3A827696C6ACA ++:153D9B00A2B109CF137235213A9F7EF662DE539E18E874C79ABA ++:153DB00054596ED05F5CC12DBF0BD24CCDB76422070F3E5B5772 ++:153DC5006B66FD43D6A7A7914F6D25BB6B98BF74FA030A9ED3D9 ++:153DDA0040987DD1B1A53CC82A3CE4390D79F6824C85E7407863 ++:153DEF00D265A57138407607A62D9BA17C7CC21065EBFED03C4A ++:153E0400E9413FAA0580E7F3F26306C6AF043E4AF7A59780FC2C ++:153E19008C770C16DDDF721EF2F8511CDA5E1C6D16587691BFD7 ++:153E2E00CBC63A4570E33883B88C9633CFEBD0665F65039D0EF2 ++:153E4300EC164EF6116FC23CE8CC045BD2E9C07D1EE046FD401A ++:153E5800A04305DAF9C0B6C1A3DED985BCC7B1FB5D5CA7605144 ++:153E6D009D9CF106EB45FBBCC0EF102E777618E039AA511DA462 ++:153E8200319C7340BDB7CFD89D8D0F68231EE6B9016075D27CEB ++:153E9700383AD8897BD4FF7CE0E7FB45B9C50890AEA70A7D760A ++:153EAC00B5E1C0CECBFB691E86FF38C64B368ED6D8703A7A6FBD ++:153EC100362E03B8BFD60261BE38BFDC5F32D337244FA36ADD4C ++:153ED600E39AA6F28CE3E3CB5924827BD6796BEF219FFFF2F1E0 ++:153EEB0008F82575BC5BC09BBB57F59EBE56918EAF54EB645735 ++:153F000017E9B4E6B6A30E89C7533C6EDA70B6B225342E4F0ACC ++:153F1500CCF334D4F167D0F6D8A6AF525E185F405E1F19A77B66 ++:153F2A000BE8FC47570B9D7B00395CFF6662AC13CF44207E1FE7 ++:153F3F00887374AF9C8D779FCF747756A1BC6E1ED3CFDFFC9DFD ++:153F5400E53F0337D69937272EDFDE0047567BB3DA8F681ED6B2 ++:153F6900779BEEDE60D7049587FDCCA2A74C3875F835DFB5043E ++:153F7E00F729315CAFCB8E459CFAC6B8D9ED12F5122EC6B94E46 ++:153F930084DBC1DB4BD971E201621C78825DCECF208F775BA70C ++:153FA8003AD3BD3C543EBB2D76BF9EF7AC063A8AF1A2BAC88FA0 ++:153FBD00E9A87F56A80BCC61ACFA3715EA8270F05D1FA4BA1001 ++:153FD2009EE2636F8927B7D4A8DAEB1E79ACAF707C17E9FAE127 ++:153FE700DC688FCBE6138003E0E99E82CDF1DC8076F2BF1C7DE8 ++:153FFC00CB16AA13EACF3A696F837448EF34A429E63377BF6960 ++:15401100B55751DEAFCBF171ED73D18930968D6D51DA7CD43A54 ++:1540260057969B80F9C2A041F6E1A72D5EEEF415DE3C60489E81 ++:15403B0009D50B3CF77E985B8926F215CDAEFF9199FA43BBA8E9 ++:15405000EA3A46F5AF02BAD9F42D8C21E5C8EFA83F68AA6507E9 ++:15406500DCEA0F17D1164AE4D0ACFEF09BEC21B28F82386BBD10 ++:15407A00C53AEF8DE53CCC863BA12D5BFDA46BD06AC700EB5097 ++:15408F0002CF30EBFDBBC9B6F9B139F4D62D7AD71F5D6E805B09 ++:1540A4008C8F17D1F5908E6966E83A6ED72B45F5429EE3ED1A8C ++:1540B900A63A2DCCF0CBB1ED3BB42CB45FF0E333686B3FA90FC2 ++:1540CE0041FFB3ECEC5BF5F802B44FA72DFAD8D1CE4A281F618E ++:1540E300B900B02C84B677A86C76DB3BF99FD0EEE422F8E200AC ++:1540F8005FBC083ED981CFE24B84CFAE4182AF982F4C4F5B7B51 ++:15410D00C8F8E5E3D69DB37A34B9B1B268CC49FCDE694B85B9DC ++:15412200AB8F454608B768CB223D9DAF28B43D906D7E81BADD7A ++:154137005FE5AF95E2D6FCDB17DDAF3E0969020D7CAFF7745A0A ++:15414C007171CCBB00C3728774E97446E1610E7E10609570CC13 ++:1541610081F683EB92828072A7A6058347FA65909112F78EF437 ++:154176006E41FFD4EF90876F114E1EA37DF073F5C3CB58EEA8CC ++:15418B006E84B85ECCA72E398C36C1FC5578BF10F827613ECE96 ++:1541A000A4618387FC708F93DC502E4F7B2AC306A5C3B2F461E7 ++:1541B500D4175D5097E13B07AC345B1230A7C77511618DA6D2CC ++:1541CA00FDBCA87364CFE91156CC7F6BB7A694F49C5713F9BC33 ++:1541DF006FE4239A8275E6214D5DF2C03A841FC74E840561C3C2 ++:1541F4003D8476802170FA88521587BA9EF88AEA631AF0F08C51 ++:15420900F22D1C17EC3CD1FE3CC8C03E4CE7D47D08F24FED3C5F ++:15421E004CF7FE627BA1B8B1435B84EDBF534D840DEA8475C1C0 ++:154233007B41912E8807A61FD3109F6DA83600E10E2ECE16F0E9 ++:15424800609555C003AEBFE62C3C04BFCF77A67A70AF79421B7B ++:15425D0000FF11EC2F8013F4C3B50D1C832D788F010E0E289865 ++:154272007F49CF6BEA66C2C301C50BF5431C48782E05F74EF013 ++:15428700CE0D280B6DDA86A0FCBAE0B97EC75EAD65DF04E6FFDB ++:15429C00AF30B6A326A5BCCACE698B42ECD38D32FF61C79E62DB ++:1542B100EE9364AF96ECCE74D31AC19251EB6C608AD245CD6D7D ++:1542C6001AB46D0F7C711FCDC8BD36D3CEF13C18AE55611B6D33 ++:1542DB00C1B934EA1E86DA35F61AE9B58DC2989B4D34B97B3965 ++:1542F00021A2F289B0BA0760AD5726F19E385D977777D1FC14F6 ++:15430500E248C03B44F9639D82FCD94E49FEC4723E26E3789DC3 ++:15431A007D0EE461FCF6E35C2AF628D9BC0D74C886953FCA8CB7 ++:15432F0063D91084B540FA2648DF08E9D1AF56FE44A79307B46F ++:15434400A74E11C205087F6EC567293F91E666AF6C71E26CC493 ++:154359007200267FC7B495B76EC18D388A60DF00385BE467BB1B ++:15436E00F88E901183705C2FE882F934970AAB5202F7D2ACF8F1 ++:15438300981FB481000FF9603CD2E77E0DCF015AF769601F6EDA ++:1543980067F6FC1ADBBC346E97B3AF1F6D3254D3D97DCB0FE76F ++:1543AD004CE8876D2260E9B05F325FE2388B9E057FC8BFD6990B ++:1543C200FF901E1F944F7704650CF3B54BE75CD6D9C17D3A8668 ++:1543D70021FF015E6B95057102B9AFA9FED35F53505EF5771D0F ++:1543EC00B2EEE580303FCEFDD9611CDFB58FBF50C26AB387DBB4 ++:1544010036C2B827DAF30C4B67D09273D066BC9038B0B40A64E3 ++:154416004F3FE61BDA67C151E0932982CF1F4D46C83E04B8311D ++:15442B00CFEAE8785B6D519E85B90BF05C4A6FF3CFDFD8ED19DF ++:15444000EB81733B80CDF71CADE934CEA4293E8F48F76DDFA789 ++:15445500FDF632E9F6CF4907ED5DBFDC7A52D4DCABFDFB65D2F4 ++:15446A00DFF52ED2BF7C997491778477AF76EE32E9DE60EF5C67 ++:15447F00DEF49B73F6D3707DA7B8FD01ADA65F9BBDBE31373CC9 ++:15449400F1FADB874FBF53F8FF76FE73C2C5E2F6FF76EB03FFC6 ++:1544A9001FFE47854B45F8F7CDE54BFF67E0B7DB47ECBDA5C765 ++:1544BE00FEB580974916FB24D9B869EA1F94E2B7AD82AE287AF2 ++:1544D3006F573508C7BB56C5EBB6AB74D607656EEF0675DEEA92 ++:1544E800EDAA2CDFA9CDBB6E40F5F7688AC835A8FECA063509AF ++:1544FD00728BDDA7D75D80B159F236A998DF1F9BD7DEEB35652F ++:154512001275FF7A70EE12D7502389974B7A3F073C392036A83C ++:15452700E53D2DEAC3D7372BF53DCD4A50BC4D1D2CF98082F66E ++:15453C002017F17167AEE2C7F83C77A54A6B0FAB078877200F1F ++:15455100A9AF4C2AA8DFE584FB28BC59757B1324DFD5DF9450C1 ++:15456600697FC9BE2F7C2E0CAB6C182A0086BD0043A0A87C2C1D ++:15457B00B70E60C078942FE45F5CF6053BDFE9A27CF3F967F20B ++:15459000229E150FB3DEB578473AE49D28896B888F3CB3F2BAA4 ++:1545A5009AB10555801B11CAF4AC69061C35288BC416B5F6430B ++:1545BA007CAF9B0DF4D57F9EEFDD3B3F4934C0759110C0817BDE ++:1545CF00705791DD9019D81126929358E21EAA1BC074D286E933 ++:1545E40028D65DBC51ADDFB956E52A1DD8F2171DD83A01B66A62 ++:1545F900B181FC1320203AF4F254B6A822C1B45D595499547755 ++:15460E006DDD51680B88E73FE4F3360C8CEA893695ACFDE3E983 ++:154623007BB0DC9C0D075793C2BBA784F99A05837767A3EA852E ++:15463800F2B06EBDB62E3F2ABD115ECA66F0520F6DA7624D974C ++:15464D001AE889103CDB4AB62BE580970A31A996B264DF0EBB47 ++:154662006D2EA6BACF947B0ECAD221CC0BF802BAFB1C1890F65F ++:15467700F5DD372A280BD5F7DCA8CCA53F74226F39ED1BCCF4C2 ++:15468C00A7FAA93D148F3BD5A2066E8AAB3CBB539D07711FE630 ++:1546A10058D06DFF1BF05FD10370427BA9A88CA8DAE31DCADEFE ++:1546B600131D4AC5A9356A4003BF9DAB55ED233740DBBF41C1A6 ++:1546CB003610009CD6AFB170C1C7B95E996DA0B60D729ADFCD92 ++:1546E000DDA28AF112BCF7C4EFC1BD9ABAEEFE79DCADAAC8AF72 ++:1546F50052C59550DE7577A8E2EA1BD4E192554A04D70156CE75 ++:15470A00C42F0B5AE766287E326CC57FF233AAF844873ABC35B0 ++:15471F00ACB861DCF53E7E9B52FFA1925EB48D2C24C27D9E6CDC ++:1547340047DFFD684F4A0BABF5A76E51B9931DAA067139618691 ++:15474900169BB08F07E99CCD3AB4A5220C40BAE31D7D34D76B64 ++:15475E0067BDA5DE505F99B7BDAF3EB556D906BC4106FF21F8F1 ++:154773007E1A79CE4FD6ABE250878A72B52CDF8AB29D20263FAF ++:15478800A3726BEE5429ECC90E080FABC38033A43FB6719C93FD ++:15479D0094FF03D75B7F0A70A80DA881539F512B4E6EA736B0B1 ++:1547B2000BDAC03CA07D7954EB2BE64B4877A41DE928DB34C57B ++:1547C70036791DC0D28BF0039EF16EBF1EF84F96DCA5CC837208 ++:1547DC0010FEC1ADD6FFAA8BF900F225C78D71616C58B7278FDB ++:1547F1006B3856DB36606A85F843BE0773AE054EBBBA1BE290E4 ++:154806003E39C070D71CFD4AEFE3B54AFDC96AC06DB57AB97630 ++:15481B00F4129B6947BF64563B421A94433B0A8A77115E1EB6C7 ++:15483000DB12B6A380067E73DAD2F6C49FAF2F0F6E00FAC4FB9D ++:15484500B7B35BD7CF0BC6FA39F10ED57157446F5D8F749A376F ++:15485A00B0B68F9DE8ED73BEF52FBBE87E9DF2C4DABE8A6C6F1C ++:15486F001FE7019A5FD9A0B9810E1781F688BFAB8916AEDE0ABE ++:154884006D0BD0E10EA0C30EE2E9C5B428B16991B4EEF5F17365 ++:15489900C29550766CDD14D105DB4D6CDDD13974019AF86EB218 ++:1548AE00E9027CD7B7B6882EEF2BA2CBABA43339D3B7B742BF10 ++:1548C3001E29A213D987863680FE9B6D5A9D063A39B4D9F01E37 ++:1548D800E971A6881E3FB2E9817D3A60D3E2123A006D8A695101 ++:1548ED0016FDD4FAD2E8DAF5EC6ED62B663FD5374FDAD057C62A ++:15490200FE7A7D79E26FFAC4ECADE4AEFF3CF5579FC8C01DBD70 ++:1549170093F0CE6F6ED05CC07B2F96C5B47207EFD04F2BC4AD95 ++:15492C00C0FFFE42AD5873EF2CBC975F0EEFA9C548F322BCC7E7 ++:1549410009EF4E7D8BF10F3CDF779D8D7F5C13C17EE2E0DF5732 ++:15495600847F17AD6D58F81DB1F15B897C0AC2F0DEF0E23EE01F ++:15496B00A47F89C6058B66988EECD3DB74B0701E9905CB97015C ++:15498000CF6286EB7D12BE49E03DA59007DE9FBCF763B7A9F5A9 ++:154995003D5D8A54B254292BB956C1362C02EF61273AFAF6FE68 ++:1549AA000B849D5AA3F84A3EA2784A3E6A8571ABFAD8F537F4B0 ++:1549BF006D8BBB7A11AEC5F69DF2D046BCA5B28BC648F4477B35 ++:1549D40018CE1C05CB47BB9125CED86D8F1F180F75A511AEE79C ++:1549E900F3793FC429F4FD27A1EFE3D87506A693B85E82F2017F ++:1549FE008C75FE27ECF8DF82FFFA9779FCFA8E505E2975976B5E ++:154A1300FC36D4D3629C7597298C2C795F74FC768369A4F38504 ++:104A2800FEFE99F5D6F2FF06E2E5D1A4A89C0000A7 ++:00000001FF +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/drivers/atm/sba200e_ecd.data Fri Jan 21 16:01:05 2000 +@@ -0,0 +1,928 @@ ++:150000001F8B0808AC5A10380203736261323030655F65636426 ++:150015002E62696E327D00DC3A0D6C14D7996FD7B3F5AE71CCD4 ++:15002A0078592F3F8DD70F0AA949E8DD022E07F61A1644AA40C3 ++:15003F00012D88A433EE52268844E8924B571792229D1B0F8EB1 ++:15005400013B7DD0C7608813E1640D5E58529C6C909D101DE4AC ++:1500690016357749A4E4BA8A7227541DC9AA17295C4A2F76455E ++:15007E00259438EC7DDF9B19EF7831C4A1524F772B8DDF9BF742 ++:15009300BEF7FDBFEFFBDE1B3FFCD3BF7F88B808896E2484FED3 ++:1500A8008890844A880EFD1CB4BBA00DB710128396439B8076CC ++:1500BD0018DA4E68B51FC3036D16DA1DB8364E88026DE92FBA6D ++:1500D2001EFE486452BF7C63D90D63AE825E0863FB54E1A984C2 ++:1500E700782F999F6AB59F9E3C49B19D522690D8ED9FFB737D9F ++:1500FC00FCD38F45DB66F353D2B6AD1433AEF2F2F209D77F491D ++:15011100BE34E18787275C3FF52678EDF13693B20B7EE47FE17D ++:15012600E71A20BB45FB4AA95D5E29DC72DD983C8589E52B4C68 ++:15013B00927E7959B9A987A7DA6E4DCF24842D778E97CC7F63BA ++:15015000F90B6D6DE8BEAEEBF97C299D49C95956A43F7A5BF4D5 ++:150165005F7C512AA1FBB7D87EF4AFBF99905E79919E97FCDF83 ++:15017A00FFB93C759E5BCDF3F48DEFDA29E89C2A8EA109DC0E0B ++:15018F005FF8FFFE2B387E24ACB3FC6765A432BB6F911CF4C674 ++:1501A400C1977CFA72F2308031121A8EE3BC3E026FE14E96FF67 ++:1501B900025AF9AA21793BD46B5B3B1A708EC8A429FF1CF1557A ++:1501CE003E4F7C81FDC4977802FA5DC447C2618EEBEA932EC057 ++:1501E3004BB79000C012130F873C52EDEA50657DA14AB86BAFA6 ++:1501F80014D4B75C5C467C1D4F126F20B8231E269759EF9EFE32 ++:15020D009D846F61249CE1FA03844C0B6A716FD52F20EB9C6518 ++:1502220035C1447C7AEB6916F59268404FA9249C341086C4F6C2 ++:15023700182477ACC79FE300570FFC87E3FBC3A4657AEB6A1692 ++:15024C0085F4D4BE7FB34AE4F5AC7D7DB3FA3C213546D2DD045F ++:150261007C32C81F7230EF6A9E22B7A8B81EE7116EDFCCCB8A9D ++:1502760067E549751FF5B490DC6C5641483010844C26EF66BEA1 ++:15028B006067FCC3B9C4E721F3D53DC3EE1669F72655BAB04CF6 ++:1502A00095B6AC654B008EF03EFD6EBA6531EA08F113F958A63E ++:1502B500F8F4EB015853B966BE7AB950A8FEB04D8DB4FF933BA0 ++:1502CA00021254BC2478DA75DB3C456FC2D306E429775C5F2546 ++:1502DF0078A202FFB7626115F9D9AB95B5608BFC601B04DD5402 ++:1502F4000575C0F90BA1C39DD5640A91FBF4DC8A2D0DE780D715 ++:150309001DC0AB3D1FAB26E3C3487898BD07DA0F053964FC6180 ++:15031E00B09F6E2C85F4EFDDC054B2B33F93978886ED30B49447 ++:15033300768879E085CA723BCEF75CC37918AB1763BB718C8F81 ++:15034800E218973A503F887F41CB78FCF545FC0256ACB3E8DA10 ++:15035D0034052D8BEE84341DF8D924F1874DFC62BDC065D1B458 ++:1503720069396575E2BF52823F5CC47F03AE9BF17F2BFD283F5C ++:15038700BE7DFE1BC41863C362AC4325B1FE8C3D3EF66ED31296 ++:15039C00F6BE39FF0257281DAF69ED17F8883C2F83386A5A1923 ++:1503B1001BB5E418C30B73E3E48AF573539E9BF37F2BFCD76E07 ++:1503C600827FCCEEB1FE1E1B7F838D9FA45929AE521C387FCD8B ++:1503DB00E143B62C02A73CD433A10CE3F647A7B91FAAFA55D204 ++:1503F00030CFB4AD06B685FE0DBED990327DD38903EC5BB9A572 ++:15040500685F6F5587E09B3474B0AC44A2105B784D2CAD1ECE76 ++:15041A00B85B80BE512D77A9570A85A0D33FD6FD99EB3BC4FAF6 ++:15042F00CE09D78FAD053C57715DCCE12B18A2352F4BE4DF3E26 ++:15044400A3E73F3562F9670D7FEEAC3AFD034D21B14BAC4EB966 ++:15045900475D4C7FC5F6DC3B9020F2BF81EF26793FC4F5605035 ++:15046E0089631EE0D00FC49222DEE3788D3E00FDB481E324B744 ++:15048300A8470EEE8A93DC7B10B366C4F7CDDCA178E9E3ACFDEA ++:15049800FD956A27C4B7F6F7D7837DE688787987152FBF0532CD ++:1504AD00C87598AB92BC1BCF26E134E7D056692EE07F3ED0CF67 ++:1504C20033CC96D2CAB56AA12CCB24D72A55EADDC8BAC949C5A3 ++:1504D700A50DB0EEB2E30AC28C421A3D4C5E56C05E0CAB886E6F ++:1504EC00F23A8C67712DF4FF45113C02DE68FE6D03E4309096C9 ++:15050100DB45AABB203749D1BBD5BB80A7629CBF17F86C6701DD ++:15051600E06D6788F8BC40FB933677C4BBE135950CFEDCC09CF9 ++:15052B0087FC728B5FC455F5515EED2E3BA9A05ED65592181934 ++:150540001C30B244C0E918E7BB519E705AC4FC2A42FC2496D294 ++:1505550047B7F635873457A377C309F0B30106F089DD3F9C0F86 ++:15056A00364FF16B85424D9DF26B359AFF9457B94EA8B1FCDB9D ++:15057F009C84327177E57915E18379C83D202BD2385A0672CBE6 ++:1505940003461053742C63CEC97F32C0F601EF8697D559078ED5 ++:1505A900C3BE4D097EC0EE19B0BBD8136BE99A8829F3A21ECFAA ++:1505BE00CAE3AAB013E634CB4601878D1EADB5725A02721ADA1A ++:1505D30000748276C8A27FA15F800E9016D959D40FEAE5975DB2 ++:1505E800DF079D844D9D583CD83A09002E874EAA854E56AC5F7D ++:1505FD002CF0900C0BB60AF9C00FF764AC07F676126B984CB013 ++:1506120055E82BFA3CD80FD619159837071F671F423DF547CC48 ++:150627009D9ABBB94EF94FD5EDFED9920D9ABB2948DDCDE3ED05 ++:15063C007B3FE4F1ACE201DD96CA8CF2A1DC1EB2006AA3679877 ++:150651000CB2CABD9BD88E3B896FAFB6B1C9BBE105F0796ED6EE ++:1506660014E1A5ACB002FD803221E3D52B26CFBC5F7F80DEBF28 ++:15067B00988492F15AB2470D8C32C12FE9EF63DDD98560AF85B3 ++:1506900006ECCF8CF5F4E05E053D0AD9486CD0C0F501D8C35394 ++:1506A5001C72BD05754ABA6D6364519B29DBDD753F5B485DC4FE ++:1506BA006BCAFA6BF53A79F216B2E641D6939396B5F5DBC477B6 ++:1506CF004CC8FA30C8BAC39435047BBBE1F7A67CB1E3FA532095 ++:1506E4005F6DF63BEAD4489390AD2C36430DE9A1E66F635D12CB ++:1506F9003B20628096FFDC38EB2553A0E5B81F85AE5007644910 ++:15070E00D12FE4BE8CF5801EFA8A7AC8BD6A209D523DF4801E4A ++:1507230074D043D0D24325E80169074B68831F4E194FF38472E3 ++:15073800C0972AEED189F7E6346B6F46C6E6D1C78027EC8760F4 ++:15074D00EF3AF72BEE55C253FAB5151EC10BC417D8AF2761BF9D ++:150762007ECADD9543AA6BE659D5D53524F6EC11C79EED297B45 ++:15077700C5DEB37E9C3F52DCB335E8FFE8D7CE7D3B0BE05046FB ++:15078C00BF4346AD9C4C71EEE7B1FC943BCDFDC1CBF1EA46B191 ++:1507A1005788F48AD452BDAC53F4AB5DEB45BC8E06486C8EF056 ++:1507B6005F6EE65EC88572F20A93D6ACC59C974940CE2B4C4D3A ++:1507CB00B05EFDB8C2662694C06E880F77A4541FFA4FCCB0FC60 ++:1507E00087C7671D931ABD55AB61BFC6581BD118FA4ADA05352E ++:1507F50041586188A322F20CD3A03568598B1F7CEB04ACF36627 ++:15080A008FA9011DF3FFEF0D51CBE01EF84BB6DB3E6764B09B53 ++:15081F00E9E04BC89773FE51F0AD1524C1B6E9879693F065A3B1 ++:150834001E6581396FB61DCE4A585F7C435A0F9AB4B278CE7380 ++:15084900CCAD4A8E3621FE34B9357E5D33D7E74BD637265BC568 ++:15085E00FAA513ACA7DA492677758B1C6DCF47110FCCDD958C37 ++:1508730034A1FEEDB501FD984A61CE8BF0B1B9803B950925C1C8 ++:15088800A6164C8305238BF5A9CC647C22F0A6D48CF11F7DAC82 ++:15089D00167D35D76F94D64FEB1E76D43FA2AE642C8AB58F2916 ++:1508B200DF196CCD7ACFEA53689DF58F63FD1C0D7D1060A1FEDC ++:1508C700411CD21AA61EC43D0BF2E27E1A572BE3F1F93E2FEEED ++:1508DC0053C31FCCC6F17C5BA75C51FF86BE06E7DDA19D24F6BF ++:1508F10004C39C9E7B40D4893C8BF50E9C875D33CD9A270A7153 ++:1509060003EB2B92DB8E7006C2C9C119702E7E5A9C8BA747FA68 ++:15091B00C59938181D54B1CEC0F544AE15676212AA8F4F8F3447 ++:150930008873309E89CB8066FBFEFBADF3F0BDEAF32EFB3CBC70 ++:15094500D43C7BDE10C78B67CF89F2349E3DDFAA29397B62AE9C ++:15095A00B6CFC3B992F33087986B3F373B0F7F4D8C7C4CDB1875 ++:15096F00F11C3CA3BA601DC6BA3D10C776BF9B56BC55C7314647 ++:150984008A5A40C43898C739A0853569CD9CA4A7C98449A13EBA ++:15099900A222060A9B891858EDADFA15F8C48098DB4EACF36D2F ++:1509AE0091DF1EC423D60B9D9B7024F62763F7BB19657A24259F ++:1509C3006C00670103C726F7FCB3217C16EC1BA8492A585360D5 ++:1509D8002C47BF7906F9224BD94BA843FB5EE0366C531F98D827 ++:1509ED003613DD0B94C796AA28EB3EBC178056DC0B403BFE5E71 ++:150A020060693CEEBAF15EE0EB6CD6FE17B0D944FAE413D8D15A ++:150A17005B750FD830CA2C7939CAEB6D9D6DE290470CBF43DE6A ++:150A2C00042153049FAD7D967D070C8499DC73613C3F729F6190 ++:150A4100E39D01786D5BDBF1E9CE478AF1C5E5EB107ADA94DD30 ++:150A5600D3689F51E58D49A5A67590C5800FAC0FF04CAA79CD1A ++:150A6B003C8DF05CE80DFC0A748363EE92B161475C9A41E7F61F ++:150A800060CCB93802B97A659F1AD0D07F1A18C81E708580C77E ++:150A950031BED23C564648A3E66944597640DFB5C63C7FE1F838 ++:150AAA00E1DA2106B508F7C82F412CEF33EEA4A70D29B9C7210B ++:150ABF0097CE104EFF119EB74C5C4B268B2B79AA880BE087AD61 ++:150AD40073A08BE8784634F0DDA6F34DE4D11DF2F43878D02783 ++:150AE900290FC2651E30E5D11DF27C2DAE1279AE96C873F536FA ++:150AFE00E5C938E479C7C1436692F2205CFE7E539E8C439EAFE6 ++:150B1300C55522CFB51279AEDDA63CC991A23C67478A3CE0F891 ++:150B280064E44138D99207FB4B268BAB449ED11279461DF2440C ++:150B3D00ADFB0C19F3B9E5E3750A53EFFB09D2357D04DF975A45 ++:150B5200EF19EBBDDE7A47FAF83E43BC2799F065A0B1AB4CB4FF ++:150B6700ECAAF59EB6DEAF59EF17ADF751EBFD1DC0B38B9EE038 ++:150B7C00D8D760AE93BECCC5BD03F47BE86B5CD403D04FD337E7 ++:150B91007994DEC5CC73C5592303EBE05C51334BF33407939EC7 ++:150BA600667FDED3EC053B606D8F3236D05302CF7658BB9ABEDF ++:150BBB002AF074437F337D83E3FAB74C3E38D2DC4E777313AFA4 ++:150BD0006E0C025EBC6B5841DE6167B6BEBC5CDC59004C15F5B9 ++:150BE50034E2D80B5B5F136359C7D8335BDF1463C8933DF6E484 ++:150BFA00D6BDCB6DFC7751D37E886796E8A7F9768B3EF2B4B65E ++:150C0F006E60998DD386455C36ACCD2BF216B26011EF5F514FEF ++:150C2400B3B84BB1743AFC88A9D39CF8EE61CA3EC3CE1F304F8C ++:150C3900C7CD9BF4EEB6700C9A638CFF9D09F3A1850369071099 ++:150C4E0007CC651F2DCE452C3DC6617E1DE80F75C7A01FA7072F ++:150C6300399E8FCE099E2E0B3E1FA5CFF15EA1DF1EE3F48870DB ++:150C780040FF03D73D4D7B67526543E88D85CFE692CA0F962315 ++:150C8D001F9D424715509B2E592E352D0AED5EC861EE6E319754 ++:150CA20011FC56243D8DB3DE949A82A1830B0D98AB5A6EF28FE3 ++:150CB700FAAA807D72FD2BA9E98BDAE7161E82B93F367B9A2BEB ++:150CCC00B4F2C6CF2EFD2182387F57CB22B8FEB7BD831184FDD0 ++:150CE100E0D269C8FB3B044DE03FA38B7686E019E4CCC444BBDF ++:150CF6004BE026E1682629DA84E0036A8E0CEE89E9172EABAEBD ++:150D0B00F735D87FAFB0CA60268EFA31D75D36368BD6D41109F9 ++:150D20006B8602EDB495C755D7FA47A0F6D9CFEEC05C097A3363 ++:150D3500E9268D0ED1EE303A45DB23F4590EE705D7FEC701FEB1 ++:150D4A007BAC2A1806782A6219C20F8A36619C15ED52A1F32969 ++:150D5F001700FEFD7F10B5D5D4600CE0A386C977D2E887F6692B ++:150D740061875D467AA498DB4808EAADB0226CB30D6C93A007C3 ++:150D8900B81CCCC1D845B6B4CCBA2B17ED45A301DA9DDF273E14 ++:150D9E001E76B7C0318F1D182DF8D1971E85F14A7A02EA055D0D ++:150DB300E8AF0CCE160BBE8370E6BEC25CB9CD82457D5BFB8D79 ++:150DC80061FF29A029FBDE533B9625AD6F6D507FC1B896FF8DAF ++:150DDD0011681D62E8C0DBF3AF1BF0CE75E02D104DA9B20FCFF3 ++:150DF20039EF1B121D323E69B0F8A1B3D9F52F4D1A4761BD6C70 ++:150E0700F1C32D7E8ECE29F283B9EE030B36EBE0277B0B7E623A ++:150E1C000E7E36033FF0CEF904FC6C76F0F39845E33DDC47160B ++:150E31003F598B9F4A073F98AB5659B0E86F363FD8BF193F51AC ++:150E4600073FAB811F78E7C909F8796B71919F8FBE30699C1BBB ++:150E5B00C19C66F28334909FD6D9457E30D79C3161052D37C413 ++:150E7000D68EE694310A676A3BC63A3F0F6874906BF434C4E84F ++:150E8500CD4C0EDE173FBC2CCDF0FF560EE74E2AD65D9091B78B ++:150E9A0062CA7F8CE0652EF17B1D79334EFB7959D57995E60779 ++:150EAF0058714DDAB868C5631B5601B86ED8DB7E888DCEF53124 ++:150EC400DACD37037D05F850E85178AEF0049DCB77D105E03353 ++:150ED9000DBC9346C056AB799DB24D35C8A1447D3EC5BAF55427 ++:150EEE00A207E093F41C4F53C60FF79E663564409DB6A597D514 ++:150F03005EBAC23AB67C97EDA99DCFF66E59C8F6F52E639D97C5 ++:150F180056B223B56718DED37CFCDB32DCD30CFFB7E7D9DEF32D ++:150F2D00ACF2C231F5E0A5FD500FEC5FE2E4EB9D30F155D1D593 ++:150F4200CD6363B176D6B090F8FCCE3121403B3B7A93F1CDD75E ++:150F57000A378C2B5A3BC77889FA09D44FB08EB7B33B9B26184E ++:150F6C00875AE06A1DF179434911ABC046F2DCE4318EF6C5F74D ++:150F81004F46AC1A413EC789CCB844C51D2BBF8AFF6810E6FCBA ++:150F96009A687BF8A8DBAC7586451B66A4007551554AEDD6878E ++:150FAB00946EBD5F9926A5D4236543CA91E88072186CF9ACFEB4 ++:150FC00086E27DEF0FAA8005E0837A9722AF632AFA4185833FB6 ++:150FD500BC8390D890187F52AB6CFCC4FE770F2B6EFCFB0A33BF ++:150FEA003F6A63B934C991E73990C72A925F35CC4A3E8179C4C6 ++:150FFF00CA8567451D63E6AFB366AC039D99F98F5B303D026617 ++:1510140047314F8AFDF09845277B039D3BC6D131F3E559510FD6 ++:15102900D97432169D0F2D3A264C0F33E3709A87AF12D21B76BE ++:15103E00B5941F48A981E83CBCDFF3FBB5EF468290ABAE5E372C ++:15105300E5FD40FBEBC6CBD0F782FEEB14380779061290B39AFC ++:151068005DA1745CA678DF1B66C92CC489A4AB65333D652C022E ++:15107D001C92FC3DC8435D3C14DD1F3948BA13788676877AE21E ++:15109200D23D50A3C5468CB974C4705BBA8ED02E234A0F1A8197 ++:1510A7007C8A734F6AE702DA67605C895D0039F2FD5C069C38D8 ++:1510BC000E276206072EAF93E6A617FA9A9DEBEB9443AA61E19E ++:1510D100C0B5D8475C147049A1FA78B464BD1FD647E97306D4F3 ++:1510E60010D6FAEE09D7E7FE1173537D1C7909C3DC02A833C232 ++:1510FB00B48BE1DD96413A120AFD2FC3E3C238779A19E470422A ++:15111000D23A0C3FE46037D6BBB17EC3AB751B95DA39718F365C ++:15112500DE8FCF5A7EAC8FF3E331FFCDA614D9E1BF55502B8C04 ++:15113A00F928F801DA0F7DB4FCC0805A43E6A9A66CF5A66CD11A ++:15114F00BE66A73F0768170F6A529384E766C29917ECB1733E0C ++:15116400F1E1FBBE999DCAC54DC4F7E2CCA422D3F9C236ABD16A ++:151179000EB096AFEE7E085BCF52F13F2D15B383264E79893719 ++:15118E002E43FF568F0947444B8336DF14F65D1D91AB16A81DE5 ++:1511A300EEF90F79AC71EED71FB2E7F1FF6AE4E8DC07251B479E ++:1511B800B4FB41BFDD5F591C17FB04E498438E36617E801A931D ++:1511CD004E8BF5604D631CA2520BD51883B37A0061360998CB74 ++:1511E200D6779F4EBCA3A0247692076973837DCF82DF034657E0 ++:1511F700342F36BFD19B7797884F4E7633C487637EB95B7D077F ++:15120C00713AE82F17B829C33B5949FE0CE87719B80EE95BEBFC ++:1512210032B80EE89D71F62F3AF158BF83B9E39073F0FBEF1552 ++:15123600568DF74FFC285B8BFB92DE1B09D2798DCC8A0F3FA1C4 ++:15124B000F35EA629F778AEFE5BBA75C413ADC2F3F67DE75C28B ++:1512600018E4AB1A1BBFA4CD6558B309D81F7EDE4272FD7C9ADA ++:1512750003B6C2829520374F16EE10F0BA0AE2DD0B5A5D13D6FA ++:15128A0008E677FE432A9C9E184473435AF339F8E46CD63B4C08 ++:15129F00104FA67AF42893454EE83FF3BB42A11AEF06B789B5BD ++:1512B40069B17681B69FD5C84FAB776AE759448333656C9E811D ++:1512C900F489DC6F081EB09F4B19923C5745DC52FEA88DDBE4E5 ++:1512DE0011F6DA589FA78C2CD058A44D6FACD2A6477EA04D6DF9 ++:1512F30044BE376975CDB67C923C5B2D956F3273820F7BACC455 ++:151308007E7C18BF7D9F03DB65E24B08A9C63AC6E53BA7BEE98E ++:15131D00C2FBC734D64D747A10725E6CC8C0DA424A0E31D7BBE7 ++:15133200E7D5FF065E7B5CC48BF6C77BF9465AD358456B227E15 ++:151347007A47E366D0D32A5ADBB8CEB237E2A8965F1577D4E057 ++:15135C000C34289F51CB80C60298AF86BE1BFA088773F6B90BB5 ++:15137100E15DD638AE0F26E78571BD8CB2027D19F8284CA5ECCB ++:1513860008E953189C8702AE3EF17DE059F17F5203D67D685A64 ++:15139B009CD1719F797D57D4368823337C4755D7CC4EF57052CB ++:1513B0006AA9B9705E9D23EE5933868EDF5E760E88EF34384755 ++:1513C5008E0DB1CBE2FB0C65B3C8A9E508432C18F17DA56F880C ++:1513DA00CDD2BE6A126B89398EDF4DF4248EFFBC89C883064DB6 ++:1513EF00A6F03B8821AF1950A330EED79AC5B817DEA980AB6D72 ++:1514040092F05E22F6BA7118FC026582FD5F8D7715B3A2A71B27 ++:15141900C59D456ED038AC4942EF788FF70CC43C5BC6A0252368 ++:15142E00CA11B1F27D7D01CF75FF43CC13064755A4D993BC91CC ++:151443001988C3038611280C0F1CD6E045326894648038C168C9 ++:151458002556E40688EE7B5CD089266EB450729055768B5B5FCA ++:15146D003081041F5CF34C206BE1DE84CD94932B2203071A3D8B ++:15148200ACCBDE79BB68A5AE721677C7D5B9DEECD69E4779615E ++:151497008D6CDC65AB38E7BEAFBBDFCC9BC9A0E0DED5FD987AC3 ++:1514AC006FBEEEF77D5F7FFDF5F77DDDFD7547F5F31B315A88AC ++:1514C1001BB88ED10BB618607BCEF31C0253B2E941318E59B05A ++:1514D600E751CCF18671A03F4CDCB28FC53814642D3F01387A39 ++:1514EB00433155770FB3BC0699D9A328ABEF954FB03595493179 ++:151500002F4698A20CB3BD8A291B2C2060E47206562A6057702E ++:151515006D46C454576DDF30DD1B292025CAB0698761DCE8CF5F ++:15152A00819102899467C3E8203CE5C8192A83AFA9C032D15E21 ++:15153F00DC8F21F4769E6B22BEBFF4E59C7F70B1EFE3D4E291CB ++:151554003FC5FFF019EAE881BE606BC0316AD10929C3F44592AE ++:1515690030FAF4188BBB3F01BB07D1C3168CBB93E9B888CB7601 ++:15157E00C1548AC935947C3DCD6728F916EDE819566B6CBC2309 ++:151593004EF46F7DA14186B319437E5C0345D9C8C3B42F1C65B4 ++:1515A800F07A019F12B1117B029F3EDC2F92193EA6035EFC1FE0 ++:1515BD008E1956FFA7447F768BFE64BA60C90D6224A00FF3A197 ++:1515D200D7696F826C29B2D96359B4C7259E72CEF3BD2FD3E9DE ++:1515E700C559F685CBFB75B6CF555344C27ADD1915C74C0DDB68 ++:1515FC0013E730B2613AACC00E2BC6711C376BC1E339C47B8D20 ++:15161100CCE1A1E409E0F7049D3FC9E4EED3053F0C0636CD57B4 ++:15162600191773BF8421C3372C8708FA8C3DC3678CD9888F0E7C ++:15163B009BF9EA933CF549BAFE5B5CD600837773773ADE8E53ED ++:151650006931CC3E443BF19DB5C90BBC5B6D82F729479CE97FDA ++:15166500C09B29DF579729B7607BF3C0A40DD3614E3B2C67FFB1 ++:15167A0091E9BB1863D6F8B58FED8E9CB18D4FE7C7710DCBAE50 ++:15168F00F58D9EE71BABEC255B19C674ED8BC82CCBA6A03CAC55 ++:1516A400727C5F72A1536BC8299F85B4EF47DA71A3028C776FB2 ++:1516B900C4B945C6BD0EC0157E28639F5037702C5865E5F6325F ++:1516CE0090834BE0614F1B8EA21C1C56FBB9FE71989E0B037C5D ++:1516E3007B2C983703D3F3C0667AB261D8A62E5B9B2D58671E54 ++:1516F80058A1C70ED38D4431D8B685423E246AA0FDC0F1E915CD ++:15170D00FA1E4FEB3BC0D017D8D63A4811616B1AA8BF5EA6BF42 ++:1517220031C3D2F39907713D3C418FC2B8F785B86DCB8743BE31 ++:15173700611C5086397BF230D6331B6CF350B4EF681FB7A15DC2 ++:15174C00C1B526F8EEC0C2B8CAF0839EC14490E683CB36B861D9 ++:15176100AFBF203F5C0678AB43D8DF626E732D99615C500F659D ++:1517760079E5E5CDDFD6591F27B43E7DB8EDC0C284CA7310AFE4 ++:15178B00436EFF8BB8B09D5FD507C68DF0F58D7165F76B42D8B7 ++:1517A0007BCB77737B9C2DEB6C7B9C8717F886F302710A3E0187 ++:1517B500F76CC4C7F6C3F3C8214F7D92AE9FCDDF6E9BDEE11865 ++:1517CA007678A68F71E2993EC60B3CD3C733C903DBEF9E3EC6AB ++:1517DF009D9EE9E359CA8161FD57ECDF66E6BC221EC371CE7D03 ++:1517F40003CA7489CDF7C15397785C62129B2F9473CA245B99AC ++:1518090037A7CC652B5B905356642B5B2C0B3F129834E23DC8D7 ++:15181E00972EF2CBAD582446838A3390893D6294E5EA425F6464 ++:15183300628FA8C6E38C9CD853CEE4C8C8BE924647DD2AE853AA ++:1518480098670742867C3B2105072B357D32E5763A3AD5367878 ++:15185D004A20935E85AFC3FE0874EA70F4F7E5646A805EE941AA ++:15187200044EC44576EDFFFFFDD5D610F7D86729370D75A835F8 ++:15188700F749EBACBD4DDC2F24EDFA293667688F9E1A67CFD1D9 ++:15189C00532CC7AA3D796A929DC989D2C446BE16678B410D07AF ++:1518B10019FE18E539713F71ABF7F3BC65EE67BBC1CF0E829F2F ++:1518C600051FC9E456C2E466F9EA1AE083783AD5F2CF84EC22A0 ++:1518DB000E263BB47D51C0E307F847F749AB91D6D98D7C8C8CD2 ++:1518F000C013D71B1D0A8B154DFCBF212BF68CD107BF617F17F3 ++:15190500B179E0A4896D045924842C12421609218B04CAA2F079 ++:15191A005E57A33D7EB95EF9E158F228CB033395AEC0D1422EFD ++:15192F002B0EBB13600702F12CD83D00EB0B9CB66045089B0F62 ++:15194400B05B03A30863FB3A5CA6572E810C4196172F4D9765C3 ++:15195900C37AE2BE700965E95F7DBDEDBADEF69CCBA30F054261 ++:15196E001F3EAA26EEDAEA6C3E2B24E2AE075E9CC0EBDA3CBC7E ++:15198300C6A17E29E3B574F58DF4C1F5F27B3C0FBF8582DF525A ++:15199800A0DD1F9AAEBFFA35F4B77322E52E8076B44F4C6F471A ++:1519AD0012F0344F603BBCAB6F54976EA43DF13CED91447B1A71 ++:1519C200818773F7417BBE01FDD6FF8236297E2A2BA594D97E0D ++:1519D700B0798EBB0889001CFF4BA4D6D88DEF01D550403A8B99 ++:1519EC0015CD9495EA57D91E33D899FA08AE37478DF001EE1352 ++:151A010095837CAE32FE32F86249077FD8CDD64B0DA837161922 ++:151A1600328B9A4E9A139F72DC7EC09B9AAD1B53F0DFC1FFBBA4 ++:151A2B002E7C9ACDCF0551F70A3C1B20DEF42A9C1E51393DA4D7 ++:151A400083F4D02BDBE92D867A454D43663DD0DB2D709CFE9440 ++:151A5500D3EB14F4E0BFCB2E4F59C8B3086489E5ED5524AB7C94 ++:151A6A008E65FFAA7879434EF95C513E26CACB73CAE789F2E328 ++:151A7F00A2DCCBCA278D1A9A39CF92823652D2A5E2DE9D0B7DD7 ++:151A940074CEF9956E888768D4B905E28CAD55B8AEA977AD2A29 ++:151AA90056A4A02AE29A9E8517D5AAD0BE60AD2D5F60CF48D3BE ++:151ABE000728ABE7DB3FAC0AD8E01FFFF0E5AB085FB3F5832A70 ++:151AD3007B7EC18537BFFF1AC29FF8DB9F559162DCDBEE373A7F ++:151AE800FFE5856AAF4FDF4A1E236E974ADCD3F8B4E58F2987E0 ++:151AFD00B2FD338F35264DB4210E0F9FC331989CDD362B3EC2C4 ++:151B12007A3341D7A7D6F2DC19ACDB5337ACCE8C3C12D85FC732 ++:151B2700EC391DB5EC39945967724637E69FEF1B9FA7DCF14B5D ++:151B3C002977661E46B55EDDAFE2BE0AC48DEEEE8551753D59D3 ++:151B51001EF490E5AB16298EE0799045CF42AA6ED0FDC17369BF ++:151B6600B9C4D99AC4CD4C1E740FC6284E88F50673CADDB672FB ++:151B7B0009CA3B3372ED2E9048B70BCA1D65D07FA2CE22E6D307 ++:151B9000F8B73741FD0651FF0EB0FF3EE1DFB0CC07651584EB9F ++:151BA50013FE5F7261402B81FF8B6C75965C8869DE1C7E1E8494 ++:151BBA007E4A4462A60B7C6CF96F53EEE8D594BBF9CBD42CD1C5 ++:151BCF00BE7511B0D3A03F5976C52BF45442F9839E86927F6EF3 ++:151BE400E84E320BF50CE3600B37AE5FE21EA16CE30B73854FA4 ++:151BF90047980F360222BFA108F02E00F97B9712B7EEE7BABFE7 ++:151C0E00600DE016FB3054F8F31749BFD13B3AA8BEB90CF7E984 ++:151C230002068F654B0C561EA830D07717B863DA0F963E5CEE8D ++:151C3800AD8CD2D65732F1168577A90F2255788EC2EF1CFC9498 ++:151C4D005EB0AFF01B17BFD65EBEFE85F82EFE12D7BF94C6F455 ++:151C6200BC4CC0A3FFC1E161012F009F5683EF7480CE837E2B7B ++:151C770000FF50CCD618264DE9DB84BC823E830E9896DCADF9D7 ++:151C8C000796596D9394037406B3ADD4083C4A48D17FA6DC93CD ++:151CA100249BAEEE22B370AD1BF1FF33CC476702DD31A81376E8 ++:151CB600733F65E191051EF932E76DF493947B90E7F5883A101A ++:151CCB0007D1210DC7EC646A361B23B837D6F7F7C7198C4CCED0 ++:151CE00026DE9F0EF277F883F2CED48D9AB89FD6377A5C9D2F99 ++:151CF500B1F50E93EFB3454DDC575B6BA3C3D71DFB8DC7C61FD8 ++:151D0A001B5F363A98A53F37A3FE209FA043814ADCA386B8203C ++:151D1F003C443146DBAFAC0BB01C45CC8D8BBC4B95C819C3C77B ++:151D340072E8BF303D7CED9BF68A7557BE8E3BC2F70C020ADF8D ++:151D49002F40BA387EC227CDE7593FDC40FC373E8438D2F3B0B3 ++:151D5E00AFE741D0065A69FA79F475DB3AF0CB69FB17A5E3B899 ++:151D7300D62B1BEC9C14192D20E037D8FA3EE0A0631B591E841D ++:151D8800CF9A67CD2103EC0C12CA784CD834FCBEFB5EE296C690 ++:151D9D005FD2E40F5F52ED362D6D77D99C6CC448FDD57B923824 ++:151DB2003324A32D66F3191AA37790C120E6EA4FFDFB7095BD05 ++:151DC7006F6E1263BBA482E45D1FE56B9BBAC03B22F026742EFA ++:151DDC003FC0ABC738DE25C7B3F0CE1078C757E7E0457B08F1E8 ++:151DF100D5BE85FD2A3BAF0F3610F126393E7D19EEC9CB83B482 ++:151E06003039AC4BC933BAAB28C6D6F966029DB961AA3922869F ++:151E1B007128296D91944EE316F91D6D2C95F279A25230334FC2 ++:151E30000D1B1877EE72A0ADAA6DB4CEDD635E358B4B587EE23F ++:151E4500A4A9E2B3B8A291C80FBCCAE64201E554E8D13CED0713 ++:151E5A00FF15E847FFD5CFFCD7BE8523AA67B4EB5E466F5CEA4B ++:151E6F00A49571CE7B38A67B301E13F082484C972B13AC7D8726 ++:151E8400C801D584B1ECDA30C8F6D1BE85361EFAC411194EB76D ++:151E99006F6E6830687DCBED46FA7D1A3FFDFD997CEC7DE0FFB5 ++:151EAE003DBAE0875E831F80CB601F91173B4D07DF4FDF9375AB ++:151EC3002604ED1501BE8B47F83C5FC44F203B2E1F9E4F922D53 ++:151ED80047B9EBD5ACFD0B186FC88303FA1AD73F43C9237B8A4E ++:151EED00F95C4DFF25C07BC351D5E5116B64C0D3C5421DCF3873 ++:151F0200CFC2F2B64D3C470A7DCC3231BFAB653A12D7FF14CA3C ++:151F17002CDE19DF507FD7261607B33C8E7A51EF7BB67AD5C94A ++:151F2C00D7F7C04F47786213DBD3D0314F00DB82F349E4A3F77A ++:151F4100A598EA1DE5FC20DCA2DB2AF09DCC4377C446779BA8EC ++:151F5600F7B6ADDE7AA08BF5466DF5DA44BD9FE4E16F7DF2845B ++:151F6B008EE3EA1CE3F16F74F403B5789E06F83BCC746798AD4C ++:151F800015F7FE1DF04A0619AFB5365EDB05EEF7F3F03A6EE3A1 ++:151F95006197A8F78F7978BD60ABB75BD4FBD7AFE035BA39C326 ++:151FAA006BFDD7F05A6FE33529700F6C9ECE6B7C7386875F8943 ++:151FBF007A439BAFD19F9B33FD59738DFEACB1D1BD68F5671EA7 ++:151FD400BA2336BA13567F5E836E77038EAFB328031AB6D3C5F7 ++:151FE900F68AFB3F106EE9FC7EA87F84C4D23ADFE0E43A7FD59C ++:151FFE00C1755E6FC8D00E3B39ED8E86AFA00D741B045D8B5E7B ++:1520130083AD9D0D02474F7E1C14C7ACB516ADE6DA3C3C4FF630 ++:152028005AC6DEB1F18CE771E5E394F92FBCB7473E4D31CE73E4 ++:15203D00157569FB206E94C197C9F5EF6A0B8C33DA41DCA3B7F4 ++:15205200D9A01F40BBF2D91EEB3B9F23A61ED18755D417BEF704 ++:15206700774085F9EA1E9C9FAE67B832BEE12EC055007E216DFF ++:15207C005743C3AA6B438CD954664F2D7FA1A33D8D317B2AD7C5 ++:1520910001FF60471DB6F7ACF61663BE4EBFEA5848B514E65951 ++:1520A600E0BAEF659EFBC57D5382D3A7C29E86FB786C07BE8FF4 ++:1520BB00B765909DE791C3BA46D12F4586C12FBDADB9A2670C99 ++:1520D000F44D79FDC98F32F33B9ECFD0A9F970BB1AD712C4FFBC ++:1520E500A9546A5EEE5C8FAF47B2FD70B3640AECAB1BC656B88C ++:1520FA00D4A0A18E36B4C5AE426E93252BCEC6F32DBF4BA57368 ++:15210F003F9529969F39DF9E372855F27B70545B3DBC8028B73B ++:152124001EFA84C30A9EA11AA188E7093C4355E6C0DBD558FC4D ++:15213900EB284E3462F92DA141ED96D0DBA8336615D6C19800DF ++:15214E00F3A901EEDB1A3333FFDFD618ECCF6218A3101F4D680E ++:15216300FCFBB7D1A77B0B3C1DDA7BBFCDF0E49F6271928DA775 ++:152178008451454EAEF1298E80451BEF02BA83D18C52ACEFBB81 ++:15218D00F50B33FDBEEE8B349DE492936B0BD2795F309F147980 ++:1521A200F8C8D7FC5B3127A28F9AEC2C5729CB19BA17C5217371 ++:1521B7005CBC6E9CA2FCC12D9AB2BC17FAFA347CD36B4ACA69E7 ++:1521CC00B3D1164F5E7C84906714E79AB30E316FCD43E7218C26 ++:1521E1005DF2E2F69B4EF94DC07DD620B4CF94A2EF9A986F8196 ++:1521F600EB9F69DF8DF38A42317E11EFB7C57D14A20CFFE7B9AD ++:15220B00EF83E596A21E4DCC40BE127482E78C5397E0CF65E79A ++:1522200003FA1BF945BCBE6082E51BB1BC0FF9A4897CC83F5F73 ++:152235008EBC73DD13EBF1150319FD463C138F703CFE298E9FB9 ++:15224A00E34D30F9CCFF791775C01C0EEFAFE823C32A9EA3C3D2 ++:15225F0098977F9330B14ED63800FCC707ECF7C9F07623FEC926 ++:152274004778FB389D78161D6B4D00EB323926B91C6FD9DA6987 ++:15228900E23D116C4E63A7993E5F1B32382F1586CCE4526BF06A ++:15229E009C8480E112F9A00C1E1EA44F2DC5D8F518CB47B4F334 ++:1522B300E07D6D39B5F71DD431257908F7E6A9A5272CC606DB7A ++:1522C8007A9874AAECDEA8B0C1E4827C61B904EDA515BA819379 ++:1522DD00E4C2A24E8D1EB8533B7F21E526E3036CFEEDC53E92E8 ++:1522F2004F6992F22EF545F8F9796BEEB2A070FAFCA9A36E8876 ++:15230700CDE7B2E650E327CD7B6F740E15FE4BD3D229CC23ECDB ++:15231C0077F2F969B64E711D425E4A845C589F04A33C7F4D1EC1 ++:1523310030713E8DFE0CF5097580C94AE773E9A35FA6E6D8F47E ++:15234600384B9F59DE7800C63E9D30E6F9028DB87EE2519697DC ++:15235B007F88FE14E6E9CF287706AFC098BC2BE965E7B07B1FA4 ++:15237000E5F4E38FE2251B0798DE610E97809B083F27E6B551F3 ++:152385005137915357C04D841F15E3DDC2FF9EF8E67CCE37023B ++:15239A006E22BC55E03F27EA2673EA0AB889F0B502FF3281BF77 ++:1523AF0053D4C57AF8BED8666FBA6D65F88E67DBF04C9B0BF426 ++:1523C400A8107C95A40C98282F49DEAFA19F092883788676EE70 ++:1523D900DC505F9504F3D3F91D135A9132642ED22FADF5557FB6 ++:1523EE00A64991D3E66B51E71617CFFB9C373332638D14993002 ++:152403002D9D9D09B62D7915D7D13263E0FBE02325766E884EE9 ++:152418001B8F627CA5ED0AE2900F0E68BD85832AF23677ABDF7C ++:15242D00B4C633D301B409101B3892EFB2FD46FEFD88993B9E8E ++:1524420079FE24D08431631F272FDDDCA925FE89AFF3C9C2A6AC ++:152457007DDD38D98BB9A2D618E91960392BB2F0A7385696619D ++:15246C006E00C41A8FB1B5F7CCDED306C51910E7A9FEF0FD47F0 ++:15248100DB78AA2DF83FB0D139F1445819A04E4F17936729E02E ++:15249600ABFF2CE377E9E7397E1778C13A44EEC03326265B170D ++:1524AB00298E373A0FC6B43ED015796D8CDFCF00B8703D05C6F8 ++:1524C000E33C764700F8662CC77BC33087D8F2BFB8BFAA46965F ++:1524D500D2420FDEBDD7618CFF3A435BCE1387B8224097AF4988 ++:1524EA0098D85F7DE0F7E5B303C6154113FB378B2694BB7268E4 ++:1524FF0066B7BFA4B1C1463F6CA3AFE4A12FD9E82FCE43DF7F80 ++:1525140083F431BEE8AC0C18162FC8C3D825CEC362A0954B5FF5 ++:152529003E3BC46829910103EF4082B9B789B18FA4F03B8F16DC ++:15253E004706E861887BD0A74DD9E31C5C7393FD66679DA1E108 ++:152553005D60532FFAABD87E5FC96D2BFC75CD41E54F2A2AB7BB ++:152568002A0FFEF1A60794CDDFDBD9DEF2EC4E6553CBB696A616 ++:15257D009D2D41A5FAF107B7EF686968DDFEDDEFB4B63F5EBE5C ++:15259200F2EE9501A5E4999DAD4FEFD8B1FDB9C79B9E6F0AADAF ++:1525A7005A55B9EAEE157F7497F2D4D3DB5A762A81CAB255156B ++:1525BC006595ABE125581E0896DFADF8D3FB5B16BDB2B2E696EB ++:1525D100B6EDED654F6E7FB6ADACA9B9A96DE70B65CF363DFDA7 ++:1525E6005CD9CE1D4F96B5EC6C2B7BEA85B2A6A66D0CB66DFB24 ++:1525FB00F6B6953B6F5B758F72A7D2D2FC74BBD2DCF254D3775B ++:15261000B7B52B4FB6363DF79D16A564577BCBAEF61548E5FA76 ++:15262500F037EF78FAF9961D654F41B31E6F6A7FF6F1E61DCF95 ++:15263A00AF7CF2B67B2AAE853F8D9E9D679AE30B37EE67F71A4D ++:15264F00F88DB9BE8AC612A59CAEC4B35CD6398D88B406EFD1B8 ++:1526640038143AD25640FA8DC6DFA7D2E7341A958DE627BF703B ++:15267900AC91E48735BF526DF861EC7D0CB6C40BCF37D176E26F ++:15268E003E09DD6FB47E9172FF74A9146C50866829942D22C3C6 ++:1526A3005521A587B2F2B0B4370030B4376B6D30AC27830F04B5 ++:1526B8009C66B752B4CEF2090BC036CE203C96C0FF5701F73E78 ++:1526CD00F9E5368C13CFFD756A16F2653FD7603FD310BDC2F71F ++:1526E200CABA58FD12A31FEA13F9B2E9856FCE027D3B4FB48D99 ++:1526F700B0B3D32B1D642EF2877C78959314DB3003E6A998E3FD ++:15270C0046C657E03EA9D7577DA7866DEF02393A7F52A9E1B5D5 ++:152721006A7EC0C5D7AB0E1961E58746CD08D08678CA0BDF5BC8 ++:1527360074F01C97B77A850630D34EF3A1548AD1EC62FD72CC9E ++:15274B003C9D4ACDC1FBC4F8BA738F7113F805C439F916AEE733 ++:152760000700768CF1E5047F7908F90AEFC775B9F956BF5967CC ++:152775006CA2BFC3BEBBCCFA0EF7571405C69DDC957029F7980F ++:15278A00CEEAE3D0DF07186E1C8738068B94D7CCD22F1D6BED4A ++:15279F00EBBF28734BDEF67EA87927E5FAAAF2D27752B3ECFD49 ++:1527B40081FCC8C08FD7D65F6D1197114DFEEC556C93121D4848 ++:1527C900CCC13BE7E8622314ED4890E2B6464F926CF14697828B ++:1527DE003F3EC7EEC3F3F96AA1ED0F18787F29CE1DDF9470BE3A ++:1527F300A41A18D348EF3FA3E11D51F5B8CF12C6B3DB611693D4 ++:15280800F6EA41D50C55AEDBA414ACFBD079D1F0856E67EB8DA0 ++:15281D00462235EB23B12F128AF6D09BB2F4A01EF3BFE763BD01 ++:1528320066A8773ABDAF1231F07EEE40B49A12F915EA666D83D9 ++:15284700793795F63ADCEB35DC4767F617BEDFE3C0F58C8BFC2C ++:15285C00CEAAE601889DCB204E78925E29242ECFD880F69872A0 ++:152871007370AE72F3AA3796CE0FBEBAECD6E018C091DED4894A ++:15288600D4AC658A23C8F8917B0C5C7376C1383C0F7A9FDE0F44 ++:15289B001B3FC6FDF1F831F32F1696A86C7D186CE4D142116F97 ++:1528B000290EB6761A075C565DAB5E3BD4395837A0E29DA7C812 ++:1528C5002FAEE7E6D2C2F18BDFB7C2F7EF39385FB8A679E10D71 ++:1528DA001C3F7BE9E2A241CDFBDF47282A4A6D14CFB45F64E72D ++:1528EF00E7CCD0EB6A1FE05D5454AADD8577C28E47D55272D174 ++:15290400E80C9D68C33D2E05FBA96E8566429FA0AE38770F1B8D ++:15291900B8B71FC4F58EF08F791F88B18B31B4C4E6610AF015FA ++:15292E006A64FC877F6C8E4DA5DCA70B783BD7439FAECDD37719 ++:15294300308F9E9FDBA6DEA914CBE9403CEDE2FB4530C69CE3B3 ++:152958003A8C83FD4601CC4B42C923863196725BDFCE80B1811F ++:15296D0036F0AC903BEEA7A22CC22007AB4E3F94B1F7F1970D63 ++:15298200CCA762FB8F50A7F48D6CD95F0539E6E315C7ED82680B ++:1529970007F57FCE653E359CFD1D933FEA33B305FB0D4BD6BDC7 ++:1529AC0020EBDAE88079F5B8F0F9F676A34E8A761FFD0D6F378E ++:1529C100F63DE2DB05F84A599F458C5D2C6E133AFA2BAEA378CF ++:1529D6007EDA51F780867B86DFB2F450F40997670657E8379C5D ++:1529EB00E736D00DE083E9C6A2A2B59AEF178EA0A523783CBFC9 ++:152A00008DEFB30A1D39A3625CB78C9C5987FAE1AD4C30BD3021 ++:152A1500F565AAEBFD214D025BBB4CE8035F0FC8EEFF1190B788 ++:152A2A004F3EC6E29DD9A01F5EB0BF577E2DE46E8D0BDB37B8AA ++:152A3F00679D4FEE2B717C437D94FD343A30AE7A218EAC17FDA3 ++:152A54003EC3A623EDA023AD1F701D71809C25A123E597B99C53 ++:152A690059EE01F6FFF14C3F223E4FB84D6BFDB7B672B0676627 ++:152A7E0049B4CEF447FFA7BDEF8F8EE2B8F3AC1EF54833D22015 ++:152A93005AC3CC20B0905A443892A33833625024598481B05E2D ++:152AA8009910769673B2DD92B0C7B1BD109B64B93B6E1FEF85E7 ++:152ABD00C42318890137B8E913589615337224AF7C0B398507C9 ++:152AD200397C4F24E2C239B021DC2C211C9764F1388FD8BAACE3 ++:152AE700CF283E62E3C466EEFBA9EE1E8D846CECDDBDF7EE8F21 ++:152AFC009B7EF3BAEBF7B7BEDF6F557DABEA5BDF5A69AC4D3DC0 ++:152B110064AC4ED519D4075AF65353DC2E34E6371EB9869F2B10 ++:152B26000ACEB2EE45FDB55654BA5B0DDE817DA2914EC869824F ++:152B3B007B50C5FAD98475AE1E32F7037C3D69949F0DE4EB5DA3 ++:152B5000B09131CED8A10527686E3ACCD7BEA454B701BDC4D514 ++:152B6500A9935CDE8BA786C193F324B9DB582D9F34747AFBF5F8 ++:152B7A0011F5B46C86B3EA61EDEA07C8832E36E6FE07F17305BB ++:152B8F005F77BC253C273C2C7C56F00937D8AFD97F633F64DFE9 ++:152BA40063C3EC5966B0DD6C07DBCEFE9A6D618FB38DEC61F62A ++:152BB90020EB600AFB125BCFFE8C7D917D81B5B17BD96AB68A61 ++:152BCE00AD642BD8729A41B6B066D6C41AD93216664B59030BD8 ++:152BE300B120FB0CBB9B7D9AD5D3F3297617ABA3A7967D929E0F ++:152BF8003BD9127A6AE8F9043D8BE9A9A647A6A78A3F95F42CC7 ++:152C0D00E24F057FEEE0CF42EB59C09F72EB999F7B02D6E3CFE1 ++:152C22003DBEBC675EDEE39DF694CD78A45B9EB9B73CA5B33E15 ++:152C3700733EF0F17CE85372DBA7F8233FEEDB3E2E6E3B338E52 ++:152C4C00F3B1C15A4DE6674B4856A96CEA8C32F928FC6AC84FD6 ++:152C6100B7BE6BE93B6D7DD7D3B724D037FA96CA5A8A1FD17442 ++:152C7600D6A6A569522C098A26C98B8F4A31FAA7E89F597C1419 ++:152C8B00E598B6496BB90D3659B6FCDC969F407E31CBAFD8F202 ++:152CA00073905FCAF22BB1FC0AC80FF95199FC2CAAC4A2412BC1 ++:152CB5002FE8F906AD3CA0D71BB4D2428F374869A202F66465D7 ++:152CCA002D880E49BE4BA3D975BF93E469F845B99D8790EE4D6B ++:152CDF00090DAE3375D4FEABFB5D679A558E9F0F091BFD90302C ++:152CF4006E7F87C24A298CFC0DF88B679B555E76BACEB07167CF ++:152D0900E31CF5485B30EA2F719AE8329F770775CCF318EAC994 ++:152D1E00D3043B815FE0507298F1E3A7AC70EA135BE5C5866EE7 ++:152D3300E593FA2FA67F94E245D15F4A8B0DD105BBA3B3BFA3AF ++:152D4800C2549C74DEB7E498FAD62D7F8EFFF1EC5CE82698E770 ++:152D5D00F7656DD2B4C76AEA6D705D4699EB74145ADFFC9CB4E6 ++:152D720083788DD11C34D8447DA783251C4D4611ECA1469AD5B9 ++:152D8700C9EA66BE1E37F943E732E0046EAC898E533A0F6B8218 ++:152D9C004EB4514FB8A08E5673C90D4611BB8B60BFCB700622DC ++:152DB1009DE959FC24C1F463F25B06FADADA996B124159E77EE0 ++:152DC600E0EF029CCB151A44A29914EF6A10313F96AAF537A019 ++:152DDB003B2F85A8C826BD9EAF3BC17E6C33D7C9803BEA28A727 ++:152DF00032EA74942F9E2957A5785D186F57BCAE01EF28EA9AFF ++:152E05000E72191A71391FC3DE6230A8C5799B68D2225CD728D1 ++:152E1A0002FF58766E1BC58972FB879095CD33CF312DC2F5F20E ++:152E2F0037F133A82CB8C53C03CDB659F714242D5D08ACEBCEA1 ++:152E440025A012345F49E83A4B28D8DF81FBAD15E23296DEA113 ++:152E59007B64B1814577C2AE9C8BA565DDB4FF6AEA31D5670A9B ++:152E6E001A789E941F5F47C277B4574F2E882B42AA17DF464EDC ++:152E8300CF23FA5FFB50BF0AF9A02ECA670DA62768DE242EFB76 ++:152E9800EE83DFA5FC5FEE833FFCEAC9AF7F865F39F9F5CCF080 ++:152EAD00DBBA82E0925EEBFBFA83AF874860D63CF2157D1B3BFC ++:152EC200A355AC7C5D6DAF7A25F46CD3045FB75814BF44F57999 ++:152ED7004A5BB4F2BCEABA4FE336CACB2DBBF3934F88CBC4D496 ++:152EEC0090EEA0F15196BFDFC7F4EB862B69DAE3E476D4C70FBC ++:152F01003406307FA2F298FEB7C61DC2EB2AF051CC5E098D3CFA ++:152F1600F86623C142B4BD42F09DD7056D9FFAEC86D7B43B22A6 ++:152F2B005486B4CF20DCC56FAE581D72ED46F93B47D94821CDB2 ++:152F4000E3BE33EA725DA3F05DFDAEB6D7C9FFE97ED3FD3796FB ++:152F5500FB3FF59FC966FD7DF679C0E8CFFB128E333AF0B68DCF ++:152F6A008D6BF11F14367CEB5B850DD07FE84F3FAB2CBCF0B4B0 ++:152F7F005270FEA2BA865D0A2D1C3FA9422748F8C900F4F5CCDC ++:152F94003A120D70EED52FFD07F5FA43578C85C2CB14E792E1D4 ++:152FA9008A1F69C4BC15F94F3E745E77A50A1B469F285CC6F5AF ++:152FBE00645FE26BDE47138E14D1FAB88E7AFCE1507738708AB3 ++:152FD300F2977EA3A12E12608EFE68D485FD1069D75189C3FEC9 ++:152FE800E3A3AF513B2C96F726B3244F16C9DDF1FD714D11D6BF ++:152FFD0069D44E7FAEC36E288D00EC2917F610B4E464F5EF0D02 ++:153012008ABBE74DB97E5994E26F8FAD6EE0EBAF05E6594D31D5 ++:15302700F56DEA279D0DB1F1C30D4C3FAE4F82FFB0BE47E1EB7B ++:15303C00C95F4C1D211EEAE6F6486A2D7B41BCBDE97BB9DDF0EB ++:153051005ADED648AE4DEDA5B616D744A2ABC4B430DE2EA635C4 ++:15306600E08D3D3257EA00EC1D733BA2E5A9842EB85EC63C93F4 ++:15307B00DB0B052FA28DB8CE216CC88842EE4E258CBBE21AF7B7 ++:153090007FEF27541EB921134ED2D4D013131BCA486E445B997A ++:1530A500AC1E321606529D63379DCB0897C6E9F7B22E89E06916 ++:1530BA00A5322EA16D05FB349DFAE156CA97A5068C8BBC7E4946 ++:1530CF009DDAA91424C0DEEED6C24C3F053BDAA3E82F7747CE85 ++:1530E4002BBF7EB4B0A18F752B7DF1034AE91271595F64AF3217 ++:1530F9003FD1ABEEDFA929FB9B2F73D952CA1CEC5BB3A4F2B3DC ++:15310E007C8F28181FC5DA6BD9A204F600F58A14AF8FB986EDC6 ++:1531230032EDF5E3BB4D24193AF39A2EB411EFEAA78DFDE39A1A ++:1531380082F541576A80D2ED028EF95E5E79E6A0519179CEA8B5 ++:15314D0025BC54503D338524165038DA67ADBC8BDB6EE1794811 ++:153162009A7191E6A1E5F2533AB7B1B841D3289D8EBE418C1DA2 ++:15317700D3C3991F50DC5DD4467A699C1B509167762EF4786000 ++:15318C004B80BAFC7327D583F15EC5BBB257756843AA6B7CB87A ++:1531A10011E7E87DA78E98F6BC4F33B6003A00D029A39FB8AE2A ++:1531B60047A57AF73BD6ED53134579776CA4B1D69FD4BEF10F46 ++:1531CB00E28F0F0A9C667C0FC4977981EB03F25B806033057EB2 ++:1531E0002CC1F5B78013733F24C9F7438CF15EA53CD3D317CC90 ++:1531F500BC9092566ABC0F2958ABA9A2AC191E17F6B807B4DAA8 ++:15320A00C881469CF3F277116FD1BCB63C0EF7712360B985B33F ++:15321F0003AA392E1C307C194F03FCB0B6EFCAED8FF4F13D009A ++:15323400077097EED56B389DCCF3C9021BD1A0476D9E4B1EE5BE ++:153249007DE9AF282F612DFAB214A7AF903CA20616751B4F47B0 ++:15325E00CC73AC584B17BEA071BBBA12A7B3693B5AE23CFF9D4E ++:15327300A35761D392EA8DF56831437D5BFA3AA7435946C4B92C ++:15328800E57980A79CDB5F4A76DA773430FD4903F6C100A7902A ++:15329D00F986569B9917CAEFFBD1E783BEBCDFCFF5F9D4FF6FB5 ++:1532B2002A6CF765DEC638C06DAB48991EE3B1F7B37EDFFBE0EC ++:1532C700779306C0B12FB34F7768BD6A598BB9E7EFA07E03F7AF ++:1532DC00DE7858EF520FF1D042D61B02FDCE7D798A77CF59B649 ++:1532F1007F2F73DDAF894ECE7B4437B845BEDF11E7FB58A037C4 ++:15330600E8CB6D5EA19D133D67D292E3DEA2C3ED70FB9169045F ++:15331B001AE4E3DEA6C7C7A04131A7419FB5CF33458BDBD220BD ++:153330006FECB5F11F1B87BDB4D2603E2DBCB14F86605F8345EF ++:15334500BB466F3CF1C946295644E36C972E901FFAB1CDDF28C2 ++:15335A006C38F147FB3CA0D99F9413ADBC8B3443A03A8176A8A8 ++:15336F00A3B9E7639681F290B77DBE7D4A7E32E9B1208F16DB67 ++:15338400393C49D3EE0E85635F51CAEC3304EBBE1BB8953CFDD8 ++:15339900E3AD79E9B77E39A7E7CBF583FBD830D7DBDC049A7748 ++:1533AE000D2B1ED9C9FBE92D5C0F50D31744CCBE29D7EEA8CE2A ++:1533C300C2268CCBF4BEEF3CC701B553DFB63F98F5CDCCB8F661 ++:1533D8000BF6DCCB03C9CE052413C82C7534C8C68F4658E668BC ++:1533ED00F93F66DDF41E25F728F98F3659E93F28BE32313DBE77 ++:15340200CB8A8F717EE0EDBC32B1DF48F391FCB4A80F9F7B51F9 ++:153417007D6E92FCD28AF573792CFED499934A2189F6A2DC9BBD ++:15342C00849D9A62F97412679ECDFDA0717EE651928FD13C2606 ++:15344100A17B324B1A4E1FC8BA81878167B3EE9979E6C3C6F7CB ++:1534560031296DABFC8C7EFD558D64259C19485A7CF8EF0DCEEC ++:15346B00BB416EB37E723FC98F0D241F7D1CDE9C7CB5574F3836 ++:15348000481E1D11DB275FD58C84A3CF6895F71B6FDF44FB88C7 ++:153495005B73952EE32A6422A23FF657652A231F2737AE4CC7E0 ++:1534AA0027F6772DF9D6D47FD60774C8D202B52FD491DC46F8DA ++:1534BF00DF91FC188C72BBDF763E727A2A1FDFEFB3AE0A9CED31 ++:1534D4000994C32EB47E91CADC06BBF91968DC46344FA6562FE1 ++:1534E9003C15527F10AF0B753735F13EAB88D1DC287D9F562434 ++:1534FE003C4C7DCB9A19B2A6639928DFA7CB99681FEC1CBB5C2A ++:15351300D514DE66C9998B1B8B694EE3A8547859B08B0879DDE3 ++:15352800D915524B23A17031953D54754F634546A631B3562FB7 ++:15353D00CF0475C1D3A2767F3BA439C769FE986E326C7BD4D0FD ++:1535520001E132BFD445F2674D4874134CD1AF8C32FDA17E5706 ++:1535670012FB88FF9ABF332B1CCB6ED5BF29B7F4306AAD7E2D55 ++:15357C0048FD5A9302B9DF2B0B413E9709364DD94049BF30BA8B ++:15359100607C405D60DD59E0A3711C63314BBF64940957D55FDC ++:1535A60057977E96914CCED88426B1DF34FA846B6A69B5B301F8 ++:1535BB0072648464F60A6158D593DD4A39E618D46FA29F14DD49 ++:1535D000AF73FB344CDA31FA00FBEF212ECBC1760CB91792FC9F ++:1535E5008DB7FD5F2817B5E7DC83669A8FF23F9CCD06642ABF7B ++:1535FA00D1CA9FDBF69F257FFB1F4F4DE57DA7FCA73C0DEC3F98 ++:15360F0049B566F92E8259B6E250BF1E58287F32945F1FF84BF5 ++:15362400DC864D11CDA95ED259E685A33E6AE7C998735945E6DD ++:15363900A08EFE14BC8A7DF5329219DA16F42E8D903C8631F194 ++:15364E004B4E9DCB608DCF68215BEEDAF47EF603E52ECFBBD91D ++:153663000F94BB9A6691BB1CE78EA890BD206FD9F2574EEE8AAB ++:153678000C37E28CBB6F25CEBABFAE35DD9CDE1FF23E9368DB97 ++:15368D0056FD686331D7C99ED03CEC64A3EFD4FF22584E6A8B1D ++:1536A200334B7278704D38DB6D3CC006D104E1E9DECC1C93BEB6 ++:1536B700382B6386EB62F2B87A37A1A1006E2B0C7E080B4085CD ++:1536CC006486DF091AAF3E088F243B841D6DD7D41BEF645DC0D6 ++:1536E1002770566FE1B0E63D138715B3E010694EBFF32F8B4708 ++:1536F6003FE457C2E3A2C089CECBC063747F5FECF733AE95B49A ++:15370B007065F3FFEDDCF2CCF4D103FA1AD6A7DD4FF39DEFFF58 ++:15372000AC77A92C9F1AA5514CF30A24A74A970C9FD54E45E8FD ++:153735005348BF34B6B1CB5A99F0867AC7CA6BEA216A87341F91 ++:15374A006FC01AB85466A898FBB2F401CD357E90DE07B53B5395 ++:15375F00628397E6805EF6BAEA3D754515F8BD15A3DCBE14B79D ++:15377400AFF4438C1B716D60FC07E13B28DE1D142F30DE13B21D ++:153789006D3F4994066D54A638B63F6C3FC11FEDAB32736F4889 ++:15379E009A28E434E736A7CE5EE16D0AF76905327786A6EC5777 ++:1537B3005DE1FD43F0D5D2507EF9F2AB81696EE9D5CA696EE8E9 ++:1537C8005BCDA7B2E673B8BAF3E03A990757771E5C272DB8FEA1 ++:1537DD0084E072E6C175320FAE25A19976B582164FE7E0CAF8FC ++:1537F200A7C3955934CD0D9EA9A0B1B531833E90DF11C9F8DC00 ++:153807004700EF8C111DC61AE711CFCC3F457C263F63283769B9 ++:15381C009E9E7E5E0F73FB865D7DF192443BDCDBF85D55C7FA7E ++:15383100A00F5570866091BBFA1DE7BECD797284AFDD3CAF0766 ++:15384600E5471BCDB897B5EB2B8A96791E7885E629BFD45DF29A ++:15385B00F7FAEBE5FF61C47F37939F7A463DD07F4CADD7CC6F34 ++:15387000CCF37B46275698F98C52BE3E2BCF1B2B3636DECDFE86 ++:15388500A681CFD3F3E2222DF2C84F778EE2EC78F2921294FFC4 ++:15389A006229FC21BFD134EECFF0FD0C64B8684F0AF323A42D33 ++:1538AF00C6990FE25D9C27ACD8FF3CE763F4AFA2957FE9B4EFA6 ++:1538C400F92187F9DD572CCF0DD15B7770BD769DE7EF786E8FEB ++:1538D900CA714CF3761FC9FF46E405458A24D472C23F3FDF2953 ++:1538EE009936FF6FF72799272924D7ABD85767D24E2E1749FE99 ++:15390300B862CB455C4642D8C7908F6CD9C8929366958F201BEC ++:1539180041460A731B30391947D3CF99328E598ECCCAE5DF195D ++:15392D00F320EB92DCE492771B23D7B2AEE294962C26B8C3914D ++:153942004483BD76514E7216E224AF8166DD3AAB15DBB75F33B8 ++:15395700E5AEF11FF3701DE141C20FD2B3D4555D583041E3BBD3 ++:15396C00466D21A915A612712F9523A58EF5A19F04DF214FCC1D ++:15398100DFC17FB5F2ABFDE6BC7E265FF7F2FE653EC9C5DE53D5 ++:153996007B492619D3C08315046BEB1FF3E55FAB8E54B7792958 ++:1539AB00677BE6CDACBF96E4DD6DBF356556BE1741F09D79D3A5 ++:1539C0004C531630CF6FB9ACFDDFD1F9CC4D7329F7C83CD38DB4 ++:1539D500F3A3DB1DCC7D86FEE6FCB0D6B28F62EA383953423B4C ++:1539EA00F33569F6D962CF4F894F4E35ABAB683EE6EC1A547BD6 ++:1539FF00D3834AA5EC6C59287FFA73580BE669A43A35771E3916 ++:153A14005A4D7C24F488B16ADD29615D59E879E3505D985DEFCD ++:153A2900D2B6FC149750CD9C0F4D2F7F55BC6EE93FAB9C5BF459 ++:153A3E00C7829D35F35989242D56A12F0E5D0DD843724A7FCB73 ++:153A5300F57BEF4ABDDF0ADDBFC03743E8C3B84E1FB761111D23 ++:153A680036D6523CBB3CF8B7927BEACE013E472F96024D9DA766 ++:153A7D0003B0AF54DBF95E00F936987A72E5ACC4131BA4B1734E ++:153A9200897AA72C34632FD513AB366E90BFF8CD2EDDD4AB1599 ++:153AA7007B2E5AF32BA7B443FD1585C13E682FE250BDB0372D1B ++:153ABC0043F78FFCC4D8A031067FFA7EA390B92F5BE98AC87D98 ++:153AD10095FCF11E221AC35ED698C33CB3DB0B9AFB26614796E4 ++:153AE600158DC02EE7354DBAF08C02BDEC729C75938E692ECFE7 ++:153AFB0011751DD1769E2CB6176506349CF3A8A07E349041FC40 ++:153B1000BD3B30C60996EDC0BB52AD4B258F797608B675E6F2B3 ++:153B25003C87FB711F93CB8CE32B4F894B85915BD3B26811D7DC ++:153B3A00D7D6096F61BF797616FA59B09B0A3D948C1F77C324AA ++:153B4F0072F73188F2756333D14D24BC78A82DC7E89BCDB21F0F ++:153B64001B8CB9B458E6C747C52B5DEA7B3E3BDF8A5CBE492BCA ++:153B7900DF98653B7B0FF52D63458C9F1966E9B8C1F793A4B0E2 ++:153B8E00265436758A995AC395811FD12AD3C4CB2FCF4C92FB54 ++:153BA3004CA79449519EB14EACB3EF59B049E17D5BE596CE8A23 ++:153BB8000C6C185CEE14E5AF196301933F6A284D6D26DD5F4F2A ++:153BCD00E9C3945FEB3CE60E527A13B63FE9036CB0B3BC0A7361 ++:153BE20028669F5B8E744632EF187B16449508CF53E98C929B8F ++:153BF700E21F5D4DEF18E55D4873DAFB33878C48E6E9BEB68CD8 ++:153C0C00DE1FA537F6A8A3F43D4EE10A9595F65AB6C4598AE365 ++:153C210000F64B61F3B13393321EA17C63049B0FFC4AB8AAA7B5 ++:153C3600B78BDEB0D12B5378057DAFA63C7CF4AEA1F9DA26FA1D ++:153C4B009E9807DE265C915F1BF989D4D75C24BF60C0A4476CD9 ++:153C6000864D72E795B84A7C57E295C5E50579F412008F3C64E5 ++:153C7500604D35280F515F3764CC464FF33C53588B3A58C9DDD8 ++:153C8A00A987C2683785CDB216E53AAD757A39BF43A8CB30756C ++:153C9F001D841E3B8F149559D537C8CFB5080BE2EA947DA00895 ++:153CB400C50B6B8CF2EB015E7CB5B9BE6DE2EF3106D6A9B8178D ++:153CC90061B1DCBE946DFD5DB7F21BC6EC7CD8D62E2DF8736B0E ++:153CDE00FF6BEBA0B685BE7B6467BB2B074FB3BE10E310C27EAD ++:153CF30063EAC9D7DBFD13F9457F0E5DD365CB5D046B8C997058 ++:153D0800DBF4E6772A5AE9026CF972B6B599E76FEB8B230DE54F ++:153D1D005552CA5A7918F22A0ADC8A2FB46F9F30759E439A7424 ++:153D3200501D4772753C7701753CA2AE8149D46F0EEB9317007C ++:153D4700306C5F99FB57F2CF281AFD23F48FD23F46FF2DF48FD5 ++:153D5C00D35FA77F8AFEA3F41FFF9919976DED36EB6A9EF9E018 ++:153D71006E7D867B74863B3DC33D39C32DBD36DD1D9CE18ECEF0 ++:153D8600706F99E1D667B8475FCB3B9342F86913A6DBB78880A5 ++:153D9B0076BED19C5DB049AA97BFEBB85ACACF365BF9548E74A6 ++:153DB000626D684D6C43D87F7258AFBD083A4DE14D21F726FA49 ++:153DC5006FA37F92FE7DF41FA1FF09FA9FA1FF65FA4FD0FFC613 ++:153DDA0045332E3B36CCF196B2E94F6EE04DCF73036FF13C37CD ++:153DEF00F0B625CF0DBCC5F2DCC05B34CF0DBC45F2DCC05B3084 ++:153E0400CF0DBCC9F9E5BF36657F93974F6E7F73CA006F433FFD ++:153E19005A7C62C33DB67D048EB3D9EC7F107E3D2C0FBF33E3C5 ++:153E2E00FC33C3D1F78C91FC42B2947E7A0E734357B658165B92 ++:153E4300FA04E676D137F5332D1E1A238BE5459FBD48E36205B5 ++:153E58007D838EA2B44BDD5C467DD65C56F218AB6989CC35FBFF ++:153E6D00B407E83B3CD7ECCB2A59CD725BFF49869D72DCFB4582 ++:153E820079006793A5347E53FA8952C80E2F4ED9E92019F152A8 ++:153E970055178DCB872123E8932B9CCB4F531CB96CF6F1C91EC9 ++:153EAC00E7B0378FF1689299363AEC781E2A77A7659780E49DE9 ++:153EC100E597292F3797F7A7F7631504EF7609E321E48BDDFA81 ++:153ED6009E18CEA5BDA8EF881CE6F5777FC6D92EC9753AFA7C2A ++:153EEB009C112A5B79006BB9DA9639D89F1AD499FEA2EE178621 ++:153F0000D516D6CDE377BB87156141138DAD83460DD54D243929 ++:153F150097DB268FEED52ECEC538A6774A65499EC7988764486F ++:153F2A004AE3925FD4451A8BDDA558571EA4BEFC450378AE91FA ++:153F3F004CF903B0A63DD3E5BB9139ACE434E5979A8371A6469B ++:153F54004FF0B1A9968F4D380F2B2C08727B0A976F66DDC5F1B1 ++:153F6900AE1667B45695E56AFD8D15C2F2CD94E6CC5C5326B23D ++:153F7E00F1E0B5740FA7F477653D4EBC29A57772BB7EC85FBA96 ++:153F9300F02905E78C00B33732B854245945A43C2729CF769297 ++:153FA800A9708E49E4BAD87C1C862D490379A0BD8BB161C323AE ++:153FBD009BF7BA66B91EFF8B9A9FFA7C51FE9E81F8B8FB976419 ++:153FD200B00D1305243FE3CEC7BCFBA71294C7DFC588F762B02A ++:153FE700B561DA75FFCF6CB0C5436E8C33C065A498B9DF269E84 ++:153FFC007D8B75B5D8B09B3819E17D13F2E0677ED892161BEE59 ++:15401100EB0437F45D890E25B02303DE100907176F64DDF6BD19 ++:1540260005F9750AE4D5C91E6F502FAEB740FD1DE0728ED39C6C ++:15403B00233AA6F13A4883FD34F7A07AEF9EB2731CEBD27ADD53 ++:15405000CCBD8660B5D37C2ED2DD029D8B9F1CF9E5618F5C6F8D ++:15406500F8B9AEB24A6D76B561C32ECA87F9BC0DDF18E3250BE4 ++:15407A00476B2D386D3D4E0B977EEC15D7539837262EF7154C5C ++:15408F00B50DC95DA39AF7EBF6F1F28C5343CB59380C1D8CAC5D ++:1540A400B96796CD7EEB5498FC123AEE46294B3FA9965DB84765 ++:1540B900914EAD542B65472BD7C94EEF864E94DB9D3F6E5A70DC ++:1540CE0036B0257C5C1E7531F715AAE32F88F7D8D6E7795E88FB ++:1540E300EF425F1F1EE2F7AEF0F34BADF5FCDC0EC9E1FA77E3C0 ++:1540F800832D38D303FC3E8D7B0B49A6B5F0EEF5669C2DF321EE ++:15410D00AF674EEAD71F7C69F92FC88D3A8B99E1D9F98D706485 ++:15412200F29BC93F9ECC71FD40C6D91E681DE6E5A19D99F4946F ++:15413700394EEDFE5A6C5D82B51884EB95E38361BBBE51613A5F ++:15414C005F42CFE6664C6801DC36DEDE1C1FE27D8027467D8299 ++:1541610055CE2F288F8F5AA7CA8C7379B0783A2FB6BD9D75AFA9 ++:15417600263A7A62797591BFA7439F3257179AC398F5AFCDD556 ++:15418B00057088AD9FE675E1788A0D7E209E9C528D6AAD9364C6 ++:1541A000515FD7A9FD5C671573A30187D54F100EA84F77E7EEE2 ++:1541B5004C487769E7FE68EB0FD7F33A411FDC4EFB08A503BD44 ++:1541CA00FB284D7E3FB3ED7D935F3DF2615D8E0D695F8F0C8732 ++:1541DF0050367851DA3E669E8B4C0FD37CA11BFB9D567D877409 ++:1541F400BBAD88992386E41E56CBA8CF3D48732B4F06FD8A6685 ++:15420900D5FFC454FD892FE6B79EE4F59F4F74B3E89B1B438A6B ++:15421E00D1DFF1F6A0C1DE7FAE3DDC840D9FF0B169EDE1B7E3CD ++:15423300C7B85D1FE0ACE121D35E01CA798EED6D215E36DB49B7 ++:154248006BB7C9C7046B4F1C67F0F5CE03B8B3217A7206BD7508 ++:15425D0093DE5563CB0D727B624379743DA623CD145D87AC7ADB ++:154272002579BDD0E794B5EEE5755A98129783F76D5AE6F89743 ++:15428700FCC414EE0A49E83DD4FECC7B42CC7AFC35F1A7CD8B26 ++:15429C005E36D6524AE503961B04CB42E2BD6345D379EFDCFF00 ++:1542B10026BE93F3E08B117CB13CF8641B3EB35FE2F86CEDE6C9 ++:1542C600F0E5F70BF1EBA6CE03DE62CCBC07588F24B694E68D22 ++:1542DB0039F1776D5ECACD5DBD2CDCCB710B5B2C7D93D9921C44 ++:1542F000EF916CF32B9C55785EBC478A99F36F6FE4B0FA32A58C ++:15430500F1578BED6517FA1487C0CAE6212C7D4C972EA414DCF3 ++:15431A00F17094609530E610FF6C06AFBA20776A5A2070A253C4 ++:15432F00261929FE646FFB0EF827DF411FBEC375EE24D7DB9887 ++:15434400A8DABB8CA5C7742328B4239FCAC45ED89CF3CDC7FD16 ++:1543590068E49FC07AB5B4D710293FECCD7337952BF23DC1BDA2 ++:15436E00064F87B2F4BDD07F9E87BB95BBCC343BE234A7C7BA03 ++:15438300886BAD063D0E3FD7A1B3E6F412BF4F604CDFD9A6299D ++:1543980005EBAEABF16CD6DBFB794D419D454A539938B201F0C4 ++:1543AD0063EC042C80CD4F75692218FC174E28F36354D7B3DF2C ++:1543C20056BD4CA33E3CA57C1FE38295A77876402519D88B7446 ++:1543D70076DD7B28FFE4BEE3FC1E66F00B8F1B3DB6C3B5FB1DAF ++:1543EC003503D8A84EA80BBB3EA0812EC003D34F6AC06723D44E ++:154401005C28DCC6C5E51C1ECCB27278C07A6DDAC443E08762E3 ++:154416004B721D742486B52EF2EF457B219CC00F6B1B18834D1B ++:15442B00784F120E8E28C8BF60DDEFD5ED1C0F479432AA1F70F9 ++:1544400020E15C15D5DB853B83A82CD84C0E52F99581894EDBE9 ++:154455001EB2699F27AEE9C4837B162495B7D884B628C8FEB2C2 ++:15446A0046163F97B3D7F917DC1E32B79BD4C6D70896F49B67EE ++:15447F005B933C5D24B30B7756B8E98D7D6023F6EE149FE33C0E ++:1544940023D6AAC0A3F5984B439736D8A4E937B89E663F8DB948 ++:1544A900E3F15A67BBE00AAB623CA40E10AC55CA28EEB9D475D6 ++:1544BE00F9402B9F9F521C89FA0E8FFCC51697FCB51649FED26B ++:1544D30072312A63BC1EBF4AF230DE9D984B455FE43695FDCD24 ++:1544E800B261E60F9971703C4861F594BE96D2D7507AF855C8F3 ++:1544FD005F6AB1F3207E6AF150B88BC2AFAEF81ACFCFC3E766D2 ++:15451200BFDB61C7D9827208265FF3A499B76EC20D1C85D136AC ++:1545270008CE7AF9D556B1396864281CEB05AD349F1692215583 ++:15453C008A630FD88C8FFC8807FC22E58378FC7C020EA4C7CC33 ++:15455100FB80D0869B9835BF06CF4B435639239DB02952CE6D45 ++:154566004F987E9833C18FEB1B9A67316E992F098249CF9C3FD4 ++:15457B00E55F61CF7FB85E2A95CFEF384B195BDEBD75CE659ECD ++:154590007D1DD11186FE07772CF8ADFEC69FFE8EEABBF01D0521 ++:1545A500F2AAAFF59879AF1085F930F767C731BE6BAFFCB680E3 ++:1545BA00558C1F6FDC42E39EC79A67983AB0A69C833B095CF13E ++:1545CF00234BE793ECE943BEC111138E5C3F99E4F0F9228930CA ++:1545E400B76F426EE4591E196AACC8CB333777A13E97A7B7FA20 ++:1545F900CFDF5AFC8C7A606E47B079AFF2359D9AA934F9E76932 ++:15460E00F9FDE74F69FF384BBAC333D211BFEBB3AD27453287BE ++:15462300B4FF394BFACD1F21FDB559D2856F0BEF216D6296747F ++:15463800EFB1DB9737F9FE8CFD27ACEFE4F31FD6FCDF9DBEBE22 ++:15464D0031335CFAC38787C76F17FE7F3BFF19E19E7CFEFFB008 ++:15466200F581FF1FFE4F0A97F2F0EF9DD92FFD3F03BFC51FD198 ++:154677008F971EED6B9E287359ECCBDC46536D67B7147B641541 ++:15468C0035454FD9A3AA46E1B82BDA73EF6E15ED14E3A4A76CC6 ++:1546A100933A67F56E55961FD7E6DCDBA5FAD6698A47A8567DC5 ++:1546B600A5D56A82E416AB4D6FB84163B35456AB22BF7F6A5E9C ++:1546CB0087EED314EC110BEB30778969D0A813E582F6AF539F69 ++:1546E000ECF754ABC5EBEAD5E7EEAB53AAD6D52901CF236A774F ++:1546F500C1A714DCC5B8488CD973151FE28BC22754BEF6B0BABF ++:15470A008BF71DE843AA4A130AF413ED702F0FAF539D65712E7A ++:15471F00DF553D1057F9FE1264E459605865C15042301C22180D ++:15473400FC79E5A3DC4A8201F178BE947F7ED937AC7C27F3F2CE ++:15474900CD665FC97A60EB20C4DAD7331640DEF18298067C644E ++:15475E009999D7DD8CCD9B4FB8F15099EEB57584A36A6591A745 ++:154773005EADF88CD8EE645D1D557F25B61F9A9BE034C0BA4825 ++:1547880090E0C01EDC5DDC76DA14EC5EAE07833DB8F813BC6EA9 ++:15479D0004D3390BA631D4DD73BF5AB56FBD2A94DAB0656FDA01 ++:1547B200B0B5106CE59E6AEE1F2701D1A697BBB45EF5709876A1 ++:1547C7002B8B4A13EAFE9D7B72BC003CFF219BB56060BC9EB026 ++:1547DC000966EE374F3E8172D3161CB81FEC0C7DCFD54C18CA91 ++:1547F100F6D5A865541EEAD66E9D4D81D226C74BD1145EAA8851 ++:15480600774AD6B6AAFE75610ECFAE82DD4A31E1A5C493500B35 ++:15481B0059A2638FC59B8B79DDA7CA9DA0B2740A2B237C11DDC4 ++:15483000BD360CA07D55DBFD0A64A1AA75F72B33E94F8DA8AC8E ++:1548450098EF1B4CB5A7AA33033C9E70BE5EF53F105345F6B844 ++:15485A003A87E23E27B080D3FA36E8BB641DC149FC52521A56D0 ++:15486F00B51F352B87CE362B25E7D7AA7E8DFCF6AD56B5CFAF8A ++:1548840021DE5FA38007FC84D3AAB5262EC498D02EB34D9CB7E4 ++:15489900494EF3398587544FAC0077EBF8DCD8ABA96CEB9C2374 ++:1548AE003CAC7AC455AA67259577EF63AA67F51A756FC12A05F2 ++:1548C300FA1EE2CAA9F84501F31C188F9F0899F15FFEAAEA3924 ++:1548D800DDACEEDD19529C34EE96FDE811A5EA3305EDB0BDEDB4 ++:1548ED008A873ADCE3CD1D07610F4D0BA955E71F528573CDAA2E ++:15490200467105D7142DB6A28D07F8B9B10DB005E4EAA274A731 ++:154917009A3BF85CAF89B51796053B8ACA9A3AAA92EB955DD473 ++:15492C0037C8E4DF43EFBF449FF3F71B554F4FB30AB95A961F63 ++:15494100866CE7F224BEAA0A6B1F5779D8CBCD141E52F712CEDB ++:15495600407FF038E624C5FF5168AF3A4F38D4BA54FFF9AFAA3B ++:15496B0025E776731ED84F3C3087685F1CD13AF2FB25D01DB469 ++:15498000E33AF5164DC193F7122CED809FF08CBB49D7D177A2D7 ++:1549950060B33287CA01FCDD3BCDEF5537B37EF44BB61B7169FF ++:1549AA006CD83090C51A8EC9DB064DAD803FF47B34E79A67F3A6 ++:1549BF00D5368AC3CF47100C9B67E80797FDA842A93A574EB8AA ++:1549D4002D5767E3A337D9141FFD9A997C041A14131F053C9B2E ++:1549E900395E9EB378097CE4D7C86F062FED8EFFF9C6E2C026AC ++:1549FE00A24FAC73377B78E39C40B453F03CA6DAEE92C8C31BD2 ++:154A130041A7395DEB3BD8D9F60EFB5D75CDC1EF702A8EAFEF25 ++:154A280028196FEF10DC44F34F546B4EA2C34DA23DF07737A785 ++:154A3D0085A3BD44DB4174788CE8B087F7E9F9B428B0689130FA ++:154A5200EF8EF209AE4F50D9D10D67385DC037D10D6333E84242 ++:154A670034F13E60D185FA5DEFFA3CBADC994797B7B8CEEF5418 ++:154A7C00DBDE49EDBA378F4EDCFE38F100FCB75BB4BA803BFF2F ++:154A91002CDA6CFA98F4B894478FBFB3E88136EDB768710B1D40 ++:154AA6008836F9B4288A7C65636164FD46B68DB57BC6BFD23197 ++:154ABB0047DAD451C4FECDC6E2F8BFEDF08C3FCCDD557FC5DBED ++:154AD000ABD7C3C81D799CE35DDC5EAD39A8EFBD5914D58A6DA5 ++:154AE500BC533B2DF1ECA4FEEF5FA9256B9F9C86F7E2D9F09E3E ++:154AFA005C0C9AE7E13DC6F16ED7371FFFD4E77BEFB5F08F35C1 ++:154B0F0011B4131BFFDE3CFC3BF8DA8689DF5E0BBFA5E8A7280A ++:154B2400AC92E65AF96DC04EFF261F174C9A211DE8A658743081 ++:154B3900711E9E06CBB708CF9E94D0FE32BD13D4F714521EB8D2 ++:154B4E00FFFDD0171F51ABD6B52A52C152A5A8E01E053CECA121 ++:154B6300BE879D6DEE38F4530A3BBF56F1167C5E71177CC10C75 ++:154B7800135675B0FBD674EC8A39DA01D762E084CA261E292BCC ++:154B8D00941D7C8C843FECB9D87314940FBBA705F6D86D8D1FA2 ++:154BA20088075D7FC0F55A36EBA338B9B6FF32B57D8C5D9768CE ++:154BB7003A89F512C80734D6F94E5BF1BF4FDF55D744BCBD27B6 ++:154BCC00785E4975BF63E8117EC65230EF62A69125EB8D0C3DF1 ++:154BE1006A308DEB88C1DF37B5DE5AFC7F00E871AED038A00037 ++:014BF60000BE ++:00000001FF --- ref/drivers/atm/suni.c Wed Sep 8 20:14:32 1999 -+++ work/drivers/atm/suni.c Mon Nov 22 13:56:16 1999 -@@ -181,14 +181,19 @@ ++++ work/drivers/atm/suni.c Fri Jan 21 16:01:05 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/suni.c - PMC SUNI (PHY) driver */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include +@@ -181,19 +181,24 @@ case SONET_GETFRSENSE: return -EINVAL; case SUNI_SETLOOP: @@ -1307,8 +13914,41 @@ case SUNI_GETLOOP: return put_user(PRIV(dev)->loop_mode,(int *) arg) ? -EFAULT : 0; + default: +- return -EINVAL; ++ return -ENOIOCTLCMD; + } + } + +--- ref/drivers/atm/uPD98402.c Thu Aug 26 21:42:33 1999 ++++ work/drivers/atm/uPD98402.c Fri Jan 21 16:01:05 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/uPD98402.c - NEC uPD98402 (PHY) declarations */ + +-/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include +@@ -118,7 +118,7 @@ + case SONET_GETFRSENSE: + return get_sense(dev,arg); + default: +- return -EINVAL; ++ return -ENOIOCTLCMD; + } + } + --- ref/drivers/atm/zatm.c Wed Sep 8 20:14:32 1999 -+++ work/drivers/atm/zatm.c Tue Nov 30 20:50:06 1999 ++++ work/drivers/atm/zatm.c Fri Jan 21 16:01:05 2000 +@@ -1,6 +1,6 @@ + /* drivers/atm/zatm.c - ZeitNet ZN122x device driver */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include @@ -729,9 +729,6 @@ zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) | ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos); @@ -1319,6 +13959,15 @@ return 0; } +@@ -1701,7 +1698,7 @@ + } + #endif + default: +- if (!dev->phy->ioctl) return -EINVAL; ++ if (!dev->phy->ioctl) return -ENOIOCTLCMD; + return dev->phy->ioctl(dev,cmd,arg); + } + } @@ -1710,21 +1707,6 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen) @@ -1341,8 +13990,49 @@ return -EINVAL; } ---- ref/include/linux/atm.h Fri Nov 12 20:29:16 1999 -+++ work/include/linux/atm.h Tue Nov 30 21:34:47 1999 +@@ -1797,21 +1779,17 @@ + + + static const struct atmdev_ops ops = { +- NULL, /* no dev_close */ +- zatm_open, +- zatm_close, +- zatm_ioctl, +- zatm_getsockopt, +- zatm_setsockopt, +- zatm_send, +- NULL /*zatm_sg_send*/, +- NULL, /* no send_oam */ +- zatm_phy_put, +- zatm_phy_get, +- zatm_feedback, +- zatm_change_qos, +- NULL, /* no free_rx_skb */ +- NULL /* no proc_read */ ++ open: zatm_open, ++ close: zatm_close, ++ ioctl: zatm_ioctl, ++ getsockopt: zatm_getsockopt, ++ setsockopt: zatm_setsockopt, ++ send: zatm_send, ++ /*zatm_sg_send*/ ++ phy_put: zatm_phy_put, ++ phy_get: zatm_phy_get, ++ feedback: zatm_feedback, ++ change_qos: zatm_change_qos, + }; + + +--- ref/include/linux/atm.h Fri Jan 21 01:06:57 2000 ++++ work/include/linux/atm.h Fri Jan 21 16:47:33 2000 +@@ -1,6 +1,6 @@ + /* atm.h - general ATM declarations */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + /* @@ -20,6 +20,7 @@ #include #include @@ -1375,7 +14065,26 @@ /* ATM cell header (for AAL0) */ -@@ -158,8 +142,9 @@ +@@ -154,12 +138,28 @@ + int min_pcr; /* minimum PCR in cells per second */ + int max_cdv; /* maximum CDV in microseconds */ + int max_sdu; /* maximum SDU in bytes */ ++ /* extra params for ABR */ ++ unsigned int icr; /* Initial Cell Rate (24-bit) */ ++ unsigned int tbe; /* Transient Buffer Exposure (24-bit) */ ++ unsigned int frtt : 24; /* Fixed Round Trip Time (24-bit) */ ++ unsigned int rif : 4; /* Rate Increment Factor (4-bit) */ ++ unsigned int rdf : 4; /* Rate Decrease Factor (4-bit) */ ++ unsigned int nrm_pres :1; /* nrm present bit */ ++ unsigned int trm_pres :1; /* rm present bit */ ++ unsigned int adtf_pres :1; /* adtf present bit */ ++ unsigned int cdf_pres :1; /* cdf present bit*/ ++ unsigned int nrm :3; /* Max # of Cells for each forward RM cell (3-bit) */ ++ unsigned int trm :3; /* Time between forward RM cells (3-bit) */ ++ unsigned int adtf :10; /* ACR Decrease Time Factor (10-bit) */ ++ unsigned int cdf :3; /* Cutoff Decrease Factor (3-bit) */ ++ unsigned int spare :9; /* spare bits */ + }; struct atm_qos { struct atm_trafprm txtp; /* parameters in TX direction */ @@ -1387,7 +14096,7 @@ }; /* PVC addressing */ -@@ -177,7 +162,7 @@ +@@ -177,7 +177,7 @@ short itf; /* ATM interface */ short vpi; /* VPI (only 8 bits at UNI) */ int vci; /* VCI (only 16 bits at UNI) */ @@ -1396,7 +14105,7 @@ }; /* SVC addressing */ -@@ -209,7 +194,7 @@ +@@ -209,7 +209,7 @@ /* unused addresses must be bzero'ed */ char lij_type; /* role in LIJ call; one of ATM_LIJ* */ uint32_t lij_id; /* LIJ call identifier */ @@ -1405,8 +14114,46 @@ }; ---- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atm_idt77105.h Mon Nov 22 14:26:39 1999 +@@ -234,10 +234,6 @@ + int length; + void *arg; + }; +- +- +-#define ATM_CREATE_LEAF _IO('a',ATMIOC_SPECIAL+2) +- /* create a point-to-multipoint leaf socket */ + + + #ifdef __KERNEL__ +--- ref/include/linux/atm_eni.h Mon Aug 23 18:56:31 1999 ++++ work/include/linux/atm_eni.h Fri Jan 21 16:47:37 2000 +@@ -1,7 +1,7 @@ + /* atm_eni.h - Driver-specific declarations of the ENI driver (for use by + driver-specific utilities) */ + +-/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #ifndef LINUX_ATM_ENI_H +@@ -9,7 +9,15 @@ + + #include + ++ ++struct eni_multipliers { ++ int tx,rx; /* values are in percent and must be > 100 */ ++}; ++ ++ + #define ENI_MEMDUMP _IOW('a',ATMIOC_SARPRV,struct atmif_sioc) + /* printk memory map */ ++#define ENI_SETMULT _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) ++ /* set buffer multipliers */ + + #endif +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/include/linux/atm_idt77105.h Fri Jan 21 16:01:06 2000 @@ -0,0 +1,40 @@ +/* atm_idt77105.h - Driver-specific declarations of the IDT77105 driver (for + * use by driver-specific utilities) */ @@ -1449,7 +14196,7 @@ + +#endif --- ref/include/linux/atm_nicstar.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atm_nicstar.h Tue Nov 30 21:42:31 1999 ++++ work/include/linux/atm_nicstar.h Fri Jan 21 16:47:47 2000 @@ -18,6 +18,7 @@ * sys/types.h for struct timeval */ @@ -1468,8 +14215,15 @@ typedef struct pool_levels --- ref/include/linux/atm_tcp.h Wed Sep 8 20:14:32 1999 -+++ work/include/linux/atm_tcp.h Tue Nov 30 21:46:18 1999 -@@ -7,6 +7,8 @@ ++++ work/include/linux/atm_tcp.h Fri Jan 21 16:48:05 2000 +@@ -1,12 +1,14 @@ + /* atm_tcp.h - Driver-specific declarations of the ATMTCP driver (for use by + driver-specific utilities) */ + +-/* Written 1997-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */ + + #ifndef LINUX_ATM_TCP_H #define LINUX_ATM_TCP_H @@ -1483,8 +14237,9 @@ struct atmtcp_control { struct atmtcp_hdr hdr; /* must be first */ - int type; /* message type; both directions */ +- unsigned long vcc; /* both directions */ + int type; /* message type; both directions */ - unsigned long vcc; /* both directions */ ++ atm_kptr_t vcc; /* both directions */ struct sockaddr_atmpvc addr; /* suggested value from kernel */ struct atm_qos qos; /* both directions */ int result; /* to kernel only */ @@ -1494,7 +14249,7 @@ /* * Field usage: --- ref/include/linux/atm_zatm.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atm_zatm.h Tue Nov 30 21:42:28 1999 ++++ work/include/linux/atm_zatm.h Fri Jan 21 16:47:42 2000 @@ -1,7 +1,7 @@ /* atm_zatm.h - Driver-specific declarations of the ZATM driver (for use by driver-specific utilities) */ @@ -1512,23 +14267,17 @@ #include #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) ---- /dev/null Tue Jan 1 05:00:00 1980 -+++ work/include/linux/atmapi.h Tue Nov 23 23:54:59 1999 -@@ -0,0 +1,23 @@ +--- /dev/null Tue May 5 22:32:27 1998 ++++ work/include/linux/atmapi.h Fri Jan 21 16:01:06 2000 +@@ -0,0 +1,29 @@ +/* atmapi.h - ATM API user space/kernel compatibility */ + -+/* Written 1999 by Werner Almesberger, EPFL ICA */ ++/* Written 1999,2000 by Werner Almesberger, EPFL ICA */ + + +#ifndef _LINUX_ATMAPI_H +#define _LINUX_ATMAPI_H + -+#ifdef __sparc_v9__ -+typedef unsigned long atm_kptr_int_t; -+#else -+typedef unsigned long long atm_kptr_int_t; -+#endif -+ +#ifdef __sparc__ +/* such alignment is not required on 32 bit sparcs, but we can't + figure that we are on a sparc64 while compiling user-space programs. */ @@ -1537,9 +14286,21 @@ +#define __ATM_API_ALIGN +#endif + ++ ++/* ++ * Opaque type for kernel pointers. Note that _ is never accessed. We need ++ * the struct in order hide the array, so that we can make simple assignments ++ * instead of being forced to use memcpy. It also improves error reporting for ++ * code that still assumes that we're passing unsigned longs. ++ * ++ * Convention: NULL pointers are passed as a field of all zeroes. ++ */ ++ ++typedef struct { unsigned char _[8]; } atm_kptr_t; ++ +#endif ---- ref/include/linux/atmarp.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmarp.h Tue Nov 30 22:00:07 1999 +--- ref/include/linux/atmarp.h Fri Jan 21 01:07:54 2000 ++++ work/include/linux/atmarp.h Fri Jan 21 16:53:11 2000 @@ -1,6 +1,6 @@ /* atmarp.h - ATM ARP protocol and kernel-demon interface definitions */ @@ -1556,8 +14317,8 @@ #include ---- ref/include/linux/atmdev.h Fri Nov 12 20:29:17 1999 -+++ work/include/linux/atmdev.h Wed Dec 1 02:00:42 1999 +--- ref/include/linux/atmdev.h Fri Jan 21 01:07:08 2000 ++++ work/include/linux/atmdev.h Fri Jan 21 16:47:33 2000 @@ -8,6 +8,8 @@ @@ -1666,7 +14427,7 @@ --- ref/include/linux/atmioc.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmioc.h Mon Nov 22 13:56:17 1999 ++++ work/include/linux/atmioc.h Fri Jan 21 16:01:07 2000 @@ -1,10 +1,10 @@ /* atmioc.h - ranges for ATM-related ioctl numbers */ @@ -1681,7 +14442,7 @@ */ --- ref/include/linux/atmlec.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmlec.h Tue Nov 30 22:00:15 1999 ++++ work/include/linux/atmlec.h Fri Jan 21 16:54:11 2000 @@ -9,6 +9,7 @@ #ifndef _ATMLEC_H_ #define _ATMLEC_H_ @@ -1736,7 +14497,7 @@ struct atmlec_ioc { int dev_num; --- ref/include/linux/atmmpc.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmmpc.h Tue Nov 30 22:00:15 1999 ++++ work/include/linux/atmmpc.h Fri Jan 21 16:54:11 2000 @@ -1,6 +1,7 @@ #ifndef _ATMMPC_H_ #define _ATMMPC_H_ @@ -1784,7 +14545,7 @@ #endif /* _ATMMPC_H_ */ - --- ref/include/linux/atmsap.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/atmsap.h Tue Nov 30 21:34:47 1999 ++++ work/include/linux/atmsap.h Fri Jan 21 16:01:07 2000 @@ -1,11 +1,13 @@ /* atmsap.h - ATM Service Access Point addressing definitions */ @@ -1842,8 +14603,14 @@ --- ref/include/linux/atmsvc.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/atmsvc.h Tue Nov 30 22:02:12 1999 -@@ -6,6 +6,7 @@ ++++ work/include/linux/atmsvc.h Fri Jan 21 16:54:11 2000 +@@ -1,11 +1,12 @@ + /* atmsvc.h - ATM signaling kernel-demon interface definitions */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + #ifndef _LINUX_ATMSVC_H #define _LINUX_ATMSVC_H @@ -1857,12 +14624,12 @@ enum atmsvc_msg_type type; - unsigned long vcc; - unsigned long listen_vcc; /* indicate */ -+ atm_kptr_int_t vcc; -+ atm_kptr_int_t listen_vcc; /* indicate */ ++ atm_kptr_t vcc; ++ atm_kptr_t listen_vcc; /* indicate */ int reply; /* for okay and close: */ /* < 0: error before active */ /* (sigd has discarded ctx) */ -@@ -31,9 +32,9 @@ +@@ -31,12 +32,12 @@ struct sockaddr_atmsvc local; /* local SVC address */ struct atm_qos qos; /* QOS parameters */ struct atm_sap sap; /* SAP */ @@ -1873,9 +14640,13 @@ +} __ATM_API_ALIGN; /* - * Message contents: see ftp://lrcftp.epfl.ch/pub/linux/atm/docs/isp-*.tar.gz +- * Message contents: see ftp://lrcftp.epfl.ch/pub/linux/atm/docs/isp-*.tar.gz ++ * Message contents: see ftp://icaftp.epfl.ch/pub/linux/atm/docs/isp-*.tar.gz + */ + + /* --- ref/include/linux/sonet.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/sonet.h Mon Nov 22 13:56:17 1999 ++++ work/include/linux/sonet.h Fri Jan 21 16:01:07 2000 @@ -1,22 +1,22 @@ /* sonet.h - SONET/SHD physical layer control */ @@ -1910,8 +14681,8 @@ #define SONET_GETSTAT _IOR('a',ATMIOC_PHYTYP,struct sonet_stats) /* get statistics */ ---- ref/include/net/atmclip.h Fri Nov 12 20:30:01 1999 -+++ work/include/net/atmclip.h Wed Dec 1 03:17:20 1999 +--- ref/include/net/atmclip.h Fri Jan 21 01:08:33 2000 ++++ work/include/net/atmclip.h Fri Jan 21 16:53:11 2000 @@ -1,6 +1,6 @@ /* net/atm/atmarp.h - RFC1577 ATM ARP */ @@ -1932,7 +14703,7 @@ }; --- ref/net/sched/sch_atm.c Wed Sep 8 20:14:32 1999 -+++ work/net/sched/sch_atm.c Tue Nov 30 21:59:42 1999 ++++ work/net/sched/sch_atm.c Fri Jan 21 16:01:07 2000 @@ -56,12 +56,14 @@ @@ -2025,7 +14796,7 @@ atm_tc_init, /* init */ --- ref/net/atm/atm_misc.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/atm_misc.c Tue Nov 30 22:05:53 1999 ++++ work/net/atm/atm_misc.c Fri Jan 21 16:01:07 2000 @@ -10,13 +10,11 @@ #include #include @@ -2051,7 +14822,15 @@ if (skb) { --- ref/net/atm/clip.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/clip.c Wed Dec 1 03:14:41 1999 ++++ work/net/atm/clip.c Fri Jan 21 16:01:07 2000 +@@ -1,6 +1,6 @@ + /* net/atm/clip.c - RFC1577 Classical IP over ATM */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include @@ -30,7 +30,6 @@ #include @@ -2060,7 +14839,7 @@ #include "resources.h" #include "ipcommon.h" #include -@@ -219,6 +218,17 @@ +@@ -219,6 +218,18 @@ } @@ -2068,7 +14847,8 @@ +{ + DPRINTK("clip_pop(vcc %p)\n",vcc); + CLIP_VCC(vcc)->old_pop(vcc,skb); -+ if (atm_may_send(vcc,0)) { ++ /* skb->dev == NULL in outbound ARP packets */ ++ if (atm_may_send(vcc,0) && skb->dev) { + skb->dev->tbusy = 0; + mark_bh(NET_BH); + } @@ -2078,7 +14858,7 @@ static void clip_neigh_destroy(struct neighbour *neigh) { DPRINTK("clip_neigh_destroy (neigh %p)\n",neigh); -@@ -346,6 +356,7 @@ +@@ -346,6 +357,7 @@ static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev) { struct atmarp_entry *entry; @@ -2086,7 +14866,7 @@ DPRINTK("clip_start_xmit (skb %p)\n",skb); if (!skb->dst) { -@@ -381,9 +392,8 @@ +@@ -381,9 +393,8 @@ return 0; } DPRINTK("neigh %p, vccs %p\n",entry,entry->vccs); @@ -2098,7 +14878,7 @@ if (entry->vccs->encap) { void *here; -@@ -391,15 +401,15 @@ +@@ -391,15 +402,15 @@ memcpy(here,llc_oui,sizeof(llc_oui)); ((u16 *) here)[3] = skb->protocol; } @@ -2119,7 +14899,7 @@ return 0; } -@@ -428,9 +438,11 @@ +@@ -428,9 +439,11 @@ clip_vcc->last_use = jiffies; clip_vcc->idle_timeout = timeout*HZ; clip_vcc->old_push = vcc->push; @@ -2131,7 +14911,7 @@ skb_migrate(&vcc->recvq,©); restore_flags(flags); /* re-process everything received between connection setup and MKIP */ -@@ -511,7 +523,12 @@ +@@ -511,7 +524,12 @@ dev->hard_header_len = RFC1483LLC_LEN; dev->mtu = RFC1626_MTU; dev->addr_len = 0; @@ -2145,8 +14925,38 @@ dev->flags = 0; dev_init_buffers(dev); /* is this ever supposed to be used ? */ return 0; +@@ -641,20 +659,7 @@ + + + static struct atmdev_ops atmarpd_dev_ops = { +- NULL, /* no dev_close */ +- NULL, /* no open */ +- atmarpd_close, /* close */ +- NULL, /* no ioctl */ +- NULL, /* no getsockopt */ +- NULL, /* no setsockopt */ +- NULL, /* send */ +- NULL, /* no sg_send */ +- NULL, /* no send_oam */ +- NULL, /* no phy_put */ +- NULL, /* no phy_get */ +- NULL, /* no feedback */ +- NULL, /* no change_qos */ +- NULL /* no free_rx_skb */ ++ close: atmarpd_close, + }; + + --- ref/net/atm/common.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/common.c Wed Dec 1 03:19:46 1999 ++++ work/net/atm/common.c Fri Jan 21 16:53:57 2000 +@@ -1,6 +1,6 @@ + /* net/atm/common.c - ATM sockets (common part for PVC and SVC) */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include @@ -24,11 +24,6 @@ #include #include @@ -2261,7 +15071,15 @@ eff = (size+3) & ~3; /* align to word boundary */ while (!(skb = vcc->alloc_tx(vcc,eff))) { if (m->msg_flags & MSG_DONTWAIT) return -EAGAIN; -@@ -488,7 +436,7 @@ +@@ -461,6 +409,7 @@ + return vcc->reply; + if (!(vcc->flags & ATM_VF_READY)) return -EPIPE; + } ++ skb->dev = NULL; /* for paths shared with net_device interfaces */ + ATM_SKB(skb)->iovcnt = 0; + ATM_SKB(skb)->atm_options = vcc->atm_options; + if (copy_from_user(skb_put(skb,size),buff,size)) { +@@ -488,7 +437,7 @@ if (sock->state != SS_CONNECTING) { if (vcc->qos.txtp.traffic_class != ATM_NONE && vcc->qos.txtp.max_sdu+atomic_read(&vcc->tx_inuse)+ @@ -2270,7 +15088,7 @@ mask |= POLLOUT | POLLWRNORM; } else if (vcc->reply != WAITING) { -@@ -530,7 +478,7 @@ +@@ -530,7 +479,7 @@ case TIOCOUTQ: if (sock->state != SS_CONNECTED || !(vcc->flags & ATM_VF_READY)) return -EINVAL; @@ -2279,7 +15097,7 @@ atomic_read(&vcc->tx_inuse)-ATM_PDU_OVHD, (int *) arg) ? -EFAULT : 0; case TIOCINQ: -@@ -569,11 +517,7 @@ +@@ -569,30 +518,13 @@ return copy_to_user((void *) arg,&vcc->timestamp, sizeof(struct timeval)) ? -EFAULT : 0; case ATM_SETSC: @@ -2292,7 +15110,36 @@ return 0; case ATMSIGD_CTRL: if (!capable(CAP_NET_ADMIN)) return -EPERM; -@@ -805,22 +749,6 @@ + error = sigd_attach(vcc); + if (!error) sock->state = SS_CONNECTED; + return error; +-#ifdef WE_DONT_SUPPORT_P2MP_YET +- case ATM_CREATE_LEAF: +- { +- struct socket *session; +- +- if (!(session = sockfd_lookup(arg,&error))) +- return error; +- if (sock->ops->family != PF_ATMSVC || +- session->ops->family != PF_ATMSVC) +- return -EPROTOTYPE; +- return create_leaf(sock,session); +- } +-#endif + #ifdef CONFIG_ATM_CLIP + case SIOCMKCLIP: + if (!capable(CAP_NET_ADMIN)) return -EPERM; +@@ -746,7 +678,8 @@ + default: + if (!dev->ops->ioctl) return -EINVAL; + size = dev->ops->ioctl(dev,cmd,buf); +- if (size < 0) return size; ++ if (size < 0) ++ return size == -ENOIOCTLCMD ? -EINVAL : size; + } + if (!size) return 0; + return put_user(size,&((struct atmif_sioc *) arg)->length) ? +@@ -805,22 +738,6 @@ vcc = ATM_SD(sock); switch (optname) { @@ -2315,7 +15162,7 @@ case SO_ATMQOS: { struct atm_qos qos; -@@ -859,18 +787,6 @@ +@@ -859,18 +776,6 @@ vcc = ATM_SD(sock); switch (optname) { @@ -2335,7 +15182,7 @@ if (!(vcc->flags & ATM_VF_HASQOS)) return -EINVAL; return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ? --- ref/net/atm/lec.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/lec.c Tue Nov 30 22:13:47 1999 ++++ work/net/atm/lec.c Fri Jan 21 16:01:07 2000 @@ -39,7 +39,6 @@ #include "lec.h" @@ -2389,7 +15236,34 @@ break; case l_flush_tran_id: lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr, -@@ -626,17 +634,9 @@ +@@ -540,24 +548,8 @@ + } + + static struct atmdev_ops lecdev_ops = { +- NULL, /*dev_close*/ +- NULL, /*open*/ +- lec_atm_close, /*close*/ +- NULL, /*ioctl*/ +- NULL, /*getsockopt */ +- NULL, /*setsockopt */ +- lec_atm_send, /*send */ +- NULL, /*sg_send */ +-#if 0 /* these are disabled in too */ +- NULL, /*poll */ +- NULL, /*send_iovec*/ +-#endif +- NULL, /*send_oam*/ +- NULL, /*phy_put*/ +- NULL, /*phy_get*/ +- NULL, /*feedback*/ +- NULL, /* change_qos*/ +- NULL /* free_rx_skb*/ ++ close: lec_atm_close, ++ send: lec_atm_send + }; + + static struct atm_dev lecatm_dev = { +@@ -626,17 +618,9 @@ return 0; } @@ -2408,7 +15282,7 @@ dev->change_mtu = lec_change_mtu; dev->open = lec_open; dev->stop = lec_close; -@@ -646,7 +646,7 @@ +@@ -646,7 +630,7 @@ dev->set_multicast_list = NULL; dev->do_ioctl = NULL; printk("%s: Initialized!\n",dev->name); @@ -2417,7 +15291,7 @@ } static unsigned char lec_ctrl_magic[] = { -@@ -660,7 +660,6 @@ +@@ -660,7 +644,6 @@ { struct net_device *dev = (struct net_device *)vcc->proto_data; struct lec_priv *priv = (struct lec_priv *)dev->priv; @@ -2425,7 +15299,7 @@ #if DUMP_PACKETS >0 int i=0; -@@ -696,9 +695,10 @@ +@@ -696,9 +679,10 @@ skb_queue_tail(&vcc->recvq, skb); wake_up(&vcc->sleep); } else { /* Data frame, queue to protocol handlers */ @@ -2438,7 +15312,7 @@ !priv->lecd) { /* Probably looping back, or if lecd is missing, lecd has gone down */ -@@ -706,7 +706,19 @@ +@@ -706,7 +690,19 @@ dev_kfree_skb(skb); return; } @@ -2459,7 +15333,7 @@ lec_arp_check_empties(priv, vcc, skb); } skb->dev = dev; -@@ -757,7 +769,7 @@ +@@ -757,7 +753,7 @@ int lecd_attach(struct atm_vcc *vcc, int arg) { @@ -2468,7 +15342,7 @@ struct lec_priv *priv; if (arg<0) -@@ -772,30 +784,28 @@ +@@ -772,30 +768,28 @@ return -EINVAL; #endif if (!dev_lec[i]) { @@ -2490,7 +15364,13 @@ if (i >= (MAX_LEC_ITF - NUM_TR_DEVS)) - priv->is_trdev = 1; + is_trdev = 1; -+ + +- dev_lec[i]->name = (char*)(dev_lec[i]+1); +- sprintf(dev_lec[i]->name, "lec%d",i); +- dev_lec[i]->init = lec_init; +- if ((result = register_netdev(dev_lec[i])) !=0) +- return result; +- sprintf(dev_lec[i]->name, "lec%d", i); /* init_trdev globbers device name */ + size = sizeof(struct lec_priv); +#ifdef CONFIG_TR + if (is_trdev) @@ -2500,13 +15380,7 @@ + dev_lec[i] = init_etherdev(NULL, size); + if (!dev_lec[i]) + return -ENOMEM; - -- dev_lec[i]->name = (char*)(dev_lec[i]+1); -- sprintf(dev_lec[i]->name, "lec%d",i); -- dev_lec[i]->init = lec_init; -- if ((result = register_netdev(dev_lec[i])) !=0) -- return result; -- sprintf(dev_lec[i]->name, "lec%d", i); /* init_trdev globbers device name */ ++ + priv = dev_lec[i]->priv; + priv->is_trdev = is_trdev; + sprintf(dev_lec[i]->name, "lec%d", i); @@ -2517,7 +15391,7 @@ if (priv->lecd) return -EADDRINUSE; } -@@ -874,7 +884,6 @@ +@@ -874,7 +868,6 @@ #endif } else unregister_netdev(dev_lec[i]); @@ -2525,8 +15399,25 @@ kfree(dev_lec[i]); dev_lec[i] = NULL; } +@@ -1535,7 +1528,7 @@ + if (entry) + entry->next = to_remove->next; + } +- if (!entry) ++ if (!entry) { + if (to_remove == priv->lec_no_forward) { + priv->lec_no_forward = to_remove->next; + } else { +@@ -1545,6 +1538,7 @@ + if (entry) + entry->next = to_remove->next; + } ++ } + lec_arp_clear_vccs(to_remove); + kfree(to_remove); + } --- ref/net/atm/mpc.c Mon Aug 23 18:56:32 1999 -+++ work/net/atm/mpc.c Tue Nov 30 22:05:06 1999 ++++ work/net/atm/mpc.c Fri Jan 21 16:01:08 2000 @@ -27,7 +27,6 @@ #include "lec.h" @@ -2554,7 +15445,31 @@ dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n", mpc->dev->name, ip[0], ip[1], ip[2], ip[3]); in_entry->shortcut = NULL; -@@ -1074,7 +1074,7 @@ +@@ -726,21 +726,8 @@ + } + + static struct atmdev_ops mpc_ops = { /* only send is required */ +- NULL, /* dev_close */ +- NULL, /* open */ +- mpoad_close, /* close */ +- NULL, /* ioctl */ +- NULL, /* getsockopt */ +- NULL, /* setsockopt */ +- msg_from_mpoad, /* send */ +- NULL, /* sg_send */ +- NULL, /* send_oam */ +- NULL, /* phy_put */ +- NULL, /* phy_get */ +- NULL, /* feedback */ +- NULL, /* change_qos */ +- NULL, /* free_rx_skb */ +- NULL /* proc_read */ ++ close: mpoad_close, ++ send: msg_from_mpoad + }; + + static struct atm_dev mpc_dev = { +@@ -1074,7 +1061,7 @@ */ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry){ uint32_t dst_ip = msg->content.in_info.in_dst_ip; @@ -2564,7 +15479,7 @@ eg_cache_entry *eg_entry = client->eg_ops->search_by_src_ip(dst_ip, client); if(eg_entry && eg_entry->shortcut){ --- ref/net/atm/mpoa_caches.c Mon Aug 23 18:56:32 1999 -+++ work/net/atm/mpoa_caches.c Mon Nov 22 13:56:17 1999 ++++ work/net/atm/mpoa_caches.c Fri Jan 21 16:01:08 2000 @@ -87,7 +87,7 @@ struct mpoa_client *client) { @@ -2584,27 +15499,32 @@ dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, ip[0], ip[1], ip[2], ip[3]); entry->entry_state = INGRESS_RESOLVING; ---- ref/net/atm/proc.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/proc.c Wed Dec 1 01:44:52 1999 -@@ -100,6 +100,7 @@ - ENTRY(devices); - ENTRY(pvc); - ENTRY(svc); -+ENTRY(vc); - #ifdef CONFIG_ATM_CLIP - ENTRY(arp); - #endif -@@ -118,6 +119,9 @@ - "TX(PCR,Class)\n"); - if (ino == INO(svc)) - return sprintf(buf,"Itf VPI VCI State Remote\n"); -+ if (ino == INO(vc)) -+ return sprintf(buf,"Address Itf VPI VCI Fam Flags Reply " -+ "Send buffer Recv buffer\n"); - #ifdef CONFIG_ATM_CLIP - if (ino == INO(arp)) - return sprintf(buf,"IPitf TypeEncp Idle IP address " -@@ -136,7 +140,7 @@ +--- ref/net/atm/mpoa_proc.c Fri Nov 19 05:02:02 1999 ++++ work/net/atm/mpoa_proc.c Fri Jan 21 16:01:08 2000 +@@ -143,7 +143,7 @@ + while(eg_entry != NULL){ + for(i=0;ictrl_info.in_MPC_data_ATM_addr[i]);} +- length += sprintf((char *)page + length,"\n%-16lu%s%-14lu%-15u",ntohl(eg_entry->ctrl_info.cache_id), egress_state_string(eg_entry->entry_state), (eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)), eg_entry->packets_rcvd); ++ length += sprintf((char *)page + length,"\n%-16lu%s%-14lu%-15u",(unsigned long) ntohl(eg_entry->ctrl_info.cache_id), egress_state_string(eg_entry->entry_state), (eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)), eg_entry->packets_rcvd); + + /* latest IP address */ + temp = (unsigned char *)&eg_entry->latest_ip_addr; +--- ref/net/atm/proc.c Sun Nov 28 00:27:49 1999 ++++ work/net/atm/proc.c Fri Jan 21 16:01:08 2000 +@@ -1,6 +1,6 @@ + /* net/atm/proc.c - ATM /proc interface */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + /* + * The mechanism used here isn't designed for speed but rather for convenience +@@ -73,10 +73,11 @@ + &proc_spec_atm_operations, /* default ATM directory file-ops */ + }; + ++ static void add_stats(char *buf,const char *aal, const struct atm_aal_stats *stats) { @@ -2613,7 +15533,7 @@ stats->tx_err,stats->rx,stats->rx_err,stats->rx_drop); } -@@ -172,7 +176,7 @@ +@@ -112,7 +113,7 @@ len = strlen(addr->sas_addr.pub); buf += len; if (*addr->sas_addr.pub) { @@ -2622,20 +15542,11 @@ len++; } } -@@ -274,7 +278,7 @@ - char *here; - int i; - -- if (!vcc->dev) sprintf(buf,"Unassigned "); -+ if (!vcc->dev) sprintf(buf,"N/A@%8p ",vcc); - else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,vcc->vci); - here = strchr(buf,0); - here += sprintf(here,"%-10s ",vcc_state(vcc)); -@@ -288,6 +292,32 @@ +@@ -209,12 +210,39 @@ } -+static int vc_info(struct atm_vcc *vcc,char *buf) ++static void vc_info(struct atm_vcc *vcc,char *buf) +{ + char *here; + @@ -2657,39 +15568,182 @@ + vcc->reply, + atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf, + atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf); -+ return here-buf; +} + + - #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) + static void svc_info(struct atm_vcc *vcc,char *buf) + { + char *here; + int i; - static char* -@@ -385,6 +415,15 @@ - } - return 0; - } -+ if (ino == INO(vc)) { -+ left = *pos-1; -+ for (dev = atm_devs; dev; dev = dev->next) -+ for (vcc = dev->vccs; vcc; vcc = vcc->next) -+ if (!left--) return vc_info(vcc,buf); -+ for (vcc = nodev_vccs; vcc; vcc = vcc->next) -+ if (!left--) return vc_info(vcc,buf); -+ return 0; -+ } - #ifdef CONFIG_ATM_CLIP - if (ino == INO(arp)) { - struct neighbour *n; -@@ -549,6 +588,7 @@ - REG(devices); - REG(pvc); - REG(svc); -+ REG(vc); +- if (!vcc->dev) sprintf(buf,"Unassigned "); ++ if (!vcc->dev) ++ sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%6s" : "N/A@%p%2s", ++ vcc,""); + else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,vcc->vci); + here = strchr(buf,0); + here += sprintf(here,"%-10s ",vcc_state(vcc)); +@@ -253,7 +281,6 @@ + lec_info(struct lec_arp_table *entry, char *buf) + { + int j, offset=0; +- + + for(j=0;jmac_addr[j]); +@@ -322,6 +349,34 @@ + return 0; + } + ++ ++static int atm_vc_info(loff_t pos,char *buf) ++{ ++ struct atm_dev *dev; ++ struct atm_vcc *vcc; ++ int left; ++ ++ if (!pos) ++ return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s", ++ "Address"," Itf VPI VCI Fam Flags Reply Send buffer" ++ " Recv buffer\n"); ++ left = pos-1; ++ for (dev = atm_devs; dev; dev = dev->next) ++ for (vcc = dev->vccs; vcc; vcc = vcc->next) ++ if (!left--) { ++ vc_info(vcc,buf); ++ return strlen(buf); ++ } ++ for (vcc = nodev_vccs; vcc; vcc = vcc->next) ++ if (!left--) { ++ vc_info(vcc,buf); ++ return strlen(buf); ++ } ++ ++ return 0; ++} ++ ++ + static int atm_svc_info(loff_t pos,char *buf) + { + struct atm_dev *dev; +@@ -388,6 +443,7 @@ + struct lec_arp_table *entry; + int i, count, d, e; + struct net_device **dev_lec; ++ + if (!pos) { + return sprintf(buf,"Itf MAC ATM destination" + " Status Flags " +@@ -449,7 +505,8 @@ + if (count < 0) return -EINVAL; + page = get_free_page(GFP_KERNEL); + if (!page) return -ENOMEM; +- dev = ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data; ++ dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) ++ ->data; + if (!dev->ops->proc_read) + length = -EINVAL; + else { +@@ -464,13 +521,15 @@ + return length; + } + ++ + static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count, + loff_t *pos) + { + unsigned long page; + int length; + int (*info)(loff_t,char *); +- info = ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data; ++ info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) ++ ->data; + + if (count < 0) return -EINVAL; + page = get_free_page(GFP_KERNEL); +@@ -485,9 +544,11 @@ + return length; + } + ++ + struct proc_dir_entry *atm_proc_root; + EXPORT_SYMBOL(atm_proc_root); + ++ + int atm_proc_dev_register(struct atm_dev *dev) + { + int digits,num; +@@ -520,48 +581,41 @@ + kfree(dev->proc_name); + } + ++ ++#define CREATE_ENTRY(name) \ ++ name = create_proc_entry(#name,0,atm_proc_root); \ ++ if (!name) goto cleanup; \ ++ name->data = atm_##name##_info; \ ++ name->ops = &proc_spec_atm_inode_operations ++ ++ + int __init atm_proc_init(void) + { +- struct proc_dir_entry *dev=NULL,*pvc=NULL,*svc=NULL,*arp=NULL,*lec=NULL; ++ struct proc_dir_entry *devices = NULL,*pvc = NULL,*svc = NULL; ++ struct proc_dir_entry *arp = NULL,*lec = NULL,*vc = NULL; ++ + atm_proc_root = proc_mkdir("atm", &proc_root); + if (!atm_proc_root) + return -ENOMEM; +- dev = create_proc_entry("devices",0,atm_proc_root); +- if (!dev) +- goto cleanup; +- dev->data = atm_devices_info; +- dev->ops = &proc_spec_atm_inode_operations; +- pvc = create_proc_entry("pvc",0,atm_proc_root); +- if (!pvc) +- goto cleanup; +- pvc->data = atm_pvc_info; +- pvc->ops = &proc_spec_atm_inode_operations; +- svc = create_proc_entry("svc",0,atm_proc_root); +- if (!svc) +- goto cleanup; +- svc->data = atm_svc_info; +- svc->ops = &proc_spec_atm_inode_operations; ++ CREATE_ENTRY(devices); ++ CREATE_ENTRY(pvc); ++ CREATE_ENTRY(svc); ++ CREATE_ENTRY(vc); #ifdef CONFIG_ATM_CLIP - REG(arp); +- arp = create_proc_entry("arp",0,atm_proc_root); +- if (!arp) +- goto cleanup; +- arp->data = atm_arp_info; +- arp->ops = &proc_spec_atm_inode_operations; ++ CREATE_ENTRY(arp); #endif + #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) +- lec = create_proc_entry("lec",0,atm_proc_root); +- if (!lec) +- goto cleanup; +- lec->data = atm_lec_info; +- lec->ops = &proc_spec_atm_inode_operations; ++ CREATE_ENTRY(lec); + #endif + return 0; ++ + cleanup: +- if (dev) remove_proc_entry("devices",atm_proc_root); ++ if (devices) remove_proc_entry("devices",atm_proc_root); + if (pvc) remove_proc_entry("pvc",atm_proc_root); + if (svc) remove_proc_entry("svc",atm_proc_root); + if (arp) remove_proc_entry("arp",atm_proc_root); + if (lec) remove_proc_entry("lec",atm_proc_root); ++ if (vc) remove_proc_entry("vc",atm_proc_root); + remove_proc_entry("atm",&proc_root); + return -ENOMEM; + } --- ref/net/atm/raw.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/raw.c Wed Dec 1 01:56:23 1999 ++++ work/net/atm/raw.c Fri Jan 21 16:01:08 2000 @@ -11,14 +11,8 @@ #include #include @@ -2717,7 +15771,7 @@ atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); dev_kfree_skb(skb); --- ref/net/atm/resources.c Mon Aug 23 18:56:32 1999 -+++ work/net/atm/resources.c Wed Dec 1 01:36:48 1999 ++++ work/net/atm/resources.c Fri Jan 21 16:01:08 2000 @@ -145,8 +145,10 @@ sk_free(sk); return NULL; @@ -2730,7 +15784,15 @@ vcc->prev = NULL; vcc->next = nodev_vccs; --- ref/net/atm/signaling.c Mon Aug 23 18:56:32 1999 -+++ work/net/atm/signaling.c Tue Nov 30 23:58:46 1999 ++++ work/net/atm/signaling.c Fri Jan 21 16:01:08 2000 +@@ -1,6 +1,6 @@ + /* net/atm/signaling.c - ATM signaling */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #include /* error codes */ @@ -13,7 +13,6 @@ #include #include @@ -2747,33 +15809,85 @@ - vcc = (struct atm_vcc *) msg->vcc; + DPRINTK("sigd_send %d (0x%lx)\n",(int) msg->type, + (unsigned long) msg->vcc); -+ vcc = (struct atm_vcc *) (unsigned long) msg->vcc; ++ vcc = *(struct atm_vcc **) &msg->vcc; switch (msg->type) { case as_okay: vcc->reply = msg->reply; -@@ -118,7 +118,8 @@ +@@ -118,7 +118,7 @@ vcc->reply = msg->reply; break; case as_indicate: - vcc = (struct atm_vcc *) msg->listen_vcc; -+ vcc = (struct atm_vcc *) (unsigned long) -+ msg->listen_vcc; ++ vcc = *(struct atm_vcc **) &msg->listen_vcc; DPRINTK("as_indicate!!!\n"); if (!vcc->backlog_quota) { sigd_enq(0,as_reject,vcc,NULL,NULL); -@@ -163,8 +164,8 @@ +@@ -152,7 +152,7 @@ + + + void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type, +- const struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, ++ struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, + const struct sockaddr_atmsvc *svc) + { + struct sk_buff *skb; +@@ -162,9 +162,10 @@ + while (!(skb = alloc_skb(sizeof(struct atmsvc_msg),GFP_KERNEL))) schedule(); msg = (struct atmsvc_msg *) skb_put(skb,sizeof(struct atmsvc_msg)); ++ memset(msg,0,sizeof(msg)); msg->type = type; - msg->vcc = (unsigned long) vcc; - msg->listen_vcc = (unsigned long) listen_vcc; -+ msg->vcc = (atm_kptr_int_t) (unsigned long) vcc; -+ msg->listen_vcc = (atm_kptr_int_t) (unsigned long) listen_vcc; ++ *(struct atm_vcc **) &msg->vcc = vcc; ++ *(struct atm_vcc **) &msg->listen_vcc = listen_vcc; msg->reply = 0; /* other ISP applications may use this field */ if (vcc) { msg->qos = vcc->qos; +@@ -210,20 +211,8 @@ + + + static struct atmdev_ops sigd_dev_ops = { +- NULL, /* no dev_close */ +- NULL, /* no open */ +- sigd_close, /* close */ +- NULL, /* no ioctl */ +- NULL, /* no getsockopt */ +- NULL, /* no setsockopt */ +- sigd_send, /* send */ +- NULL, /* no sg_send */ +- NULL, /* no send_oam */ +- NULL, /* no phy_put */ +- NULL, /* no phy_get */ +- NULL, /* no feedback */ +- NULL, /* no change_qos */ +- NULL /* no free_rx_skb */ ++ close: sigd_close, ++ send: sigd_send + }; + + +--- ref/net/atm/signaling.h Mon Aug 23 18:56:32 1999 ++++ work/net/atm/signaling.h Fri Jan 21 16:54:11 2000 +@@ -1,6 +1,6 @@ + /* net/atm/signaling.h - ATM signaling */ + +-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ ++/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #ifndef NET_ATM_SIGNALING_H +@@ -18,7 +18,7 @@ + + + void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type, +- const struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, ++ struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, + const struct sockaddr_atmsvc *svc); + int sigd_attach(struct atm_vcc *vcc); + void signaling_init(void); --- ref/net/atm/tunable.h Wed Sep 8 20:14:32 1999 -+++ work/net/atm/tunable.h Wed Dec 1 03:29:41 1999 ++++ work/net/atm/tunable.h Fri Jan 21 16:01:08 2000 @@ -1,16 +0,0 @@ -/* net/atm/tunable.h - Tunable parameters of ATM support */ - diff -ur --new-file old/atm/debug/delay.c new/atm/debug/delay.c --- old/atm/debug/delay.c Tue Mar 11 11:54:16 1997 +++ new/atm/debug/delay.c Tue Jan 18 22:23:38 2000 @@ -1,6 +1,6 @@ /* delay.c - Simplistic AAL5-level software delay line */ -/* Written 1996,1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ /* @@ -100,12 +100,13 @@ for (lnk = links; lnk; lnk = lnk->next) while (1) { size = read(lnk->in,buffer,ATM_MAX_AAL5_PDU); - if (size < 0) + if (size < 0) { if (errno == EAGAIN) break; else { perror("read"); exit(1); } + } if (size > 0) { if (!(p = malloc(sizeof(PACKET)-1+size))) { perror("malloc"); diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex --- old/atm/doc/usage.tex Tue Nov 30 22:29:48 1999 +++ new/atm/doc/usage.tex Fri Jan 21 07:04:44 2000 @@ -1,7 +1,7 @@ %def%:= %:\begin{verbatim} -%:Usage instructions - ATM on Linux, release 0.64 +%:Usage instructions - ATM on Linux, release 0.65 %:------------------------------------------------- %: %:\end{verbatim} @@ -38,14 +38,14 @@ \title{ATM on Linux \\ User's guide \\ - Release 0.64 (beta)} + Release 0.65 (beta)} \author{Werner Almesberger \\ {\tt Werner.Almesberger@epfl.ch} \\ \\ Institute for computer Communications and Applications (ICA) \\ EPFL, CH-1015 Lausanne, Switzerland} -\date{November 30, 1999} +\date{January 21, 2000} \begin{document} \maketitle @@ -82,9 +82,9 @@ In order to install this package, you need \begin{itemize} \item the package itself - \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.64.tar.gz} - \item the Linux kernel, version 2.3.28, e.g. from - \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.28.tar.gz} + \url{ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.65.tar.gz} + \item the Linux kernel, version 2.3.40, e.g. from + \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.40.tar.gz} \item Perl, version 4 or 5 \item if you want memory debugging: MPR version 1.6, e.g. from \url{ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz} @@ -99,13 +99,13 @@ distribution: \begin{verbatim} -tar xfz atm-0.64.tar.gz +tar xfz atm-0.65.tar.gz \end{verbatim} and the kernel source: \begin{verbatim} -tar xfz linux-2.3.28.tar.gz +tar xfz linux-2.3.40.tar.gz \end{verbatim} Finally, you can extract the ATM-related patches: @@ -126,7 +126,7 @@ \item[\path{atm/qgen/}] Q.2931-style message handling \item[\path{atm/ilmid/}] ILMI address registration demon: \name{ilmid} \item[\path{atm/maint/}] ATM maintenance programs: \name{atmaddr}, - \name{atmdiag}, \name{atmdump}, \name{atmtcp}, \name{esi}, + \name{atmdiag}, \name{atmdump}, \name{atmtcp}, \name{enitune}, \name{esi}, \name{sonetdiag}, \name{saaldump}, and \name{zntune} \item[\path{atm/test/}] Test programs: \name{align}, \name{aping}, \name{aread}, \name{awrite}, \name{br}, \name{bw}, \name{isp}, @@ -295,7 +295,7 @@ outside of the ATM context. For such packages, only patches are contained in the ATM on Linux distribution. The complete packages can be obtained either from the original source (described in \path{atm/extra/extra.html}) -or from \url{ftp://lrcftp.epfl.ch/pub/linux/atm/extra/}. +or from \url{ftp://icaftp.epfl.ch/pub/linux/atm/extra/}. The packages are automatically downloaded, patched, and built by running \raw{make \meta{package\_name}} in the \path{atm/extra/} directory @@ -339,27 +339,35 @@ and run the following command on one of them (let's call it ``a''): \begin{command} -a\# atmtcp -l +a\# atmtcp virtual listen \end{command} Then, on the other system (``b''), run \begin{command} -b\# atmtcp -c \meta{ip\_address\_of\_a} +b\# atmtcp virtual connect \meta{address\_of\_a} \end{command} Both \name{atmtcp}s will report on their progress and the kernel should -display a message like +display messages like \begin{verbatim} -atmtcp (itf 1): ready +Link 0: virtual interface 2 +Link 1: incoming ATMTCP connection from 127.0.0.1 \end{verbatim} -on each system. Note that \name{atmtcp} keeps running and that interrupting +and + +\begin{verbatim} +Link 0: virtual interface 3 +Link 1: ATMTCP connection to localhost +\end{verbatim} + +on the two systems. Note that \name{atmtcp} keeps running and that interrupting it breaks the virtual wire. Multiple ``wires'' can be attached to the same machine by specifying a -port number (default is 8401). Note that no AAL processing is performed. +port number (default is 2812). Note that no AAL processing is performed. It is therefore not possible to receive data using a different AAL (e.g. AAL0) than the one with which the data was sent. @@ -1100,7 +1108,7 @@ % ITU, 1993. \bibitem{api}Almesberger, Werner. {\em Linux ATM API}, - \url{ftp://lrcftp.epfl.ch/pub/linux/atm/api/}, + \url{ftp://icaftp.epfl.ch/pub/linux/atm/api/}, July 1996. % \bibitem{RFC1483}Heinanen, Juha. % {\em Multiprotocol Encapsulation over ATM Adaptation Layer 5}, diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt --- old/atm/doc/usage.txt Wed Dec 1 02:08:36 1999 +++ new/atm/doc/usage.txt Fri Jan 21 09:17:27 2000 @@ -1,4 +1,4 @@ -%:Usage instructions - ATM on Linux, release 0.64 +%:Usage instructions - ATM on Linux, release 0.65 %:------------------------------------------------- %: %: @@ -20,9 +20,9 @@ In order to install this package, you need - the package itself - ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.64.tar.gz - - the Linux kernel, version 2.3.28, e.g. from - ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.28.tar.gz + ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.65.tar.gz + - the Linux kernel, version 2.3.40, e.g. from + ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.40.tar.gz - Perl, version 4 or 5 - if you want memory debugging: MPR version 1.6, e.g. from ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz @@ -36,11 +36,11 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.64.tar.gz +tar xfz atm-0.65.tar.gz and the kernel source: -tar xfz linux-2.3.28.tar.gz +tar xfz linux-2.3.40.tar.gz Finally, you can extract the ATM-related patches: @@ -56,7 +56,7 @@ atm/qgen/ Q.2931-style message handling atm/ilmid/ ILMI address registration demon: ilmid atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmtcp, - esi, sonetdiag, saaldump, and zntune + enitune, esi, sonetdiag, saaldump, and zntune atm/test/ Test programs: align, aping, aread, awrite, br, bw, isp, ttcp_atm, window atm/arpd/ ATMARP tools and demon: atmarp, atmarpd @@ -197,7 +197,7 @@ outside of the ATM context. For such packages, only patches are contained in the ATM on Linux distribution. The complete packages can be obtained either from the original source (described in atm/extra/extra.html) or from -ftp://lrcftp.epfl.ch/pub/linux/atm/extra/ . +ftp://icaftp.epfl.ch/pub/linux/atm/extra/ . The packages are automatically downloaded, patched, and built by running make in the atm/extra/ directory (requires that the Lynx @@ -235,22 +235,28 @@ run both sides on the same system to create two connected "interfaces") and run the following command on one of them (let's call it "a"): - a# atmtcp -l + a# atmtcp virtual listen Then, on the other system ("b"), run - b# atmtcp -c + b# atmtcp virtual connect -Both atmtcps will report on their progress and the kernel should display a -message like +Both atmtcps will report on their progress and the kernel should display +messages like -atmtcp (itf 1): ready +Link 0: virtual interface 2 +Link 1: incoming ATMTCP connection from 127.0.0.1 -on each system. Note that atmtcp keeps running and that interrupting it +and + +Link 0: virtual interface 3 +Link 1: ATMTCP connection to localhost + +on the two systems. Note that atmtcp keeps running and that interrupting it breaks the virtual wire. Multiple "wires" can be attached to the same machine by specifying a port -number (default is 8401). Note that no AAL processing is performed. It is +number (default is 2812). Note that no AAL processing is performed. It is therefore not possible to receive data using a different AAL (e.g. AAL0) than the one with which the data was sent. @@ -915,7 +921,7 @@ ========== [1] Almesberger, Werner. Linux ATM API, - ftp://lrcftp.epfl.ch/pub/linux/atm/api/ , July 1996. + ftp://icaftp.epfl.ch/pub/linux/atm/api/ , July 1996. [2] Laubach, Mark. Classical IP and ARP over ATM, RFC1577, January 1994. [6] Cole, Christopher. Bridging mini-Howto, diff -ur --new-file old/atm/extra/Makefile new/atm/extra/Makefile --- old/atm/extra/Makefile Fri Feb 19 17:10:49 1999 +++ new/atm/extra/Makefile Fri Jan 21 16:17:04 2000 @@ -8,6 +8,8 @@ ANSPATCH=bind-4.9.5-REL.patch DIR=ftp://lrcftp.epfl.ch/pub/linux/atm/extra +CLEAN = clean_extra +SPOTLESS = spotless_extra include ../Rules.make all: tcpdump ans @@ -59,7 +61,7 @@ [ -f $(ANSDIR)/.compiled ] || $(MAKE) ans cd $(ANSDIR) && make install # brute-force -clean: +clean_extra: [ ! -f $(TCPDUMPDIR)/Makefile ] || \ { cd $(TCPDUMPDIR) && make clean; } [ ! -f $(LIBPCAPDIR)/Makefile ] || \ diff -ur --new-file old/atm/ilmid/Makefile new/atm/ilmid/Makefile --- old/atm/ilmid/Makefile Thu Sep 24 18:00:31 1998 +++ new/atm/ilmid/Makefile Fri Jan 21 16:17:09 2000 @@ -6,6 +6,7 @@ OBJS = $(SRCS:%.c=%.o) BOOTPGMS=ilmid +CLEAN = clean_ilmid include ../Rules.make CFLAGS = $(CFLAGS_NOWARN) $(CFLAGS_OPT) $(CFLAGS_PRIVATE) $(STANDARDS) @@ -19,6 +20,6 @@ ilmid: asn1/libasn1.a $(OBJS) $(CC) $(OBJS) $(LIBS) -o ilmid -clean: +clean_ilmid: @cd asn1; make clean rm -rf ilmid $(OBJS) *~ diff -ur --new-file old/atm/lane/Makefile new/atm/lane/Makefile --- old/atm/lane/Makefile Wed Nov 19 12:59:25 1997 +++ new/atm/lane/Makefile Fri Jan 21 16:17:16 2000 @@ -22,6 +22,7 @@ LECSOBJS = lecs_db.o lecs_load.o lecs.o ldb.o mem_lecs.o atm_lecs.o OBJS = $(LESOBJS) $(BUSOBJS) $(LECSOBJS) +CLEAN = clean_lane include ../Rules.make load_lex.c : load_lex.l @@ -42,6 +43,6 @@ @echo "Linking $@" $(CC) $(LDFLAGS) -o $@ $(LECSOBJS) $(LDLIBS) -clean: +clean_lane: rm -f $(SYSPGMS) *.o *.d *~ .*~ core *.bak *.tar* *.errs load_lex.c \ lecs_db.c *~ diff -ur --new-file old/atm/lane/db.c new/atm/lane/db.c --- old/atm/lane/db.c Wed Nov 19 12:59:25 1997 +++ new/atm/lane/db.c Tue Jan 18 22:32:43 2000 @@ -244,7 +244,7 @@ return tmp; } } - else if ((tmp->mac_address).tag == htons(LANE_DEST_RD)) + else if ((tmp->mac_address).tag == htons(LANE_DEST_RD)) { if (memcmp((char *)&(tmp->mac_address.a_r.route), (char *)&maddr.a_r.route, 4 + sizeof(unsigned short)) == 0) { @@ -255,7 +255,8 @@ (char *)&maddr, sizeof(LaneDestination_t)) == 0) { Debug_unit(&conn_unit, "MAC found from database"); - return tmp; + return tmp; + } } tmp = tmp->next; } diff -ur --new-file old/atm/led/main.c new/atm/led/main.c --- old/atm/led/main.c Mon Nov 22 19:16:39 1999 +++ new/atm/led/main.c Tue Jan 18 22:31:32 2000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,7 @@ char atm2textbuff[100]; char esibuff[20]; int esi_set = 0; + int listen_addr_set = 0; int atm_set=0; int proxy_flag = 0; int lane_version = 0; /* LANE2 */ @@ -199,6 +201,7 @@ memset(preferred_les, 0, ATM_ESA_LEN); memset(&manual_atm_addr, 0, sizeof(struct sockaddr_atmsvc)); memset(&listen_addr, 0, sizeof(struct sockaddr_atmsvc)); + listen_addr.sas_family = AF_ATMSVC; set_application("zeppelin"); /* for debug msgs */ @@ -266,20 +269,17 @@ selector >=0 && selector <= 0xff) { listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = (char) selector; - listen_addr.sas_family = AF_ATMSVC; diag(COMPONENT, DIAG_INFO, "Selector byte set " "to %d", selector); - } - else - if (text2atm(optarg, (struct sockaddr *)&listen_addr, - sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { - diag(COMPONENT, DIAG_ERROR, "Invalid ATM listen address\n"); - usage(argv[0]); - exit(-1); + } else { + if (text2atm(optarg, (struct sockaddr *)&listen_addr, + sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { + diag(COMPONENT, DIAG_ERROR, "Invalid ATM listen address\n"); + usage(argv[0]); + exit(-1); + } + listen_addr_set = 1; } - atm2text(atm2textbuff, sizeof(atm2textbuff), - (struct sockaddr *)&listen_addr, 0); - diag(COMPONENT, DIAG_INFO, "Our ATM address: %s\n", atm2textbuff); break; case 'i': if (sscanf(optarg, "%d", &itf) <= 0 || itf >= MAX_LEC_ITF) { @@ -356,10 +356,18 @@ /* Reserve signals */ signal(SIGHUP, sig_reset); - if (get_listenaddr(listen_addr.sas_addr.prv, phys_itf) < 0) { - diag(COMPONENT, DIAG_FATAL, "Could not figure out my ATM address\n"); - exit(-1); + if (!listen_addr_set) { + char sel = listen_addr.sas_addr.prv[ATM_ESA_LEN - 1]; + if (get_listenaddr(listen_addr.sas_addr.prv, phys_itf) < 0) { + diag(COMPONENT, DIAG_FATAL, "Could not figure out my ATM address\n"); + exit(-1); + } + listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = sel; } + + atm2text(atm2textbuff, sizeof(atm2textbuff), + (struct sockaddr *)&listen_addr, A2T_NAME | A2T_PRETTY | A2T_LOCAL); + diag(COMPONENT, DIAG_INFO, "Our ATM address: %s\n", atm2textbuff); if (!esi_set) { if(addr_getesi(mac_addr, phys_itf) < 0) { diff -ur --new-file old/atm/lib/Makefile new/atm/lib/Makefile --- old/atm/lib/Makefile Tue Aug 24 00:02:12 1999 +++ new/atm/lib/Makefile Fri Jan 21 06:27:10 2000 @@ -5,7 +5,7 @@ else ATM_OBJS += ans.o endif -ATMD_OBJS=common.o diag.o text2ip.o timer.o unix.o +ATMD_OBJS=common.o diag.o kptr.o text2ip.o timer.o unix.o PGMS=#test GENLIBS=libatm.a libatmd.a SYSHDR=atm.h atmd.h atmsap.h diff -ur --new-file old/atm/lib/ans.c new/atm/lib/ans.c --- old/atm/lib/ans.c Mon Nov 22 13:24:08 1999 +++ new/atm/lib/ans.c Tue Jan 18 22:17:49 2000 @@ -1,6 +1,6 @@ /* ans.c - Interface for text2atm and atm2text to ANS */ -/* Written 1996-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ /* @@ -209,10 +209,11 @@ while (fgets(buffer,MAX_LINE,file)) { here = strchr(buffer,'#'); if (here) *here = 0; - if (sscanf(buffer,"%d",&cc) == 1) + if (sscanf(buffer,"%d",&cc) == 1) { if (cc < 10) cc_table[cc] = 1; else if (cc < 100) cc_table[cc] = 2; else cc_table[cc/10] = 3; + } } fclose(file); } diff -ur --new-file old/atm/lib/atm.h new/atm/lib/atm.h --- old/atm/lib/atm.h Thu Apr 22 15:33:08 1999 +++ new/atm/lib/atm.h Tue Jan 18 19:51:15 2000 @@ -1,6 +1,6 @@ /* atm.h - Functions useful for ATM applications */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef _ATM_H @@ -86,8 +86,6 @@ #define MAX_ATM_QOS_LEN 116 /* 5+4+2*(3+3*(7+9)+2)+1 */ #define MAX_ATM_SAP_LEN 255 /* BHLI(27)+1+3*BLLI(L2=33,L3=41,+1)+2 */ - -int create_leaf(int session); int text2atm(const char *text,struct sockaddr *addr,int length,int flags); int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags); diff -ur --new-file old/atm/lib/atmd.h new/atm/lib/atmd.h --- old/atm/lib/atmd.h Fri Nov 19 09:52:49 1999 +++ new/atm/lib/atmd.h Fri Jan 21 08:03:42 2000 @@ -1,6 +1,6 @@ /* atmd.h - Functions useful for demons (and some other ATM tools) */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef _ATMD_H @@ -171,6 +171,31 @@ * component is non-NULL, they are logged using diag(). Otherwise, they are * printed on standard error. Note that T2I_NAME uses gethostbyname() which * may attempt resolution via DNS or NIS. + */ + + +/* ------------------------ Kernel pointer handles ------------------------- */ + + +#include + + +#define KPRT_PRINT_BUFS 4 /* up to that many buffers are concurrently + available */ + +int kptr_eq(const atm_kptr_t *a,const atm_kptr_t *b); + +/* + * Returns 1 if A and B are equal, 0 otherwise. Note that unused areas of the + * handles must be initialized to a system-wide constant pattern, e.g. 0. + */ + +const char *kptr_print(const atm_kptr_t *p); + +/* + * Returns a pointer to a static buffer containing an ASCII representation of + * a kernel pointer handle. After KPRT_PRINT_BUFS calls to kptr_print, old + * buffers are reused. */ #endif diff -ur --new-file old/atm/lib/atmequal.c new/atm/lib/atmequal.c --- old/atm/lib/atmequal.c Wed Apr 21 19:14:39 1999 +++ new/atm/lib/atmequal.c Tue Jan 18 22:17:27 2000 @@ -1,6 +1,6 @@ /* atmequal.c - Compares ATM addresses for equality */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -35,7 +35,7 @@ a_prv = a->sas_addr.prv; b_prv = b->sas_addr.prv; if ((flags & AXE_WILDCARD) && len >= 8 && *a_prv == ATM_AFI_E164 && - *b_prv == ATM_AFI_E164) + *b_prv == ATM_AFI_E164) { if (len < 68) return 0; /* no comparison possible */ else { int a_pos,b_pos; @@ -57,6 +57,7 @@ b_prv += 9; if ((len -= 72) < 0) len = 0; } + } if (memcmp(a_prv,b_prv,len/8)) return 0; if ((len & 7) && (a_prv[len/8+1]^b_prv[len/8+1]) & (0xff00 >> (len & 7))) return 0; diff -ur --new-file old/atm/lib/kptr.c new/atm/lib/kptr.c --- old/atm/lib/kptr.c Thu Jan 1 01:00:00 1970 +++ new/atm/lib/kptr.c Fri Jan 21 08:03:54 2000 @@ -0,0 +1,44 @@ +/* kptr.c - Helper functions to use kernel pointer handles */ + +/* Written 2000 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include + +#include "atmd.h" + + +int kptr_eq(const atm_kptr_t *a,const atm_kptr_t *b) +{ + unsigned long *_a = (unsigned long *) a,*_b = (unsigned long *) b; + + assert(sizeof(atm_kptr_t) == 8); + switch (sizeof(unsigned long)) { + case 2: /* Wow, ATM on ELKS ? :-) */ + if (_a[2] != _b[2]) return 0; + if (_a[3] != _b[3]) return 0; + case 4: + if (_a[1] != _b[1]) return 0; + case 8: + return *_a == *_b; + default: + abort(); + } +} + + +const char *kptr_print(const atm_kptr_t *p) +{ + static char buf[KPRT_PRINT_BUFS][sizeof(atm_kptr_t)*2+1]; + static int curr_buf = 0; + char *result; + int i; + + result = buf[curr_buf]; + curr_buf = (curr_buf+1) & (KPRT_PRINT_BUFS-1); + for (i = 0; i < sizeof(atm_kptr_t); i++) + sprintf(result+2*i,"%02x",((unsigned char *) p)[i]); + return result; +} diff -ur --new-file old/atm/lib/misc.c new/atm/lib/misc.c --- old/atm/lib/misc.c Sat Jun 6 01:48:11 1998 +++ new/atm/lib/misc.c Tue Jan 18 19:51:24 2000 @@ -1,6 +1,6 @@ /* misc.c - Miscellaneous library functions */ -/* Written 1997,1998 by Werner Almesberger, EPFL-ICA/ICA */ +/* Written 1997-2000 by Werner Almesberger, EPFL-ICA/ICA */ #include @@ -12,17 +12,6 @@ #include #include - - -int create_leaf(int session) -{ - int leaf; - - leaf = socket(PF_ATMSVC,SOCK_DGRAM,0); - if (leaf < 0) return -1; - if (ioctl(leaf,ATM_CREATE_LEAF,session) < 0) return -1; - return leaf; -} int __atmlib_fetch(const char **pos,...) diff -ur --new-file old/atm/lib/qos2text.c new/atm/lib/qos2text.c --- old/atm/lib/qos2text.c Thu Nov 6 00:26:30 1997 +++ new/atm/lib/qos2text.c Tue Jan 18 20:28:06 2000 @@ -1,7 +1,7 @@ /* qos2text.c - Converts binary encoding of QOS parameters to textual representation */ -/* Written 1996,1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1996-2000 by Werner Almesberger, EPFL-LRC */ #include @@ -67,6 +67,10 @@ break; case ATM_CBR: strcpy(buffer,"cbr"); + pos += 3; + break; + case ATM_ABR: + strcpy(buffer,"abr"); pos += 3; break; default: diff -ur --new-file old/atm/lib/text2atm.c new/atm/lib/text2atm.c --- old/atm/lib/text2atm.c Wed Mar 18 21:35:17 1998 +++ new/atm/lib/text2atm.c Tue Jan 18 22:16:46 2000 @@ -1,7 +1,7 @@ /* text2atm.c - Converts textual representation of ATM address to binary encoding */ -/* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -94,14 +94,15 @@ addr->sas_addr.prv[0] = ATM_AFI_E164; addr->sas_addr.prv[1] = 0; memset(addr->sas_addr.prv+1,0,8); - for (pos = 18-count-1; *text; text++) - if (*text != '.') - if (*text == ':') break; - else { - if (pos & 1) addr->sas_addr.prv[pos >> 1] |= *text-'0'; - else addr->sas_addr.prv[pos >> 1] = (*text-'0') << 4; - pos++; - } + for (pos = 18-count-1; *text; text++) { + if (*text == '.') continue; + if (*text == ':') break; + else { + if (pos & 1) addr->sas_addr.prv[pos >> 1] |= *text-'0'; + else addr->sas_addr.prv[pos >> 1] = (*text-'0') << 4; + pos++; + } + } addr->sas_addr.prv[8] |= 0xf; text++; pos++; @@ -174,12 +175,13 @@ addr->sas_addr.pub[i] = 0; *addr->sas_addr.prv = 0; result = 0; - if (*text) + if (*text) { if (*text++ != '+') return TRY_OTHER; else { result = do_try_nsap(text,addr,flags); if (result < 0) return FATAL; } + } addr->sas_family = AF_ATMSVC; return result; } diff -ur --new-file old/atm/lib/text2qos.c new/atm/lib/text2qos.c --- old/atm/lib/text2qos.c Wed Mar 24 15:16:19 1999 +++ new/atm/lib/text2qos.c Tue Jan 18 20:28:44 2000 @@ -1,7 +1,7 @@ /* text2qos.c - Converts textual representation of QOS parameters to binary encoding */ -/* Written 1996-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -129,15 +129,17 @@ static const unsigned char aal_number[] = { ATM_AAL0, ATM_AAL5 }; int item; - item = fetch(&text,"!none","ubr","cbr","aal0","aal5",NULL); + item = fetch(&text,"!none","ubr","cbr","vbr","abr","aal0","aal5",NULL); switch (item) { case 1: case 2: + /* we don't support VBR yet */ + case 4: traffic_class = item; break; - case 3: - case 4: - aal = aal_number[item-3]; + case 5: + case 6: + aal = aal_number[item-5]; break; default: return -1; diff -ur --new-file old/atm/maint/Makefile new/atm/maint/Makefile --- old/atm/maint/Makefile Mon Nov 22 12:58:10 1999 +++ new/atm/maint/Makefile Fri Jan 21 09:23:21 2000 @@ -1,7 +1,7 @@ LDLIBS=-latmd INCLUDES=-I../qgen -I../saal BOOTPGMS=atmaddr esi -SYSPGMS=atmtcp natmtcp zntune loop25 # nstune +SYSPGMS=atmtcp enitune zntune loop25 # nstune USRPGMS=atmdiag atmdump sonetdiag saaldump MAN8=atmaddr.8 atmdiag.8 atmdump.8 atmtcp.8 diff -ur --new-file old/atm/maint/atmaddr.c new/atm/maint/atmaddr.c --- old/atm/maint/atmaddr.c Sat Jun 6 02:11:51 1998 +++ new/atm/maint/atmaddr.c Tue Jan 18 10:11:24 2000 @@ -1,6 +1,6 @@ /* atmaddr.c - Get/set local ATM adresses */ -/* Written 1995,1996,1998 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -8,9 +8,9 @@ #include #include #include -#include #include "atm.h" +#include #define MAX_ADDR 1024 /* that should do it for now ... */ diff -ur --new-file old/atm/maint/atmdiag.c new/atm/maint/atmdiag.c --- old/atm/maint/atmdiag.c Fri Nov 19 13:25:11 1999 +++ new/atm/maint/atmdiag.c Tue Jan 18 22:28:13 2000 @@ -1,6 +1,6 @@ /* atmdiag.c - ATM diagnostics */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -10,9 +10,9 @@ #include #include #include -#include #include +#include #define BUF_LEN 1024 /* ugly */ @@ -55,13 +55,14 @@ int s,zero; zero = 0; - if (argc > 1 && *argv[1] == '-') + if (argc > 1 && *argv[1] == '-') { if (strcmp(argv[1],"-z")) usage(argv[0]); else { zero = 1; argv++; argc--; } + } if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) { perror("socket"); return 1; diff -ur --new-file old/atm/maint/atmtcp.8 new/atm/maint/atmtcp.8 --- old/atm/maint/atmtcp.8 Tue Aug 4 17:57:20 1998 +++ new/atm/maint/atmtcp.8 Fri Jan 21 19:25:09 2000 @@ -1,88 +1,140 @@ -.TH ATMTCP 8 "August 4, 1998" "Linux" "Maintenance Commands" +.TH ATMTCP 8 "January 21, 2000" "Linux" "Maintenance Commands" .SH NAME atmtcp \- set up ATM over TCP connections .SH SYNOPSIS .ad l .B atmtcp -.RB [ \-b ] -.RB [ \-i\ \fIitf\fB ] -.B \-l -.RB [ \fIlclport\fB ] -.br -.B atmtcp -.RB [ \-b ] -.RB [ \-i\ \fIitf\fB ] -.B \-c -.I host -.RB [ \fIrmtport\fB ] -.br -.B atmtcp -.RB [ \-b ] -.RB [ \-i\ \fIitf\fB ] -.B \-s -.I host -.I line -.RB [ \fIrmtport\fB ] -.br -\fBatmtcp\fP \fB\-p\fP [[\fB\-i\fP] \fIitf\fP] -.br -\fBatmtcp\fP \fB\-r\fP [[\fB\-i\fP] \fIitf\fP] +.RB [ \-d ] +.RB [ \-v ] +.I command +.B ... .ad b .SH DESCRIPTION -.B atmtcp -establishes TCP connections and configures them as virtual ATM devices. +The main purpose of \fBatmtcp\fP +is to establish TCP connections and to configures them as virtual ATM devices. Such pairs of "ATM over TCP" devices are connected as if they were real ATM adapters linked by a cable or fiber, i.e. SDUs sent on a given VPI/VCI are received at the other end on the same VPI/VCI. .PP -.B atmtcp -can operate with two types of interfaces: ephemeral or persistent. -By default, -.B atmtcp -interfaces ephemeral. When the -.B atmtcp -process that created an interface terminates, the virtual ATM device is removed -as soon all VCs are closed. -However, if the interface was previously created -as a persistent interface, only the communication stops, but the interface -and all VCs on it remain intact. Attempts to send data on an -.B atmtcp -interface in this state fail silently, i.e. the interface behaves just like -a real ATM interface without a wire. -A new -.B atmtcp -process can then attach to the interface and resume operation. Persistent -interfaces need to be removed explicitly. +Virtual interfaces and ATM over TCP connections are called \fIlinks\fP. +Other link types supported by \fBatmtcp\fP are real interfaces, files for +recording and playback of ATM traffic, and printing a hex dump of the +PDU content on standard output. Any pair of such links can be connected +with \fBatmtcp\fP. If additional links are attached to such a connection, +they send to all other links, except to the first link and the respective +sender, and they receive from all other links. .PP -The optional port arguments are used to run -.B atmtcp -on a different port than the default port (8401). +\fBatmtcp\fP can operate with two types of virtual interfaces: ephemeral or +persistent. By default, \fBatmtcp\fP interfaces are ephemeral. When the +\fBatmtcp\fP process that created an interface terminates, the virtual ATM +device is removed as soon all VCs are closed. However, if the interface was +previously created as a persistent interface, only the communication stops, +but the interface and all VCs on it remain intact. Attempts to send data on +an \fBatmtcp\fP interface in this state fail silently, i.e. the interface +behaves just like a real ATM interface without a wire. +A new \fBatmtcp\fP process can then attach to the interface and resume +operation. Persistent interfaces need to be removed explicitly. +.PP +If \fBatmtcp\fP has any readable links after processing the command line, +it enters a loop to perform the data forwarding. If no readable links +have been specified, \fBatmtcp\fP terminates after processing the command +line. If any setup operation fails, \fBatmtcp\fP terminates at this point +and does not attempt to cancel previous operations (e.g. creation of +permanent interfaces). .SH OPTIONS -.IP \fB\-b\fP -Run in background (i.e. in a forked child process) after initializing. -.IP \fB\-i\ \fIitf\fP -create the interface with the specified number instead of picking the first -available number. \fBatmtcp\fP fails if the requested interface already exists. -.IP \fB\-l\fP -listen for an incoming connection. Only one connection is accepted. -.IP \fB\-c\ \fIhost\fP -connect to an instance of \fBatmtcp\fP running on the specified host. -.IP \fB\-s\ \fIhost\fP\ \fIline\fP -connect to an \fBatmtcp\fP "switch", attaching to the specified virtual line. -.IP \fB\-p\fP -create a persistent interface. -.IP \fB\-r\fP +.IP \fB\-d\fP +print detailed progress information on standard error. +.IP \fB\-v\fP +print some progress information on standard error. +.SH COMMANDS +.IP \fBcreate\fP\ [\fIitf\fP] +create a persistent interface. If no interface number is specified, +\fBatmtcp\fP uses the default value 0. +.IP \fBremove\fP\ [\fIitf\fP] remove a persistent interface. If the interface is still in use, it is marked -as non-persistent and will be removed as soon as all VCs are closed. +as ephemeral and will be removed as soon as all VCs are closed. If no +interface number is specified, \fBatmtcp\fP uses the default value 0. +.IP \fBvirtual\fP\ [\fIitf\fP] +link to the corresponding virtual (ATM over TCP) interface. If no interface +number is specified, the kernel assigns the first available number. +.IP \fBreal\fP\ [\fIitf\fP] +link to the corresponding ATM interface. If no +interface number is specified, \fBatmtcp\fP uses the default value 0. +If a link requests that a VC be +opened, \fBatmtcp\fP will attempt to open a VC with the specified QoS +parameters on that interface. If the operation succeeds, data can be +sent or received on that VC. If the operation fails, an error code is +returned to the requester. Note that only data arriving on open VCs can be +received and that a \fIreal\fP ATM interface never initiates a connection. +\fBatmtcp\fP can share ATM interfaces with other applications. +.IP \fBconnect\fP\ \fIhost\fP\ [\fIport\fP] +connect to an instance of \fBatmtcp\fP running on the specified host. +If the port argument is omitted, \fBatmtcp\fP uses the default port 2812. +.IP \fBswitch\fP\ \fIhost\fP\ \fIline\fP\ [\fIport\fP] +like \fBconnect\fP, but connects to an ATM over TCP "switch" and selects +the specified virtual line. +.IP \fBlisten\fP\ [\fIport\fP] +listen for an incoming ATM over TCP connection. +If the port argument is omitted, \fBatmtcp\fP uses the default port 2812. +\fBatmtcp\fP waits until the connection +is established. Only one connection is accepted per \fBlisten\fP command. +.IP \fBlisten-bg\fP\ [\fIport\fP] +like \fBlisten\fP, but run in background after beginning to listen. +.IP \fBread\fP\ \fIfile\fP\ [\fIstream\fP] +play back all streams from the specified file. If a stream number is +specified, only that stream is played back. +.IP \fBwrite\fP\ \fIfile\fP +record the traffic of all links in the specified file. The PDUs from each +link are stored in a stream with the same number as the link. +.IP \fBprint\fP +print a hex dump of the content of all received PDUs on standard output. +.IP \fBbg\fP +continue to run in background (i.e. in a forked child process). +.IP \fBwait\fP\ [\fIseconds\fP] +wait for the specified number of seconds. If no time is specified, +\fBatmtcp\fP waits for a newline on standard input. .SH RESTRICTIONS +Due to recent protocol changes, \fBatmtcp\fP is currently not compatible +with the ATM over TCP "switch". +.PP Only AAL SDUs are exchanged, no segmentation or reassembly is performed. That implies that using different AALs (e.g. AAL5 and AAL0) on either side will reveal limitations of this emulation. .PP -.B atmtcp -continues to run during the the whole lifetime of the connection. +The \fBatmtcp\fP process needs to run during the the whole lifetime of the +connection. +.SH EXAMPLES +Create a pair of virtual ATM over TCP interfaces on the local host and +connect them: +.nf +.sp + # session A + atmtcp virtual listen + # session B + atmtcp virtual connect localhost +.sp +.fi +Create virtual interface 1, connect it to real ATM interface 0, then start +\fBatmsigd\fP on the virtual interface, and log all the traffic in a file: +.nf +.sp + atmtcp virtual 1 real 0 write /tmp/log + atmsigd 1.0.5 +.sp +.fi +Take the previously created file and examine the traffic sent from +\fBatmsigd\fP using \fBsaaldump\fP: +.nf +.sp + # session A + atmtcp virtual 1 read /tmp/log 0 wait + # session B + saaldump 1.0.5 + # press [Enter] in session A +.sp +.fi .SH AUTHOR Werner Almesberger, EPFL ICA .SH "SEE ALSO" -atmdiag(8), clip(8), sonetdiag(8) +atmdiag(8) .\"{{{}}} diff -ur --new-file old/atm/maint/atmtcp.c new/atm/maint/atmtcp.c --- old/atm/maint/atmtcp.c Sat Sep 4 21:20:10 1999 +++ new/atm/maint/atmtcp.c Fri Jan 21 19:24:54 2000 @@ -1,17 +1,18 @@ /* atmtcp.c - control ATM on TCP emulation */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include #include #include +#include #include +#include #include #include #include #include -#include #include #include @@ -20,317 +21,901 @@ #include -#define PORT 8402 /* old ATMTCP used 8401, but now the header is in - network byte order, so we're incompatible in most - cases */ - -/* IANA port number assignment pending. Include control messages in - network protocol when changing port number. */ +#define DEFAULT_PORT 2812 /* IANA-assigned; old ATMTCP used 8401 & 8402 */ +#define MAX_PACKET (ATM_MAX_AAL5_PDU+sizeof(struct atmtcp_control)+ \ + sizeof(int)) + + +typedef struct _in { + int fd; + void (*recv)(struct _in *in); + int link; + unsigned char buf[MAX_PACKET]; + int bytes; + void *user; + struct _in *next; +} IN; + + +typedef struct _out { + const struct _out_ops *ops; + int link; + void *user; + struct _out *next; +} OUT; + + +typedef struct _out_ops { + int (*open)(struct _out *out,int in_link,struct atmtcp_control *msg); + void (*send)(struct _out *out,int in_link,const struct atmtcp_hdr *hdr, + int size); + int (*close)(struct _out *out,int in_link,struct atmtcp_control *msg); +} OUT_OPS; + + +static OUT *outputs = NULL; +static IN *inputs = NULL; +static fd_set in_set; +static int fds = 0; +static int debug = 0; +static int links = 0; -#define MAX_PACKET ATM_MAX_AAL5_PDU+sizeof(struct atmtcp_hdr) +/* misc. */ -static int s_tcp,s_krn; -static int debug = 0; +/* + * Policy: + * - first link sends to everybody except itself + * - second link sends to everybody except itself + * - all other links send to everybody except the first link the sender itself + */ -static void net_write(const void *data,int size) +static int right_link(const OUT *out,int in_link) { - int wrote; - - wrote = write(s_tcp,data,size); - if (wrote < 0) { - perror("write to TCP"); - exit(1); - } - if (!wrote) exit(0); /* EOF */ - if (wrote != size) { - fprintf(stderr,"bad write (%d != %d)\n",wrote,size); - exit(1); - } + if (out->link == in_link) return 0; + return out != outputs || in_link == 1; } -static void kernel_write(const void *data,int size) +static void emit(int in_link,const struct atmtcp_hdr *hdr,int size) { - int wrote; + OUT *out; - wrote = write(s_krn,data,size); - if (wrote < 0) perror("write to kernel"); - else if (wrote != size) { - fprintf(stderr,"bad write (%d != %d)\n",wrote,size); - exit(1); - } + if (debug) + fprintf(stderr,"Emit: %d.%d, %d bytes\n",ntohs(hdr->vpi), + ntohs(hdr->vci),(int) ntohl(hdr->length)); + for (out = outputs; out; out = out->next) + if (out->ops->send) out->ops->send(out,in_link,hdr,size); } -static void control(struct atmtcp_control *msg) +static void control(int in_link,struct atmtcp_control *msg) { + OUT *out; + int changed = 0; + if (debug) + fprintf(stderr,"Control: (%d.%d) %s %d.%d, vcc %s\n", + ntohs(msg->hdr.vpi),ntohs(msg->hdr.vci), + msg->type == ATMTCP_CTRL_OPEN ? "OPEN" : + msg->type == ATMTCP_CTRL_CLOSE ? "CLOSE" : "???", + msg->addr.sap_addr.vpi,msg->addr.sap_addr.vci,kptr_print(&msg->vcc)); + for (out = outputs; out; out = out->next) switch (msg->type) { case ATMTCP_CTRL_OPEN: - fprintf(stderr,"OPEN %d.%d, vcc 0x%08lx\n", - msg->addr.sap_addr.vpi,msg->addr.sap_addr.vci,msg->vcc); + if (out->ops->open) + changed += out->ops->open(out,in_link,msg); break; case ATMTCP_CTRL_CLOSE: - fprintf(stderr,"CLOSE vcc 0x%08lx\n",msg->vcc); + if (out->ops->close) + changed += out->ops->close(out,in_link,msg); break; default: - fprintf(stderr,"Unknown control message type %d\n",msg->type); - return; + fprintf(stderr,"interval error\n"); + exit(1); } - kernel_write(msg,sizeof(*msg)); + if (changed > 1) fprintf(stderr,"WARNING: multiple changes on control()\n"); } -/* - * This is a pretty poor implementation because we need to read twice for each - * PDU. But then, atmtcp isn't exactly designed for throughput ... - */ +/* ----- Registries -------------------------------------------------------- */ -static void from_tcp(void) +static IN *register_in(int fd,void (*receive)(IN *in),void *user) { - static char buf[MAX_PACKET]; - static struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) buf; - static int bytes = 0; - int ret,size; + IN *in = alloc_t(IN); + IN **walk; - size = sizeof(struct atmtcp_hdr)-bytes; - if (size <= 0) size += ntohl(hdr->length); - ret = read(s_tcp,buf+bytes,size); - if (ret < 0) { - perror("read from TCP"); + in->fd = fd; + in->recv = receive; + in->link = links; + in->bytes = 0; + in->user = user; + in->next = NULL; + for (walk = &inputs; *walk; walk = &(*walk)->next); + *walk = in; + if (fd >= fds) fds = fd+1; + FD_SET(fd,&in_set); + return in; +} + + +static void unregister_in(IN *in) +{ + IN **walk; + + for (walk = &inputs; *walk != in; walk = &(*walk)->next); + FD_CLR(in->fd,&in_set); + if (fds > in->fd+1) return; + fds = 0; + for (walk = &inputs; *walk; walk = &(*walk)->next) + if ((*walk)->fd >= fds) fds = (*walk)->fd+1; +} + + +static void register_out(const OUT_OPS *ops,void *user) +{ + OUT *out = alloc_t(OUT); + OUT **walk; + + out->ops = ops; + out->link = links; + out->user = user; + out->next = NULL; + for (walk = &outputs; *walk; walk = &(*walk)->next); + *walk = out; +} + + +/* ----- Virtual (ATMTCP) interface ---------------------------------------- */ + + +static void virtual_do_send(int fd,const void *data,int size) +{ + int wrote; + + wrote = write(fd,data,size); + if (wrote < 0) perror("write to kernel"); + else if (wrote != size) { + fprintf(stderr,"bad write (%d != %d)\n",wrote,size); + exit(1); + } +} + + +static void virtual_in(IN *in) +{ + const struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; + int got; + + got = read(in->fd,in->buf,MAX_PACKET); + if (got < 0) { + perror("virtual interface"); + exit(1); + } + if (!got) exit(0); /* we don't use that yet */ + if (got < sizeof(struct atmtcp_hdr)) { + fprintf(stderr,"kernel message too small (%d)\n",got); + exit(1); + } + if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) { + if (got < sizeof(struct atmtcp_control)) { + fprintf(stderr,"invalid control message\n"); + exit(1); + } + control(in->link,(struct atmtcp_control *) in->buf); + virtual_do_send(in->fd,hdr,sizeof(struct atmtcp_control)); + return; + } + if (got != sizeof(struct atmtcp_hdr)+ntohl(hdr->length)) { + fprintf(stderr,"invalid kernel message\n"); exit(1); } - if (!ret) exit(0); /* EOF */ - bytes += ret; - if (bytes < sizeof(struct atmtcp_hdr)) return; - if (ntohl(((struct atmtcp_hdr *) buf)->length) > ATM_MAX_AAL5_PDU) { + emit(in->link,hdr,got); +} + + +static void virtual_send(OUT *out,int in_link,const struct atmtcp_hdr *hdr, + int size) +{ + if (!right_link(out,in_link)) return; + virtual_do_send(*(int *) out->user,hdr,size); +} + + +static OUT_OPS virtual_ops = { + NULL, /* open */ + virtual_send, /* send */ + NULL /* close */ +}; + + +/* ----- Real ATM interface ------------------------------------------------ */ + + +typedef struct _vcc { + struct sockaddr_atmpvc addr; + int fd; /* for output */ + IN *in; /* NULL is output only */ + struct _vcc *next; +} VCC; + + +typedef struct { + int itf; + VCC *vccs; +} REAL_DATA; + + +static VCC **real_lookup(REAL_DATA *data,const struct sockaddr_atmpvc *addr) +{ + VCC **walk; + + for (walk = &data->vccs; *walk; walk = &(*walk)->next) + if ((*walk)->addr.sap_addr.vpi == addr->sap_addr.vpi && + (*walk)->addr.sap_addr.vci == addr->sap_addr.vci) break; + return walk; +} + + +static void real_in(IN *in) +{ + VCC *vcc = (VCC *) in->user; + struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; + int got; + + got = read(in->fd,hdr+1,MAX_PACKET-sizeof(*hdr)); + if (got < 0) { + perror("real interface"); + exit(1); + } + hdr->length = htonl(got); + hdr->vpi = htons(vcc->addr.sap_addr.vpi); + hdr->vci = htons(vcc->addr.sap_addr.vci); + emit(in->link,hdr,got+sizeof(*hdr)); +} + + +static int real_open(OUT *out,int in_link,struct atmtcp_control *msg) +{ + REAL_DATA *data = (REAL_DATA *) out->user; + VCC **vcc; + int s; + + if (!right_link(out,in_link)) return 0; + vcc = real_lookup(data,&msg->addr); + if (*vcc) { + msg->result = -EADDRINUSE; + return 1; + } + if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) { + msg->result = -errno; + if (debug) perror("socket"); + return 1; + } + if (setsockopt(s,SOL_ATM,SO_ATMQOS,&msg->qos,sizeof(msg->qos)) < 0) { + msg->result = -errno; + if (debug) perror("setsockopt SO_ATMQOS"); + return 1; + } + msg->addr.sap_addr.itf = data->itf; + if (connect(s,(struct sockaddr *) &msg->addr, + sizeof(struct sockaddr_atmpvc)) < 0) { + msg->result = -errno; + if (debug) perror("connect"); + return 1; + } + (*vcc) = alloc_t(VCC); + (*vcc)->addr = msg->addr; + (*vcc)->next = NULL; + (*vcc)->fd = s; + (*vcc)->in = msg->qos.rxtp.traffic_class == ATM_NONE ? NULL : + register_in(s,real_in,*vcc); + return 1; +} + + +static void real_send(OUT *out,int in_link,const struct atmtcp_hdr *hdr, + int size) +{ + REAL_DATA *data = (REAL_DATA *) out->user; + struct sockaddr_atmpvc addr; + VCC **vcc; + int wrote; + + if (!right_link(out,in_link)) return; + addr.sap_addr.vpi = ntohs(hdr->vpi); + addr.sap_addr.vci = ntohs(hdr->vci); + vcc = real_lookup(data,&addr); + if (!*vcc) { + if (debug) + fprintf(stderr,"VCC %d.%d not found\n",addr.sap_addr.vpi, + addr.sap_addr.vci); + return; + } + wrote = write((*vcc)->fd,hdr+1,ntohl(hdr->length)); + if (wrote < 0) { + perror("real write"); + exit(1); + } + if (!wrote) exit(0); /* EOF */ + if (wrote != ntohl(hdr->length)) { + fprintf(stderr,"bad write (%d != %d)\n",wrote,(int) ntohl(hdr->length)); + exit(1); + } +} + + +static int real_close(OUT *out,int in_link,struct atmtcp_control *msg) +{ + REAL_DATA *data = (REAL_DATA *) out->user; + VCC **vcc,*this; + int fd; + + if (!right_link(out,in_link)) return 0; + vcc = real_lookup(data,&msg->addr); + if (!*vcc) { + msg->result = -ENOENT; + return 1; + } + this = *vcc; + *vcc = this->next; + if (this->in) unregister_in(this->in); + fd = this->fd; + free(this); + if (close(fd) >= 0) return 0; + msg->result = -errno; + return 1; +} + + +static OUT_OPS real_ops = { + real_open, /* open */ + real_send, /* send */ + real_close /* close */ +}; + + +/* ----- ATMTCP connection ------------------------------------------------- */ + + +static void tcp_do_send(int fd,const void *data,int size) +{ + int wrote; + + wrote = write(fd,data,size); + if (wrote < 0) { + perror("write to TCP"); + exit(1); + } + if (!wrote) exit(0); /* EOF */ + if (wrote != size) { + fprintf(stderr,"bad write (%d != %d)\n",wrote,size); + exit(1); + } +} + + +static void tcp_in(IN *in) +{ + struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; + char *msg = (char *) (hdr+1); + int vpi,vci; + char orig_addr[MAX_ATM_ADDR_LEN]; + char qos[MAX_ATM_QOS_LEN]; + struct atmtcp_control ctl; + int size,got; + + size = sizeof(*hdr)-in->bytes; + if (size <= 0) size += ntohl(hdr->length); + got = read(in->fd,in->buf+in->bytes,size); + if (got < 0) { + perror("read from file"); + exit(1); + } + if (!got) { + fprintf(stderr,"TCP disconnected\n"); + exit(0); + } + in->bytes += got; + if (in->bytes < sizeof(*hdr)) return; + if (ntohl(hdr->length) > ATM_MAX_AAL5_PDU) { fprintf(stderr,"giant PDU (length = %d) received\n", (unsigned int) ntohl(hdr->length)); exit(1); } - if (bytes < sizeof(struct atmtcp_hdr)+ntohl(hdr->length)) return; + if (in->bytes < sizeof(*hdr)+ntohl(hdr->length)) return; if (debug) - fprintf(stderr,"TCP %d.%d, %d bytes\n",ntohs(hdr->vpi),ntohs(hdr->vci), - (unsigned int) ntohl(hdr->length)); - kernel_write(buf,bytes); - bytes = 0; + fprintf(stderr,"TCP %d.%d, %d bytes\n",ntohs(hdr->vpi), + ntohs(hdr->vci),(unsigned int) ntohl(hdr->length)); + in->bytes = 0; + if (hdr->vpi || hdr->vci) { + emit(in->link,hdr,sizeof(*hdr)+ntohl(hdr->length)); + return; + } + msg[ntohl(hdr->length)] = 0; + memset(&ctl,0,sizeof(ctl)); + if (sscanf(msg,"O %d.%d %s %s",&vpi,&vci,orig_addr,qos) == 4) + ctl.type = ATMTCP_CTRL_OPEN; + else if (sscanf(msg,"C %d.%d",&vpi,&vci) == 2) ctl.type = ATMTCP_CTRL_CLOSE; + else { + fprintf(stderr,"unrecognized control message \"%s\"\n",msg); + return; + } + if (debug) fprintf(stderr,"received control \"%s\"\n",msg); + ctl.hdr.vpi = htons(vpi); + ctl.hdr.vci = htons(vci); + ctl.hdr.length = htonl(ATMTCP_HDR_MAGIC); + ctl.addr.sap_family = AF_ATMPVC; + ctl.addr.sap_addr.itf = 0; + ctl.addr.sap_addr.vpi = vpi; + ctl.addr.sap_addr.vci = vci; + if (ctl.type == ATMTCP_CTRL_OPEN) { + if (text2atm(orig_addr,(struct sockaddr *) &ctl.addr,sizeof(ctl.addr), + T2A_PVC) < 0) { + fprintf(stderr,"invalid address \"%s\"\n",orig_addr); + return; + } + if (text2qos(qos,&ctl.qos,0) < 0) { + fprintf(stderr,"invalid QOS \"%s\"\n",qos); + return; + } + } + control(in->link,&ctl); } -static void to_tcp(void) +static void tcp_send(OUT *out,int in_link,const struct atmtcp_hdr *hdr,int size) { - char buf[MAX_PACKET]; + if (!right_link(out,in_link)) return; + tcp_do_send(*(int *) out->user,hdr,size); +} + + +static int tcp_control(OUT *out,int in_link,struct atmtcp_control *msg) +{ + char buf[MAX_ATM_NAME_LEN*2+MAX_ATM_NAME_LEN+5]; struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) buf; - int ret; + char *start = (char *) (hdr+1); + char *pos = start; - ret = read(s_krn,buf,MAX_PACKET); - if (ret < 0) { - perror("read from kernel"); - exit(1); + if (!right_link(out,in_link)) return 0; + if (msg->type != ATMTCP_CTRL_OPEN && msg->type != ATMTCP_CTRL_CLOSE) { + fprintf(stderr,"unrecognized control message %d\n",msg->type); + return 0; + } + pos += sprintf(pos,"%c %d.%d",msg->type == ATMTCP_CTRL_OPEN ? 'O' : 'C', + msg->addr.sap_addr.vpi,msg->addr.sap_addr.vci); + if (msg->type == ATMTCP_CTRL_OPEN) { + *pos++ = ' '; + if (atm2text(pos,sizeof(buf)-(pos-buf),(struct sockaddr *) &msg->addr, + 0) < 0) { + fprintf(stderr,"invalid ATM address\n"); + return 0; + } + pos = strchr(pos,0); + *pos++ = ' '; + if (qos2text(pos,sizeof(buf)-(pos-buf),&msg->qos,0) < 0) { + fprintf(stderr,"invalid QOS\n"); + return 0; + } + pos = strchr(pos,0); } - if (!ret) exit(0); /* we don't use that yet */ - if (ret < sizeof(struct atmtcp_hdr)) { - fprintf(stderr,"kernel message too small (%d)\n",ret); - exit(1); + hdr->vpi = hdr->vci = htons(0); + hdr->length = htonl(pos-start); + if (debug) fprintf(stderr,"sending control \"%s\"\n",start); + tcp_do_send(*(int *) out->user,buf,pos-buf); + return 0; +} + + +static OUT_OPS tcp_ops = { + tcp_control, /* open */ + tcp_send, /* send */ + tcp_control /* close */ +}; + + +/* ----- File -------------------------------------------------------------- */ + + +static void file_in(IN *in) +{ + int *stream = (int *) in->buf; + struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) (stream+1); + int size,got; + + size = sizeof(int)+sizeof(*hdr)-in->bytes; + if (size <= 0) + size += ntohl(hdr->length) == ATMTCP_HDR_MAGIC ? + sizeof(struct atmtcp_control)-sizeof(*hdr) : ntohl(hdr->length); + got = read(in->fd,in->buf+in->bytes,size); + if (got < 0) { + perror("read from file"); + exit(1); + } + if (!got) { + fprintf(stderr,"EOF\n"); + exit(0); + } + in->bytes += got; + if (in->bytes < sizeof(int)+sizeof(*hdr)) return; + if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) { + if (in->bytes < sizeof(int)+sizeof(struct atmtcp_control)) return; } - if (hdr->length == ATMTCP_HDR_MAGIC) { - if (ret < sizeof(struct atmtcp_control)) { - fprintf(stderr,"invalid control message\n"); + else { + if (ntohl(hdr->length) > ATM_MAX_AAL5_PDU) { + fprintf(stderr,"giant PDU (length = %d) received\n", + (unsigned int) ntohl(hdr->length)); exit(1); } - control((struct atmtcp_control *) buf); - return; + if (in->bytes < sizeof(int)+sizeof(*hdr)+ntohl(hdr->length)) return; + if (debug) + fprintf(stderr,"File %d.%d, %d bytes\n",ntohs(hdr->vpi), + ntohs(hdr->vci),(unsigned int) ntohl(hdr->length)); + } + in->bytes = 0; + if (*(int *) in->user != -1 && ntohl(*stream) != *(int *) in->user) return; + if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) + control(in->link,(struct atmtcp_control *) hdr); + else emit(in->link,hdr,sizeof(*hdr)+ntohl(hdr->length)); +} + + +static void file_write(int fd,int stream,int is_control,const void *data, + int size) +{ + int wrote; + + stream = htonl(stream); + wrote = write(fd,&stream,sizeof(stream)); + if (wrote < 0) { + perror("file write"); + exit(1); } - if (debug) - fprintf(stderr,"KRN %d.%d, %d bytes\n",ntohs(hdr->vpi),ntohs(hdr->vci), - (unsigned int) ntohl(hdr->length)); - if (ret != sizeof(struct atmtcp_hdr)+ntohl(hdr->length)) { - fprintf(stderr,"invalid kernel message\n"); + if (wrote != sizeof(stream)) { + fprintf(stderr,"short write (%d < %d)\n",wrote,sizeof(stream)); + exit(1); + } + wrote = write(fd,data,size); + if (wrote < 0) { + perror("file write"); + exit(1); + } + if (wrote != size) { + fprintf(stderr,"short write (%d < %d)\n",wrote,size); exit(1); } - net_write(buf,ret); +} + + +static void file_send(OUT *out,int in_link,const struct atmtcp_hdr *hdr, + int size) +{ + file_write(*(int *) out->user,in_link,0,hdr,size); +} + + +static int file_control(OUT *out,int in_link,struct atmtcp_control *msg) +{ + file_write(*(int *) out->user,in_link,1,msg,sizeof(*msg)); + return 0; +} + + +static OUT_OPS file_ops = { + file_control, /* open */ + file_send, /* send */ + file_control /* close */ +}; + + +/* ----- Print ------------------------------------------------------------- */ + + +static void print_send(OUT *out,int in_link,const struct atmtcp_hdr *hdr, + int size) +{ + int length = ntohl(hdr->length); + int i; + + printf("Link %d (from link %d), VPI %d, VCI %d, %d byte%s:",out->link, + in_link,ntohs(hdr->vpi),ntohs(hdr->vci),length,length == 1 ? "" : "s"); + for (i = 0; i < length; i++) { + if (!(i & 15)) printf("\n "); + printf(" %02x",((unsigned char *) (hdr+1))[i]); + } + putchar('\n'); + fflush(stdout); +} + + +static OUT_OPS print_ops = { + NULL, /* open */ + print_send, /* send */ + NULL /* close */ +}; + + +/* ----- Initialization ---------------------------------------------------- */ + + +static void background(void) +{ + static int backgrounding = 0; + pid_t pid; + + if (backgrounding++) { + fprintf(stderr,"\"bg\" only allowed once\n"); + exit(1); + } + pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } + if (pid) exit(0); } static void usage(const char *name) { - fprintf(stderr,"%s [ -b ] [ -d ] [ -i itf ] -l [ ]\n",name); - fprintf(stderr,"%s [ -b ] [ -d ] [ -i itf ] -c [ ]\n", + fprintf(stderr,"%s [ -d ] [ -v ] ...\n\n", name); - fprintf(stderr,"%s [ -b ] [ -d ] [ -i itf ] -s " - "[ ]\n",name); - fprintf(stderr,"%s -p [ [ -i ] itf ]\n",name); - fprintf(stderr,"%s -r [ [ -i ] itf ]\n",name); - fprintf(stderr,"\n -b background\n -d debug\n -i interface\n"); - fprintf(stderr," -l listen\n -c connect\n -s connect to switch\n"); - fprintf(stderr," -p create persistent\n -r remove persistent\n"); + fprintf(stderr," -d debug\n"); + fprintf(stderr," -v verbose\n\n"); + fprintf(stderr,": create [ ] (persistent; default itf: 0)\n"); + fprintf(stderr," remove [ ] (persistent; default itf: 0)\n"); + fprintf(stderr," virtual [ ] (default itf: assigned by " + "kernel)\n"); + fprintf(stderr," real [ ] (default itf: 0)\n"); + fprintf(stderr," connect [ ]\n"); + fprintf(stderr," switch [ ] (to ATMTCP " + "virtual switch)\n"); + fprintf(stderr," listen [ ]\n"); + fprintf(stderr," read [ ]\n"); + fprintf(stderr," write \n"); + fprintf(stderr," print\n"); + fprintf(stderr," bg (background)\n"); + fprintf(stderr," wait [ ] (default: wait for [Enter])\n\n"); + fprintf(stderr,"create, remove, bg, and wait don't create new links.\n"); exit(1); } +#define NEXT (++optind < argc) +#define HAS_MORE (optind < argc-1) +#define NEED_NEXT { if (!NEXT) usage(*argv); } +#define ARG argv[optind] +#define NEXT_ARG argv[optind+1] + + int main(int argc,char **argv) { - enum { m_undefined,m_listen,m_connect,m_switch,m_create,m_remove } mode; struct sockaddr_in addr; - const char *name; char *end; - char *host,*line; - int background,port,itf; - int s2; + int verbose = 0; + int do_create,do_background = 0,to_switch = 0; int c; - name = argv[0]; - mode = m_undefined; - background = 0; - host = line = NULL; /* for gcc */ - itf = -1; - port = 0; /* for gcc */ - while ((c = getopt(argc,argv,"bdi:lc:prs:")) != EOF) + FD_ZERO(&in_set); + while ((c = getopt(argc,argv,"dv")) != EOF) switch (c) { - case 'b': - background = 1; - break; case 'd': debug = 1; break; - case 'i': - if (itf != -1) usage(name); - itf = strtoul(optarg,&end,10); - if (*end) usage(name); - break; - case 'l': - if (mode != m_undefined) usage(name); - mode = m_listen; - break; - case 'c': - if (mode != m_undefined) usage(name); - mode = m_connect; - host = optarg; - break; - case 's': - if (mode != m_undefined) usage(name); - mode = m_switch; - host = optarg; - break; - case 'p': - if (mode != m_undefined) usage(name); - mode = m_create; - break; - case 'r': - if (mode != m_undefined) usage(name); - mode = m_remove; + case 'v': + verbose = 1; break; default: - usage(name); - } - if (mode == m_undefined) usage(name); - switch (mode) { - case m_switch: - if (argc == optind) usage(name); - line = argv[optind++]; - /* fall through */ - case m_connect: - /* fall through */ - case m_listen: - if (argc > optind+1) usage(name); - port = argc == optind+1 ? atoi(argv[optind]) : -1; - break; - case m_remove: - /* fall through */ - case m_create: - if (background || debug) usage(name); - if (argc != optind && itf != -1) usage(name); - if (argc != optind+1) usage(name); - itf = strtoul(argv[optind],&end,10); - if (*end) usage(name); - break; - default: - abort(); - } - if ((s_krn = socket(PF_ATMSVC,SOCK_DGRAM,0)) < 0) { - perror("socket"); - return 1; - } - if (mode == m_create || mode == m_remove) { - if (mode == m_remove && itf == -1) itf = 0; - if (ioctl(s_krn,mode == m_create ? ATMTCP_CREATE : ATMTCP_REMOVE,itf) - >= 0) return 0; - perror(mode == m_create ? - "ioctl ATMTCP_CREATE" : "ioctl ATMTCP_REMOVE"); - return 1; - } - if ((s_tcp = socket(PF_INET,SOCK_STREAM,0)) < 0) { - perror("socket"); - return 1; - } - if (!port) usage(name); - addr.sin_family = AF_INET; - addr.sin_port = htons(port == -1 ? PORT : port); - /* - * Create atmtcp interface before setting up the TCP connection in order - * to make the assignment of interface numbers a bit more predictable. - */ - if ((itf = ioctl(s_krn,SIOCSIFATMTCP,itf)) < 0) { - perror("ioctl SIOCSIFATMTCP"); - return 1; - } - if (mode == m_listen) { - addr.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(s_tcp,(struct sockaddr *) &addr,sizeof(addr)) < 0) { - perror("bind"); - return 1; - } - printf("Listening on port %d ...\n",ntohs(addr.sin_port)); - if (listen(s_tcp,5) < 0) { - perror("listen"); - return 1; - } - if ((s2 = accept(s_tcp,NULL,NULL)) < 0) { - perror("accept"); - return 1; + usage(*argv); } - (void) close(s_tcp); - s_tcp = s2; - } - else { - addr.sin_addr.s_addr = text2ip(host,NULL,T2I_NAME | T2I_ERROR); - if (addr.sin_addr.s_addr == INADDR_NONE) return 1; - if (connect(s_tcp,(struct sockaddr *) &addr,sizeof(addr)) < 0) { - perror("connect"); - return 1; - } - if (mode == m_switch) net_write(line,strlen(line)+1); - } - printf("Connected, interface %d\n",itf); - if (background) { - pid_t pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - return 1; + optind--; + if (!HAS_MORE) usage(*argv); + while (NEXT) { + if ((do_create = !strcmp(ARG,"create")) || !strcmp(ARG,"remove")) { + int s; + int itf = 0; + + if ((s = socket(PF_ATMSVC,SOCK_DGRAM,0)) < 0) { + perror("socket"); + return 1; + } + if (HAS_MORE) { + itf = strtoul(NEXT_ARG,&end,10); + if (*end) itf = 0; + else (void) NEXT; + } + if (ioctl(s,do_create ? ATMTCP_CREATE : ATMTCP_REMOVE,itf) < 0) { + perror(do_create ? "ioctl ATMTCP_CREATE" : + "ioctl ATMTCP_REMOVE"); + return 1; + } + (void) close(s); + if (verbose) + fprintf(stderr,"Persistent ATMTCP interface %d %s\n",itf, + do_create ? "created" : "removed"); + } + else if (!strcmp(ARG,"virtual")) { + int *fd = alloc_t(int); + int itf = -1; + + if (HAS_MORE) { + itf = strtoul(NEXT_ARG,&end,10); + if (*end) itf = -1; + else (void) NEXT; + } + if ((*fd = socket(PF_ATMSVC,SOCK_DGRAM,0)) < 0) { + perror("socket"); + return 1; + } + if ((itf = ioctl(*fd,SIOCSIFATMTCP,itf)) < 0) { + perror("ioctl SIOCSIFATMTCP"); + return 1; + } + (void) register_in(*fd,&virtual_in,NULL); + register_out(&virtual_ops,fd); + fprintf(stderr,"Link %d: virtual interface %d\n",links++,itf); + } + else if (!strcmp(ARG,"real")) { + REAL_DATA *data = alloc_t(REAL_DATA); + int itf = 0; + + if (HAS_MORE) { + itf = strtoul(NEXT_ARG,&end,10); + if (*end) itf = 0; + else (void) NEXT; + } + data->itf = itf; + data->vccs = NULL; + register_out(&real_ops,data); + fprintf(stderr,"Link %d: real interface %d\n",links++,itf); + } + else if (!strcmp(ARG,"connect") || (to_switch = !strcmp(ARG,"switch"))) + { + int *fd = alloc_t(int); + const char *host,*line = NULL; + int port; + + NEED_NEXT; + host = ARG; + if ((*fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { + perror("socket"); + return 1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = text2ip(ARG,NULL,T2I_NAME | T2I_ERROR); + if (addr.sin_addr.s_addr == INADDR_NONE) return 1; + if (to_switch) { + NEED_NEXT; + line = ARG; + } + if (!HAS_MORE) port = DEFAULT_PORT; + else { + port = strtoul(NEXT_ARG,&end,10); + if (*end) port = DEFAULT_PORT; + else (void) NEXT; + } + addr.sin_port = htons(port); + if (connect(*fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { + perror("connect"); + return 1; + } + (void) register_in(*fd,&tcp_in,NULL); + register_out(&tcp_ops,fd); + fprintf(stderr,"Link %d: ATMTCP connection to %s\n",links++,host); + if (to_switch) tcp_do_send(*fd,line,strlen(line)+1); + } + else if (!strcmp(ARG,"listen") || + (do_background = !strcmp(ARG,"listen-bg"))) { + int fd,port,addr_len; + int *fd2 = alloc_t(int); + + if ((fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { + perror("socket"); + return 1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + if (!HAS_MORE) port = DEFAULT_PORT; + else { + port = strtoul(NEXT_ARG,&end,10); + if (*end) port = DEFAULT_PORT; + else (void) NEXT; + } + addr.sin_port = htons(port); + if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { + perror("bind"); + return 1; + } + if (listen(fd,5) < 0) { + perror("listen"); + return 1; + } + if (verbose) + fprintf(stderr,"Listening on TCP port %d\n",port); + if (do_background) background(); + addr_len = sizeof(addr); + if ((*fd2 = accept(fd,(struct sockaddr *) &addr,&addr_len)) < 0) { + perror("accept"); + return 1; + } + (void) close(fd); + (void) register_in(*fd2,&tcp_in,NULL); + register_out(&tcp_ops,fd2); + fprintf(stderr,"Link %d: incoming ATMTCP connection from %s\n", + links++,addr.sin_family == AF_INET ? inet_ntoa(addr.sin_addr) : + "non-IPv4 host"); } - if (pid) return 0; + else if (!strcmp(ARG,"read")) { + int *stream = alloc_t(int); + const char *name; + int fd; + + NEED_NEXT; + name = ARG; + if ((fd = open(ARG,O_RDONLY)) < 0) { + perror(ARG); + return 1; + } + if (!HAS_MORE) *stream = -1; + else { + *stream = strtoul(NEXT_ARG,&end,10); + if (*end) *stream = -1; + else (void) NEXT; + } + (void) register_in(fd,&file_in,stream); + fprintf(stderr,"Link %d: read-only file \"%s\"\n",links++,name); + } + else if (!strcmp(ARG,"write")) { + int *fd = alloc_t(int); + + NEED_NEXT; + if ((*fd = open(ARG,O_CREAT | O_WRONLY | O_TRUNC,0666)) < 0) { + perror(ARG); + return 1; + } + register_out(&file_ops,fd); + fprintf(stderr,"Link %d: write-only file \"%s\"\n",links++,ARG); + } + else if (!strcmp(ARG,"print")) { + register_out(&print_ops,0); + fprintf(stderr,"Link %d: printing on standard output\n",links++); + } + else if (!strcmp(ARG,"bg")) background(); + else if (!strcmp(ARG,"wait")) { + int secs = -1; + + if (HAS_MORE) { + secs = strtoul(NEXT_ARG,&end,10); + if (*end) secs = -1; + else (void) NEXT; + } + if (secs != -1) { + sleep(secs); + continue; + } + fprintf(stderr,"Press to continue\n"); + do c = getchar(); + while (c != EOF && c != '\n'); + } + else usage(*argv); } + if (!fds) return 0; while (1) { + IN *in; fd_set set; int ret; - FD_ZERO(&set); - FD_SET(s_tcp,&set); - FD_SET(s_krn,&set); - ret = select(s_tcp > s_krn ? s_tcp+1 : s_krn+1,&set,NULL,NULL,0); + set = in_set; + ret = select(fds,&set,NULL,NULL,NULL); if (ret < 0) { if (errno != EINTR) perror("select"); + continue; } - else { - if (FD_ISSET(s_tcp,&set)) from_tcp(); - if (FD_ISSET(s_krn,&set)) to_tcp(); - } + for (in = inputs; in; in = in->next) + if (FD_ISSET(in->fd,&set)) in->recv(in); } - return 0; } diff -ur --new-file old/atm/maint/enitune.c new/atm/maint/enitune.c --- old/atm/maint/enitune.c Thu Jan 1 01:00:00 1970 +++ new/atm/maint/enitune.c Fri Jan 21 09:25:36 2000 @@ -0,0 +1,59 @@ +/* enitune.c - ENI buffer size tuning */ + +/* Written 2000 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static void usage(const char *name) +{ + fprintf(stderr,"usage: %s [ -t tx_mult ] [ -r rx_mult ] itf\n",name); + fprintf(stderr," multipliers are in percent and must be > 100\n"); + exit(1); +} + + +int main(int argc,char **argv) +{ + char *name,*end; + struct atmif_sioc sioc; + struct eni_multipliers mult; + int c,s; + + name = argv[0]; + mult.tx = mult.rx = 0; + while ((c = getopt(argc,argv,"t:r:")) != EOF) + switch (c) { + case 't': + mult.tx = strtol(optarg,&end,0); + if (*end || mult.tx <= 100) usage(name); + break; + case 'r': + mult.rx = strtol(optarg,&end,0); + if (*end || mult.rx <= 100) usage(name); + break; + default: + } + if (argc != optind+1) usage(name); + sioc.number = strtol(argv[optind],&end,0); + if (*end || sioc.number < 0) usage(name); + if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) { + perror("socket"); + return 1; + } + sioc.arg = &mult; + sioc.length = sizeof(mult); + if (ioctl(s,ENI_SETMULT,&sioc) < 0) { + perror("ioctl ENI_SETMULT"); + return 1; + } + return 0; +} diff -ur --new-file old/atm/maint/esi.c new/atm/maint/esi.c --- old/atm/maint/esi.c Tue Apr 7 14:01:42 1998 +++ new/atm/maint/esi.c Tue Jan 18 22:22:40 2000 @@ -1,6 +1,6 @@ /* esi.c - Get or set End System Identifier (ESI) */ -/* Written 1997,1998 by Werner Almesberger, EPFL LRC/ICA */ +/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */ #include @@ -64,12 +64,13 @@ if (*end) usage(*argv); esi = argv[optind]; } - if (argc == optind+1) + if (argc == optind+1) { if (strlen(argv[optind]) == ESI_LEN*2) esi = argv[optind]; else { req.number = strtoul(argv[optind],&end,0); if (*end) usage(*argv); } + } if (op == ATM_SETESIF && !esi) usage(*argv); if (esi) { int i,byte; diff -ur --new-file old/atm/maint/natmtcp.c new/atm/maint/natmtcp.c --- old/atm/maint/natmtcp.c Sun Sep 5 05:13:38 1999 +++ new/atm/maint/natmtcp.c Thu Jan 1 01:00:00 1970 @@ -1,830 +0,0 @@ -/* natmtcp.c - control ATM on TCP emulation */ - -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#define DEFAULT_PORT 8403 /* old ATMTCP used 8401 and 8402. Awaiting - IANA assignment */ -#define MAX_PACKET (ATM_MAX_AAL5_PDU+sizeof(struct atmtcp_control)+ \ - sizeof(int)) - - -typedef struct _in { - int fd; - void (*recv)(struct _in *in); - int link; - unsigned char buf[MAX_PACKET]; - int bytes; - void *user; - struct _in *next; -} IN; - - -struct _out; - - -typedef struct { - int (*open)(struct _out *out,int in_link,struct atmtcp_control *msg); - void (*send)(struct _out *out,int in_link,struct atmtcp_hdr *hdr,int size); - int (*close)(struct _out *out,int in_link,struct atmtcp_control *msg); -} OUT_OPS; - - -typedef struct _out { - const OUT_OPS *ops; - int link; - void *user; - struct _out *next; -} OUT; - - -static OUT *outputs = NULL; -static IN *inputs = NULL; -static fd_set in_set; -static int fds = 0; -static int debug = 0; -static int links = 0; - - -/* misc. */ - - -/* - * Policy: - * - first link sends to everybody except itself - * - second link sends to everybody except itself - * - all other links send to everybody except the first link - */ - - -static int right_link(const OUT *out,int in_link) -{ - if (out->link == in_link) return 0; - return out != outputs || in_link == 1; -} - - -static void emit(int in_link,struct atmtcp_hdr *hdr,int size) -{ - OUT *out; - - if (debug) - fprintf(stderr,"Emit: %d.%d, %d bytes\n",ntohs(hdr->vpi), - ntohs(hdr->vci),(int) ntohl(hdr->length)); - for (out = outputs; out; out = out->next) - if (out->ops->send) out->ops->send(out,in_link,hdr,size); -} - - -static void control(int in_link,struct atmtcp_control *msg) -{ - OUT *out; - int changed = 0; - - if (debug) - fprintf(stderr,"Control: (%d.%d) %s %d.%d, vcc 0x%lx\n", - ntohs(msg->hdr.vpi),ntohs(msg->hdr.vci), - msg->type == ATMTCP_CTRL_OPEN ? "OPEN" : - msg->type == ATMTCP_CTRL_CLOSE ? "CLOSE" : "???", - msg->addr.sap_addr.vpi,msg->addr.sap_addr.vci,msg->vcc); - for (out = outputs; out; out = out->next) - switch (msg->type) { - case ATMTCP_CTRL_OPEN: - if (out->ops->open) - changed += out->ops->open(out,in_link,msg); - break; - case ATMTCP_CTRL_CLOSE: - if (out->ops->close) - changed += out->ops->close(out,in_link,msg); - break; - default: - fprintf(stderr,"interval error\n"); - exit(1); - } - if (changed > 1) fprintf(stderr,"WARNING: multiple changes on control()\n"); -} - - -/* ----- Registries -------------------------------------------------------- */ - - -static IN *register_in(int fd,void (*receive)(IN *in),void *user) -{ - IN *in = alloc_t(IN); - IN **walk; - - in->fd = fd; - in->recv = receive; - in->link = links; - in->bytes = 0; - in->user = user; - in->next = NULL; - for (walk = &inputs; *walk; walk = &(*walk)->next); - *walk = in; - if (fd >= fds) fds = fd+1; - FD_SET(fd,&in_set); - return in; -} - - -static void unregister_in(IN *in) -{ - IN **walk; - - for (walk = &inputs; *walk != in; walk = &(*walk)->next); - FD_CLR(in->fd,&in_set); - if (fds > in->fd+1) return; - fds = 0; - for (walk = &inputs; *walk; walk = &(*walk)->next) - if ((*walk)->fd >= fds) fds = (*walk)->fd+1; -} - - -static void register_out(const OUT_OPS *ops,void *user) -{ - OUT *out = alloc_t(OUT); - OUT **walk; - - out->ops = ops; - out->link = links; - out->user = user; - out->next = NULL; - for (walk = &outputs; *walk; walk = &(*walk)->next); - *walk = out; -} - - -/* ----- Virtual (ATMTCP) interface ---------------------------------------- */ - - -static void virtual_do_send(int fd,void *data,int size) -{ - int wrote; - - wrote = write(fd,data,size); - if (wrote < 0) perror("write to kernel"); - else if (wrote != size) { - fprintf(stderr,"bad write (%d != %d)\n",wrote,size); - exit(1); - } -} - - -static void virtual_in(IN *in) -{ - struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; - int got; - - got = read(in->fd,in->buf,MAX_PACKET); - if (got < 0) { - perror("virtual interface"); - exit(1); - } - if (!got) exit(0); /* we don't use that yet */ - if (got < sizeof(struct atmtcp_hdr)) { - fprintf(stderr,"kernel message too small (%d)\n",got); - exit(1); - } - if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) { - if (got < sizeof(struct atmtcp_control)) { - fprintf(stderr,"invalid control message\n"); - exit(1); - } - control(in->link,(struct atmtcp_control *) in->buf); - virtual_do_send(in->fd,hdr,sizeof(struct atmtcp_control)); - return; - } - if (got != sizeof(struct atmtcp_hdr)+ntohl(hdr->length)) { - fprintf(stderr,"invalid kernel message\n"); - exit(1); - } - emit(in->link,hdr,got); -} - - -static void virtual_send(OUT *out,int in_link,struct atmtcp_hdr *hdr,int size) -{ - if (!right_link(out,in_link)) return; - virtual_do_send(*(int *) out->user,hdr,size); -} - - -static OUT_OPS virtual_ops = { - NULL, /* open */ - virtual_send, /* send */ - NULL /* close */ -}; - - -/* ----- Real ATM interface ------------------------------------------------ */ - - -typedef struct _vcc { - struct sockaddr_atmpvc addr; - int fd; /* for output */ - IN *in; /* NULL is output only */ - struct _vcc *next; -} VCC; - - -typedef struct { - int itf; - VCC *vccs; -} REAL_DATA; - - -static VCC **real_lookup(REAL_DATA *data,const struct sockaddr_atmpvc *addr) -{ - VCC **walk; - - for (walk = &data->vccs; *walk; walk = &(*walk)->next) - if ((*walk)->addr.sap_addr.vpi == addr->sap_addr.vpi && - (*walk)->addr.sap_addr.vci == addr->sap_addr.vci) break; - return walk; -} - - -static void real_in(IN *in) -{ - VCC *vcc = (VCC *) in->user; - struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; - int got; - - got = read(in->fd,hdr+1,MAX_PACKET-sizeof(*hdr)); - if (got < 0) { - perror("real interface"); - exit(1); - } - hdr->length = htonl(got); - hdr->vpi = htons(vcc->addr.sap_addr.vpi); - hdr->vci = htons(vcc->addr.sap_addr.vci); - emit(in->link,hdr,got+sizeof(*hdr)); -} - - -static int real_open(OUT *out,int in_link,struct atmtcp_control *msg) -{ - REAL_DATA *data = (REAL_DATA *) out->user; - VCC **vcc; - int s; - - if (!right_link(out,in_link)) return 0; - vcc = real_lookup(data,&msg->addr); - if (*vcc) { - msg->result = -EADDRINUSE; - return 1; - } - if ((s = socket(PF_ATMPVC,SOCK_DGRAM,0)) < 0) { - msg->result = -errno; - if (debug) perror("socket"); - return 1; - } - if (setsockopt(s,SOL_ATM,SO_ATMQOS,&msg->qos,sizeof(msg->qos)) < 0) { - msg->result = -errno; - if (debug) perror("setsockopt SO_ATMQOS"); - return 1; - } - msg->addr.sap_addr.itf = data->itf; - if (connect(s,(struct sockaddr *) &msg->addr, - sizeof(struct sockaddr_atmpvc)) < 0) { - msg->result = -errno; - if (debug) perror("connect"); - return 1; - } - (*vcc) = alloc_t(VCC); - (*vcc)->addr = msg->addr; - (*vcc)->next = NULL; - (*vcc)->fd = s; - (*vcc)->in = msg->qos.rxtp.traffic_class == ATM_NONE ? NULL : - register_in(s,real_in,*vcc); - return 1; -} - - -static void real_send(OUT *out,int in_link,struct atmtcp_hdr *hdr,int size) -{ - REAL_DATA *data = (REAL_DATA *) out->user; - struct sockaddr_atmpvc addr; - VCC **vcc; - int wrote; - - if (!right_link(out,in_link)) return; - addr.sap_addr.vpi = ntohs(hdr->vpi); - addr.sap_addr.vci = ntohs(hdr->vci); - vcc = real_lookup(data,&addr); - if (!*vcc) { - if (debug) - fprintf(stderr,"VCC %d.%d not found\n",addr.sap_addr.vpi, - addr.sap_addr.vci); - return; - } - wrote = write((*vcc)->fd,hdr+1,ntohl(hdr->length)); - if (wrote < 0) { - perror("real write"); - exit(1); - } - if (!wrote) exit(0); /* EOF */ - if (wrote != ntohl(hdr->length)) { - fprintf(stderr,"bad write (%d != %ld)\n",wrote,ntohl(hdr->length)); - exit(1); - } -} - - -static int real_close(OUT *out,int in_link,struct atmtcp_control *msg) -{ - REAL_DATA *data = (REAL_DATA *) out->user; - VCC **vcc,*this; - int fd; - - if (!right_link(out,in_link)) return 0; - vcc = real_lookup(data,&msg->addr); - if (!*vcc) { - msg->result = -ENOENT; - return 1; - } - this = *vcc; - *vcc = this->next; - if (this->in) unregister_in(this->in); - fd = this->fd; - free(this); - if (close(fd) >= 0) return 0; - msg->result = -errno; - return 1; -} - - -static OUT_OPS real_ops = { - real_open, /* open */ - real_send, /* send */ - real_close /* close */ -}; - - -/* ----- ATMTCP connection ------------------------------------------------- */ - - -static void tcp_do_send(int fd,void *data,int size) -{ - int wrote; - - wrote = write(fd,data,size); - if (wrote < 0) { - perror("write to TCP"); - exit(1); - } - if (!wrote) exit(0); /* EOF */ - if (wrote != size) { - fprintf(stderr,"bad write (%d != %d)\n",wrote,size); - exit(1); - } -} - - -static void tcp_in(IN *in) -{ - struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) in->buf; - char *msg = (char *) (hdr+1); - int vpi,vci; - char orig_addr[MAX_ATM_ADDR_LEN]; - char qos[MAX_ATM_QOS_LEN]; - struct atmtcp_control ctl; - int size,got; - - size = sizeof(*hdr)-in->bytes; - if (size <= 0) size += ntohl(hdr->length); - got = read(in->fd,in->buf+in->bytes,size); - if (got < 0) { - perror("read from file"); - exit(1); - } - if (!got) { - fprintf(stderr,"EOF\n"); - exit(0); - } - in->bytes += got; - if (in->bytes < sizeof(*hdr)) return; - if (ntohl(hdr->length) > ATM_MAX_AAL5_PDU) { - fprintf(stderr,"giant PDU (length = %d) received\n", - (unsigned int) ntohl(hdr->length)); - exit(1); - } - if (in->bytes < sizeof(*hdr)+ntohl(hdr->length)) return; - if (debug) - fprintf(stderr,"TCP %d.%d, %d bytes\n",ntohs(hdr->vpi), - ntohs(hdr->vci),(unsigned int) ntohl(hdr->length)); - in->bytes = 0; - if (hdr->vpi || hdr->vci) { - emit(in->link,hdr,sizeof(*hdr)+ntohl(hdr->length)); - return; - } - msg[ntohl(hdr->length)] = 0; - memset(&ctl,0,sizeof(ctl)); - if (sscanf(msg,"O %d.%d %s %s",&vpi,&vci,orig_addr,qos) == 4) - ctl.type = ATMTCP_CTRL_OPEN; - else if (sscanf(msg,"C %d.%d",&vpi,&vci) == 2) ctl.type = ATMTCP_CTRL_CLOSE; - else { - fprintf(stderr,"unrecognized control message \"%s\"\n",msg); - return; - } - if (debug) fprintf(stderr,"received control \"%s\"\n",msg); - ctl.hdr.vpi = htons(vpi); - ctl.hdr.vci = htons(vci); - ctl.hdr.length = htonl(ATMTCP_HDR_MAGIC); - if (ctl.type == ATMTCP_CTRL_OPEN) { - if (text2atm(orig_addr,(struct sockaddr *) &ctl.addr,sizeof(ctl.addr), - T2A_PVC) < 0) { - fprintf(stderr,"invalid address \"%s\"\n",orig_addr); - return; - } - if (text2qos(qos,&ctl.qos,0) < 0) { - fprintf(stderr,"invalid QOS \"%s\"\n",qos); - return; - } - } - control(in->link,&ctl); -} - - -static void tcp_send(OUT *out,int in_link,struct atmtcp_hdr *hdr,int size) -{ - if (!right_link(out,in_link)) return; - tcp_do_send(*(int *) out->user,hdr,size); -} - - -static int tcp_control(OUT *out,int in_link,struct atmtcp_control *msg) -{ - char buf[MAX_ATM_NAME_LEN*2+MAX_ATM_NAME_LEN+5]; - struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) buf; - char *start = (char *) (hdr+1); - char *pos = start; - - if (!right_link(out,in_link)) return 0; - if (msg->type != ATMTCP_CTRL_OPEN && msg->type != ATMTCP_CTRL_CLOSE) { - fprintf(stderr,"unrecognized control message %d\n",msg->type); - return 0; - } - pos += sprintf(pos,"%c %d.%d",msg->type == ATMTCP_CTRL_OPEN ? 'O' : 'C', - ntohs(msg->hdr.vpi),ntohs(msg->hdr.vci)); - if (msg->type == ATMTCP_CTRL_OPEN) { - *pos++ = ' '; - if (atm2text(pos,sizeof(buf)-(pos-buf),(struct sockaddr *) &msg->addr, - 0) < 0) { - fprintf(stderr,"invalid ATM address\n"); - return 0; - } - pos = strchr(pos,0); - *pos++ = ' '; - if (qos2text(pos,sizeof(buf)-(pos-buf),&msg->qos,0) < 0) { - fprintf(stderr,"invalid QOS\n"); - return 0; - } - pos = strchr(pos,0); - } - hdr->vpi = hdr->vci = htons(0); - hdr->length = htonl(pos-start); - if (debug) fprintf(stderr,"sending control \"%s\"\n",start); - tcp_do_send(*(int *) out->user,buf,pos-buf); - return 0; -} - - -static OUT_OPS tcp_ops = { - tcp_control, /* open */ - tcp_send, /* send */ - tcp_control /* close */ -}; - - -/* ----- File -------------------------------------------------------------- */ - - -static void file_in(IN *in) -{ - int *stream = (int *) in->buf; - struct atmtcp_hdr *hdr = (struct atmtcp_hdr *) (stream+1); - int size,got; - - size = sizeof(int)+sizeof(*hdr)-in->bytes; - if (size <= 0) - size += ntohl(hdr->length) == ATMTCP_HDR_MAGIC ? - sizeof(struct atmtcp_control)-sizeof(*hdr) : ntohl(hdr->length); - got = read(in->fd,in->buf+in->bytes,size); - if (got < 0) { - perror("read from file"); - exit(1); - } - if (!got) { - fprintf(stderr,"EOF\n"); - exit(0); - } - in->bytes += got; - if (in->bytes < sizeof(int)+sizeof(*hdr)) return; - if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) { - if (in->bytes < sizeof(int)+sizeof(struct atmtcp_control)) return; - } - else { - if (ntohl(hdr->length) > ATM_MAX_AAL5_PDU) { - fprintf(stderr,"giant PDU (length = %d) received\n", - (unsigned int) ntohl(hdr->length)); - exit(1); - } - if (in->bytes < sizeof(int)+sizeof(*hdr)+ntohl(hdr->length)) return; - if (debug) - fprintf(stderr,"File %d.%d, %d bytes\n",ntohs(hdr->vpi), - ntohs(hdr->vci),(unsigned int) ntohl(hdr->length)); - } - in->bytes = 0; - if (*(int *) in->user != -1 && ntohl(*stream) != *(int *) in->user) return; - if (ntohl(hdr->length) == ATMTCP_HDR_MAGIC) - control(in->link,(struct atmtcp_control *) hdr); - else emit(in->link,hdr,sizeof(*hdr)+ntohl(hdr->length)); -} - - -static void file_write(int fd,int stream,int is_control,void *data,int size) -{ - int wrote; - - stream = htonl(stream); - wrote = write(fd,&stream,sizeof(stream)); - if (wrote < 0) { - perror("file write"); - exit(1); - } - if (wrote != sizeof(stream)) { - fprintf(stderr,"short write (%d < %d)\n",wrote,sizeof(stream)); - exit(1); - } - wrote = write(fd,data,size); - if (wrote < 0) { - perror("file write"); - exit(1); - } - if (wrote != size) { - fprintf(stderr,"short write (%d < %d)\n",wrote,size); - exit(1); - } -} - - -static void file_send(OUT *out,int in_link,struct atmtcp_hdr *hdr,int size) -{ - file_write(*(int *) out->user,in_link,0,hdr,size); -} - - -static int file_control(OUT *out,int in_link,struct atmtcp_control *msg) -{ - file_write(*(int *) out->user,in_link,1,msg,sizeof(*msg)); - return 0; -} - - -static OUT_OPS file_ops = { - file_control, /* open */ - file_send, /* send */ - file_control /* close */ -}; - - -/* ----- Initialization ---------------------------------------------------- */ - - -static void usage(const char *name) -{ - fprintf(stderr,"%s [ -b ] [ -d ] ...\n\n", - name); - fprintf(stderr," -b background\n"); - fprintf(stderr," -d debug\n\n"); - fprintf(stderr,": virtual [ ] (default: assign)\n"); - fprintf(stderr," real [ ] (default: 0)\n"); - fprintf(stderr," connect [ ]\n"); - fprintf(stderr," listen [ ]\n"); - fprintf(stderr," read [ ]\n"); - fprintf(stderr," write \n"); - fprintf(stderr," wait [ ]\n"); - exit(1); -} - - -#define NEXT (++optind < argc) -#define HAS_MORE (optind < argc-1) -#define NEED_NEXT { if (!NEXT) usage(*argv); } -#define ARG argv[optind] -#define NEXT_ARG argv[optind+1] - - -int main(int argc,char **argv) -{ - struct sockaddr_in addr; - char *end; - int background = 0; - int c; - - FD_ZERO(&in_set); - while ((c = getopt(argc,argv,"bd")) != EOF) - switch (c) { - case 'b': - background = 1; - break; - case 'd': - debug = 1; - break; - default: - usage(*argv); - } - optind--; - if (!HAS_MORE) usage(*argv); - while (NEXT) { - if (!strcmp(ARG,"virtual")) { - int *fd = alloc_t(int); - int itf = -1; - - if (HAS_MORE) { - itf = strtoul(ARG,&end,10); - if (*end) itf = -1; - else (void) NEXT; - } - if ((*fd = socket(PF_ATMSVC,SOCK_DGRAM,0)) < 0) { - perror("socket"); - return 1; - } - if ((itf = ioctl(*fd,SIOCSIFATMTCP,itf)) < 0) { - perror("ioctl SIOCSIFATMTCP"); - return 1; - } - (void) register_in(*fd,&virtual_in,NULL); - register_out(&virtual_ops,fd); - fprintf(stderr,"Link %d: virtual interface %d\n",links++,itf); - } - else if (!strcmp(ARG,"real")) { - REAL_DATA *data = alloc_t(REAL_DATA); - int itf = 0; - - if (HAS_MORE) { - itf = strtoul(NEXT_ARG,&end,10); - if (*end) itf = 0; - else (void) NEXT; - } - data->itf = itf; - data->vccs = NULL; - register_out(&real_ops,data); - fprintf(stderr,"Link %d: real interface %d\n",links++,itf); - } - else if (!strcmp(ARG,"connect")) { - int *fd = alloc_t(int); - const char *host; - int port; - - NEED_NEXT; - host = ARG; - if ((*fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { - perror("socket"); - return 1; - } - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = text2ip(ARG,NULL,T2I_NAME | T2I_ERROR); - if (addr.sin_addr.s_addr == INADDR_NONE) return 1; - if (!HAS_MORE) port = DEFAULT_PORT; - else { - port = strtoul(NEXT_ARG,&end,10); - if (*end) port = DEFAULT_PORT; - else (void) NEXT; - } - addr.sin_port = htons(port); - if (connect(*fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { - perror("connect"); - return 1; - } - (void) register_in(*fd,&tcp_in,NULL); - register_out(&tcp_ops,fd); - fprintf(stderr,"Link %d: ATMTCP connection to %s\n",links++,host); - } - else if (!strcmp(ARG,"listen")) { - int fd,port; - int *fd2 = alloc_t(int); - - if ((fd = socket(PF_INET,SOCK_STREAM,0)) < 0) { - perror("socket"); - return 1; - } - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - if (!HAS_MORE) port = DEFAULT_PORT; - else { - port = strtoul(NEXT_ARG,&end,10); - if (*end) port = DEFAULT_PORT; - else (void) NEXT; - } - addr.sin_port = htons(port); - if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { - perror("bind"); - return 1; - } - if (listen(fd,5) < 0) { - perror("listen"); - return 1; - } - if ((*fd2 = accept(fd,NULL,NULL)) < 0) { - perror("accept"); - return 1; - } - (void) close(fd); - (void) register_in(*fd2,&tcp_in,NULL); - register_out(&tcp_ops,fd2); - fprintf(stderr,"Link %d: incoming ATMTCP connection\n",links++); - } - else if (!strcmp(ARG,"read")) { - int *stream = alloc_t(int); - const char *name; - int fd; - - NEED_NEXT; - name = ARG; - if ((fd = open(ARG,O_RDONLY)) < 0) { - perror(ARG); - return 1; - } - if (!HAS_MORE) *stream = -1; - else { - *stream = strtoul(NEXT_ARG,&end,10); - if (*end) *stream = -1; - else (void) NEXT; - } - (void) register_in(fd,&file_in,stream); - fprintf(stderr,"Link %d: read-only file \"%s\"\n",links++,name); - } - else if (!strcmp(ARG,"write")) { - int *fd = alloc_t(int); - - NEED_NEXT; - if ((*fd = open(ARG,O_CREAT | O_WRONLY | O_TRUNC,0666)) < 0) { - perror(ARG); - return 1; - } - register_out(&file_ops,fd); - fprintf(stderr,"Link %d: write-only file \"%s\"\n",links++,ARG); - } - else if (!strcmp(ARG,"wait")) { - int secs = -1; - - if (HAS_MORE) { - secs = strtoul(NEXT_ARG,&end,10); - if (*end) secs = -1; - else (void) NEXT; - } - if (secs != -1) { - sleep(secs); - continue; - } - fprintf(stderr,"Press to continue\n"); - do c = getchar(); - while (c != EOF && c != '\n'); - } - else usage(*argv); - } - if (background) { - pid_t pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - return 1; - } - if (pid) return 0; - } - while (1) { - IN *in; - fd_set set; - int ret; - - set = in_set; - ret = select(fds,&set,NULL,NULL,NULL); - if (ret < 0) { - if (errno != EINTR) perror("select"); - continue; - } - for (in = inputs; in; in = in->next) - if (FD_ISSET(in->fd,&set)) in->recv(in); - } -} diff -ur --new-file old/atm/man/Makefile new/atm/man/Makefile --- old/atm/man/Makefile Wed Nov 5 21:27:31 1997 +++ new/atm/man/Makefile Fri Jan 21 16:17:26 2000 @@ -1,8 +1,9 @@ MAN7=qos.7 sap.7 +DEPEND = depend_man include ../Rules.make all: -depend: +depend_man: @ diff -ur --new-file old/atm/man/qos.7 new/atm/man/qos.7 --- old/atm/man/qos.7 Wed Nov 5 23:10:42 1997 +++ new/atm/man/qos.7 Tue Jan 18 20:29:50 2000 @@ -1,4 +1,4 @@ -.TH QOS 7 "March 11, 1997" "Linux" "Miscellaneous" +.TH QOS 7 "January 18, 2000" "Linux" "Miscellaneous" .SH NAME qos \- Quality of Service specification .SH DESCRIPTION @@ -18,6 +18,8 @@ Unassigned Bit Rate .IP \fBcbr\fP Constant Bit Rate +.IP \fBabr\fP +Available Bit Rate .P The following AAL types are recognized: .IP \fBaal0\fP diff -ur --new-file old/atm/mkdist new/atm/mkdist --- old/atm/mkdist Mon Nov 22 13:33:23 1999 +++ new/atm/mkdist Fri Jan 21 09:16:41 2000 @@ -3,6 +3,7 @@ VERSION=`cat ./VERSION` #SRCDIR=$HOME/k/2117 ARCHDIR=$HOME/l/arch +[ -d $ARCHDIR ] || ARCHDIR=`pwd` #( # cd $SRCDIR # ./mkpatch @@ -68,10 +69,11 @@ atm/ilmid/asn1/print.h atm/ilmid/asn1/print.c \ atm/ilmid/asn1/str_stk.h atm/ilmid/asn1/str_stk.c \ atm/maint/Makefile atm/maint/atmaddr.c atm/maint/atmdiag.c \ - atm/maint/atmdump.c atm/maint/atmtcp.c atm/maint/natmtcp.c \ + atm/maint/atmdump.c atm/maint/atmtcp.c \ atm/maint/sonetdiag.c atm/maint/loop25.c \ atm/maint/atmaddr.8 atm/maint/atmdiag.8 atm/maint/atmdump.8 \ - atm/maint/atmtcp.8 atm/maint/zntune.c atm/maint/esi.c atm/maint/esi.8 \ + atm/maint/atmtcp.8 atm/maint/zntune.c atm/maint/enitune.c atm/maint/esi.c \ + atm/maint/esi.8 \ atm/maint/saaldump.c atm/maint/README.nstune atm/maint/nstune.c \ atm/test/Makefile atm/test/aread.c atm/test/awrite.c atm/test/br.c \ atm/test/bw.c atm/test/ttcp.c atm/test/aping.c atm/test/window.c \ @@ -82,7 +84,7 @@ atm/lib/Makefile atm/lib/atm2text.c atm/lib/atm.h atm/lib/text2atm.c \ atm/lib/atmequal.c atm/lib/sdu2cell.c atm/lib/atmsap.h \ atm/lib/atmd.h atm/lib/common.c atm/lib/diag.c \ - atm/lib/timer.c \ + atm/lib/kptr.c atm/lib/timer.c \ atm/lib/text2qos.c atm/lib/qos2text.c atm/lib/qosequal.c \ atm/lib/sap2text.c atm/lib/text2sap.c atm/lib/sapequal.c atm/lib/misc.c \ atm/lib/atmres.h atm/lib/ans.c atm/lib/rtf2e164_cc.pl \ diff -ur --new-file old/atm/mkpatch new/atm/mkpatch --- old/atm/mkpatch Mon Nov 22 19:22:04 1999 +++ new/atm/mkpatch Tue Jan 18 20:37:13 2000 @@ -8,6 +8,9 @@ #--- Documentation ------------------------------------------------------------ Documentation/Configure.help Documentation/atm.txt +Documentation/networking/atm.txt +Documentation/networking/fore200e.txt +Documentation/networking/iphase.txt #--- arch/i386 ---------------------------------------------------------------- arch/i386/config.in #--- arch/alpha --------------------------------------------------------------- @@ -31,14 +34,23 @@ drivers/atm/atmsar11.start drivers/atm/atmtcp.c drivers/atm/eni.c +drivers/atm/eni.h +drivers/atm/fore200e.c +drivers/atm/fore200e.h +drivers/atm/fore200e_mkfirm.c drivers/atm/horizon.c drivers/atm/horizon.h drivers/atm/idt77105.c drivers/atm/idt77105.h +drivers/atm/iphase.c +drivers/atm/iphase.h drivers/atm/midway.h drivers/atm/nicstar.c drivers/atm/nicstar.h drivers/atm/nicstarmac.copyright +drivers/atm/pca200e.data +drivers/atm/pca200e_ecd.data +drivers/atm/sba200e_ecd.data drivers/atm/suni.c drivers/atm/suni.h drivers/atm/tonga.h diff -ur --new-file old/atm/mpoad/io.c new/atm/mpoad/io.c --- old/atm/mpoad/io.c Sat Dec 5 01:43:15 1998 +++ new/atm/mpoad/io.c Tue Jan 18 22:33:07 2000 @@ -305,7 +305,7 @@ void keep_alive_sm(unsigned keep_alive_lifetime, int sequence_number){ struct k_message msg; static unsigned previous_sequence_number = 0; - static start_keep_alive_sm = 0; + static int start_keep_alive_sm = 0; time_t now = time(NULL); memset(&msg,0,sizeof(struct k_message)); if(!keep_alive_sm_running){ diff -ur --new-file old/atm/qgen/qgen.c new/atm/qgen/qgen.c --- old/atm/qgen/qgen.c Thu Aug 14 20:02:42 1997 +++ new/atm/qgen/qgen.c Tue Jan 18 22:18:29 2000 @@ -1,6 +1,6 @@ /* qgen.c - constructor/parser generator for Q.2931-like data structures */ -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -17,7 +17,7 @@ extern FIELD *def; extern int group,field,offset,varlen_fields; extern int constr_size,parser_size; -extern sym_tables,symbols; +extern int sym_tables,symbols; int debug = 0; diff -ur --new-file old/atm/qgen/second.c new/atm/qgen/second.c --- old/atm/qgen/second.c Thu Aug 14 20:06:35 1997 +++ new/atm/qgen/second.c Tue Jan 18 22:19:06 2000 @@ -1,6 +1,6 @@ /* second.c - Phase II, table generation */ -/* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -180,12 +180,13 @@ fields(walk->my_block,group); continue; } - if (*walk->id != '_') + if (*walk->id != '_') { if (walk->value && walk->value->type == vt_case) to_c(" { %d, %d, %d, values_%d, %d }, /* %s */\n",group, walk->pos,walk->size,walk->field,walk->var_len,walk->id); else to_c(" { %d, %d, %d, NULL, %d }, /* %s */\n",group, walk->pos,walk->size,walk->var_len,walk->id); + } if (walk->value) switch (walk->value->type) { case vt_id: diff -ur --new-file old/atm/sigd/Makefile new/atm/sigd/Makefile --- old/atm/sigd/Makefile Thu Apr 22 17:29:12 1999 +++ new/atm/sigd/Makefile Fri Jan 21 16:30:25 2000 @@ -5,7 +5,8 @@ policy.o lex.yy.o y.tab.o EXTOBJS=../qgen/q.out.o ../qgen/qd.dump.o BOOTPGMS=atmsigd -TRASH=mess.c q.out.h +TRASH=mess.c +TRASH_SPOTLESS=q.out.h MAN4=atmsigd.conf.4 MAN8=atmsigd.8 @@ -32,7 +33,7 @@ # included. An second "make depend" will also use the right file. # -depend: fake_q.out.h +$(DEPEND): fake_q.out.h fake_q.out.h: echo "! This must not compile" >q.out.h diff -ur --new-file old/atm/sigd/atmsigd.c new/atm/sigd/atmsigd.c --- old/atm/sigd/atmsigd.c Fri Nov 19 13:42:02 1999 +++ new/atm/sigd/atmsigd.c Fri Jan 21 07:23:29 2000 @@ -1,6 +1,6 @@ /* atmsigd.c - ATM signaling demon */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -11,7 +11,6 @@ #include #include #include -#include #include "atm.h" #include "atmd.h" @@ -174,8 +173,8 @@ for (sig = entities; sig; sig = sig->next) { fprintf(file,"--- Entity %d.%d.%d ---\n",S_PVC(sig)); for (walk = sockets; walk; walk = walk->next) { - fprintf(file,"0x%lx: %s, CR 0x%06lX, PVC %d.%d.%d\n", - (unsigned long) walk->id, + fprintf(file,"%s: %s, CR 0x%06lX, PVC %d.%d.%d\n", + kptr_print(&walk->id), state_name[walk->state],walk->call_ref,walk->pvc.sap_addr.itf, walk->pvc.sap_addr.vpi,walk->pvc.sap_addr.vci); dump_addr(file,"local ",&walk->local); @@ -419,7 +418,7 @@ default: usage(argv[0]); } - if (_entity.mode == sm_unknown) + if (_entity.mode == sm_unknown) { if (net) { if (allocate_ci) { _entity.mode = sm_net; @@ -434,6 +433,7 @@ } else if (allocate_ci) _entity.mode = sm_user; else usage(argv[0]); + } if (optind < argc) { manual_override(); if (text2atm(argv[optind],(struct sockaddr *) &_entity.signaling_pvc, diff -ur --new-file old/atm/sigd/io.c new/atm/sigd/io.c --- old/atm/sigd/io.c Fri Nov 19 13:22:30 1999 +++ new/atm/sigd/io.c Fri Jan 21 08:28:39 2000 @@ -1,6 +1,6 @@ /* io.c - I/O operations */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -13,11 +13,11 @@ #include #include #include + +#include "atm.h" #include -#include /* linux/atmsvc.h includes linux/atm.h */ #include -#include "atm.h" #include "atmd.h" #include "uni.h" #include "pdu.h" @@ -93,9 +93,9 @@ { int wrote; - diag("KERNEL",DIAG_DEBUG,"TO KERNEL: %s (%d) for 0x%lx/0x%lx", - as_name[msg->type],msg->reply,(unsigned long) msg->vcc, - (unsigned long) msg->listen_vcc); + diag("KERNEL",DIAG_DEBUG,"TO KERNEL: %s (%d) for %s/%s", + as_name[msg->type],msg->reply,kptr_print(&msg->vcc), + kptr_print(&msg->listen_vcc)); /* should be "IO" ... */ trace_kernel("TO KERNEL",msg); wrote = write(kernel,msg,sizeof(*msg)); diff -ur --new-file old/atm/sigd/kernel.c new/atm/sigd/kernel.c --- old/atm/sigd/kernel.c Fri Nov 19 13:23:01 1999 +++ new/atm/sigd/kernel.c Fri Jan 21 08:39:30 2000 @@ -1,17 +1,17 @@ /* kernel.c - Processing of incoming kernel messages */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include #include #include #include -#include /* linux/atmsvc.h includes linux/atm.h */ + +#include "atm.h" #include #include -#include "atm.h" #include "atmd.h" #include "uni.h" #include "qlib.h" @@ -66,7 +66,7 @@ } } } - if (local) + if (local) { if (*local->sas_addr.pub) { q_assign(&dsc,QF_cgpn_plan,ATM_NP_E164); q_assign(&dsc,QF_cgpn_type,ATM_TON_INTRNTNL); @@ -78,6 +78,7 @@ q_assign(&dsc,QF_cgpn_type,ATM_TON_UNKNOWN); q_write(&dsc,QF_cgpn,(void *) local->sas_addr.prv,ATM_ESA_LEN); } + } q_assign(&dsc,QF_call_ref,call_ref); q_assign(&dsc,QF_msg_type,ATM_MSG_SETUP); q_assign(&dsc,QF_aal_type,5); /* AAL 5 */ @@ -201,14 +202,15 @@ if (!get_local(NULL)) SEND_ERROR(msg->vcc,-EADDRNOTAVAIL); else #endif - send_kernel(msg->vcc,0,as_okay,0,NULL,NULL,get_local(NULL), - NULL,NULL); + send_kernel(msg->vcc,kptr_null,as_okay,0,NULL,NULL, + get_local(NULL),NULL,NULL); else { if (!route_local(&msg->svc)) { SEND_ERROR(msg->vcc,-EADDRNOTAVAIL); return; } - send_kernel(msg->vcc,0,as_okay,0,NULL,NULL,NULL,NULL,NULL); + send_kernel(msg->vcc,kptr_null,as_okay,0,NULL,NULL,NULL,NULL, + NULL); } return; case as_connect: /* NULL state only */ @@ -291,7 +293,7 @@ sock->local = msg->svc; sock->sap = msg->sap; sock->qos = msg->qos; - send_kernel(sock->id,0,as_okay,0,NULL,NULL,NULL,NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,NULL,NULL,NULL); sock->state = ss_listening; return; case as_close: /* all but INDICATED, PROCEEDING, ZOMBIE, and WAIT_REL */ @@ -376,33 +378,33 @@ #if defined(Q2963_1) || defined(DYNAMIC_UNI) case as_modify: if (sock && !(sock->sig->uni & S_Q2963_1)) { - send_kernel(sock->id,0,as_okay,-ENOPROTOOPT,NULL,NULL,NULL, - NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,-ENOPROTOOPT,NULL,NULL, + NULL,NULL,NULL); return; } if (sock && (sock->state == ss_mod_lcl || sock->state == ss_mod_req || sock->state == ss_mod_rcv || sock->state == ss_mod_fin_ok || sock->state == ss_mod_fin_fail || sock->state == ss_mod_fin_ack)) { - send_kernel(sock->id,0,as_okay,-EALREADY,NULL,NULL,NULL,NULL, - NULL); + send_kernel(sock->id,kptr_null,as_okay,-EALREADY,NULL,NULL, + NULL,NULL,NULL); return; } if (!sock || sock->state != ss_connected || !sock->owner) { - send_kernel(sock->id,0,as_okay,-EBADFD,NULL,NULL,NULL,NULL, - NULL); + send_kernel(sock->id,kptr_null,as_okay,-EBADFD,NULL,NULL,NULL, + NULL,NULL); return; } if (sock->qos.txtp.traffic_class != msg->qos.txtp.traffic_class || sock->qos.rxtp.traffic_class != msg->qos.rxtp.traffic_class) { /* @@@ may do more checking */ - send_kernel(sock->id,0,as_okay,-EINVAL,NULL,NULL,NULL,NULL, - NULL); + send_kernel(sock->id,kptr_null,as_okay,-EINVAL,NULL,NULL,NULL, + NULL,NULL); return; } sock->new_qos = msg->qos; - send_kernel(sock->id,0,as_modify,ATM_MF_INC_RSV | ATM_MF_DEC_SHP, - NULL,NULL,NULL,NULL,&msg->qos); + send_kernel(sock->id,kptr_null,as_modify, + ATM_MF_INC_RSV | ATM_MF_DEC_SHP,NULL,NULL,NULL,NULL,&msg->qos); new_state(sock,ss_mod_lcl); return; case as_okay: @@ -418,12 +420,13 @@ new_state(sock,ss_connected); return; case ss_mod_fin_ok: - send_kernel(sock->id,0,as_okay,0,NULL,NULL,NULL,NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,NULL, + NULL,NULL); new_state(sock,ss_connected); return; case ss_mod_fin_fail: - send_kernel(sock->id,0,as_okay,sock->error,NULL,NULL,NULL, - NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,sock->error,NULL, + NULL,NULL,NULL,NULL); sock->error = 0; /* fall through */ case ss_mod_fin_ack: @@ -435,8 +438,8 @@ case as_error: switch (sock ? sock->state : ss_null) { case ss_mod_lcl: - send_kernel(sock->id,0,as_okay,msg->reply,NULL,NULL,NULL, - NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,msg->reply,NULL, + NULL,NULL,NULL,NULL); new_state(sock,ss_connected); return; case ss_mod_rcv: @@ -445,14 +448,15 @@ return; case ss_mod_fin_ok: diag(COMPONENT,DIAG_ERROR,"QOS commit failed"); - send_kernel(sock->id,0,as_okay,0,NULL,NULL,NULL,NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,NULL, + NULL,NULL); /* @@@ clear call instead ? */ new_state(sock,ss_connected); return; case ss_mod_fin_fail: diag(COMPONENT,DIAG_ERROR,"QOS rollback failed"); - send_kernel(sock->id,0,as_okay,sock->error,NULL,NULL,NULL, - NULL,NULL); + send_kernel(sock->id,kptr_null,as_okay,sock->error,NULL, + NULL,NULL,NULL,NULL); sock->error = 0; /* @@@ clear call instead ? */ new_state(sock,ss_connected); @@ -557,22 +561,21 @@ */ return; } - if (msg->listen_vcc && (msg->type == as_accept || msg->type == as_reject || - msg->type == as_identify)) { + if (kptr_eq(&msg->listen_vcc,&kptr_null) && (msg->type == as_accept || + msg->type == as_reject || msg->type == as_identify)) { dispatcher = dispatch_listen; for (curr = sockets; curr; curr = curr->next) - if (msg->listen_vcc == curr->id && (curr->state == ss_listening || - curr->state == ss_listen_zombie)) + if (kptr_eq(&msg->listen_vcc,&curr->id) && + (curr->state == ss_listening || curr->state == ss_listen_zombie)) break; } else { dispatcher = dispatch; for (curr = sockets; curr; curr = curr->next) - if (msg->vcc == curr->id) break; + if (kptr_eq(&msg->vcc,&curr->id)) break; } - diag(COMPONENT,DIAG_DEBUG,"FROM KERNEL: %s for socket %p (0x%lx/0x%lx) " - "in state %s",as_name[msg->type],curr,(unsigned long) msg->vcc, - (unsigned long) msg->listen_vcc, - state_name[curr ? curr->state : ss_null]); + diag(COMPONENT,DIAG_DEBUG,"FROM KERNEL: %s for socket %p (%s/%s) " + "in state %s",as_name[msg->type],curr,kptr_print(&msg->vcc), + kptr_print(&msg->listen_vcc),state_name[curr ? curr->state : ss_null]); dispatcher(curr,msg); } diff -ur --new-file old/atm/sigd/proto.c new/atm/sigd/proto.c --- old/atm/sigd/proto.c Fri Nov 19 13:36:50 1999 +++ new/atm/sigd/proto.c Fri Jan 21 08:39:55 2000 @@ -1,6 +1,6 @@ /* proto.c - Common protocol functions and structures */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -59,12 +59,13 @@ ps_active }; /*12 */ +atm_kptr_t kptr_null; SIG_ENTITY *entities = &_entity; SOCKET *sockets = NULL; unsigned char q_buffer[MAX_Q_MSG]; -SOCKET *new_sock(atm_kptr_int_t id) +SOCKET *new_sock(atm_kptr_t id) { SOCKET *sock; @@ -92,22 +93,22 @@ { SOCKET **walk; - diag(COMPONENT,DIAG_DEBUG,"freeing socket 0x%lx@%p", - (unsigned long) sock->id,sock); + diag(COMPONENT,DIAG_DEBUG,"freeing socket %s@%p", + kptr_print(&sock->id),sock); for (walk = &sockets; *walk != sock; walk = &(*walk)->next); if (!*walk) diag(COMPONENT,DIAG_FATAL, - "INTERNAL ERROR: freeing non-existing socket 0x%lx", - (unsigned long) sock->id); + "INTERNAL ERROR: freeing non-existing socket %s", + kptr_print(&sock->id)); *walk = sock->next; if (sock->conn_timer) { - diag(COMPONENT,DIAG_ERROR,"socket 0x%lx has timer (%p) running", - (unsigned long) sock->id,sock->conn_timer->callback); + diag(COMPONENT,DIAG_ERROR,"socket %s has timer (%p) running", + kptr_print(&sock->id),sock->conn_timer->callback); stop_timer(sock->conn_timer); } if (sock->listen) - diag(COMPONENT,DIAG_ERROR,"socket 0x%lx has non-empty listen queue", - (unsigned long) sock->id); + diag(COMPONENT,DIAG_ERROR,"socket %s has non-empty listen queue", + kptr_print(&sock->id)); sock->state = ss_invalid; free(sock); } @@ -115,8 +116,8 @@ void new_state(SOCKET *sock,STATE state) { - diag(COMPONENT,DIAG_DEBUG,"socket 0x%lx enters state %s (UNI %s)", - (unsigned long) sock->id,state_name[state],cs_name[state_map[state]]); + diag(COMPONENT,DIAG_DEBUG,"socket %s enters state %s (UNI %s)", + kptr_print(&sock->id),state_name[state],cs_name[state_map[state]]); sock->state = state; sock->call_state = state_map[state]; } @@ -132,14 +133,16 @@ new_wc = !atmsvc_addr_in_use(*addr); wildcard = NULL; - for (walk = sockets; walk; walk = walk->next) - if (walk->state == ss_listening && sap_compat(&walk->local, + for (walk = sockets; walk; walk = walk->next) { + if (walk->state != ss_listening || !sap_compat(&walk->local, addr,res_addr,&walk->sap,sap,res_sap,&walk->qos,qos,res_qos)) - if (atmsvc_addr_in_use(walk->local)) return walk; - else if (exact_match) { - if (new_wc) return walk; - } - else wildcard = walk; + continue; + if (atmsvc_addr_in_use(walk->local)) return walk; + else if (exact_match) { + if (new_wc) return walk; + } + else wildcard = walk; + } return wildcard; } @@ -205,7 +208,7 @@ } -void send_kernel(atm_kptr_int_t vcc,atm_kptr_int_t listen_vcc, +void send_kernel(atm_kptr_t vcc,atm_kptr_t listen_vcc, enum atmsvc_msg_type type,int reply,const struct sockaddr_atmpvc *pvc, const struct sockaddr_atmsvc *svc,const struct sockaddr_atmsvc *local, const struct atm_sap *sap,const struct atm_qos *qos) @@ -311,7 +314,8 @@ void send_close(SOCKET *sock) { if (sock->error == 1234) diag(COMPONENT,DIAG_FATAL,"BUG! BUG! BUG!"); - send_kernel(sock->id,0L,as_close,sock->error,NULL,NULL,NULL,NULL,NULL); + send_kernel(sock->id,kptr_null,as_close,sock->error,NULL,NULL,NULL,NULL, + NULL); sock->error = 1234; } diff -ur --new-file old/atm/sigd/proto.h new/atm/sigd/proto.h --- old/atm/sigd/proto.h Fri Nov 19 13:32:35 1999 +++ new/atm/sigd/proto.h Fri Jan 21 08:34:07 2000 @@ -75,7 +75,7 @@ SIG_ENTITY *sig; struct sockaddr_atmpvc pvc; /* --- socket layer information ---------------------------------------- */ - atm_kptr_int_t id; + atm_kptr_t id; struct sockaddr_atmsvc local; /* local address */ struct sockaddr_atmsvc remote; /* remote address */ struct atm_sap sap; /* SAP (BHLI and BLLI) */ @@ -104,6 +104,8 @@ * stable enough to be useful to test the "real" thing against it. */ +extern atm_kptr_t kptr_null; + #define S_PVC(e) \ (e)->signaling_pvc.sap_addr.itf, \ (e)->signaling_pvc.sap_addr.vpi, \ @@ -128,7 +130,7 @@ #define SEND_ERROR(vcc,code) \ - send_kernel(vcc,0L,as_error,code,NULL,NULL,NULL,NULL,NULL) + send_kernel(vcc,kptr_null,as_error,code,NULL,NULL,NULL,NULL,NULL) void poll_signals(void); @@ -137,7 +139,7 @@ void sync_addr(VPCI *vpci); void to_uni(SIG_ENTITY *sig,void *msg,int size); -void send_kernel(atm_kptr_int_t vcc,atm_kptr_int_t listen_vcc, +void send_kernel(atm_kptr_t vcc,atm_kptr_t listen_vcc, enum atmsvc_msg_type type,int reply,const struct sockaddr_atmpvc *pvc, const struct sockaddr_atmsvc *svc,const struct sockaddr_atmsvc *local, const struct atm_sap *sap,const struct atm_qos *qos); @@ -148,7 +150,7 @@ void clear_all_calls(SIG_ENTITY *sig); void clear_all_calls_on_T309(SIG_ENTITY *sig); -SOCKET *new_sock(atm_kptr_int_t id); +SOCKET *new_sock(atm_kptr_t id); void free_sock(SOCKET *sock); void new_state(SOCKET *sock,STATE state); SOCKET *lookup_sap(const struct sockaddr_atmsvc *addr, diff -ur --new-file old/atm/sigd/timeout.c new/atm/sigd/timeout.c --- old/atm/sigd/timeout.c Tue Nov 30 22:39:20 1999 +++ new/atm/sigd/timeout.c Fri Jan 21 16:32:10 2000 @@ -1,12 +1,13 @@ /* timeout.c - Processing of signaling timeout events */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include #include #include -#include /* linux/atmdev.h includes linux/atm.h */ + +#include "atm.h" #include #include "atmd.h" @@ -30,7 +31,7 @@ { SOCKET *sock = user; - diag(COMPONENT,DIAG_DEBUG,"T303 on 0x%lx",(unsigned long) sock->id); + diag(COMPONENT,DIAG_DEBUG,"T303 on %s",kptr_print(&sock->id)); if (sock->state != ss_connecting) complain(sock,"T303"); SEND_ERROR(sock->id,-ETIMEDOUT); sock->conn_timer = NULL; @@ -42,7 +43,7 @@ { SOCKET *sock = user; - diag(COMPONENT,DIAG_DEBUG,"T308_1 on 0x%lx",(unsigned long) sock->id); + diag(COMPONENT,DIAG_DEBUG,"T308_1 on %s",kptr_print(&sock->id)); if (sock->state != ss_wait_rel && sock->state != ss_rel_req) complain(sock,"T308_1"); send_release(sock,ATM_CV_TIMER_EXP,308); /* @@@ ? */ @@ -82,7 +83,7 @@ { SOCKET *sock = user; - diag(COMPONENT,DIAG_DEBUG,"T313 on 0x%lx",(unsigned long) sock->id); + diag(COMPONENT,DIAG_DEBUG,"T313 on %s",kptr_print(&sock->id)); if (sock->state != ss_accepting) complain(sock,"T313"); send_release(sock,ATM_CV_TIMER_EXP,313); sock->conn_timer = NULL; @@ -97,7 +98,7 @@ { SOCKET *sock = user; - diag(COMPONENT,DIAG_DEBUG,"T360 on 0x%lx",(unsigned long) sock->id); + diag(COMPONENT,DIAG_DEBUG,"T360 on %s",kptr_print(&sock->id)); if (sock->state != ss_mod_req) complain(sock,"T360"); send_release(sock,ATM_CV_TIMER_EXP,360); sock->conn_timer = NULL; @@ -110,10 +111,11 @@ { SOCKET *sock = user; - diag(COMPONENT,DIAG_DEBUG,"T361 on 0x%lx",(unsigned long) sock->id); + diag(COMPONENT,DIAG_DEBUG,"T361 on %s",kptr_print(&sock->id)); if (sock->state != ss_connected) complain(sock,"T361"); sock->qos = sock->new_qos; - send_kernel(sock->id,0,as_modify,ATM_MF_SET,NULL,NULL,NULL,NULL,&sock->qos); + send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL,NULL, + &sock->qos); sock->conn_timer = NULL; new_state(sock,ss_mod_fin_ack); } diff -ur --new-file old/atm/sigd/trace.c new/atm/sigd/trace.c --- old/atm/sigd/trace.c Fri Nov 19 13:31:37 1999 +++ new/atm/sigd/trace.c Fri Jan 21 08:41:18 2000 @@ -1,6 +1,6 @@ /* trace.c - Support functions for message tracing */ -/* Written 1996-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -9,10 +9,10 @@ #include #include #include -#include /* linux/atmsvc.h includes linux/atm.h */ -#include #include "atm.h" +#include + #include "atmd.h" #include "atmsap.h" #include "trace.h" @@ -185,9 +185,9 @@ "as_close","as_itf_notify","as_modify","as_identify" }; struct atmsvc_msg *m = msg; - append(" %s (vcc 0x%lx, listen_vcc 0x%lx)\n",m->type < sizeof(type)/ - sizeof(*type) ? type[m->type] : "???",(unsigned long) m->vcc, - (unsigned long) m->listen_vcc); + append(" %s (vcc %s, listen_vcc %s)\n",m->type < sizeof(type)/ + sizeof(*type) ? type[m->type] : "???",kptr_print(&m->vcc), + kptr_print(&m->listen_vcc)); append(" reply %d",m->reply); if (m->reply) { const char *error; diff -ur --new-file old/atm/sigd/uni.c new/atm/sigd/uni.c --- old/atm/sigd/uni.c Tue Nov 30 22:38:35 1999 +++ new/atm/sigd/uni.c Fri Jan 21 08:40:11 2000 @@ -1,6 +1,6 @@ /* uni.c - Processing of incoming UNI signaling messages */ -/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #include @@ -9,10 +9,10 @@ #include #include #include -#include /* linux/atmdev.h includes linux/atm.h */ -#include #include "atm.h" +#include + #include "atmd.h" #include "uni.h" #include "qlib.h" @@ -97,7 +97,7 @@ send_release_complete(sig,call_ref,ATM_CV_REJ_CLIR); return; } - this = new_sock(0); + this = new_sock(kptr_null); this->sig = sig; sock = lookup_sap(&in_addr,&in_sap,&in_qos,&this->local,&this->sap, &this->qos,0); @@ -164,8 +164,8 @@ diag(COMPONENT,DIAG_DEBUG,"Incoming call from %s",buffer); } } - send_kernel(0,sock->id,as_indicate,0,&this->pvc,&this->remote,&in_addr, - &this->sap,&this->qos); + send_kernel(kptr_null,sock->id,as_indicate,0,&this->pvc,&this->remote, + &in_addr,&this->sap,&this->qos); for (walk = &sock->listen; *walk; walk = &(*walk)->listen); *walk = this; diag(COMPONENT,DIAG_DEBUG,"SE vpi.vci=%d.%d",this->pvc.sap_addr.vpi, @@ -380,8 +380,8 @@ send_connect_ack(sock); /* @@@ fill in sock->remote */ /* @@@ fill in traffic parameters */ - send_kernel(sock->id,0,as_okay,0,&sock->pvc,NULL,&sock->local, - &sock->sap,&sock->qos); + send_kernel(sock->id,kptr_null,as_okay,0,&sock->pvc,NULL, + &sock->local,&sock->sap,&sock->qos); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 1; @@ -389,8 +389,7 @@ if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,""); diag(COMPONENT,DIAG_INFO,"Active open succeeded (CR 0x%06X, " - "ID 0x%08lx, to %s)",sock->call_ref,(unsigned long) sock->id, - buffer); + "ID %s, to %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_CONN_ACK: /* ACCEPTING, WAIT_REL, REL_REQ */ diag(COMPONENT,DIAG_DEBUG,"CA vpi.vci=%d.%d", @@ -402,8 +401,8 @@ } if (sock->state != ss_accepting) break; STOP_TIMER(sock); - send_kernel(sock->id,0,as_okay,0,NULL,NULL,&sock->local,&sock->sap, - NULL); + send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,&sock->local, + &sock->sap,NULL); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 0; @@ -411,8 +410,7 @@ if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,""); diag(COMPONENT,DIAG_INFO,"Passive open succeeded (CR 0x%06X, " - "ID 0x%08lx, from %s)",sock->call_ref,(unsigned long) sock->id, - buffer); + "ID %s, from %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_RELEASE: /* all states */ { @@ -584,8 +582,9 @@ sock->new_qos.rxtp.max_pcr = q_fetch(&in_dsc,QF_fw_pcr_01); if (q_present(&in_dsc,QF_bw_pcr_01)) sock->new_qos.txtp.max_pcr = q_fetch(&in_dsc,QF_bw_pcr_01); - send_kernel(sock->id,0,as_modify,ATM_MF_INC_RSV | ATM_MF_DEC_RSV | - ATM_MF_DEC_SHP,NULL,NULL,NULL,NULL,&sock->new_qos); + send_kernel(sock->id,kptr_null,as_modify, + ATM_MF_INC_RSV | ATM_MF_DEC_RSV | ATM_MF_DEC_SHP, + NULL,NULL,NULL,NULL,&sock->new_qos); new_state(sock,ss_mod_rcv); return; case ATM_MSG_MODIFY_ACK: @@ -594,8 +593,8 @@ STOP_TIMER(sock); sock->qos = sock->new_qos; if (q_present(&in_dsc,QG_bbrt)) send_conn_avail(sock); - send_kernel(sock->id,0,as_modify,ATM_MF_SET,NULL,NULL,NULL,NULL, - &sock->qos); + send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, + NULL,&sock->qos); new_state(sock,ss_mod_fin_ok); return; case ATM_MSG_MODIFY_REJ: @@ -603,16 +602,16 @@ if (sock->state != ss_mod_req) break; STOP_TIMER(sock); sock->error = -EAGAIN; - send_kernel(sock->id,0,as_modify,ATM_MF_SET,NULL,NULL,NULL,NULL, - &sock->qos); + send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, + NULL,&sock->qos); new_state(sock,ss_mod_fin_fail); return; case ATM_MSG_CONN_AVAIL: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_connected || sock->owner) break; STOP_TIMER(sock); - send_kernel(sock->id,0,as_modify,ATM_MF_SET,NULL,NULL,NULL,NULL, - &sock->qos); + send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, + NULL,&sock->qos); new_state(sock,ss_mod_fin_ack); return; _default: /* jump here if we don't want to understand a message */ @@ -656,10 +655,10 @@ trace_msg("SAAL went down"); for (curr = sockets; curr; curr = next) { next = curr->next; - if (curr->sig == sig && curr->call_state != cs_null) - if (curr->call_state != cs_active) - uni_call(curr,ATM_MSG_RESTART); - else if (!t309) t309 = start_timer(T309_TIME,on_T309,sig); + if (curr->sig != sig || curr->call_state == cs_null) continue; + if (curr->call_state != cs_active) + uni_call(curr,ATM_MSG_RESTART); + else if (!t309) t309 = start_timer(T309_TIME,on_T309,sig); } } @@ -752,8 +751,8 @@ for (curr = sockets; curr; curr = curr->next) if (curr->sig == sig && curr->call_ref == call_ref) break; diag(COMPONENT,DIAG_DEBUG,"FROM SAAL %d.%d.%d: %s (0x%02X) CR 0x%06lx for " - "0x%lx",S_PVC(sig),mid2name(((unsigned char *) msg)[5]), - ((unsigned char *)msg)[5],call_ref,curr ? (unsigned long) curr->id : 0UL); + "%s",S_PVC(sig),mid2name(((unsigned char *) msg)[5]), + ((unsigned char *) msg)[5],call_ref,curr ? kptr_print(&curr->id) : "?"); if (mid == ATM_MSG_SETUP) { if (!curr) setup_call(sig,call_ref); return; @@ -773,11 +772,11 @@ } } if (!curr || curr->call_state == cs_null) { - if (mid != ATM_MSG_REL_COMP) - if (mid != ATM_MSG_STATUS) - send_release_complete(sig,call_ref,ATM_CV_INV_CR); - else if (q_fetch(&in_dsc,QF_call_state) != (int) cs_null) - send_release_complete(sig,call_ref,ATM_CV_INCOMP_MSG); + if (mid == ATM_MSG_REL_COMP) return; + if (mid != ATM_MSG_STATUS) + send_release_complete(sig,call_ref,ATM_CV_INV_CR); + else if (q_fetch(&in_dsc,QF_call_state) != (int) cs_null) + send_release_complete(sig,call_ref,ATM_CV_INCOMP_MSG); return; } uni_call(curr,mid); diff -ur --new-file old/atm/switch/debug/README new/atm/switch/debug/README --- old/atm/switch/debug/README Sat Jun 6 04:13:40 1998 +++ new/atm/switch/debug/README Fri Jan 21 18:39:06 2000 @@ -17,10 +17,11 @@ Preparation (only once): - # atmtcp -b -i 1 -l 8412 - # atmtcp -b -i 2 -c localhost 8412 - # atmtcp -b -i 3 -l 8434 - # atmtcp -b -i 4 -c localhost 8434 + # atmtcp -b virtual 1 listen 8412 & + # atmtcp -b virtual 2 connect localhost 8412 + # atmtcp -b virtual 3 listen 8434 & + # atmtcp -b virtual 4 connect localhost 8434 + # atmaddr -a 1 +123 Start the "network" (no privileges required): @@ -46,15 +47,21 @@ | atmsigd -N -A 2.0.105 /tmp/2 | | atmsigd -N -A 3.0.105 /tmp/3 | +------------------------------+ +------------------------------+ | | - itf 2 itf 3 + itf 2 | | | - +-------------------------------+ +-------------------------------+ - | atmtcp -i 2 -c localhost 8412 | | atmtcp -i 3 -l 8434 | - +-------------------------------+ +-------------------------------+ - | atmtcp -i 1 -l 8412 | | atmtcp -i 4 -c localhost 8434 | - +-------------------------------+ +-------------------------------+ ++-----------------------------------------+ | +| atmtcp virtual 2 connect localhost 8412 | | ++-----------------------------------------+ | +| atmtcp virtual 1 listen 8412 | | ++-----------------------------------------+ itf 3 | | - itf 1 itf 4 + itf 1 +-----------------------------------------+ + | | atmtcp virtual 3 listen 8434 | + | +-----------------------------------------+ + | | atmtcp virtual 4 connect localhost 8434 | + | +-----------------------------------------+ + | | + | itf 4 | | +------------------------+ +------------------------+ | atmsigd 1.0.105 /tmp/1 | | atmsigd 4.0.105 /tmp/4 | diff -ur --new-file old/atm/switch/proto.c new/atm/switch/proto.c --- old/atm/switch/proto.c Thu Jun 25 11:06:47 1998 +++ new/atm/switch/proto.c Fri Jan 21 08:51:10 2000 @@ -1,7 +1,7 @@ /* proto.c - Common protocol functions and structures */ /* Written 1997-1998 by Roman Pletka, EPFL-SSC */ -/* Modified 1998 by Werner Almesberger, EPFL ICA */ +/* Modified 1998,2000 by Werner Almesberger, EPFL ICA */ #include @@ -72,7 +72,7 @@ memset(&msg,0,sizeof(msg)); /* compose the message */ msg.type = as_listen; - msg.vcc = (unsigned long) sig; + *(unsigned long *) &msg.vcc = (unsigned long) sig; msg.svc.sas_family = AF_ATMSVC; msg.qos.aal = ATM_AAL5; msg.qos.txtp.traffic_class = msg.qos.rxtp.traffic_class = ATM_ANYCLASS; @@ -90,8 +90,8 @@ /* compose the message */ msg.type = as_identify; - msg.vcc = (unsigned long) call | CALLER; - msg.listen_vcc = (unsigned long) call->in.sig; + *(unsigned long *) &msg.vcc = (unsigned long) call | CALLER; + *(unsigned long *) &msg.listen_vcc = (unsigned long) call->in.sig; /* We have to complete the message (vci,vpi..) */ msg.pvc = call->in.pvc; @@ -107,7 +107,8 @@ memset(&msg,0,sizeof(msg)); /* compose the message */ msg.type = as_connect; - msg.vcc = (unsigned long) call | CALLED; /* some kind of magic... */ + *(unsigned long *) &msg.vcc = (unsigned long) call | CALLED; + /* some kind of magic... */ msg.local = call->in.svc; msg.qos.aal = call->in.qos.aal; /* or should we rather use out.qos ? @@@ */ msg.qos.txtp = call->in.qos.rxtp; @@ -127,7 +128,7 @@ /* this is always sent to caller */ memset(&msg,0,sizeof(msg)); msg.type = as_reject; - msg.vcc = (unsigned long) call | CALLER; + *(unsigned long *) &msg.vcc = (unsigned long) call | CALLER; msg.reply = err_code; sig_send(call->in.sig,&msg); } @@ -140,7 +141,7 @@ /* this is always sent to caller */ memset(&msg,0,sizeof(msg)); msg.type = as_reject; - msg.listen_vcc = (unsigned long) sig; + *(unsigned long *) &msg.listen_vcc = (unsigned long) sig; msg.reply = err_code; sig_send(sig,&msg); } @@ -152,7 +153,8 @@ memset(&msg,0,sizeof(msg)); msg.type = as_close; - msg.vcc = (unsigned long) call | dest; /* dest: CALLER or CALLED */ + *(unsigned long *) &msg.vcc = (unsigned long) call | dest; + /* dest: CALLER or CALLED */ /* msg.reply = ??!! */ sig_send(dest == CALLER ? call->in.sig : call->out.sig,&msg); } @@ -164,7 +166,7 @@ memset(&msg,0,sizeof(msg)); msg.type = as_accept; - msg.vcc = (unsigned long) call | CALLER; + *(unsigned long *) &msg.vcc = (unsigned long) call | CALLER; sig_send(call->in.sig,&msg); } @@ -179,8 +181,8 @@ of the call pointer. We can do this, because the compiler aligns memory reservation to pointers with 3 ls-bits = 0. */ - *srce = (unsigned long) (msg->vcc & 3); - return (CALL *) (msg->vcc & ~3); + *srce = *(unsigned long *) &msg->vcc & 3; + return (CALL *) (*(unsigned long *) &msg->vcc & ~3); } /*****************************************************************************/ @@ -188,9 +190,9 @@ /*****************************************************************************/ void print_msg(struct atmsvc_msg *msg, CALL *call,unsigned long source) { - printf("Msg '%s' received from %s vcc=%ld for call 0x%p, listen: %ld\n", - as_msgs[msg->type], sources[source], msg->vcc, call, - msg->listen_vcc); + printf("Msg '%s' received from %s vcc=%s for call 0x%p, listen: %s\n", + as_msgs[msg->type], sources[source], kptr_print(&msg->vcc), call, + kptr_print(&msg->listen_vcc)); } void print_state(CALL *call) { printf(" Call 0x%p entered state '%s'\n", diff -ur --new-file old/atm/switch/proto.h new/atm/switch/proto.h --- old/atm/switch/proto.h Thu Oct 1 18:52:10 1998 +++ new/atm/switch/proto.h Fri Jan 21 08:47:42 2000 @@ -1,7 +1,7 @@ /* proto.h - Common protocol functions and structures */ /* Written 1997-1998 by Roman Pletka, EPFL SSC */ -/* Modified 1998 by Werner Almesberger, EPFL ICA */ +/* Modified 1998,2000 by Werner Almesberger, EPFL ICA */ #ifndef PROTO_H #define PROTO_H @@ -38,7 +38,6 @@ typedef struct _call { STATE state; - unsigned long caller_id,called_id; /* file descriptors to pipes */ PARTY in; /* caller data */ PARTY out; /* called data */ diff -ur --new-file old/atm/switch/tcp/README new/atm/switch/tcp/README --- old/atm/switch/tcp/README Thu Oct 1 19:31:13 1998 +++ new/atm/switch/tcp/README Fri Jan 21 06:09:28 2000 @@ -4,11 +4,11 @@ Commands: lrcpc4:~/w/atm/switch/tcp# ./sw_tcp -b -d -lrcpc4:~# atmtcp -b -i 1 -s localhost 1 -lrcpc4:~# atmtcp -b -i 2 -s localhost 2 +lrcpc4:~# atmtcp -b virtual 1 switch localhost 1 +lrcpc4:~# atmtcp -b virtual 2 switch localhost 2 lrcpc4:~# atmaddr -a 2 +1 lrcpc4:~/w/atm/switch/tcp# atmsigd -b -c 2.conf -lrcpc15:~# atmtcp -b -i 1 -s lrcpc4 3 +lrcpc15:~# atmtcp -b virtual 1 switch lrcpc4 3 lrcpc15:~# atmaddr -a 1 +2 lrcpc15:~/w/atm/switch/tcp# atmsigd -b -c 1.conf lrcpc15:~$ ttcp_atm -r -a @@ -81,30 +81,32 @@ | | | | | | | | | | | 2.0.5 <--> 1.0.100 | | | | -| 3.0.5 <--> 1.0.101 | 2 3 1 | | | +| 3.0.5 <--> 1.0.101 | 2 3 1 | | | | +--------------+ | | -| | | | | | -+-------------------------------|----|-----|------------------------|---+ - | | | | - +----------------------------+ | +----------------------------+ - | atmtcp -i 2 -s localhost 2 | | | atmtcp -i 1 -s localhost 1 | - +----------------------------+ | +----------------------------+ +| | | | | | ++-------------------------------|-----|----|------------------------|---+ + | | | | + +------------+ | | | + | | | | ++-----------------------------------+ | +-----------------------------------+ +|atmtcp virtual 2 switch localhost 2| | |atmtcp virtual 1 switch localhost 1| ++-----------------------------------+ | +-----------------------------------+ | | - itf 2 (+1) +----- - - - - -----+ - | | - +---------------+ | on lrcpc15: | - | atmsigd 2.0.5 | | - +---------------+ | | - | - | +-------------------------+ - | atmtcp -i 1 -s lrcpc4 3 | - | +-------------------------+ - | - | itf 1 (+2) - | - | +---------------+ - | atmsigd 1.0.5 | - | +---------------+ + itf 2 (+1) +----- - - - - - -----+ + | | + +---------------+ | on lrcpc15: | + | atmsigd 2.0.5 | | + +---------------+ | | + | + | +--------------------------------+ + | |atmtcp virtual 1 switch lrcpc4 3| + | +--------------------------------+ + | + | itf 1 (+2) + | + | +---------------+ + | atmsigd 1.0.5 | + | +---------------+ In order to control the switch with swc, add the line control diff -ur --new-file old/atm/switch/tcp/tcpsw.c new/atm/switch/tcp/tcpsw.c --- old/atm/switch/tcp/tcpsw.c Thu Oct 1 22:41:51 1998 +++ new/atm/switch/tcp/tcpsw.c Fri Jan 21 17:44:12 2000 @@ -28,7 +28,7 @@ #define MAX_VCI 1024 -#define PORT 8402 /* @@@ should merge with atmtcp.c */ +#define PORT 2812 /* @@@ should merge with atmtcp.c */ #define MAX_PACKET (ATM_MAX_AAL5_PDU+sizeof(struct atmtcp_hdr)) #define BUFFER_SIZE (MAX_PACKET*2) diff -ur --new-file old/atm/test/Makefile new/atm/test/Makefile --- old/atm/test/Makefile Thu Apr 16 10:07:12 1998 +++ new/atm/test/Makefile Fri Jan 21 16:09:34 2000 @@ -34,7 +34,7 @@ # errnos.inc # -depend: fake_errnos.inc +$(DEPEND): fake_errnos.inc fake_errnos.inc: echo "! This must not compile" >errnos.inc diff -ur --new-file old/atm/test/isp.c new/atm/test/isp.c --- old/atm/test/isp.c Tue Nov 3 18:21:12 1998 +++ new/atm/test/isp.c Fri Jan 21 18:05:09 2000 @@ -1,6 +1,6 @@ /* isp.c - Internal Signaling Protocol test generator */ -/* Written 1997,1998 by Werner Almesberger, EPFL-ICA */ +/* Written 1997-2000 by Werner Almesberger, EPFL-ICA */ #include @@ -110,7 +110,7 @@ printf("\"%s\"",val.u.text); return; case vt_vcc: - printf("%d (0x%x)",val.u.num,val.u.num); + printf("%s",kptr_print(&val.u.id)); return; case vt_error: printf("%s",errno2str(val.u.num)); @@ -245,7 +245,8 @@ out.type = type; switch (type) { case vt_vcc: - out.u.num = strtoul(in.u.text,&end,0); + memset(&out.u.id,0,sizeof(out.u.id)); + *(unsigned long *) &out.u.id = strtoul(in.u.text,&end,0); if (*end) yyerror("invalid number"); break; case vt_error: @@ -290,7 +291,7 @@ switch (a.type) { case vt_vcc: case vt_error: - if (a.u.num == b.u.num) return; + if (kptr_eq(&a.u.id,&b.u.id)) return; break; case vt_svc: if (atm_equal((struct sockaddr *) &a.u.svc, @@ -321,8 +322,8 @@ #define COPY_MSG_VAL(V) \ switch (field) { \ - case F_VCC: _COPY(V.u.num,msg->vcc); break; \ - case F_LISTEN_VCC: _COPY(V.u.num,msg->listen_vcc); break; \ + case F_VCC: _COPY(V.u.id,msg->vcc); break; \ + case F_LISTEN_VCC: _COPY(V.u.id,msg->listen_vcc); break; \ case F_REPLY: _COPY(V.u.num,msg->reply); break; \ case F_PVC: _COPY(V.u.pvc,msg->pvc); break; \ case F_LOCAL: _COPY(V.u.svc,msg->local); break; \ diff -ur --new-file old/atm/test/isp.h new/atm/test/isp.h --- old/atm/test/isp.h Thu Apr 16 11:08:04 1998 +++ new/atm/test/isp.h Fri Jan 21 08:06:35 2000 @@ -1,6 +1,6 @@ /* isp.h - Internal Signaling Protocol test generator */ -/* Written 1997,1998 by Werner Almesberger, EPFL-ICA */ +/* Written 1997-2000 by Werner Almesberger, EPFL-ICA */ #ifndef ISP_H @@ -29,6 +29,7 @@ VALUE_TYPE type; union { const char *text; + atm_kptr_t id; int num; struct sockaddr_atmsvc svc; struct sockaddr_atmpvc pvc; .