diff -ur --new-file old/atm/.kernel new/atm/.kernel --- old/atm/.kernel Wed Feb 2 21:35:15 2000 +++ new/atm/.kernel Mon Feb 28 23:41:04 2000 @@ -1,2 +1,2 @@ # this file is used to control automated generation of differences -2.3.42 +2.3.48 diff -ur --new-file old/atm/CHANGES new/atm/CHANGES --- old/atm/CHANGES Wed Feb 2 22:52:23 2000 +++ new/atm/CHANGES Mon Feb 28 23:40:43 2000 @@ -1,3 +1,70 @@ +Version 0.67 to 0.68 (28-FEB-2000) +==================== + +Bug fixes +--------- + + - removed potential dev_kfree_skb(NULL) from *_send of eni.c, zatm.c, iphase.c + - eni.c, zatm.c, iphase.c sometimes returned PCI error codes instead of errno + codes + - arpd/io.c could try to de-reference entry->addr with addr == NULL (fixed by + Thomas Dietz) + - LANE copied more than dev->addr_len address bytes (fixed by Heikki + Vatiainen) + - sch_atm didn't remove filters on destroy + - fixed typo in esi.c error message + - esi.8 claimed to be the man page of atmarp, and it wasn't installed + - added checking for VPI/VCI when sending AAL0 cells (by Mitchell Blank) + - atmtcp allowed sending on receive-only VCs + - various ioctl permission checks were missing (fixed by Mitchell Blank) + - fore200e.c and horizon.c didn't always free skbs on send error (fixed by + Mitchell Blank) + - included an ugly hack to fix the wd.c driver that was broken around 2.3.47 + (not related to ATM at all...) + +New features +------------ + + - upgraded to the 2.3.48 kernel + - added device-independent SAR/PHY loopback setting interface (with many good + ideas from Greg Banks and Mitchell Blank), and removed old loopback ioctls + - new utility atmloop to set loopback mode + - added "stop" to atmphy_ops (requested by Mitchell Blank) + +Other changes +------------- + + - mkdiff can now also use pre-release kernels + - changed *kfree_skb to dev_kfree_skb_{irq,any} in eni.c, zatm.c, and raw.c, + where necessary (with help from Heikki Vatiainen) + - changed {dev_,}kfree_skb to dev_kfree_skb_any in ambassador.c, horizon.c, + iphase.c, and nicstar.c (needs further cleanup) + - softnet updates for LANE (by Heikki Vatiainen) + - fixed firmeware license of Fore 200E driver and general 0.46/0.47 updates + (Christophe Lizzi) + - more CREDITS file additions + - softnet updates for sch_atm + - softnet updates for CLIP (also cleaned up flow control for > 1 VCC/itf; + reported by Alexey Kuznetsov) + - updated documentation for iproute2-2.2.4-now-ss000225 and streamlined the + build procedure + - PCI DMA updates for ENI driver + - changed the default install location of executables and man pages from + /usr/local to /usr + - make install no longer installs align, aping, br, bw, delay, isp, svctor, + sw_debug, sw_tcp, swc, and window + - eni.c: made highly controversial aal5 = ... line more readable + - moved /proc/atm to /proc/net/atm + - added vcc->send function to allow for AAL-specific processing (may be set + to dev->ops->send) + - atm_do_connect_dev now calls bind_vcc before AAL initialization to make + vcc->dev available + - change_qos no longer allows changing of AAL or traffic class (by Mitchell + Blank) + - changes for new loopback support to fore200e driver and sparc64 code (by + Christophe Lizzi) + + Version 0.66 to 0.67 (2-FEB-2000) ==================== diff -ur --new-file old/atm/README new/atm/README --- old/atm/README Wed Feb 2 20:52:02 2000 +++ new/atm/README Mon Feb 28 23:41:24 2000 @@ -1,4 +1,4 @@ -ATM on Linux, release 0.67 (beta) by Werner Almesberger, EPFL ICA +ATM on Linux, release 0.68 (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.42 kernel. +The kernel patch is relative to the 2.3.48 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/Rules.make new/atm/Rules.make --- old/atm/Rules.make Fri Jan 21 16:30:11 2000 +++ new/atm/Rules.make Thu Feb 24 17:14:34 2000 @@ -65,7 +65,7 @@ LIBDEPS += $(TOPDIR)/lib/libatm.a YACC=bison -y -d #-v INSTROOT= -INSTPREFIX=$(INSTROOT)/usr/local +INSTPREFIX=$(INSTROOT)/usr INSTBOOTBIN=$(INSTPREFIX)/sbin INSTUSRBIN=$(INSTPREFIX)/bin INSTSYSBIN=$(INSTPREFIX)/sbin diff -ur --new-file old/atm/USAGE new/atm/USAGE --- old/atm/USAGE Wed Feb 2 22:53:12 2000 +++ new/atm/USAGE Mon Feb 28 23:42:24 2000 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.67 +Usage instructions - ATM on Linux, release 0.68 ------------------------------------------------- For updates of ATM on Linux, please check the Web page at @@ -17,9 +17,9 @@ In order to install this package, you need - the package itself - ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.67.tar.gz - - the Linux kernel, version 2.3.42, e.g. from - ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.42.tar.gz + ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.68.tar.gz + - the Linux kernel, version 2.3.48, e.g. from + ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.48.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 @@ -33,11 +33,11 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.67.tar.gz +tar xfz atm-0.68.tar.gz and the kernel source: -tar xfz linux-2.3.42.tar.gz +tar xfz linux-2.3.48.tar.gz Finally, you can extract the ATM-related patches: @@ -52,8 +52,8 @@ atm/saal/ Signaling AAL library (SSCOP, SSCF, and SAAL) atm/qgen/ Q.2931-style message handling atm/ilmid/ ILMI address registration demon: ilmid - atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmtcp, - enitune, esi, sonetdiag, saaldump, sunimode, and zntune + atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmloop, + atmtcp, 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 @@ -65,7 +65,7 @@ atm/lib/ Libraries for applications and demons atm/doc/ Documentation in LaTeX and conversion tools atm/man/ Miscellaneous man pages - atm/extra/ Extra packages (tcpdump and ans) + atm/extra/ Extra packages (tc, tcpdump, and ans) atm/config/ Configuration file examples atm/switch/ Switch fabric control (under construction) @@ -311,14 +311,14 @@ Use the -z option to reset the "Alarm" and "Under" counters. -Files in /proc/atm ------------------- +Files in /proc/net/atm +---------------------- Some status information about the ATM subsystem can be obtained through -files in /proc/atm. /proc/atm/arp contains information specific to +files in /proc/net/atm. /proc/net/atm/arp contains information specific to Classical IP over ATM, see section "CLIP". -/proc/atm/devices lists all active ATM devices. For each device, the +/proc/net/atm/devices lists all active ATM devices. For each device, the interface number, the type label, the end system identifier (ESI), and statistics are shown. The statistics correspond to the ones available via atmdiag. @@ -326,12 +326,16 @@ Individual ATM devices may register entries of the form : (e.g. eni:0 ) which contain device-specific information. -/proc/atm/pvc and /proc/atm/svc list all PVC and SVC sockets. For both -types of sockets, the interface, VPI and VCI numbers are shown. For PVCs, -this is followed by the AAL and the traffic class and the selected PCR for -the receive and the transmit direction. For SVCs, the SVC state and the -address of the remote party are shown. SVCs with the interface number 999 -are used for special control purposes as indicated in the "State" column. +/proc/net/atm/pvc and /proc/net/atm/svc list all PVC and SVC sockets. For +both types of sockets, the interface, VPI and VCI numbers are shown. For +PVCs, this is followed by the AAL and the traffic class and the selected +PCR for the receive and the transmit direction. For SVCs, the SVC state and +the address of the remote party are shown. SVCs with the interface number +999 are used for special control purposes as indicated in the "State" +column. + +Furthermore, /proc/net/atm/vc shows buffer sizes and additional internal +information for all ATM sockets. ATM diagnostics @@ -774,11 +778,11 @@ Note that the ATMARP server currently has to be started and configured before any clients are configured. -The kernel ATMARP table can be read via /proc/atm/arp. The table used by -atmarpd is regularly printed on standard error if atmarpd is started with -the -d option. If atmarpd is invoked without -d , the table is written -to the file atmarpd.table in the dump directory (by default /var/run; can -be changed with -D ), and it can be read with atmarp -a . +The kernel ATMARP table can be read via /proc/net/atm/arp. The table used +by atmarpd is regularly printed on standard error if atmarpd is started +with the -d option. If atmarpd is invoked without -d , the table is +written to the file atmarpd.table in the dump directory (by default +/var/run; can be changed with -D ), and it can be read with atmarp -a . LAN Emulation @@ -837,7 +841,7 @@ according to the MTU of the current ELAN. The state of the LANE ARP cache entries can be monitored through -/proc/atm/lec. For each entry the MAC and ATM addresses and status is +/proc/net/atm/lec. For each entry the MAC and ATM addresses and status is listed. If the entry has an active connection, the connection identifiers are also listed. @@ -889,15 +893,15 @@ the available options. The contents of MPOA ingress and egress caches can be monitored through -/proc/atm/mpc file. +/proc/net/atm/mpc file. The Linux MPOA client also supports CBR traffic class for shortcuts SVCs instead of default UBR. The QoS specifications for future shortcuts can be -set and modified using /proc/atm/mpc. +set and modified using /proc/net/atm/mpc. -# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/atm/mpc +# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/net/atm/mpc # # generate enough traffic to trigger a shortcut -# cat /proc/atm/mpc +# cat /proc/net/atm/mpc QoS entries for shortcuts: IP address TX:max_pcr pcr min_pcr max_cdv max_sdu diff -ur --new-file old/atm/VERSION new/atm/VERSION --- old/atm/VERSION Wed Feb 2 21:35:10 2000 +++ new/atm/VERSION Mon Feb 28 23:41:08 2000 @@ -1 +1 @@ -0.67 +0.68 diff -ur --new-file old/atm/arpd/io.c new/atm/arpd/io.c --- old/atm/arpd/io.c Tue Nov 30 21:59:13 1999 +++ new/atm/arpd/io.c Sun Feb 20 02:49:23 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 @@ -138,7 +138,7 @@ memset(&reply,0,sizeof(reply)); reply.type = art_query; reply.ip = ip; - if (entry) reply.addr = *entry->addr; + if (entry && entry->addr) reply.addr = *entry->addr; if (un_send(ctx,&reply,sizeof(reply)) < 0) diag(COMPONENT,DIAG_WARN,"notify: %s",strerror(errno)); } diff -ur --new-file old/atm/atm.patch new/atm/atm.patch --- old/atm/atm.patch Wed Feb 2 22:53:03 2000 +++ new/atm/atm.patch Mon Feb 28 23:39:43 2000 @@ -1,16108 +1,1934 @@ ---- ref/CREDITS Tue Feb 1 08:37:19 2000 -+++ work/CREDITS Wed Feb 2 20:33:04 2000 -@@ -24,6 +24,12 @@ - S: Iasi 6600 - S: Romania - -+N: Monalisa Agrawal -+E: magrawal@nortelnetworks.com -+D: Basic Interphase 5575 driver with UBR and ABR support. -+S: 75 Donald St, Apt 42 -+S: Weymouth, MA 02188 -+ - N: Dave Airlie - E: airlied@linux.ie - W: http://www.csn.ul.ie/~airlied -@@ -38,11 +44,11 @@ - S: United Kingdom - - N: Werner Almesberger --E: werner.almesberger@lrc.di.epfl.ch --D: dosfs, LILO, some fd features, various other hacks here and there -+E: werner.almesberger@epfl.ch -+D: dosfs, LILO, some fd features, ATM, various other hacks here and there - S: Ecole Polytechnique Federale de Lausanne --S: DI-LRC --S: INR (Ecublens) -+S: DSC ICA -+S: INN (Ecublens) - S: CH-1015 Lausanne - S: Switzerland - -@@ -155,6 +161,14 @@ - S: Notre Dame, Indiana - S: USA - -+N: Greg Banks -+E: gnb@linuxfan.com -+D: IDT77105 ATM network driver -+S: NEC Australia -+S: 649-655 Springvale Rd -+S: Mulgrave, Victoria 3170 -+S: Australia -+ - N: James Banks - E: james@sovereign.org - D: TLAN network driver -@@ -461,6 +475,13 @@ - S: NN1 3QT - S: United Kingdom - -+N: Uwe Dannowski -+E: Uwe.Dannowski@ira.uka.de -+W: http://i30www.ira.uka.de/~dannowsk/ -+D: FORE PCA-200E driver -+S: University of Karlsruhe -+S: Germany -+ - N: Ray Dassen - E: jdassen@wi.LeidenUniv.nl - W: http://www.wi.leidenuniv.nl/~jdassen/ -@@ -1123,6 +1144,13 @@ - S: TW9 1AE - S: United Kingdom - -+N: Marko Kiiskila -+E: marko@iprg.nokia.com -+D: Author of ATM Lan Emulation -+S: 660 Harvard Ave. #7 -+S: Santa Clara, CA 95051 -+S: USA -+ - N: Russell King - E: rmk@arm.uk.linux.org - D: Linux/arm integrator, maintainer & hacker -@@ -1321,6 +1349,15 @@ - S: (ask for current address) - S: Germany - -+N: Christophe Lizzi -+E: lizzi@cnam.fr -+W: http://cedric.cnam.fr/personne/lizzi -+D: FORE Systems 200E-series ATM network driver, sparc64 port of ATM -+S: CNAM, Laboratoire CEDRIC -+S: 292, rue St-Martin -+S: 75141 Paris Cedex 03 -+S: France -+ - N: Siegfried "Frieder" Loeffler (dg1sek) - E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net - W: http://www.mathematik.uni-stuttgart.de/~floeff -@@ -1773,6 +1810,10 @@ - E: Frederic.Potter@masi.ibp.fr - D: Some PCI kernel support - -+N: Rui Prior -+E: rprior@inescn.pt -+D: ATM device driver for NICStAR based cards -+ - N: Stefan Probst - E: sp@caldera.de - D: The Linux Support Team Erlangen, 1993-97 -@@ -2347,6 +2388,13 @@ - S: UC Berkeley - S: Berkeley, CA 94720-1776 - S: USA -+ -+N: Mike Westall -+D: IBM Turboways 25 ATM Device Driver -+E: westall@cs.clemson.edu -+S: Department of Computer Science -+S: Clemson University -+S: Clemson SC 29634 USA - - N: Greg Wettstein - E: greg@wind.rmcc.com ---- ref/Documentation/Configure.help Mon Jan 31 19:19:21 2000 -+++ work/Documentation/Configure.help Wed Feb 2 20:33:04 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. - --IDT 77201 (NICStAR) -+IDT 77201/11 (NICStAR) (ForeRunnerLE) - CONFIG_ATM_NICSTAR - 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 -+ found in most 155Mbps NICStAR based ATM cards, namely in the -+ ForeRunner LE155 cards. This driver provides detection of cable -+ removal and reinsertion and provides some statistics. This driver -+ doesn't have removal capability when compiled as a module, so if you -+ need that capability don't include S-UNI support (it's not needed to -+ make the card work). -+ -+ForeRunner LE25 PHYsical layer -+CONFIG_ATM_NICSTAR_USE_IDT77105 -+ Support for the PHYsical layer chip in ForeRunner LE25 cards. In -+ addition to cable removal/reinsertion detection, this driver allows -+ 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 - 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 Wed Feb 2 20:33:04 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 Wed Feb 2 20:33:04 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 Wed Feb 2 20:33:04 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 Wed Feb 2 20:33:04 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 Tue Feb 1 08:37:19 2000 -+++ work/arch/sparc64/config.in Wed Feb 2 20:33:04 2000 -@@ -216,6 +216,9 @@ - # bool ' FDDI driver support' CONFIG_FDDI - # if [ "$CONFIG_FDDI" = "y" ]; then - # fi -+ if [ "$CONFIG_ATM" = "y" ]; then -+ source drivers/atm/Config.in -+ fi - fi - endmenu - fi ---- ref/arch/sparc64/kernel/ioctl32.c Tue Feb 1 08:37:19 2000 -+++ work/arch/sparc64/kernel/ioctl32.c Wed Feb 2 20:33:04 2000 -@@ -61,6 +61,18 @@ - - #include - -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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)) -@@ -1753,6 +1765,217 @@ - return err; - } - -+struct atmif_sioc32 { -+ int number; -+ int length; -+ __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 atm_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) -+#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32) -+#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32) -+#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32) -+#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32) -+#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32) -+#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32) -+#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32) -+#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32) -+#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32) -+ -+static struct { -+ unsigned int cmd32; -+ unsigned int cmd; -+} atm_ioctl_map[] = { -+ { ATM_GETLINKRATE32, ATM_GETLINKRATE }, -+ { ATM_GETNAMES32, ATM_GETNAMES }, -+ { ATM_GETTYPE32, ATM_GETTYPE }, -+ { ATM_GETESI32, ATM_GETESI }, -+ { ATM_GETADDR32, ATM_GETADDR }, -+ { ATM_RSTADDR32, ATM_RSTADDR }, -+ { ATM_ADDADDR32, ATM_ADDADDR }, -+ { ATM_DELADDR32, ATM_DELADDR }, -+ { ATM_GETCIRANGE32, ATM_GETCIRANGE }, -+ { ATM_SETCIRANGE32, ATM_SETCIRANGE }, -+ { ATM_SETESI32, ATM_SETESI }, -+ { ATM_SETESIF32, ATM_SETESIF }, -+ { ATM_GETSTAT32, ATM_GETSTAT }, -+ { ATM_GETSTATZ32, ATM_GETSTATZ } -+}; -+ -+#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) -+{ -+ struct atmif_sioc32 sioc32; -+ struct atmif_sioc sioc = { 0, 0, NULL }; -+ mm_segment_t old_fs; -+ int err; -+ -+ err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg, -+ sizeof(struct atmif_sioc32)); -+ if (err) -+ return -EFAULT; -+ -+ sioc.number = sioc32.number; -+ sioc.length = sioc32.length; -+ -+ 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) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length); -+ if (err) { -+ err = -EFAULT; -+ goto out; -+ } -+ } -+ -+ old_fs = get_fs(); set_fs (KERNEL_DS); -+ err = sys_ioctl (fd, cmd, (unsigned long)&sioc); -+ set_fs (old_fs); -+ if(err) { -+ goto out; -+ } -+ -+ if(sioc.arg && sioc.length > 0) { -+ err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length); -+ if (err) { -+ err = -EFAULT; -+ goto out; -+ } -+ } -+ err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); -+ -+ out: -+ if(sioc32.arg && sioc32.length > 0) -+ kfree(sioc.arg); -+ -+ return err; -+} -+ -+ -+static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) -+{ -+ int i; -+ unsigned int cmd = 0; -+ -+ 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 -EINVAL; -+ } -+ } -+ -+ switch (cmd) { -+ case ATM_GETNAMES: -+ return do_atm_iobuf(fd, cmd, arg); -+ -+ case ATM_GETLINKRATE: -+ case ATM_GETTYPE: -+ case ATM_GETESI: -+ case ATM_GETADDR: -+ case ATM_RSTADDR: -+ case ATM_ADDADDR: -+ case ATM_DELADDR: -+ case ATM_GETCIRANGE: -+ case ATM_SETCIRANGE: -+ case ATM_SETESI: -+ case ATM_SETESIF: -+ case ATM_GETSTAT: -+ case ATM_GETSTATZ: -+ return do_atmif_sioc(fd, cmd, arg); -+ } -+ -+ return -EINVAL; -+} -+ - asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) - { - struct file * filp; -@@ -1945,6 +2168,33 @@ - error = do_smb_getmountuid(fd, cmd, arg); - goto out; - -+ case ATM_GETLINKRATE32: -+ case ATM_GETNAMES32: -+ case ATM_GETTYPE32: -+ case ATM_GETESI32: -+ case ATM_GETADDR32: -+ case ATM_RSTADDR32: -+ case ATM_ADDADDR32: -+ case ATM_DELADDR32: -+ case ATM_GETCIRANGE32: -+ case ATM_SETCIRANGE32: -+ case ATM_SETESI32: -+ 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... - */ -@@ -2454,6 +2704,23 @@ - /* SMB ioctls which do not need any translations */ - case SMB_IOC_NEWCONN: - -+ /* Little a */ -+ case ATMSIGD_CTRL: -+ case ATMARPD_CTRL: -+ case ATMLEC_CTRL: -+ case ATMLEC_MCAST: -+ case ATMLEC_DATA: -+ case ATM_SETSC: -+ case SIOCSIFATMTCP: -+ case SIOCMKCLIP: -+ case ATMARP_MKIP: -+ case ATMARP_SETENTRY: -+ case ATMARP_ENCAP: -+ case ATMTCP_CREATE: -+ case ATMTCP_REMOVE: -+ case ATMMPC_CTRL: -+ case ATMMPC_DATA: -+ - error = sys_ioctl (fd, cmd, arg); - goto out; - ---- ref/drivers/atm/Config.in Thu Oct 7 19:17:09 1999 -+++ work/drivers/atm/Config.in Wed Feb 2 20:33:04 2000 -@@ -8,7 +8,7 @@ - fi - if [ "$CONFIG_PCI" = "y" ]; then - tristate 'Efficient Networks ENI155P' CONFIG_ATM_ENI -- if [ ! "$CONFIG_ATM_ENI" = "n" ]; then -+ if [ "$CONFIG_ATM_ENI" != "n" ]; then - bool ' Enable extended debugging' CONFIG_ATM_ENI_DEBUG - bool ' Fine-tune burst settings' CONFIG_ATM_ENI_TUNE_BURST - if [ "$CONFIG_ATM_ENI_TUNE_BURST" = "y" ]; then -@@ -23,17 +23,20 @@ - fi - fi - tristate 'ZeitNet ZN1221/ZN1225' CONFIG_ATM_ZATM -- if [ ! "$CONFIG_ATM_ZATM" = "n" ]; then -+ if [ "$CONFIG_ATM_ZATM" != "n" ]; then - bool ' Enable extended debugging' CONFIG_ATM_ZATM_DEBUG -- bool ' Enable usec resolution timestamps' CONFIG_ATM_ZATM_EXACT_TS -+ if [ "$CONFIG_X86" = "y" ]; then -+ bool ' Enable usec resolution timestamps' CONFIG_ATM_ZATM_EXACT_TS -+ fi - fi - # bool 'Rolfs TI TNETA1570' CONFIG_ATM_TNETA1570 y - # if [ "$CONFIG_ATM_TNETA1570" = "y" ]; then - # bool ' Enable extended debugging' CONFIG_ATM_TNETA1570_DEBUG n - # fi -- tristate 'IDT 77201 (NICStAR)' CONFIG_ATM_NICSTAR -+ tristate 'IDT 77201 (NICStAR) (ForeRunnerLE)' CONFIG_ATM_NICSTAR - if [ "$CONFIG_ATM_NICSTAR" != "n" ]; then -- bool ' Use suni PHY driver' CONFIG_ATM_NICSTAR_USE_SUNI -+ bool ' Use suni PHY driver (155Mbps)' CONFIG_ATM_NICSTAR_USE_SUNI -+ bool ' Use IDT77015 PHY driver (25Mbps)' CONFIG_ATM_NICSTAR_USE_IDT77105 - fi - tristate 'Madge Ambassador (Collage PCI 155 Server)' CONFIG_ATM_AMBASSADOR - if [ "$CONFIG_ATM_AMBASSADOR" != "n" ]; then -@@ -43,5 +46,34 @@ - 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 -+ 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 Wed Feb 2 20:33:04 2000 -@@ -43,12 +43,18 @@ - ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y) - NEED_SUNI_LX = suni.o - endif -+ ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y) -+ NEED_IDT77105_LX = idt77105.o -+ endif - else - ifeq ($(CONFIG_ATM_NICSTAR),m) - M_OBJS += nicstar.o - ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y) - NEED_SUNI_MX = suni.o - endif -+ ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y) -+ NEED_SUNI_MX = idt77105.o -+ endif - endif - endif - -@@ -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 - --ifeq ($(CONFIG_ATM_TCP),y) --L_OBJS += atmtcp.o -+ifeq ($(NEED_IDT77105_LX),) -+ MX_OBJS += $(NEED_IDT77105_MX) - else -- ifeq ($(CONFIG_ATM_TCP),m) -- M_OBJS += atmtcp.o -- endif -+ LX_OBJS += $(NEED_IDT77105_LX) - endif - - 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 Wed Feb 2 20:33:04 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 Wed Feb 2 20:33:05 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/atmsar11.data Mon Aug 23 18:56:31 1999 -+++ work/drivers/atm/atmsar11.data Wed Feb 2 20:33:05 2000 -@@ -2,12 +2,12 @@ - Madge Ambassador ATM Adapter microcode. - Copyright (C) 1995-1999 Madge Networks Ltd. - -- This is provided here for your convenience only. -+ This microcode data is placed under the terms of the GNU General -+ Public License. The GPL is contained in /usr/doc/copyright/GPL on a -+ Debian system and in the file COPYING in the Linux kernel source. - -- No restrictions are placed on its use, so long as this file remains -- unchanged. -- -- You may not make, use or re-distribute modified versions of this code. -+ We would prefer you not to distribute modified versions without -+ consultation and not to ask for assembly/other microcode source. - */ - - 0x401a6800, ---- ref/drivers/atm/atmsar11.regions Mon Aug 23 18:56:31 1999 -+++ work/drivers/atm/atmsar11.regions Wed Feb 2 20:33:05 2000 -@@ -1,3 +1,6 @@ -+/* -+ See copyright and licensing conditions in ambassador.* files. -+*/ - { 0x00000080, 993, }, - { 0xa0d0d500, 80, }, - { 0xa0d0f000, 978, }, ---- ref/drivers/atm/atmsar11.start Mon Aug 23 18:56:31 1999 -+++ work/drivers/atm/atmsar11.start Wed Feb 2 20:33:05 2000 -@@ -1 +1,4 @@ -+/* -+ See copyright and licensing conditions in ambassador.* files. -+*/ - 0xa0d0f000 ---- ref/drivers/atm/atmtcp.c Wed Sep 8 20:14:31 1999 -+++ work/drivers/atm/atmtcp.c Wed Feb 2 20:33:05 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 Feb 2 20:33:05 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); -- if (res != enq_ok) { -+ if (res == enq_ok) tx->backlog_len--; -+ else { - DPRINTK("re-queuing TX PDU\n"); - skb_queue_head(&tx->backlog,skb); - requeued++; -@@ -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); -+ tx->backlog_len = 0; - for (order = 0; size > (1 << (order+10)); order++); - eni_out((order << MID_SIZE_SHIFT) | - ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)), -@@ -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) - { --#ifdef CONFIG_MMU_HACKS -- --static const struct atm_buffconst bctx = { PAGE_SIZE,0,PAGE_SIZE,0,0,0 }; --static const struct atm_buffconst bcrx = { PAGE_SIZE,0,PAGE_SIZE,0,0,0 }; -- --#else -- --static const struct atm_buffconst bctx = { sizeof(int),0,sizeof(int),0,0,0 }; --static const struct atm_buffconst bcrx = { sizeof(int),0,sizeof(int),0,0,0 }; -- --#endif -- if (level == SOL_AAL && (optname == SO_BCTXOPT || -- optname == SO_BCRXOPT)) -- return copy_to_user(optval,optname == SO_BCTXOPT ? &bctx : -- &bcrx,sizeof(struct atm_buffconst)) ? -EFAULT : 0; - return -EINVAL; - } - -@@ -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); -- backlogged++; -+ ENI_VCC(vcc)->tx->backlog_len++; -+backlogged++; - } - restore_flags(flags); - return 0; -@@ -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; -+ if (!--left) { -+ return sprintf(page,"tx[%d]: 0x%06lx-0x%06lx " -+ "(%6ld bytes), rsv %d cps, shp %d cps%s\n",i, -+ tx->send-eni_dev->ram, -+ tx->send-eni_dev->ram+tx->words*4-1,tx->words*4, -+ tx->reserved,tx->shaping, -+ tx == eni_dev->ubr ? " (UBR)" : ""); -+ } - if (--left) continue; -- return sprintf(page,"tx[%d]: 0x%06lx-0x%06lx (%6ld bytes), " -- "rsv %d cps, shp %d cps%s\n",i, -- tx->send-eni_dev->ram, -- tx->send-eni_dev->ram+tx->words*4-1,tx->words*4, -- tx->reserved,tx->shaping, -- tx == eni_dev->ubr ? " (UBR)" : ""); -+ return sprintf(page,"%10sbacklog %d bytes\n","", -+ tx->backlog_len); - } - for (vcc = dev->vccs; vcc; vcc = vcc->next) { - struct eni_vcc *eni_vcc = ENI_VCC(vcc); -@@ -2139,8 +2159,8 @@ - if (eni_vcc->tx) length += sprintf(page+length,", "); - } - if (eni_vcc->tx) -- length += sprintf(page+length,"tx[%d]", -- eni_vcc->tx->index); -+ length += sprintf(page+length,"tx[%d], txing %d bytes", -+ eni_vcc->tx->index,eni_vcc->txing); - page[length] = '\n'; - return length+1; - } -@@ -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 Wed Feb 2 20:40:44 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 Wed Feb 2 20:33:05 2000 -@@ -0,0 +1,2958 @@ -+/* -+ $Id: $ -+ -+ A FORE Systems 200E-series driver for ATM on Linux. -+ Christophe Lizzi (lizzi@cnam.fr), October 1999-January 2000. -+ -+ 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 architectures. -+ -+ 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 -+ -+#ifdef CONFIG_ATM_FORE200E_PCA -+#include -+#endif -+ -+#ifdef CONFIG_ATM_FORE200E_SBA -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+#ifdef MODULE -+#include -+#endif -+ -+#include "fore200e.h" -+#include "suni.h" -+ -+#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.2" -+ -+ -+#define FORE200E "fore200e: " -+ -+#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 -+ -+ -+#define FORE200E_ALIGN(addr, alignment) \ -+ ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr)) -+ -+#define FORE200E_DMA_INDEX(dma_addr, type, index) ((dma_addr) + (index) * sizeof(type)) -+ -+#define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ]) -+ -+#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 -+} -+ -+ -+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; -+} -+ -+ -+static void -+fore200e_kfree(void* chunk) -+{ -+ kfree(chunk); -+} -+ -+ -+/* allocate and align a chunk of memory intended to hold the data behing exchanged -+ between the driver and the adapter (using streaming DVMA on SBUS hosts) */ -+ -+static int -+fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment) -+{ -+ unsigned long offset = 0; -+ -+ if (alignment <= sizeof(int)) -+ alignment = 0; -+ -+ chunk->alloc_size = size + alignment; -+ chunk->align_size = size; -+ -+ chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA); -+ if (chunk->alloc_addr == NULL) -+ return -ENOMEM; -+ -+ if (alignment > 0) -+ offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); -+ -+ chunk->align_addr = chunk->alloc_addr + offset; -+ -+ chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size); -+ -+ return 0; -+} -+ -+ -+/* free a chunk of memory */ -+ -+static void -+fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk) -+{ -+ fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); -+ -+ fore200e_kfree(chunk->alloc_addr); -+} -+ -+ -+ -+#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; -+ -+ mb(); -+ do { -+ if ((ok = (*addr == val)) || (*addr & STATUS_ERROR)) -+ 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 int -+fore200e_io_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 "I/O 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++) { -+ -+ struct chunk* data = &buffer[ nbr ].data; -+ -+ if (data->alloc_addr != NULL) -+ fore200e_chunk_free(fore200e, data); -+ } -+ } -+ } -+ } -+} -+ -+ -+static void -+fore200e_uninit_bs_queue(struct fore200e* fore200e) -+{ -+ int scheme, magn; -+ -+ for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) { -+ for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) { -+ -+ struct chunk* status = &fore200e->host_bsq[ scheme ][ magn ].status; -+ struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block; -+ -+ if (status->alloc_addr) -+ fore200e->bus->dma_chunk_free(fore200e, status); -+ -+ if (rbd_block->alloc_addr) -+ fore200e->bus->dma_chunk_free(fore200e, rbd_block); -+ } -+ } -+} -+ -+ -+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_io_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_chunk_free(fore200e, &fore200e->host_rxq.status); -+ fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd); -+ -+ case FORE200E_STATE_INIT_TXQ: -+ fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status); -+ fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd); -+ -+ case FORE200E_STATE_INIT_CMDQ: -+ fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status); -+ -+ 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 */ -+ return swab32(readl(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) -+ /* on big-endian hosts, the board is configured to convert -+ the endianess of slave RAM accesses */ -+ writel(swab32(val), addr); -+#elif defined(__LITTLE_ENDIAN) -+ writel(val, addr); -+#else -+#error unknown endianess -+#endif -+} -+ -+ -+/* make DMA mapping */ -+ -+static u32 -+fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size) -+{ -+ u32 dma_addr = (u32) virt_to_bus(virt_addr); -+ -+ DPRINTK(3, "PCI DMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", -+ virt_addr, size, dma_addr); -+ -+ return dma_addr; -+} -+ -+ -+/* remove DMA mapping */ -+ -+static void -+fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) -+{ -+ DPRINTK(3, "PCI DMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); -+ -+ return; -+} -+ -+ -+/* allocate a DMA consistant chunk of memory intended to act as a communication mechanism -+ (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ -+ -+static int -+fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, -+ int size, int nbr, int alignment) -+{ -+ if (fore200e_chunk_alloc(fore200e, chunk, size * nbr, alignment) < 0) -+ return -ENOMEM; -+ -+ chunk->dma_addr = fore200e_pca_dma_map(fore200e, chunk->align_addr, chunk->align_size); -+ -+ return 0; -+} -+ -+ -+/* free a DMA consistant chunk of memory */ -+ -+static void -+fore200e_pca_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) -+{ -+ fore200e_pca_dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); -+ -+ fore200e_chunk_free(fore200e, chunk); -+} -+ -+ -+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); -+ -+ fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH); -+ -+ 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() does nothing on powerpc (at least in 2.2.12 and 2.3.18), -+ this leads to 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 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->resource[0].start & 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; -+ u32 prom_dma; -+ -+ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); -+ -+ opcode.opcode = OPCODE_GET_PROM; -+ opcode.pad = 0; -+ -+ prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data)); -+ -+ fore200e->bus->write(prom_dma, &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; -+ -+ fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data)); -+ -+ 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 = (struct 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 sbus_readl(addr); -+} -+ -+ -+static void -+fore200e_sba_write(u32 val, volatile u32* addr) -+{ -+ sbus_writel(val, addr); -+} -+ -+ -+static u32 -+fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size) -+{ -+ u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size); -+ -+ DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", virt_addr, size, dma_addr); -+ -+ return dma_addr; -+} -+ -+ -+static void -+fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) -+{ -+ DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); -+ -+ sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); -+ -+ return; -+} -+ -+ -+static void -+fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size) -+{ -+ DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size); -+ -+ sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); -+} -+ -+ -+/* allocate a DVMA consistant chunk of memory intended to act as a communication mechanism -+ (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ -+ -+static int -+fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment) -+{ -+ chunk->alloc_size = chunk->align_size = size * nbr; -+ -+ /* returned chunks are page-aligned */ -+ chunk->alloc_addr = sbus_alloc_consistant((struct sbus_dev*)fore200e->bus_dev, -+ chunk->alloc_size, -+ &chunk->dma_addr); -+ -+ if (chunk->alloc_addr == NULL || chunk->dma_addr == 0) -+ return -ENOMEM; -+ -+ chunk->align_addr = chunk->alloc_addr; -+ -+ return 0; -+} -+ -+ -+/* free a DVMA consistant chunk of memory */ -+ -+static void -+fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) -+{ -+ sbus_free_consistant((struct sbus_dev*)fore200e->bus_dev, -+ chunk->alloc_size, -+ chunk->alloc_addr, -+ chunk->dma_addr); -+} -+ -+ -+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_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 sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; -+ -+ /* gain access to the SBA-200E specific registers */ -+ -+ fore200e->regs.sba.hcr = (u32*)sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); -+ fore200e->regs.sba.bsr = (u32*)sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); -+ fore200e->regs.sba.isr = (u32*)sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); -+ fore200e->virt_base = (u32*)sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); -+ -+ fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ -+ -+ 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) -+{ -+ sbus_iounmap((ulong)fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); -+ sbus_iounmap((ulong)fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); -+ sbus_iounmap((ulong)fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); -+ sbus_iounmap((ulong)fore200e->virt_base, SBA200E_RAM_LENGTH); -+} -+ -+ -+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 sbus_bus* sbus_bus; -+ struct sbus_dev* sbus_dev = NULL; -+ -+ unsigned int count = 0; -+ -+ for_each_sbus (sbus_bus) { -+ for_each_sbusdev (sbus_dev, sbus_bus) { -+ if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) { -+ if (count >= index) -+ goto found; -+ count++; -+ } -+ } -+ } -+ 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 sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev; -+ int len; -+ -+ 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 sbus_dev* sbus_dev = (struct sbus_dev*)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); -+ -+ /* remove DMA mapping */ -+ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); -+ -+ /* 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_addr; -+ 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_addr, rpd->rsd[ i ].length); -+ -+ memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, 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->dma_map(fore200e, entry->data, tx_len); -+ } -+ else { -+ entry->data = NULL; -+ tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, skb_data, tx_len); -+ } -+ -+ 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); -+ -+ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); -+ -+ 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; -+ u32 stats_dma_addr; -+ -+ if (fore200e->stats == NULL) { -+ fore200e->stats = fore200e_kmalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA); -+ if (fore200e->stats == NULL) -+ return -ENOMEM; -+ } -+ -+ stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats, sizeof(struct stats)); -+ -+ FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); -+ -+ opcode.opcode = OPCODE_GET_STATS; -+ opcode.pad = 0; -+ -+ fore200e->bus->write(stats_dma_addr, &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; -+ -+ fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats)); -+ -+ 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; -+ u32 oc3_regs_dma_addr; -+ -+ oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs)); -+ -+ 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(oc3_regs_dma_addr, &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; -+ -+ fore200e->bus_dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs)); -+ -+ 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_swap(unsigned int in) -+{ -+#if defined(__LITTLE_ENDIAN) -+ 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_swap(fore200e->stats->oc3.section_bip8_errors); -+ tmp.line_bip = fore200e_swap(fore200e->stats->oc3.line_bip24_errors); -+ tmp.path_bip = fore200e_swap(fore200e->stats->oc3.path_bip8_errors); -+ tmp.line_febe = fore200e_swap(fore200e->stats->oc3.line_febe_errors); -+ tmp.path_febe = fore200e_swap(fore200e->stats->oc3.path_febe_errors); -+ tmp.corr_hcs = fore200e_swap(fore200e->stats->oc3.corr_hcs_errors); -+ tmp.uncorr_hcs = fore200e_swap(fore200e->stats->oc3.ucorr_hcs_errors); -+ tmp.tx_cells = fore200e_swap(fore200e->stats->aal0.cells_transmitted) + -+ fore200e_swap(fore200e->stats->aal34.cells_transmitted) + -+ fore200e_swap(fore200e->stats->aal5.cells_transmitted); -+ tmp.rx_cells = fore200e_swap(fore200e->stats->aal0.cells_received) + -+ fore200e_swap(fore200e->stats->aal34.cells_received) + -+ fore200e_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(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 the receive buffer body */ -+ if (fore200e_chunk_alloc(fore200e, -+ &buffer[ i ].data, size, fore200e->bus->buffer_alignment) < 0) { -+ -+ while (i > 0) -+ fore200e_chunk_free(fore200e, &buffer[ --i ].data); -+ fore200e_kfree(buffer); -+ -+ return -ENOMEM; -+ } -+ } -+ /* 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; -+ -+ 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_chunk_alloc(fore200e, -+ &bsq->status, -+ 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_chunk_alloc(fore200e, -+ &bsq->rbd_block, -+ sizeof(struct rbd_block), -+ QUEUE_SIZE_BS, -+ fore200e->bus->descr_alignment) < 0) { -+ -+ fore200e->bus->dma_chunk_free(fore200e, &bsq->status); -+ 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 = -+ FORE200E_INDEX(bsq->status.align_addr, enum status, i); -+ bsq->host_entry[ i ].rbd_block = -+ FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i); -+ bsq->host_entry[ i ].rbd_block_dma = -+ FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i); -+ bsq->host_entry[ i ].cp_entry = &cp_entry[ i ]; -+ -+ *bsq->host_entry[ i ].status = STATUS_FREE; -+ -+ fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, 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; -+ int i; -+ -+ DPRINTK(2, "receive queue is being initialized\n"); -+ -+ /* allocate and align the array of status words */ -+ if (fore200e->bus->dma_chunk_alloc(fore200e, -+ &rxq->status, -+ 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_chunk_alloc(fore200e, -+ &rxq->rpd, -+ sizeof(struct rpd), -+ QUEUE_SIZE_RX, -+ fore200e->bus->descr_alignment) < 0) { -+ -+ fore200e->bus->dma_chunk_free(fore200e, &rxq->status); -+ 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 = -+ FORE200E_INDEX(rxq->status.align_addr, enum status, i); -+ rxq->host_entry[ i ].rpd = -+ FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i); -+ rxq->host_entry[ i ].rpd_dma = -+ FORE200E_DMA_INDEX(rxq->rpd.dma_addr, 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(rxq->status.dma_addr, enum status, i), -+ &cp_entry[ i ].status_haddr); -+ -+ fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, 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; -+ int i; -+ -+ DPRINTK(2, "transmit queue is being initialized\n"); -+ -+ /* allocate and align the array of status words */ -+ if (fore200e->bus->dma_chunk_alloc(fore200e, -+ &txq->status, -+ 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_chunk_alloc(fore200e, -+ &txq->tpd, -+ sizeof(struct tpd), -+ QUEUE_SIZE_TX, -+ fore200e->bus->descr_alignment) < 0) { -+ -+ fore200e->bus->dma_chunk_free(fore200e, &txq->status); -+ 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 = -+ FORE200E_INDEX(txq->status.align_addr, enum status, i); -+ txq->host_entry[ i ].tpd = -+ FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i); -+ txq->host_entry[ i ].tpd_dma = -+ FORE200E_DMA_INDEX(txq->tpd.dma_addr, 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(txq->status.dma_addr, 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 -+ operation 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; -+ int i; -+ -+ DPRINTK(2, "command queue is being initialized\n"); -+ -+ /* allocate and align the array of status words */ -+ if (fore200e->bus->dma_chunk_alloc(fore200e, -+ &cmdq->status, -+ 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 = -+ FORE200E_INDEX(cmdq->status.align_addr, enum status, i); -+ cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ]; -+ -+ *cmdq->host_entry[ i ].status = STATUS_FREE; -+ -+ fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, 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); -+ init_MUTEX(&fore200e->rate_sf); -+ -+ 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_io_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_io_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_swap(fore200e->stats->phy.crc_header_errors), -+ fore200e_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_swap(fore200e->stats->oc3.section_bip8_errors), -+ fore200e_swap(fore200e->stats->oc3.path_bip8_errors), -+ fore200e_swap(fore200e->stats->oc3.line_bip24_errors), -+ fore200e_swap(fore200e->stats->oc3.line_febe_errors), -+ fore200e_swap(fore200e->stats->oc3.path_febe_errors), -+ fore200e_swap(fore200e->stats->oc3.corr_hcs_errors), -+ fore200e_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_swap(fore200e->stats->atm.cells_transmitted), -+ fore200e_swap(fore200e->stats->atm.cells_received), -+ fore200e_swap(fore200e->stats->atm.vpi_bad_range), -+ fore200e_swap(fore200e->stats->atm.vpi_no_conn), -+ fore200e_swap(fore200e->stats->atm.vci_bad_range), -+ fore200e_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_swap(fore200e->stats->aal0.cells_transmitted), -+ fore200e_swap(fore200e->stats->aal0.cells_received), -+ fore200e_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_swap(fore200e->stats->aal34.cells_transmitted), -+ fore200e_swap(fore200e->stats->aal34.cells_received), -+ fore200e_swap(fore200e->stats->aal34.cells_dropped), -+ fore200e_swap(fore200e->stats->aal34.cells_crc_errors), -+ fore200e_swap(fore200e->stats->aal34.cells_protocol_errors), -+ fore200e_swap(fore200e->stats->aal34.cspdus_transmitted), -+ fore200e_swap(fore200e->stats->aal34.cspdus_received), -+ fore200e_swap(fore200e->stats->aal34.cspdus_dropped), -+ fore200e_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_swap(fore200e->stats->aal5.cells_transmitted), -+ fore200e_swap(fore200e->stats->aal5.cells_received), -+ fore200e_swap(fore200e->stats->aal5.cells_dropped), -+ fore200e_swap(fore200e->stats->aal5.congestion_experienced), -+ fore200e_swap(fore200e->stats->aal5.cspdus_transmitted), -+ fore200e_swap(fore200e->stats->aal5.cspdus_received), -+ fore200e_swap(fore200e->stats->aal5.cspdus_dropped), -+ fore200e_swap(fore200e->stats->aal5.cspdus_crc_errors), -+ fore200e_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_swap(fore200e->stats->aux.small_b1_failed), -+ fore200e_swap(fore200e->stats->aux.large_b1_failed), -+ fore200e_swap(fore200e->stats->aux.small_b2_failed), -+ fore200e_swap(fore200e->stats->aux.large_b2_failed), -+ fore200e_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 = -+{ -+ NULL, /* fore200e_dev_close */ -+ fore200e_open, -+ fore200e_close, -+ fore200e_ioctl, -+ fore200e_getsockopt, -+ fore200e_setsockopt, -+ fore200e_send, -+ NULL, /* fore200e_sg_send, */ -+ NULL, /* fore200e_send_oam, */ -+ NULL, /* fore200e_phy_put, */ -+ NULL, /* fore200e_phy_get, */ -+ NULL, /* fore200e_feedback, */ -+ fore200e_change_qos, -+ NULL, /* free_rx_skb */ -+ 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_dma_map, -+ fore200e_pca_dma_unmap, -+ NULL, -+ fore200e_pca_dma_chunk_alloc, -+ fore200e_pca_dma_chunk_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, -+ 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_dma_map, -+ fore200e_sba_dma_unmap, -+ fore200e_sba_dma_sync, -+ fore200e_sba_dma_chunk_alloc, -+ fore200e_sba_dma_chunk_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_proc_read, -+ }, -+#endif -+ {} -+}; ---- /dev/null Tue May 5 22:32:27 1998 -+++ work/drivers/atm/fore200e.h Wed Feb 2 20:33:05 2000 -@@ -0,0 +1,945 @@ -+#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; -+ -+ -+/* chunk of memory */ -+ -+typedef struct chunk { -+ void* alloc_addr; /* base address of allocated chunk */ -+ void* align_addr; /* base address of aligned chunk */ -+ u32 dma_addr; /* DMA address of aligned chunk */ -+ u32 alloc_size; /* length of allocated chunk */ -+ u32 align_size; /* length of aligned chunk */ -+} chunk_t; -+ -+#define dma_size align_size /* DMA useable size */ -+ -+ -+/* 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 */ -+ struct chunk data; /* data buffer */ -+} 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 */ -+ struct chunk status; /* 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 chunk tpd; /* array of tpds */ -+ struct chunk status; /* arry 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 chunk rpd; /* array of rpds */ -+ struct chunk status; /* 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 chunk rbd_block; /* array of rbds */ -+ struct chunk status; /* 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 (*dma_map)(struct fore200e*, void*, int); -+ void (*dma_unmap)(struct fore200e*, u32, int); -+ void (*dma_sync)(struct fore200e*, u32, int); -+ int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); -+ void (*dma_chunk_free)(struct fore200e*, struct chunk*); -+ 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*); -+ 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 */ -+ -+ -+/* size of SBA-200E registers */ -+ -+#define SBA200E_HCR_LENGTH 4 -+#define SBA200E_BSR_LENGTH 4 -+#define SBA200E_ISR_LENGTH 4 -+#define SBA200E_RAM_LENGTH 0x40000 -+ -+ -+/* 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 Wed Feb 2 20:33:05 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 Wed Feb 2 20:33:05 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 Wed Feb 2 20:33:05 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; -+static struct idt77105_priv *idt77105_all = NULL; -+ -+/* -+ * Retrieve the value of one of the IDT77105's counters. -+ * `counter' is one of the IDT77105_CTRSEL_* constants. -+ */ -+static u16 get_counter(struct atm_dev *dev, int counter) -+{ -+ u16 val; -+ -+ /* write the counter bit into PHY register 6 */ -+ PUT(counter, CTRSEL); -+ /* read the low 8 bits from register 4 */ -+ val = GET(CTRLO); -+ /* read the high 8 bits from register 5 */ -+ val |= GET(CTRHI)<<8; -+ -+ return val; -+} -+ -+/* -+ * Timer function called every second to gather statistics -+ * from the 77105. This is done because the h/w registers -+ * will overflow if not read at least once per second. The -+ * kernel's stats are much higher precision. Also, having -+ * a separate copy of the stats allows implementation of -+ * an ioctl which gathers the stats *without* zero'ing them. -+ */ -+static void idt77105_stats_timer_func(unsigned long dummy) -+{ -+ struct idt77105_priv *walk; -+ struct atm_dev *dev; -+ struct idt77105_stats *stats; -+ -+ DPRINTK("IDT77105 gathering statistics\n"); -+ for (walk = idt77105_all; walk; walk = walk->next) { -+ dev = walk->dev; -+ -+ stats = &walk->stats; -+ stats->symbol_errors += get_counter(dev, IDT77105_CTRSEL_SEC); -+ stats->tx_cells += get_counter(dev, IDT77105_CTRSEL_TCC); -+ stats->rx_cells += get_counter(dev, IDT77105_CTRSEL_RCC); -+ stats->rx_hec_errors += get_counter(dev, IDT77105_CTRSEL_RHEC); -+ } -+ if (!start_timer) mod_timer(&stats_timer,jiffies+IDT77105_STATS_TIMER_PERIOD); -+} -+ -+ -+/* -+ * A separate timer func which handles restarting PHY chips which -+ * have had the cable re-inserted after being pulled out. This is -+ * done by polling the Good Signal Bit in the Interrupt Status -+ * register every 5 seconds. The other technique (checking Good -+ * Signal Bit in the interrupt handler) cannot be used because PHY -+ * interrupts need to be disabled when the cable is pulled out -+ * to avoid lots of spurious cell error interrupts. -+ */ -+static void idt77105_restart_timer_func(unsigned long dummy) -+{ -+ struct idt77105_priv *walk; -+ struct atm_dev *dev; -+ unsigned char istat; -+ -+ DPRINTK("IDT77105 checking for cable re-insertion\n"); -+ for (walk = idt77105_all; walk; walk = walk->next) { -+ dev = walk->dev; -+ -+ if (dev->signal != ATM_PHY_SIG_LOST) -+ continue; -+ -+ istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ -+ if (istat & IDT77105_ISTAT_GOODSIG) { -+ /* Found signal again */ -+ dev->signal = ATM_PHY_SIG_FOUND; -+ printk(KERN_NOTICE "%s(itf %d): signal detected again\n", -+ dev->type,dev->number); -+ /* flush the receive FIFO */ -+ PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG); -+ /* re-enable interrupts */ -+ PUT( walk->old_mcr ,MCR); -+ } -+ } -+ if (!start_timer) mod_timer(&restart_timer,jiffies+IDT77105_RESTART_TIMER_PERIOD); -+} -+ -+ -+static int fetch_stats(struct atm_dev *dev,struct idt77105_stats *arg,int zero) -+{ -+ unsigned long flags; -+ int error; -+ -+ error = 0; -+ save_flags(flags); -+ cli(); -+ if (arg) -+ error = copy_to_user(arg,&PRIV(dev)->stats, -+ sizeof(struct idt77105_stats)); -+ if (zero && !error) -+ memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); -+ restore_flags(flags); -+ return error ? -EFAULT : sizeof(struct idt77105_stats); -+} -+ -+ -+ -+static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) -+{ -+ printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number); -+ switch (cmd) { -+ case IDT77105_GETSTATZ: -+ case IDT77105_GETSTAT: -+ return fetch_stats(dev,(struct idt77105_stats *) arg, -+ cmd == IDT77105_GETSTATZ); -+ case IDT77105_SETLOOP: -+ if (!capable(CAP_NET_ADMIN)) return -EPERM; -+ if ((int) arg < 0 || (int) arg > IDT77105_LM_LOOP) -+ return -EINVAL; -+ PUT((GET(DIAG) & ~IDT77105_DIAG_LCMASK) | -+ ((int) arg == IDT77105_LM_NONE ? IDT77105_DIAG_LC_NORMAL : 0) | -+ ((int) arg == IDT77105_LM_DIAG ? IDT77105_DIAG_LC_PHY_LOOPBACK : 0) | -+ ((int) arg == IDT77105_LM_LOOP ? IDT77105_DIAG_LC_LINE_LOOPBACK : 0), -+ DIAG); -+ printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", -+ dev->type, dev->number, -+ ((int) arg == IDT77105_LM_NONE ? "NONE" : -+ ((int) arg == IDT77105_LM_DIAG ? "DIAG (local)" : -+ ((int) arg == IDT77105_LM_LOOP ? "LOOP (remote)" : -+ "unknown"))) -+ ); -+ PRIV(dev)->loop_mode = (int) arg; -+ return 0; -+ case IDT77105_GETLOOP: -+ return put_user(PRIV(dev)->loop_mode,(int *) arg) ? -+ -EFAULT : sizeof(int); -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+ -+ -+ -+static void idt77105_int(struct atm_dev *dev) -+{ -+ unsigned char istat; -+ -+ istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ -+ -+ DPRINTK("IDT77105 generated an interrupt, istat=%02x\n", (unsigned)istat); -+ -+ if (istat & IDT77105_ISTAT_RSCC) { -+ /* Rx Signal Condition Change - line went up or down */ -+ if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */ -+ /* This should not happen (restart timer does it) but JIC */ -+ dev->signal = ATM_PHY_SIG_FOUND; -+ } else { /* signal lost */ -+ /* -+ * Disable interrupts and stop all transmission and -+ * reception - the restart timer will restore these. -+ */ -+ PRIV(dev)->old_mcr = GET(MCR); -+ PUT( -+ (PRIV(dev)->old_mcr| -+ IDT77105_MCR_DREC| -+ IDT77105_MCR_DRIC| -+ IDT77105_MCR_HALTTX -+ ) & ~IDT77105_MCR_EIP, MCR); -+ dev->signal = ATM_PHY_SIG_LOST; -+ printk(KERN_NOTICE "%s(itf %d): signal lost\n", -+ dev->type,dev->number); -+ } -+ } -+ -+ if (istat & IDT77105_ISTAT_RFO) { -+ /* Rx FIFO Overrun -- perform a FIFO flush */ -+ PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG); -+ printk(KERN_NOTICE "%s(itf %d): receive FIFO overrun\n", -+ dev->type,dev->number); -+ } -+#ifdef GENERAL_DEBUG -+ if (istat & (IDT77105_ISTAT_HECERR | IDT77105_ISTAT_SCR | -+ IDT77105_ISTAT_RSE)) { -+ /* normally don't care - just report in stats */ -+ printk(KERN_NOTICE "%s(itf %d): received cell with error\n", -+ dev->type,dev->number); -+ } -+#endif -+} -+ -+ -+static int idt77105_start(struct atm_dev *dev) -+{ -+ unsigned long flags; -+ -+ if (!(PRIV(dev) = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) -+ return -ENOMEM; -+ PRIV(dev)->dev = dev; -+ save_flags(flags); -+ cli(); -+ PRIV(dev)->next = idt77105_all; -+ idt77105_all = PRIV(dev); -+ restore_flags(flags); -+ memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); -+ -+ /* initialise dev->signal from Good Signal Bit */ -+ dev->signal = GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? ATM_PHY_SIG_FOUND : -+ ATM_PHY_SIG_LOST; -+ if (dev->signal == ATM_PHY_SIG_LOST) -+ printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, -+ dev->number); -+ -+ /* initialise loop mode from hardware */ -+ switch ( GET(DIAG) & IDT77105_DIAG_LCMASK ) { -+ case IDT77105_DIAG_LC_NORMAL: -+ PRIV(dev)->loop_mode = IDT77105_LM_NONE; -+ break; -+ case IDT77105_DIAG_LC_PHY_LOOPBACK: -+ PRIV(dev)->loop_mode = IDT77105_LM_DIAG; -+ break; -+ case IDT77105_DIAG_LC_LINE_LOOPBACK: -+ PRIV(dev)->loop_mode = IDT77105_LM_LOOP; -+ break; -+ } -+ -+ /* enable interrupts, e.g. on loss of signal */ -+ PRIV(dev)->old_mcr = GET(MCR); -+ if (dev->signal == ATM_PHY_SIG_FOUND) { -+ PRIV(dev)->old_mcr |= IDT77105_MCR_EIP; -+ PUT(PRIV(dev)->old_mcr, MCR); -+ } -+ -+ -+ idt77105_stats_timer_func(0); /* clear 77105 counters */ -+ (void) fetch_stats(dev,NULL,1); /* clear kernel counters */ -+ -+ cli(); -+ if (!start_timer) restore_flags(flags); -+ else { -+ start_timer = 0; -+ restore_flags(flags); -+ -+ init_timer(&stats_timer); -+ stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD; -+ stats_timer.function = idt77105_stats_timer_func; -+ add_timer(&stats_timer); -+ -+ init_timer(&restart_timer); -+ restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD; -+ restart_timer.function = idt77105_restart_timer_func; -+ add_timer(&restart_timer); -+ } -+ 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 Wed Feb 2 20:40:54 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 Wed Feb 2 20:33: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 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);) -+ -+} -+ -+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; -+} -+ -+void ia_suni_pm7345_init (IADEV *iadev) -+{ -+ 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; -+ -+ 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); -+ -+ 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"); -+ -+ 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 -+ -+ 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; -+ } -+ -+ error = suni_init(dev); -+ if (error) { -+ free_irq(iadev->irq, dev); -+ return error; -+ } -+ -+ /* 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; -+ -+ 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; -+} -+ -+static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb) -+{ -+ 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; -+ -+} -+ -+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; -+ -+ 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 Wed Feb 2 20:41:20 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 */ -+}; -+ -+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 */ -+}; -+ -+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; -+ -+ -+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; -+ -+/* -+ * 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 */ -+ -+/* -+ * 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 */ -+ -+/* -+ * 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 *); -+ -+/*********************** 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 */ -+ -+/* -+ * 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 */ -+ -+/* -+ * 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*/ -+ -+/* -+ * 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 */ -+ -+/* -+ * 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. -+ * -+ ***********/ -+ -+/* -+ * a list of the commands that can be sent to the NOVRAM -+ */ -+ -+#define EXTEND 0x100 -+#define IAWRITE 0x140 -+#define IAREAD 0x180 -+#define ERASE 0x1c0 -+ -+#define EWDS 0x00 -+#define WRAL 0x10 -+#define ERAL 0x20 -+#define EWEN 0x30 -+ -+/* -+ * these bits duplicate the hw_flip.h register settings -+ * note: how the data in / out bits are defined in the flipper specification -+ */ -+ -+#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 Wed Feb 2 20:33:05 2000 -@@ -44,6 +44,9 @@ - #ifdef CONFIG_ATM_NICSTAR_USE_SUNI - #include "suni.h" - #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ -+#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 -+#include "idt77105.h" -+#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ - - - /* Additional code ************************************************************/ -@@ -99,8 +102,10 @@ - - #define NS_DELAY mdelay(1) - --#define ALIGN_ADDRESS(addr, alignment) \ -+#define ALIGN_BUS_ADDR(addr, alignment) \ - ((((u32) (addr)) + (((u32) (alignment)) - 1)) & ~(((u32) (alignment)) - 1)) -+#define ALIGN_ADDRESS(addr, alignment) \ -+ bus_to_virt(ALIGN_BUS_ADDR(virt_to_bus(addr), alignment)) - - #undef CEIL(d) - -@@ -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]; - -+#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 -+ if (card->max_pcr == IDT_25_PCR) { -+ idt77105_stop(card->atmdev); -+ } -+#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ -+ - /* Stop everything */ - writel(0x00000000, card->membase + CFG); - -@@ -457,15 +460,16 @@ - cards[i] = card; - - card->index = i; -+ card->atmdev = NULL; - card->pcidev = pcidev; -- card->membase = (u32) pcidev->resource[1].start; -+ card->membase = pcidev->resource[1].start; - #ifdef __powerpc__ - /* Compensate for different memory map between host CPU and PCI bus. - Shouldn't we use a macro for this? */ - card->membase += KERNELBASE; - #endif /* __powerpc__ */ -- card->membase = (u32) ioremap(card->membase, NS_IOREMAP_SIZE); -- if (card->membase == (u32) (NULL)) -+ 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; -@@ -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; -- - card->atmdev->phy = NULL; -+ - #ifdef CONFIG_ATM_NICSTAR_USE_SUNI - if (card->max_pcr == ATM_OC3_PCR) { - suni_init(card->atmdev); -@@ -883,6 +889,17 @@ - #endif /* MODULE */ - } - #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ -+ -+#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 -+ if (card->max_pcr == IDT_25_PCR) { -+ idt77105_init(card->atmdev); -+ /* Note that for the IDT77105 PHY we don't need the awful -+ * module count hack that the SUNI needs because we can -+ * stop the '105 when the nicstar module is cleaned up. -+ */ -+ } -+#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ -+ - if (card->atmdev->phy && card->atmdev->phy->start) - card->atmdev->phy->start(card->atmdev); - -@@ -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; - } -+#if 0 - /* Dump 25.6 Mbps PHY registers */ -+ /* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it -+ here just in case it's needed for debugging. */ - if (card->max_pcr == IDT_25_PCR && !left--) - { - u32 phy_regs[4]; -@@ -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]); - } -+#endif /* 0 - Dump 25.6 Mbps PHY registers */ - #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 Feb 2 20:40:54 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 ************************************************/ - - -+/* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */ -+ - enum ns_regs - { -- DR0 = 0x00, -- DR1 = 0x04, -- DR2 = 0x08, -- DR3 = 0x0C, -- CMD = 0x10, -- CFG = 0x14, -- STAT = 0x18, -- RSQB = 0x1C, -- RSQT = 0x20, -- RSQH = 0x24, -- CDC = 0x28, -- VPEC = 0x2C, -- ICC = 0x30, -- RAWCT = 0x34, -- TMR = 0x38, -- TSTB = 0x3C, -- TSQB = 0x40, -- TSQT = 0x44, -- TSQH = 0x48, -- GP = 0x4C, -- VPM = 0x50 -+ DR0 = 0x00, /* Data Register 0 R/W*/ -+ DR1 = 0x04, /* Data Register 1 W */ -+ DR2 = 0x08, /* Data Register 2 W */ -+ DR3 = 0x0C, /* Data Register 3 W */ -+ CMD = 0x10, /* Command W */ -+ CFG = 0x14, /* Configuration R/W */ -+ STAT = 0x18, /* Status R/W */ -+ RSQB = 0x1C, /* Receive Status Queue Base W */ -+ RSQT = 0x20, /* Receive Status Queue Tail R */ -+ RSQH = 0x24, /* Receive Status Queue Head W */ -+ CDC = 0x28, /* Cell Drop Counter R/clear */ -+ VPEC = 0x2C, /* VPI/VCI Lookup Error Count R/clear */ -+ ICC = 0x30, /* Invalid Cell Count R/clear */ -+ RAWCT = 0x34, /* Raw Cell Tail R */ -+ TMR = 0x38, /* Timer R */ -+ TSTB = 0x3C, /* Transmit Schedule Table Base R/W */ -+ TSQB = 0x40, /* Transmit Status Queue Base W */ -+ TSQT = 0x44, /* Transmit Status Queue Tail R */ -+ TSQH = 0x48, /* Transmit Status Queue Head W */ -+ GP = 0x4C, /* General Purpose R/W */ -+ VPM = 0x50 /* VPI/VCI Mask W */ - }; - - - /* NICStAR commands issued to the CMD register ********************************/ - -+ -+/* Top 4 bits are command opcode, lower 28 are parameters. */ -+ - #define NS_CMD_NO_OPERATION 0x00000000 -+ /* params always 0 */ -+ - #define NS_CMD_OPENCLOSE_CONNECTION 0x20000000 -+ /* b19{1=open,0=close} b18-2{SRAM addr} */ -+ - #define NS_CMD_WRITE_SRAM 0x40000000 -+ /* b18-2{SRAM addr} b1-0{burst size} */ -+ - #define NS_CMD_READ_SRAM 0x50000000 -+ /* b18-2{SRAM addr} */ -+ - #define NS_CMD_WRITE_FREEBUFQ 0x60000000 -+ /* b0{large buf indicator} */ -+ - #define NS_CMD_READ_UTILITY 0x80000000 -+ /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ -+ - #define NS_CMD_WRITE_UTILITY 0x90000000 -+ /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ - - #define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000) - #define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION -@@ -497,28 +515,35 @@ - - /* NICStAR configuration bits *************************************************/ - --#define NS_CFG_SWRST 0x80000000 --#define NS_CFG_RXPATH 0x20000000 --#define NS_CFG_SMBUFSIZE_MASK 0x18000000 --#define NS_CFG_LGBUFSIZE_MASK 0x06000000 --#define NS_CFG_EFBIE 0x01000000 --#define NS_CFG_RSQSIZE_MASK 0x00C00000 --#define NS_CFG_ICACCEPT 0x00200000 --#define NS_CFG_IGNOREGFC 0x00100000 --#define NS_CFG_VPIBITS_MASK 0x000C0000 --#define NS_CFG_RCTSIZE_MASK 0x00030000 --#define NS_CFG_VCERRACCEPT 0x00008000 --#define NS_CFG_RXINT_MASK 0x00007000 --#define NS_CFG_RAWIE 0x00000800 --#define NS_CFG_RSQAFIE 0x00000400 --#define NS_CFG_RXRM 0x00000200 --#define NS_CFG_TMRROIE 0x00000080 --#define NS_CFG_TXEN 0x00000020 --#define NS_CFG_TXIE 0x00000010 --#define NS_CFG_TXURIE 0x00000008 --#define NS_CFG_UMODE 0x00000004 --#define NS_CFG_TSQFIE 0x00000002 --#define NS_CFG_PHYIE 0x00000001 -+#define NS_CFG_SWRST 0x80000000 /* Software Reset */ -+#define NS_CFG_RXPATH 0x20000000 /* Receive Path Enable */ -+#define NS_CFG_SMBUFSIZE_MASK 0x18000000 /* Small Receive Buffer Size */ -+#define NS_CFG_LGBUFSIZE_MASK 0x06000000 /* Large Receive Buffer Size */ -+#define NS_CFG_EFBIE 0x01000000 /* Empty Free Buffer Queue -+ Interrupt Enable */ -+#define NS_CFG_RSQSIZE_MASK 0x00C00000 /* Receive Status Queue Size */ -+#define NS_CFG_ICACCEPT 0x00200000 /* Invalid Cell Accept */ -+#define NS_CFG_IGNOREGFC 0x00100000 /* Ignore General Flow Control */ -+#define NS_CFG_VPIBITS_MASK 0x000C0000 /* VPI/VCI Bits Size Select */ -+#define NS_CFG_RCTSIZE_MASK 0x00030000 /* Receive Connection Table Size */ -+#define NS_CFG_VCERRACCEPT 0x00008000 /* VPI/VCI Error Cell Accept */ -+#define NS_CFG_RXINT_MASK 0x00007000 /* End of Receive PDU Interrupt -+ Handling */ -+#define NS_CFG_RAWIE 0x00000800 /* Raw Cell Qu' Interrupt Enable */ -+#define NS_CFG_RSQAFIE 0x00000400 /* Receive Queue Almost Full -+ Interrupt Enable */ -+#define NS_CFG_RXRM 0x00000200 /* Receive RM Cells */ -+#define NS_CFG_TMRROIE 0x00000080 /* Timer Roll Over Interrupt -+ Enable */ -+#define NS_CFG_TXEN 0x00000020 /* Transmit Operation Enable */ -+#define NS_CFG_TXIE 0x00000010 /* Transmit Status Interrupt -+ Enable */ -+#define NS_CFG_TXURIE 0x00000008 /* Transmit Under-run Interrupt -+ Enable */ -+#define NS_CFG_UMODE 0x00000004 /* Utopia Mode (cell/byte) Select */ -+#define NS_CFG_TSQFIE 0x00000002 /* Transmit Status Queue Full -+ Interrupt Enable */ -+#define NS_CFG_PHYIE 0x00000001 /* PHY Interrupt Enable */ - - #define NS_CFG_SMBUFSIZE_48 0x00000000 - #define NS_CFG_SMBUFSIZE_96 0x08000000 -@@ -552,22 +577,22 @@ - - /* NICStAR STATus bits ********************************************************/ - --#define NS_STAT_SFBQC_MASK 0xFF000000 --#define NS_STAT_LFBQC_MASK 0x00FF0000 --#define NS_STAT_TSIF 0x00008000 --#define NS_STAT_TXICP 0x00004000 --#define NS_STAT_TSQF 0x00001000 --#define NS_STAT_TMROF 0x00000800 --#define NS_STAT_PHYI 0x00000400 --#define NS_STAT_CMDBZ 0x00000200 --#define NS_STAT_SFBQF 0x00000100 --#define NS_STAT_LFBQF 0x00000080 --#define NS_STAT_RSQF 0x00000040 --#define NS_STAT_EOPDU 0x00000020 --#define NS_STAT_RAWCF 0x00000010 --#define NS_STAT_SFBQE 0x00000008 --#define NS_STAT_LFBQE 0x00000004 --#define NS_STAT_RSQAF 0x00000002 -+#define NS_STAT_SFBQC_MASK 0xFF000000 /* hi 8 bits Small Buffer Queue Count */ -+#define NS_STAT_LFBQC_MASK 0x00FF0000 /* hi 8 bits Large Buffer Queue Count */ -+#define NS_STAT_TSIF 0x00008000 /* Transmit Status Queue Indicator */ -+#define NS_STAT_TXICP 0x00004000 /* Transmit Incomplete PDU */ -+#define NS_STAT_TSQF 0x00001000 /* Transmit Status Queue Full */ -+#define NS_STAT_TMROF 0x00000800 /* Timer Overflow */ -+#define NS_STAT_PHYI 0x00000400 /* PHY Device Interrupt */ -+#define NS_STAT_CMDBZ 0x00000200 /* Command Busy */ -+#define NS_STAT_SFBQF 0x00000100 /* Small Buffer Queue Full */ -+#define NS_STAT_LFBQF 0x00000080 /* Large Buffer Queue Full */ -+#define NS_STAT_RSQF 0x00000040 /* Receive Status Queue Full */ -+#define NS_STAT_EOPDU 0x00000020 /* End of PDU */ -+#define NS_STAT_RAWCF 0x00000010 /* Raw Cell Flag */ -+#define NS_STAT_SFBQE 0x00000008 /* Small Buffer Queue Empty */ -+#define NS_STAT_LFBQE 0x00000004 /* Large Buffer Queue Empty */ -+#define NS_STAT_RSQAF 0x00000002 /* Receive Status Queue Almost Full */ - - #define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23) - #define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15) -@@ -723,7 +748,7 @@ - { - int index; /* Card ID to the device driver */ - int sram_size; /* In k x 32bit words. 32 or 128 */ -- u32 membase; /* Card's memory base address */ -+ unsigned long membase; /* Card's memory base address */ - 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 Wed Feb 2 20:33: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 Wed Feb 2 20:33: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 Wed Feb 2 20:33: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 Wed Feb 2 20:33: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: -- if (!capable(CAP_NET_ADMIN)) return -EPERM; -- if ((int) arg < 0 || (int) arg > SUNI_LM_LOOP) -- return -EINVAL; -- PUT((GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE)) | -- ((int) arg == SUNI_LM_DIAG ? SUNI_MCT_DLE : 0) | -- ((int) arg == SUNI_LM_LOOP ? SUNI_MCT_LLE : 0),MCT); -- PRIV(dev)->loop_mode = (int) arg; -- return 0; -+ { -+ int int_arg = (int) (long) arg; -+ -+ if (!capable(CAP_NET_ADMIN)) return -EPERM; -+ if (int_arg < 0 || int_arg > SUNI_LM_LOOP) -+ return -EINVAL; -+ PUT((GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE)) -+ | (int_arg == SUNI_LM_DIAG ? SUNI_MCT_DLE : -+ 0) | (int_arg == SUNI_LM_LOOP ? -+ SUNI_MCT_LLE : 0),MCT); -+ PRIV(dev)->loop_mode = int_arg; -+ return 0; -+ } - 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 Wed Feb 2 20:33: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 Wed Feb 2 20:33: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); - restore_flags(flags); --/* Ugly hack to ensure that ttcp_atm will work with the current allocation -- scheme. @@@ */ --if (vcc->rx_quota < 200000) vcc->rx_quota = 200000; - 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) - { --#ifdef CONFIG_MMU_HACKS -- --static const struct atm_buffconst bctx = { PAGE_SIZE,0,PAGE_SIZE,0,0,0 }; --static const struct atm_buffconst bcrx = { PAGE_SIZE,0,PAGE_SIZE,0,0,0 }; -- --#else -- --static const struct atm_buffconst bctx = { 4,0,4,0,0,0 }; --static const struct atm_buffconst bcrx = { 4,0,4,0,0,0 }; -- --#endif -- if (level == SOL_AAL && (optname == SO_BCTXOPT || -- optname == SO_BCRXOPT)) -- return copy_to_user(optval,optname == SO_BCTXOPT ? &bctx : -- &bcrx,sizeof(struct atm_buffconst)) ? -EFAULT : 0; - return -EINVAL; - } - -@@ -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 Tue Feb 1 02:14:10 2000 -+++ work/include/linux/atm.h Wed Feb 2 20:40:40 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 - #endif -+#include - #include - #include - -@@ -84,23 +85,6 @@ - * please speak up ... - */ - --/* socket layer */ --#define SO_BCTXOPT __SO_ENCODE(SOL_SOCKET,16,struct atm_buffconst) -- /* not ATM specific - should go somewhere else */ --#define SO_BCRXOPT __SO_ENCODE(SOL_SOCKET,17,struct atm_buffconst) -- -- --/* for SO_BCTXOPT and SO_BCRXOPT */ -- --struct atm_buffconst { -- unsigned long buf_fac; /* buffer alignment factor */ -- unsigned long buf_off; /* buffer alignment offset */ -- unsigned long size_fac; /* buffer size factor */ -- unsigned long size_off; /* buffer size offset */ -- unsigned long min_size; /* minimum size */ -- unsigned long max_size; /* maximum size, 0 = unlimited */ --}; -- - - /* ATM cell header (for AAL0) */ - -@@ -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 */ -- struct atm_trafprm rxtp; /* parameters in RX direction */ -- unsigned char aal; -+ struct atm_trafprm rxtp __ATM_API_ALIGN; -+ /* parameters in RX direction */ -+ unsigned char aal __ATM_API_ALIGN; - }; - - /* PVC addressing */ -@@ -177,7 +177,7 @@ - short itf; /* ATM interface */ - short vpi; /* VPI (only 8 bits at UNI) */ - int vci; /* VCI (only 16 bits at UNI) */ -- } sap_addr; /* PVC address */ -+ } sap_addr __ATM_API_ALIGN; /* PVC address */ - }; - - /* SVC addressing */ -@@ -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 */ -- } sas_addr; /* SVC address */ -+ } sas_addr __ATM_API_ALIGN; /* SVC address */ - }; - - -@@ -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 Wed Feb 2 20:33:05 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 @@ +--- ref/arch/sparc64/kernel/ioctl32.c Thu Feb 17 18:26:30 2000 ++++ work/arch/sparc64/kernel/ioctl32.c Mon Feb 28 22:16:23 2000 +@@ -1793,6 +1793,8 @@ + #define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32) + #define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32) + #define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32) ++#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32) ++#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32) + + static struct { + unsigned int cmd32; +@@ -1811,7 +1813,9 @@ + { ATM_SETESI32, ATM_SETESI }, + { ATM_SETESIF32, ATM_SETESIF }, + { ATM_GETSTAT32, ATM_GETSTAT }, +- { ATM_GETSTATZ32, ATM_GETSTATZ } ++ { ATM_GETSTATZ32, ATM_GETSTATZ }, ++ { ATM_GETLOOP32, ATM_GETLOOP }, ++ { ATM_SETLOOP32, ATM_SETLOOP } + }; + + #define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0])) +@@ -1931,8 +1935,6 @@ + unsigned int cmd = 0; + + switch (cmd32) { +- case SUNI_GETLOOP: +- case SUNI_SETLOOP: + case SONET_GETSTAT: + case SONET_GETSTATZ: + case SONET_GETDIAG: +@@ -1944,7 +1946,6 @@ + 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; +@@ -1954,7 +1955,6 @@ + if (i == NR_ATM_IOCTL) { + return -EINVAL; + } +- } + + switch (cmd) { + case ATM_GETNAMES: +@@ -1973,6 +1973,8 @@ + case ATM_SETESIF: + case ATM_GETSTAT: + case ATM_GETSTATZ: ++ case ATM_GETLOOP: ++ case ATM_SETLOOP: + return do_atmif_sioc(fd, cmd, arg); + } - #include +@@ -2657,8 +2659,8 @@ + HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl) + HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl) + HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl) +-HANDLE_IOCTL(SUNI_GETLOOP, do_atm_ioctl) +-HANDLE_IOCTL(SUNI_SETLOOP, do_atm_ioctl) ++HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl) ++HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl) + HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl) + HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl) + HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl) +--- ref/drivers/atm/ambassador.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/ambassador.c Mon Feb 28 20:54:25 2000 +@@ -435,7 +435,7 @@ + if (ATM_SKB(skb)->vcc->pop) { + ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb); + } else { +- dev_kfree_skb (skb); ++ dev_kfree_skb_any (skb); + } + } +@@ -524,7 +524,7 @@ + dev->stats.rx.unused++; + } + +- dev_kfree_skb (skb); ++ dev_kfree_skb_any (skb); + return; + } + +@@ -796,7 +796,7 @@ + return; + } + if (check_area (skb->data, skb->truesize)) { +- dev_kfree_skb (skb); ++ dev_kfree_skb_any (skb); + return; + } + // cast needed as there is no %? for pointer differences +@@ -805,7 +805,7 @@ + rx.handle = virt_to_bus (skb); + rx.host_address = cpu_to_be32 (virt_to_bus (skb->data)); + if (rx_give (dev, &rx, pool)) +- dev_kfree_skb (skb); ++ dev_kfree_skb_any (skb); + + } + +@@ -952,7 +952,7 @@ + if (rx == rxq->in.start) + rx = rxq->in.limit; + --rx; +- dev_kfree_skb (bus_to_virt (rx->handle)); ++ dev_kfree_skb_any (bus_to_virt (rx->handle)); + } + } + +@@ -1394,6 +1394,7 @@ + static int amb_ioctl (struct atm_dev * dev, unsigned int cmd, void * arg) { + unsigned short newdebug; + if (cmd == AMB_SETDEBUG) { ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (copy_from_user (&newdebug, arg, sizeof(newdebug))) { + // moan + return -EFAULT; +@@ -1402,6 +1403,7 @@ + return 0; + } + } else if (cmd == AMB_DONTPANIC) { ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + dont_panic (dev); + } else { + // moan +@@ -1564,7 +1566,7 @@ + // at. However, I note that the ATM layer calls kfree_skb rather + // than dev_kfree_skb at this point so we are least covered as far + // as buffer locking goes. There may be bugs if pcap clones RX skbs. +- + -+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+7,struct atmif_sioc) -+ /* set buffer multipliers */ + PRINTD (DBG_FLOW|DBG_SKB, "amb_rx_free skb %p (atm_vcc %p, vcc %p)", + skb, atm_vcc, vcc); + +@@ -1582,7 +1584,7 @@ + } + + // just do what the ATM layer would have done +- kfree_skb (skb); ++ dev_kfree_skb_any (skb); + + return; + } +--- ref/drivers/atm/atmtcp.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/atmtcp.c Mon Feb 28 20:54:26 2000 +@@ -168,6 +168,11 @@ + struct atmtcp_hdr *hdr; + int size; + ++ if (vcc->qos.txtp.traffic_class == ATM_NONE) { ++ if (vcc->pop) vcc->pop(vcc,skb); ++ else dev_kfree_skb(skb); ++ return -EINVAL; ++ } + dev_data = PRIV(vcc->dev); + if (dev_data) out_vcc = dev_data->vcc; + if (!dev_data || !out_vcc) { +--- ref/drivers/atm/eni.c Tue Feb 22 01:32:27 2000 ++++ work/drivers/atm/eni.c Mon Feb 28 20:54:26 2000 +@@ -1054,8 +1054,9 @@ + * 1 DMA xfer & 2 DMA'ed bytes (protocol layering is for wimps :-) + */ ++ aal5 = vcc->qos.aal == ATM_AAL5; + /* check space in buffer */ +- if (!(aal5 = vcc->qos.aal == ATM_AAL5)) ++ if (!aal5) + size = (ATM_CELL_PAYLOAD >> 2)+TX_DESCR_SIZE; + /* cell without HEC plus segmentation header (includes + four-byte cell header) */ +--- ref/drivers/atm/fore200e.c Tue Feb 22 01:32:27 2000 ++++ work/drivers/atm/fore200e.c Mon Feb 28 22:16:23 2000 +@@ -67,7 +67,7 @@ + #define FORE200E_52BYTE_AAL0_SDU #endif ---- /dev/null Tue May 5 22:32:27 1998 -+++ work/include/linux/atm_idt77105.h Wed Feb 2 20:33:05 2000 -@@ -0,0 +1,40 @@ -+/* atm_idt77105.h - Driver-specific declarations of the IDT77105 driver (for -+ * use by driver-specific utilities) */ -+ -+/* Written 1999 by Greg Banks . Copied from atm_suni.h. */ -+ -+ -+#ifndef LINUX_ATM_IDT77105_H -+#define LINUX_ATM_IDT77105_H -+ -+#include -+#include -+ -+/* -+ * Structure for IDT77105_GETSTAT and IDT77105_GETSTATZ ioctls. -+ * Pointed to by `arg' in atmif_sioc. -+ */ -+struct idt77105_stats { -+ __u32 symbol_errors; /* wire symbol errors */ -+ __u32 tx_cells; /* cells transmitted */ -+ __u32 rx_cells; /* cells received */ -+ __u32 rx_hec_errors; /* Header Error Check errors on receive */ -+}; -+ -+#define IDT77105_GETLOOP _IOW('a',ATMIOC_PHYPRV,struct atmif_sioc) /* get loopback mode */ -+#define IDT77105_SETLOOP _IOW('a',ATMIOC_PHYPRV+1,struct atmif_sioc) /* set loopback mode */ -+#define IDT77105_GETSTAT _IOW('a',ATMIOC_PHYPRV+2,struct atmif_sioc) /* get stats */ -+#define IDT77105_GETSTATZ _IOW('a',ATMIOC_PHYPRV+3,struct atmif_sioc) /* get stats and zero */ -+ -+ -+/* -+ * TODO: what we need is a global loopback mode get/set ioctl for -+ * all devices, not these device-specific hacks -- Greg Banks -+ */ -+#define IDT77105_LM_NONE 0 /* no loopback */ -+#define IDT77105_LM_DIAG 1 /* diagnostic (i.e. loop TX to RX) -+ * (a.k.a. local loopback) */ -+#define IDT77105_LM_LOOP 2 /* line (i.e. loop RX to TX) -+ * (a.k.a. remote loopback) */ -+ -+#endif ---- ref/include/linux/atm_nicstar.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atm_nicstar.h Wed Feb 2 20:33:05 2000 -@@ -18,6 +18,7 @@ - * sys/types.h for struct timeval - */ -+#include - #include - - #define NS_GETPSTAT _IOWR('a',ATMIOC_SARPRV+1,struct atmif_sioc) -@@ -32,7 +33,7 @@ - unsigned min; - unsigned init; - unsigned max; --} buf_nr; -+}buf_nr; - - - typedef struct pool_levels ---- ref/include/linux/atm_tcp.h Wed Sep 8 20:14:32 1999 -+++ work/include/linux/atm_tcp.h Wed Feb 2 20:41:09 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 - -+#include -+ - #ifdef __KERNEL__ - #include - #endif -@@ -33,12 +35,12 @@ +-#define FORE200E_VERSION "0.2a" ++#define FORE200E_VERSION "0.2b" - 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 */ -+ 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 */ --}; -+} __ATM_API_ALIGN; - /* - * Field usage: ---- ref/include/linux/atm_zatm.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atm_zatm.h Wed Feb 2 20:33:05 2000 -@@ -1,7 +1,7 @@ - /* atm_zatm.h - Driver-specific declarations of the ZATM driver (for use by - driver-specific utilities) */ + #define FORE200E "fore200e: " +@@ -187,10 +187,10 @@ --/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ + /* allocate and align a chunk of memory intended to hold the data behing exchanged +- between the driver and the adapter (using streaming DVMA on SBUS hosts) */ ++ between the driver and the adapter (using streaming DVMA) */ - #ifndef LINUX_ATM_ZATM_H -@@ -12,6 +12,7 @@ - * sys/types.h for struct timeval - */ + static int +-fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment) ++fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction) + { + unsigned long offset = 0; -+#include - #include +@@ -199,6 +199,7 @@ - #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) ---- /dev/null Tue May 5 22:32:27 1998 -+++ work/include/linux/atmapi.h Wed Feb 2 20:33:05 2000 -@@ -0,0 +1,29 @@ -+/* atmapi.h - ATM API user space/kernel compatibility */ -+ -+/* Written 1999,2000 by Werner Almesberger, EPFL ICA */ -+ -+ -+#ifndef _LINUX_ATMAPI_H -+#define _LINUX_ATMAPI_H -+ -+#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. */ -+#define __ATM_API_ALIGN __attribute__((aligned(8))) -+#else -+#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 Tue Feb 1 02:14:11 2000 -+++ work/include/linux/atmarp.h Wed Feb 2 20:46:30 2000 -@@ -1,6 +1,6 @@ - /* atmarp.h - ATM ARP protocol and kernel-demon interface definitions */ - --/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ - + chunk->alloc_size = size + alignment; + chunk->align_size = size; ++ chunk->direction = direction; - #ifndef _LINUX_ATMARP_H -@@ -9,6 +9,7 @@ - #ifdef __KERNEL__ - #include - #endif -+#include - #include + chunk->alloc_addr = fore200e_kmalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA); + if (chunk->alloc_addr == NULL) +@@ -209,7 +210,7 @@ + + chunk->align_addr = chunk->alloc_addr + offset; +- chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size); ++ chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size, direction); + + return 0; + } +@@ -220,7 +221,7 @@ + static void + fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk) + { +- fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); ++ fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size, chunk->direction); ---- ref/include/linux/atmdev.h Tue Feb 1 02:14:43 2000 -+++ work/include/linux/atmdev.h Wed Feb 2 20:40:40 2000 -@@ -8,6 +8,8 @@ + fore200e_kfree(chunk->alloc_addr); + } +@@ -463,34 +464,32 @@ - #include -+#include -+#include - #include + static u32 +-fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size) ++fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction) + { +- u32 dma_addr = pci_map_single((struct pci_dev*)fore200e->bus_dev, virt_addr, size, PCI_DMA_BIDIRECTIONAL); ++ u32 dma_addr = pci_map_single((struct pci_dev*)fore200e->bus_dev, virt_addr, size, direction); +- DPRINTK(3, "PCI DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", +- virt_addr, size, dma_addr); ++ DPRINTK(3, "PCI DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d, --> dma_addr = 0x%08x\n", ++ virt_addr, size, direction, dma_addr); + + return dma_addr; + } -@@ -26,9 +28,9 @@ + static void +-fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) ++fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) + { +- DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); ++ DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - struct atm_aal_stats { -- long tx,tx_err; /* TX okay and errors */ -- long rx,rx_err; /* RX okay and errors */ -- long rx_drop; /* RX out of memory */ -+ int tx,tx_err; /* TX okay and errors */ -+ int rx,rx_err; /* RX okay and errors */ -+ int rx_drop; /* RX out of memory */ - }; +- pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, +- PCI_DMA_BIDIRECTIONAL); ++ pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); + } -@@ -36,7 +38,7 @@ - struct atm_aal_stats aal0; - struct atm_aal_stats aal34; - struct atm_aal_stats aal5; --}; -+} __ATM_API_ALIGN; - - - #define ATM_GETLINKRATE _IOW('a',ATMIOC_ITF+1,struct atmif_sioc) -@@ -123,6 +125,12 @@ - #define ATM_VS2TXT_MAP \ - "IDLE", "CONNECTED", "CLOSING", "LISTEN", "INUSE", "BOUND" - -+#define ATM_VF2TXT_MAP \ -+ "ADDR", "READY", "PARTIAL", "REGIS", \ -+ "RELEASED", "HASQOS", "LISTEN", "META", \ -+ "256", "512", "1024", "2048", \ -+ "SESSION", "HASSAP", "BOUND", "CLOSE" -+ + static void +-fore200e_pca_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size) ++fore200e_pca_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int direction) + { +- DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size); ++ DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - #ifdef __KERNEL__ +- pci_dma_sync_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, +- PCI_DMA_BIDIRECTIONAL); ++ pci_dma_sync_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); + } -@@ -132,6 +140,7 @@ - #include /* struct sk_buff */ - #include - #include -+#include - #include - - #ifdef CONFIG_PROC_FS -@@ -156,10 +165,10 @@ - #define ATM_VF_META 128 /* SVC socket isn't used for normal data - traffic and doesn't depend on signaling - to be available */ --#define ATM_VF_AQREL 256 /* Arequipa VC is being released */ --#define ATM_VF_AQDANG 512 /* VC is in Arequipa's dangling list */ --#define ATM_VF_SCRX ATM_SC_RX /* 1024; allow single-copy in the RX dir. */ --#define ATM_VF_SCTX ATM_SC_TX /* 2048; allow single-copy in the TX dir. */ -+ /* 256; unused */ -+ /* 512; unused */ -+ /* 1024; unused */ -+ /* 2048; unused */ - #define ATM_VF_SESSION 4096 /* VCC is p2mp session control descriptor */ - #define ATM_VF_HASSAP 8192 /* SAP has been set */ - #define ATM_VF_CLOSE 32768 /* asynchronous close - treat like VF_RELEASED*/ -@@ -191,7 +200,6 @@ - struct atm_dev *dev; /* device back pointer */ - struct atm_qos qos; /* QOS */ - struct atm_sap sap; /* SAP */ -- unsigned long tx_quota,rx_quota; /* buffer quotas */ - atomic_t tx_inuse,rx_inuse; /* buffer space in use */ - void (*push)(struct atm_vcc *vcc,struct sk_buff *skb); - void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */ -@@ -207,6 +215,7 @@ - struct atm_aal_stats *stats; /* pointer to AAL stats group */ - wait_queue_head_t sleep; /* if socket is busy */ - wait_queue_head_t wsleep; /* if waiting for write buffer space */ -+ struct sock *sk; /* socket backpointer */ - struct atm_vcc *prev,*next; - /* SVC part --- may move later ------------------------------------- */ - short itf; /* interface number */ -@@ -220,7 +229,9 @@ - /* Multipoint part ------------------------------------------------- */ - struct atm_vcc *session; /* session VCC descriptor */ - /* Other stuff ----------------------------------------------------- */ -- void *user_back; /* user backlink - not touched */ -+ void *user_back; /* user backlink - not touched by */ -+ /* native ATM stack. Currently used */ -+ /* by CLIP and sch_atm. */ - }; +@@ -511,10 +510,8 @@ -@@ -335,6 +346,12 @@ - static __inline__ void atm_return(struct atm_vcc *vcc,int truesize) - { - atomic_sub(truesize+ATM_PDU_OVHD,&vcc->rx_inuse); -+} -+ -+ -+static __inline__ int atm_may_send(struct atm_vcc *vcc,unsigned int size) -+{ -+ return size+atomic_read(&vcc->tx_inuse)+ATM_PDU_OVHD < vcc->sk->sndbuf; + chunk->align_addr = chunk->alloc_addr; + #else +- if (fore200e_chunk_alloc(fore200e, chunk, size * nbr, alignment) < 0) ++ if (fore200e_chunk_alloc(fore200e, chunk, size * nbr, alignment, FORE200E_DMA_BIDIRECTIONAL) < 0) + return -ENOMEM; +- +- chunk->dma_addr = fore200e_pca_dma_map(fore200e, chunk->align_addr, chunk->align_size); + #endif + + return 0; +@@ -532,8 +529,6 @@ + chunk->alloc_addr, + chunk->dma_addr); + #else +- fore200e_pca_dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size); +- + fore200e_chunk_free(fore200e, chunk); + #endif } +@@ -685,7 +680,7 @@ + opcode.opcode = OPCODE_GET_PROM; + opcode.pad = 0; +- prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data)); ++ prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE); ---- ref/include/linux/atmioc.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmioc.h Wed Feb 2 20:33:05 2000 -@@ -1,10 +1,10 @@ - /* atmioc.h - ranges for ATM-related ioctl numbers */ - --/* Written 1995-1998 by Werner Almesberger, EPFL LRC */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ + fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr); + +@@ -697,7 +692,7 @@ + *entry->status = STATUS_FREE; - /* -- * See http://lrcwww.epfl.ch/linux-atm/magic.html for the complete list of -+ * See http://icawww1.epfl.ch/linux-atm/magic.html for the complete list of - * "magic" ioctl numbers. - */ +- fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data)); ++ fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE); ---- ref/include/linux/atmlec.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmlec.h Wed Feb 2 20:47:25 2000 -@@ -9,6 +9,7 @@ - #ifndef _ATMLEC_H_ - #define _ATMLEC_H_ + if (ok == 0) { + printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name); +@@ -748,31 +743,32 @@ -+#include - #include - #include - #include -@@ -43,15 +44,16 @@ - - struct atmlec_config_msg { - unsigned int maximum_unknown_frame_count; -- unsigned long max_unknown_frame_time; -+ unsigned int max_unknown_frame_time; - unsigned short max_retry_count; -- unsigned long aging_time; -- unsigned long forward_delay_time; -- unsigned long arp_response_time; -- unsigned long flush_timeout; -- unsigned long path_switching_delay; -+ unsigned int aging_time; -+ unsigned int forward_delay_time; -+ unsigned int arp_response_time; -+ unsigned int flush_timeout; -+ unsigned int path_switching_delay; - unsigned int lane_version; /* LANE2: 1 for LANEv1, 2 for LANEv2 */ - int mtu; -+ int is_proxy; - }; - - struct atmlec_msg { -@@ -61,7 +63,7 @@ - struct { - unsigned char mac_addr[ETH_ALEN]; - unsigned char atm_addr[ATM_ESA_LEN]; -- unsigned long flag;/* Topology_change flag, -+ unsigned int flag;/* Topology_change flag, - remoteflag, permanent flag, - lecid, transaction id */ - unsigned int targetless_le_arp; /* LANE2 */ -@@ -73,9 +75,10 @@ - uint32_t tran_id; /* transaction id */ - unsigned char mac_addr[ETH_ALEN]; /* dst mac addr */ - unsigned char atm_addr[ATM_ESA_LEN]; /* reqestor ATM addr */ -- } proxy; /* For mapping LE_ARP requests to responses. Filled by */ -+ } proxy; -+ /* For mapping LE_ARP requests to responses. Filled by */ - } content; /* zeppelin, returned by kernel. Used only when proxying */ --}; -+} __ATM_API_ALIGN; - - struct atmlec_ioc { - int dev_num; ---- ref/include/linux/atmmpc.h Mon Aug 23 18:56:31 1999 -+++ work/include/linux/atmmpc.h Wed Feb 2 20:47:25 2000 -@@ -1,6 +1,7 @@ - #ifndef _ATMMPC_H_ - #define _ATMMPC_H_ -+#include - #include - #include + static u32 +-fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size) ++fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction) + { +- u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size); ++ u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size, direction); -@@ -37,16 +38,16 @@ - uint16_t holding_time; - } eg_ctrl_info; - --struct mpc_parameters{ -+struct mpc_parameters { - uint16_t mpc_p1; /* Shortcut-Setup Frame Count */ - uint16_t mpc_p2; /* Shortcut-Setup Frame Time */ - uint8_t mpc_p3[8]; /* Flow-detection Protocols */ - uint16_t mpc_p4; /* MPC Initial Retry Time */ - uint16_t mpc_p5; /* MPC Retry Time Maximum */ - uint16_t mpc_p6; /* Hold Down Time */ --}; -+} ; - --struct k_message{ -+struct k_message { - uint16_t type; - uint32_t ip_mask; - uint8_t MPS_ctrl[ATM_ESA_LEN]; -@@ -56,9 +57,10 @@ - struct mpc_parameters params; - } content; - struct atm_qos qos; --}; -+} __ATM_API_ALIGN; - --struct llc_snap_hdr { /* RFC 1483 LLC/SNAP encapsulation for routed IP PDUs */ -+struct llc_snap_hdr { -+ /* RFC 1483 LLC/SNAP encapsulation for routed IP PDUs */ - uint8_t dsap; /* Destination Service Access Point (0xAA) */ - uint8_t ssap; /* Source Service Access Point (0xAA) */ - uint8_t ui; /* Unnumbered Information (0x03) */ -@@ -121,4 +123,3 @@ - #define RELOAD 301 /* kill -HUP the daemon for reload */ +- DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d --> dma_addr = 0x%08x\n", virt_addr, size, dma_addr); ++ DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n", ++ virt_addr, size, direction, dma_addr); + + return dma_addr; + } - #endif /* _ATMMPC_H_ */ -- ---- ref/include/linux/atmsap.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/atmsap.h Wed Feb 2 20:33:05 2000 -@@ -1,11 +1,13 @@ - /* atmsap.h - ATM Service Access Point addressing definitions */ --/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ + static void +-fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size) ++fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) + { +- DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d\n", dma_addr, size); ++ DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", dma_addr, size, direction); +- sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); ++ sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); + } - #ifndef _LINUX_ATMSAP_H - #define _LINUX_ATMSAP_H -+#include -+ - /* - * BEGIN_xx and END_xx markers are used for automatic generation of - * documentation. Do not change them. -@@ -116,24 +118,22 @@ - unsigned char def_size; /* default packet size (log2), 4-12 (0 to */ - /* omit) */ - unsigned char window;/* packet window size, 1-127 (0 to omit) */ -- } itu; /* ITU-T ecoding */ -+ } itu; /* ITU-T encoding */ - unsigned char user; /* user specified l3 information */ -- struct { /* if l3_proto = ATM_L3_H310 */ -- unsigned char term_type; /* terminal type */ -+ struct { /* if l3_proto = ATM_L3_H310 */ -+ unsigned char term_type; /* terminal type */ - unsigned char fw_mpx_cap; /* forward multiplexing capability */ - /* only if term_type != ATM_TT_NONE */ - unsigned char bw_mpx_cap; /* backward multiplexing capability */ - /* only if term_type != ATM_TT_NONE */ - } h310; -- struct { /* if l3_proto = ATM_L3_TR9577 */ -- unsigned char ipi; /* initial protocol id */ -+ struct { /* if l3_proto = ATM_L3_TR9577 */ -+ unsigned char ipi; /* initial protocol id */ - unsigned char snap[5];/* IEEE 802.1 SNAP identifier */ - /* (only if ipi == NLPID_IEEE802_1_SNAP) */ - } tr9577; - } l3; -- struct atm_blli *next; /* next BLLI or NULL (undefined when used in */ -- /* atmsvc_msg) ONLY USED IN OLD-STYLE API */ --}; -+} __ATM_API_ALIGN; - - - struct atm_bhli { -@@ -149,7 +149,8 @@ - - struct atm_sap { - struct atm_bhli bhli; /* local SAP, high-layer information */ -- struct atm_blli blli[ATM_MAX_BLLI]; /* local SAP, low-layer info */ -+ struct atm_blli blli[ATM_MAX_BLLI] __ATM_API_ALIGN; -+ /* local SAP, low-layer info */ - }; + static void +-fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size) ++fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int direction) + { +- DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d\n", dma_addr, size); ++ DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); + +- sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size); ++ sbus_dma_sync_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); + } ---- ref/include/linux/atmsvc.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/atmsvc.h Wed Feb 2 20:47:25 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 */ - +@@ -1002,7 +998,8 @@ + kfree(entry->data); - #ifndef _LINUX_ATMSVC_H - #define _LINUX_ATMSVC_H + /* remove DMA mapping */ +- fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); ++ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, ++ FORE200E_DMA_TODEVICE); -+#include - #include - #include + /* notify tx completion */ + if (entry->vcc->pop) +@@ -1146,7 +1143,7 @@ + buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle); + + /* ensure DMA synchronisation */ +- fore200e->bus->dma_sync(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length); ++ fore200e->bus->dma_sync(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE); + + memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length); + } +@@ -1556,7 +1553,10 @@ + + printk(FORE200E "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n", + fore200e->name, fore200e->cp_queues->heartbeat); +- ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); + return -EIO; + } + } +@@ -1584,6 +1584,10 @@ + if (entry->data == NULL) { + + spin_unlock_irqrestore(&fore200e->tx_lock, flags); ++ if (vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ dev_kfree_skb(skb); + return -ENOMEM; + } -@@ -19,8 +20,8 @@ +@@ -1591,11 +1595,11 @@ + if (skb_len < tx_len) + memset(entry->data + skb_len, 0x00, tx_len - skb_len); + +- tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, entry->data, tx_len); ++ tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, entry->data, tx_len, FORE200E_DMA_TODEVICE); + } + else { + entry->data = NULL; +- tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, skb_data, tx_len); ++ tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, skb_data, tx_len, FORE200E_DMA_TODEVICE); + } + + tpd->tsd[ 0 ].length = tx_len; +@@ -1606,7 +1610,7 @@ + spin_unlock_irqrestore(&fore200e->tx_lock, flags); + + /* ensure DMA synchronisation */ +- fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length); ++ fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE); + + DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", + vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), +@@ -1661,8 +1665,19 @@ + { + int ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 10); + +- fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length); ++ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, ++ FORE200E_DMA_TODEVICE); + ++ /* 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); ++ + if (ok == 0) { + printk(FORE200E "synchronous tx on %d:%d:%d failed\n", vcc->itf, vcc->vpi, vcc->vci); - struct atmsvc_msg { - enum atmsvc_msg_type type; -- unsigned long vcc; -- unsigned long 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,12 +32,12 @@ - struct sockaddr_atmsvc local; /* local SVC address */ - struct atm_qos qos; /* QOS parameters */ - struct atm_sap sap; /* SAP */ -- unsigned long session; /* for p2pm */ -+ unsigned int session; /* for p2pm */ - struct sockaddr_atmsvc svc; /* SVC address */ --}; -+} __ATM_API_ALIGN; +@@ -1673,15 +1688,6 @@ - /* -- * 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 - */ + DPRINTK(3, "synchronous tx on %d:%d:%d succeeded\n", vcc->itf, vcc->vpi, vcc->vci); - /* ---- ref/include/linux/sonet.h Mon Aug 23 18:56:32 1999 -+++ work/include/linux/sonet.h Wed Feb 2 20:33:05 2000 -@@ -1,22 +1,22 @@ - /* sonet.h - SONET/SHD physical layer control */ - --/* Written 1995 by Werner Almesberger, EPFL LRC */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ - +- /* 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 - #ifndef LINUX_SONET_H - #define LINUX_SONET_H +@@ -1704,7 +1710,7 @@ + return -ENOMEM; + } + +- stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats, sizeof(struct stats)); ++ stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats, sizeof(struct stats), FORE200E_DMA_FROMDEVICE); + + FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); + +@@ -1721,7 +1727,7 @@ + + *entry->status = STATUS_FREE; + +- fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats)); ++ fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), FORE200E_DMA_FROMDEVICE); + + if (ok == 0) { + printk(FORE200E "unable to get statistics from device %s\n", fore200e->name); +@@ -1766,7 +1772,7 @@ + int ok; + u32 oc3_regs_dma_addr; + +- oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs)); ++ oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE); + + FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD); + +@@ -1785,7 +1791,7 @@ + + *entry->status = STATUS_FREE; + +- fore200e->bus_dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs)); ++ fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE); + + if (ok == 0) { + printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name); +@@ -1842,16 +1848,16 @@ + + switch (loop_mode) { + +- case SUNI_LM_NONE: ++ case ATM_LM_NONE: + mct_value = 0; + mct_mask = SUNI_MCT_DLE | SUNI_MCT_LLE; + break; + +- case SUNI_LM_DIAG: ++ case ATM_LM_LOC_PHY: + mct_value = mct_mask = SUNI_MCT_DLE; + break; + +- case SUNI_LM_LOOP: ++ case ATM_LM_RMT_PHY: + mct_value = mct_mask = SUNI_MCT_LLE; + break; + +@@ -1921,11 +1927,11 @@ + + case SONET_GETDIAG: + return put_user(0, (int*)arg) ? -EFAULT : 0; +- +- case SUNI_SETLOOP: ++ ++ case ATM_SETLOOP: + return fore200e_setloop(fore200e, (int)(unsigned long)arg); + +- case SUNI_GETLOOP: ++ case ATM_GETLOOP: + return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0; + } + +@@ -2051,7 +2057,8 @@ + + /* allocate the receive buffer body */ + if (fore200e_chunk_alloc(fore200e, +- &buffer[ i ].data, size, fore200e->bus->buffer_alignment) < 0) { ++ &buffer[ i ].data, size, fore200e->bus->buffer_alignment, ++ FORE200E_DMA_FROMDEVICE) < 0) { + + while (i > 0) + fore200e_chunk_free(fore200e, &buffer[ --i ].data); +@@ -2690,17 +2697,29 @@ + static const char* oc3_mode[] = { + "normal operation", + "diagnostic loopback", +- "line loopback" ++ "line loopback", ++ "unknown" + }; - struct sonet_stats { -- long section_bip; /* section parity errors (B1) */ -- long line_bip; /* line parity errors (B2) */ -- long path_bip; /* path parity errors (B3) */ -- long line_febe; /* line parity errors at remote */ -- long path_febe; /* path parity errors at remote */ -- long corr_hcs; /* correctable header errors */ -- long uncorr_hcs; /* uncorrectable header errors */ -- long tx_cells; /* cells sent */ -- long rx_cells; /* cells received */ --}; -+ int section_bip; /* section parity errors (B1) */ -+ int line_bip; /* line parity errors (B2) */ -+ int path_bip; /* path parity errors (B3) */ -+ int line_febe; /* line parity errors at remote */ -+ int path_febe; /* path parity errors at remote */ -+ int corr_hcs; /* correctable header errors */ -+ int uncorr_hcs; /* uncorrectable header errors */ -+ int tx_cells; /* cells sent */ -+ int rx_cells; /* cells received */ -+} __attribute__ ((packed)); - - #define SONET_GETSTAT _IOR('a',ATMIOC_PHYTYP,struct sonet_stats) - /* get statistics */ ---- ref/include/net/atmclip.h Tue Feb 1 02:14:43 2000 -+++ work/include/net/atmclip.h Wed Feb 2 20:46:30 2000 -@@ -1,6 +1,6 @@ - /* net/atm/atmarp.h - RFC1577 ATM ARP */ - --/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */ -+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ - - - #ifndef _ATMCLIP_H -@@ -26,7 +26,9 @@ - unsigned long last_use; /* last send or receive operation */ - unsigned long idle_timeout; /* keep open idle for so many jiffies*/ - void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); -- /* keep old push fn for detaching */ -+ /* keep old push fn for chaining */ -+ void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); -+ /* keep old pop fn for chaining */ - struct clip_vcc *next; /* next VCC */ - }; + 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)); ++ u32 oc3_index; + + if (media_index < 0 || media_index > 4) + media_index = 5; + ++ switch(fore200e->loop_mode) { ++ case ATM_LM_NONE: oc3_index = 0; ++ break; ++ case ATM_LM_LOC_PHY: oc3_index = 1; ++ break; ++ case ATM_LM_RMT_PHY: oc3_index = 2; ++ break; ++ default: oc3_index = 3; ++ } ++ + return sprintf(page, + " firmware release:\t\t%d.%d.%d\n" + " monitor release:\t\t%d.%d\n" +@@ -2711,7 +2730,7 @@ + mon960_release >> 16, mon960_release << 16 >> 16, + media_name[ media_index ], + oc3_revision, +- oc3_mode[ fore200e->loop_mode ]); ++ oc3_mode[ oc3_index ]); + } + + if (!left--) { +--- ref/drivers/atm/fore200e.h Tue Feb 22 01:32:27 2000 ++++ work/drivers/atm/fore200e.h Mon Feb 28 22:25:18 2000 +@@ -559,6 +559,7 @@ + void* alloc_addr; /* base address of allocated chunk */ + void* align_addr; /* base address of aligned chunk */ + u32 dma_addr; /* DMA address of aligned chunk */ ++ int direction; /* direction of DMA mapping */ + u32 alloc_size; /* length of allocated chunk */ + u32 align_size; /* length of aligned chunk */ + } chunk_t; +@@ -796,9 +797,9 @@ + const unsigned int* fw_size; /* address of firmware data size */ + u32 (*read)(volatile u32*); + void (*write)(u32, volatile u32*); +- u32 (*dma_map)(struct fore200e*, void*, int); +- void (*dma_unmap)(struct fore200e*, u32, int); +- void (*dma_sync)(struct fore200e*, u32, int); ++ u32 (*dma_map)(struct fore200e*, void*, int, int); ++ void (*dma_unmap)(struct fore200e*, u32, int, int); ++ void (*dma_sync)(struct fore200e*, u32, int, int); + int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int); + void (*dma_chunk_free)(struct fore200e*, struct chunk*); + struct fore200e* (*detect)(const struct fore200e_bus*, int); +@@ -812,6 +813,31 @@ + void (*irq_ack)(struct fore200e*); + int (*proc_read)(struct fore200e*, char*); + } fore200e_bus_t; ++ ++ ++#if defined(CONFIG_ATM_FORE200E_SBA) ++# if defined(CONFIG_ATM_FORE200E_PCA) ++# if (PCI_DMA_BIDIRECTIONAL == SBUS_DMA_BIDIRECTIONAL) && \ ++ (PCI_DMA_TODEVICE == SBUS_DMA_TODEVICE) && \ ++ (PCI_DMA_FROMDEVICE == SBUS_DMA_FROMDEVICE) ++# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL ++# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE ++# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE ++# else ++ /* in that case, we'll need to add an extra indirection, e.g. ++ fore200e->bus->dma_direction[ fore200e_dma_direction ] */ ++# error PCI and SBUS DMA direction flags differ! ++# endif ++# else ++# define FORE200E_DMA_BIDIRECTIONAL SBA_DMA_BIDIRECTIONAL ++# define FORE200E_DMA_TODEVICE SBA_DMA_TODEVICE ++# define FORE200E_DMA_FROMDEVICE SBA_DMA_FROMDEVICE ++# endif ++#else ++# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL ++# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE ++# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE ++#endif ---- ref/net/sched/sch_atm.c Wed Sep 8 20:14:32 1999 -+++ work/net/sched/sch_atm.c Wed Feb 2 20:33:05 2000 -@@ -1,6 +1,6 @@ - /* net/sched/sch_atm.c - ATM VC selection "queueing discipline" */ --/* Written 1998,1999 by Werner Almesberger, EPFL ICA */ -+/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ + /* per-device data */ +--- ref/drivers/atm/horizon.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/horizon.c Mon Feb 28 20:54:26 2000 +@@ -813,7 +813,7 @@ + if (ATM_SKB(skb)->vcc->pop) { + ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb); + } else { +- dev_kfree_skb (skb); ++ dev_kfree_skb_any (skb); + } + } +@@ -1662,6 +1662,7 @@ + + if (!channel) { + PRINTD (DBG_ERR|DBG_TX, "attempt to transmit on zero (rx_)channel"); ++ hrz_kfree_skb (skb); + return -EIO; + } + +@@ -1699,9 +1700,11 @@ + #endif + + // wait until TX is free and grab lock +- if (tx_hold (dev)) ++ if (tx_hold (dev)) { ++ hrz_kfree_skb (skb); + return -ERESTARTSYS; +- ++ } ++ + // Wait for enough space to be available in transmit buffer memory. + + // should be number of cells needed + 2 (according to hardware docs) +@@ -1722,6 +1725,7 @@ + PRINTD (DBG_TX|DBG_ERR, "spun out waiting for tx buffers, got %d of %d", + free_buffers, buffers_required); + tx_release (dev); ++ hrz_kfree_skb (skb); + return -ERESTARTSYS; + } + } +--- ref/drivers/atm/idt77105.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/idt77105.c Mon Feb 28 21:59:48 2000 +@@ -157,34 +157,49 @@ + } - #include -@@ -56,12 +56,14 @@ ++static int set_loopback(struct atm_dev *dev,int mode) ++{ ++ int diag; ++ ++ diag = GET(DIAG) & ~IDT77105_DIAG_LCMASK; ++ switch (mode) { ++ case ATM_LM_NONE: ++ break; ++ case ATM_LM_LOC_ATM: ++ diag |= IDT77105_DIAG_LC_PHY_LOOPBACK; ++ break; ++ case ATM_LM_RMT_ATM: ++ diag |= IDT77105_DIAG_LC_LINE_LOOPBACK; ++ break; ++ default: ++ return -EINVAL; ++ } ++ PUT(diag,DIAG); ++ printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", dev->type, ++ dev->number, ++ (mode == ATM_LM_NONE ? "NONE" : ++ (mode == ATM_LM_LOC_ATM ? "DIAG (local)" : ++ (mode == IDT77105_DIAG_LC_LINE_LOOPBACK ? "LOOP (remote)" : ++ "unknown"))) ++ ); ++ PRIV(dev)->loop_mode = mode; ++ return 0; ++} ++ - #define PRIV(sch) ((struct atm_qdisc_data *) (sch)->data) -+#define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back)) + static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) + { + printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number); + switch (cmd) { + case IDT77105_GETSTATZ: ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ /* fall through */ + case IDT77105_GETSTAT: + return fetch_stats(dev,(struct idt77105_stats *) arg, + cmd == IDT77105_GETSTATZ); +- case IDT77105_SETLOOP: +- if (!capable(CAP_NET_ADMIN)) return -EPERM; +- if ((int) arg < 0 || (int) arg > IDT77105_LM_LOOP) +- return -EINVAL; +- PUT((GET(DIAG) & ~IDT77105_DIAG_LCMASK) | +- ((int) arg == IDT77105_LM_NONE ? IDT77105_DIAG_LC_NORMAL : 0) | +- ((int) arg == IDT77105_LM_DIAG ? IDT77105_DIAG_LC_PHY_LOOPBACK : 0) | +- ((int) arg == IDT77105_LM_LOOP ? IDT77105_DIAG_LC_LINE_LOOPBACK : 0), +- DIAG); +- printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", +- dev->type, dev->number, +- ((int) arg == IDT77105_LM_NONE ? "NONE" : +- ((int) arg == IDT77105_LM_DIAG ? "DIAG (local)" : +- ((int) arg == IDT77105_LM_LOOP ? "LOOP (remote)" : +- "unknown"))) +- ); +- PRIV(dev)->loop_mode = (int) arg; +- return 0; +- case IDT77105_GETLOOP: ++ case ATM_SETLOOP: ++ return set_loopback(dev,(int) (long) arg); ++ case ATM_GETLOOP: + return put_user(PRIV(dev)->loop_mode,(int *) arg) ? + -EFAULT : sizeof(int); + default: +@@ -266,13 +281,13 @@ + /* initialise loop mode from hardware */ + switch ( GET(DIAG) & IDT77105_DIAG_LCMASK ) { + case IDT77105_DIAG_LC_NORMAL: +- PRIV(dev)->loop_mode = IDT77105_LM_NONE; ++ PRIV(dev)->loop_mode = ATM_LM_NONE; + break; + case IDT77105_DIAG_LC_PHY_LOOPBACK: +- PRIV(dev)->loop_mode = IDT77105_LM_DIAG; ++ PRIV(dev)->loop_mode = ATM_LM_LOC_ATM; + break; + case IDT77105_DIAG_LC_LINE_LOOPBACK: +- PRIV(dev)->loop_mode = IDT77105_LM_LOOP; ++ PRIV(dev)->loop_mode = ATM_LM_RMT_ATM; + break; + } + +--- ref/drivers/atm/iphase.c Tue Feb 22 01:32:27 2000 ++++ work/drivers/atm/iphase.c Mon Feb 28 20:54:26 2000 +@@ -625,12 +625,12 @@ + 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); ++ dev_kfree_skb_any(skb); + printk("ia_que_tx: Null vcc\n"); + break; + } + if ((vcc->flags & ATM_VF_READY) == 0 ) { +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + printk("Free the SKB on closed vci %d \n", vcc->vci); + break; + } +@@ -658,14 +658,14 @@ + vcc = ATM_SKB(skb)->vcc; + if (!vcc) { + printk("ia_tx_poll: vcc is null\n"); +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return; + } + + iavcc = INPH_IA_VCC(vcc); + if (!iavcc) { + printk("ia_tx_poll: iavcc is null\n"); +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return; + } + +@@ -682,7 +682,7 @@ + (long)skb1);) + } + else +- dev_kfree_skb(skb1); ++ dev_kfree_skb_any(skb1); + skb1 = skb_dequeue(&iavcc->txing_skb); + } + if (!skb1) { +@@ -696,7 +696,7 @@ + IF_EVENT(printk("Tx Done - skb 0x%lx return\n",(long)skb);) + } + else +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + kfree(rtne); + } + ia_que_tx(iadev); +@@ -1297,7 +1297,7 @@ + if (!skb->len) + { + printk("rx_dle_intr: skb len 0\n"); +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + } + else + { +@@ -1309,14 +1309,14 @@ + if (!vcc) { + printk("IA: null vcc\n"); + vcc->stats->rx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + goto INCR_DLE; + } + ia_vcc = INPH_IA_VCC(vcc); + if (ia_vcc == NULL) + { + vcc->stats->rx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + #if LINUX_VERSION_CODE >= 0x20312 + atm_return(vcc, atm_guess_pdu2truesize(skb->len)); + #else +@@ -1332,7 +1332,7 @@ + (skb->len - sizeof(struct cpcs_trailer)))) + { + vcc->stats->rx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)", + length, skb->len);) + #if LINUX_VERSION_CODE >= 0x20312 +@@ -1710,13 +1710,13 @@ + vcc = ATM_SKB(skb)->vcc; + if (!vcc) { + printk("tx_dle_intr: vcc is null\n"); +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return; + } + iavcc = INPH_IA_VCC(vcc); + if (!iavcc) { + printk("tx_dle_intr: iavcc is null\n"); +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return; + } + if (vcc->qos.txtp.pcr >= iadev->rate_limit) { +@@ -1725,7 +1725,7 @@ + vcc->pop(vcc, skb); + } + else { +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + } + } + else { /* Hold the rate-limited skb for flow control */ +@@ -2611,7 +2611,7 @@ + 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 dev_kfree_skb_any(skb); + } + else + skb_queue_tail(&tmp_tx_backlog, skb); +@@ -2749,7 +2749,7 @@ + + static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg) + { +- PIA_CMDBUF ia_cmds; ++ IA_CMDBUF ia_cmds; + IADEV *iadev; + int i, board; + u16 *tmps; +@@ -2757,34 +2757,37 @@ + 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 (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; ++ board = ia_cmds.status; + if ((board < 0) || (board > iadev_count)) + board = 0; + iadev = ia_dev[board]; +- switch (ia_cmds->cmd) { ++ switch (ia_cmds.cmd) { + case MEMDUMP: + { +- switch (ia_cmds->sub_cmd) { ++ switch (ia_cmds.sub_cmd) { + case MEMDUMP_DEV: +- memcpy((char*)ia_cmds->buf, (char*)iadev, +- sizeof(IADEV)); +- ia_cmds->status = 0; ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ if (copy_to_user(ia_cmds.buf, iadev, sizeof(IADEV))) ++ return -EFAULT; ++ ia_cmds.status = 0; + break; + case MEMDUMP_SEGREG: +- tmps = (u16 *)ia_cmds->buf; ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ 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; ++ if(put_user(*(u16*)(iadev->seg_reg+i), tmps)) return -EFAULT; ++ ia_cmds.status = 0; ++ ia_cmds.len = 0x80; + break; + case MEMDUMP_REASSREG: +- tmps = (u16 *)ia_cmds->buf; ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ 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; ++ if(put_user(*(u16*)(iadev->reass_reg+i), tmps)) return -EFAULT; ++ ia_cmds.status = 0; ++ ia_cmds.len = 0x80; + break; + case MEMDUMP_FFL: + { +@@ -2792,6 +2795,7 @@ + ffredn_t *ffL = ®s_local.ffredn; + rfredn_t *rfL = ®s_local.rfredn; + ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + /* 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; +@@ -2799,20 +2803,22 @@ + 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)); ++ if (copy_to_user(ia_cmds.buf, ®s_local,sizeof(ia_regs_t))) ++ return -EFAULT; + printk("Board %d registers dumped\n", board); +- ia_cmds->status = 0; ++ ia_cmds.status = 0; + } + break; + case READ_REG: + { ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + desc_dbg(iadev); +- ia_cmds->status = 0; ++ ia_cmds.status = 0; + } + break; + case 0x6: + { +- ia_cmds->status = 0; ++ 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)); + } +@@ -2831,31 +2837,33 @@ + printk("tx_cells : %d\n", stats->tx_cells); + printk("rx_cells : %d\n", stats->rx_cells); + } +- ia_cmds->status = 0; ++ ia_cmds.status = 0; + break; + case 0x9: ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + 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; ++ ia_cmds.status = 0; + break; + + case 0xb: ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + IaFrontEndIntr(iadev); + break; + case 0xa: ++ if (!capable(CAP_NET_ADMIN)) return -EPERM; + { +- ia_cmds->status = 0; +- IADebugFlag = ia_cmds->maddr; ++ 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; ++ ia_cmds.status = 0; + break; + } + } +@@ -2896,7 +2904,7 @@ + if (!iavcc->txing) { + printk("discard packet on closed VC\n"); + if (vcc->pop) vcc->pop(vcc, skb); +- else dev_kfree_skb(skb); ++ else dev_kfree_skb_any(skb); + } - struct atm_flow_data { - struct Qdisc *q; /* FIFO, TBF, etc. */ - struct tcf_proto *filter_list; - struct atm_vcc *vcc; /* VCC; NULL if VCC is closed */ -+ void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* chaining */ - struct socket *sock; /* for closing */ - u32 classid; /* x:y type ID */ - int ref; /* reference count */ -@@ -133,7 +135,7 @@ + if (skb->len > iadev->tx_buf_sz - 8) { +@@ -2904,7 +2912,7 @@ + if (vcc->pop) + vcc->pop(vcc, skb); + else +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return 0; + } + if ((u32)skb->data & 3) { +@@ -2912,7 +2920,7 @@ + if (vcc->pop) + vcc->pop(vcc, skb); + else +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return 0; + } + /* Get a descriptor number from our free descriptor queue +@@ -2933,7 +2941,7 @@ + if (vcc->pop) + vcc->pop(vcc, skb); + else +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return 0; /* return SUCCESS */ + } + +@@ -3074,12 +3082,12 @@ + { + if (!skb) + printk(KERN_CRIT "null skb in ia_send\n"); +- else dev_kfree_skb(skb); ++ else dev_kfree_skb_any(skb); + return -EINVAL; + } + spin_lock_irqsave(&iadev->tx_lock, flags); + if ((vcc->flags & ATM_VF_READY) == 0){ +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&iadev->tx_lock, flags); + return -EINVAL; + } +--- ref/drivers/atm/nicstar.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/nicstar.c Mon Feb 28 20:54:26 2000 +@@ -284,7 +284,7 @@ + card = cards[i]; - static unsigned long atm_tc_get(struct Qdisc *sch,u32 classid) - { -- struct atm_qdisc_data *p = PRIV(sch); -+ struct atm_qdisc_data *p __attribute__((unused)) = PRIV(sch); - struct atm_flow_data *flow; + #ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 +- if (card->max_pcr == IDT_25_PCR) { ++ if (card->max_pcr == ATM_25_PCR) { + idt77105_stop(card->atmdev); + } + #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ +@@ -311,7 +311,7 @@ + PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); + while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) + { +- kfree_skb(hb); ++ dev_kfree_skb_any(hb); + j++; + } + PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); +@@ -319,14 +319,14 @@ + PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); + while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) + { +- kfree_skb(iovb); ++ dev_kfree_skb_any(iovb); + j++; + } + PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); + while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) +- kfree_skb(lb); ++ dev_kfree_skb_any(lb); + while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) +- kfree_skb(sb); ++ dev_kfree_skb_any(sb); + free_scq(card->scq0, NULL); + for (j = 0; j < NS_FRSCD_NUM; j++) + { +@@ -547,7 +547,7 @@ + switch(data) { + case 0x00000009: + printk("nicstar%d: PHY seems to be 25 Mbps.\n", i); +- card->max_pcr = IDT_25_PCR; ++ card->max_pcr = ATM_25_PCR; + while(CMD_BUSY(card)); + writel(0x00000008, card->membase + DR0); + writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD); +@@ -891,7 +891,7 @@ + #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ - DPRINTK("atm_tc_get(sch %p,[qdisc %p],classid %x)\n",sch,p,classid); -@@ -184,6 +186,7 @@ - } - if (flow->sock) { - DPRINTK("atm_tc_put: f_count %d\n",file_count(flow->sock->file)); -+ flow->vcc->pop = flow->old_pop; - sockfd_put(flow->sock); - } - if (flow->excess) atm_tc_put(sch,(unsigned long) flow->excess); -@@ -195,6 +198,13 @@ + #ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 +- if (card->max_pcr == IDT_25_PCR) { ++ if (card->max_pcr == ATM_25_PCR) { + idt77105_init(card->atmdev); + /* Note that for the IDT77105 PHY we don't need the awful + * module count hack that the SUNI needs because we can +@@ -936,26 +936,26 @@ + { + struct sk_buff *iovb; + while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) +- kfree_skb(iovb); ++ dev_kfree_skb_any(iovb); + } + if (error >= 15) + { + struct sk_buff *sb; + while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) +- kfree_skb(sb); ++ dev_kfree_skb_any(sb); + free_scq(card->scq0, NULL); + } + if (error >= 14) + { + struct sk_buff *lb; + while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) +- kfree_skb(lb); ++ dev_kfree_skb_any(lb); + } + if (error >= 13) + { + struct sk_buff *hb; + while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) +- kfree_skb(hb); ++ dev_kfree_skb_any(hb); + } + if (error >= 12) + { +@@ -1039,7 +1039,7 @@ + if (vcc->pop != NULL) + vcc->pop(vcc, scq->skb[i]); + else +- dev_kfree_skb(scq->skb[i]); ++ dev_kfree_skb_any(scq->skb[i]); + } + } + else /* vcc must be != NULL */ +@@ -1048,7 +1048,7 @@ + { + printk("nicstar: free_scq() called with vcc == NULL for fixed rate scq."); + for (i = 0; i < scq->num_entries; i++) +- dev_kfree_skb(scq->skb[i]); ++ dev_kfree_skb_any(scq->skb[i]); + } + else + for (i = 0; i < scq->num_entries; i++) +@@ -1058,7 +1058,7 @@ + if (vcc->pop != NULL) + vcc->pop(vcc, scq->skb[i]); + else +- dev_kfree_skb(scq->skb[i]); ++ dev_kfree_skb_any(scq->skb[i]); + } + } + } +@@ -1130,9 +1130,9 @@ + if (card->sbfqc >= card->sbnr.max) + { + skb_unlink((struct sk_buff *) handle1); +- kfree_skb((struct sk_buff *) handle1); ++ dev_kfree_skb_any((struct sk_buff *) handle1); + skb_unlink((struct sk_buff *) handle2); +- kfree_skb((struct sk_buff *) handle2); ++ dev_kfree_skb_any((struct sk_buff *) handle2); + return; + } + else +@@ -1143,9 +1143,9 @@ + if (card->lbfqc >= card->lbnr.max) + { + skb_unlink((struct sk_buff *) handle1); +- kfree_skb((struct sk_buff *) handle1); ++ dev_kfree_skb_any((struct sk_buff *) handle1); + skb_unlink((struct sk_buff *) handle2); +- kfree_skb((struct sk_buff *) handle2); ++ dev_kfree_skb_any((struct sk_buff *) handle2); + return; + } + else +@@ -1779,7 +1779,7 @@ + { + printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", card->index); + vcc->stats->tx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return -EINVAL; + } + +@@ -1787,7 +1787,7 @@ + { + printk("nicstar%d: Trying to transmit on a non-tx VC.\n", card->index); + vcc->stats->tx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return -EINVAL; + } + +@@ -1795,7 +1795,7 @@ + { + printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", card->index); + vcc->stats->tx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return -EINVAL; + } + +@@ -1803,7 +1803,7 @@ + { + printk("nicstar%d: No scatter-gather yet.\n", card->index); + vcc->stats->tx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return -EINVAL; + } + +@@ -1848,7 +1848,7 @@ + if (push_scqe(card, vc, scq, &scqe, skb) != 0) + { + vcc->stats->tx_err++; +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + return -EIO; + } + vcc->stats->tx++; +@@ -2071,7 +2071,7 @@ + if (vcc->pop != NULL) + vcc->pop(vcc, skb); + else +- dev_kfree_skb(skb); ++ dev_kfree_skb_any(skb); + scq->skb[i] = NULL; + } + if (++i == scq->num_entries) +@@ -2163,7 +2163,7 @@ + RXPRINTK("nicstar%d: atm_charge() dropped aal0 packets.\n", + card->index); + vcc->stats->rx_drop += i - 1; /* already increased by 1 */ +- kfree_skb(sb); ++ dev_kfree_skb_any(sb); + break; + } + /* Rebuild the header */ +@@ -2431,7 +2431,7 @@ + card->hbpool.count++; + } + else +- kfree_skb(hb); ++ dev_kfree_skb_any(hb); + } + else + { +@@ -2556,7 +2556,7 @@ + else + { + printk("nicstar%d: What kind of rx buffer is this?\n", card->index); +- kfree_skb(skb); ++ dev_kfree_skb_any(skb); + } } - -+static void sch_atm_pop(struct atm_vcc *vcc,struct sk_buff *skb) -+{ -+ VCC2FLOW(vcc)->old_pop(vcc,skb); -+ mark_bh(NET_BH); /* may allow to send more */ -+} -+ -+ - static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, - struct rtattr **tca, unsigned long *arg) - { -@@ -289,7 +299,10 @@ - DPRINTK("atm_tc_change: qdisc %p\n",flow->q); - flow->sock = sock; - flow->vcc = ATM_SD(sock); /* speedup */ -+ flow->vcc->user_back = flow; - DPRINTK("atm_tc_change: vcc %p\n",flow->vcc); -+ flow->old_pop = flow->vcc->pop; -+ flow->vcc->pop = sch_atm_pop; - flow->classid = classid; - flow->ref = 1; - flow->excess = excess; -@@ -440,6 +453,10 @@ - * little bursts. Otherwise, it may ... @@@ - */ - while ((skb = flow->q->dequeue(flow->q))) { -+ if (!atm_may_send(flow->vcc,skb->truesize)) { -+ flow->q->ops->requeue(skb,flow->q); -+ break; -+ } - sch->q.qlen--; - D2PRINTK("atm_tc_deqeueue: sending on class %p\n",flow); - /* remove any LL header somebody else has attached */ -@@ -468,6 +485,22 @@ +@@ -2578,7 +2578,7 @@ + else + { + printk("nicstar%d: What kind of rx buffer is this?\n", card->index); +- kfree_skb(skb); ++ dev_kfree_skb_any(skb); + } + } + } +@@ -2593,7 +2593,7 @@ + card->iovpool.count++; + } + else +- kfree_skb(iovb); ++ dev_kfree_skb_any(iovb); } -+static int atm_tc_requeue(struct sk_buff *skb,struct Qdisc *sch) -+{ -+ struct atm_qdisc_data *p = PRIV(sch); -+ int ret; -+ -+ D2PRINTK("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p); -+ ret = p->link.q->ops->requeue(skb,p->link.q); -+ if (!ret) sch->q.qlen++; -+ else { -+ sch->stats.drops++; -+ p->link.stats.drops++; +@@ -2700,7 +2700,7 @@ + /* Dump 25.6 Mbps PHY registers */ + /* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it + here just in case it's needed for debugging. */ +- if (card->max_pcr == IDT_25_PCR && !left--) ++ if (card->max_pcr == ATM_25_PCR && !left--) + { + u32 phy_regs[4]; + u32 i; +@@ -2787,7 +2787,7 @@ + return -EFAULT; + + case NS_SETBUFLEV: +- if (!suser()) ++ if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&pl, (pool_levels *) arg, sizeof(pl))) + return -EFAULT; +@@ -2836,7 +2836,7 @@ + return 0; + + case NS_ADJBUFLEV: +- if (!suser()) ++ if (!capable(CAP_NET_ADMIN)) + return -EPERM; + btype = (int) arg; /* an int is the same size as a pointer */ + switch (btype) +@@ -2882,7 +2882,7 @@ + printk("nicstar%d: huge buffer count inconsistent.\n", + card->index); + else +- kfree_skb(hb); ++ dev_kfree_skb_any(hb); + + } + while (card->hbpool.count < card->hbnr.init) +@@ -2912,7 +2912,7 @@ + printk("nicstar%d: iovec buffer count inconsistent.\n", + card->index); + else +- kfree_skb(iovb); ++ dev_kfree_skb_any(iovb); + + } + while (card->iovpool.count < card->iovnr.init) +--- ref/drivers/atm/nicstar.h Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/nicstar.h Mon Feb 28 22:24:51 2000 +@@ -100,8 +100,6 @@ + + #define NS_IOREMAP_SIZE 4096 + +-#define IDT_25_PCR ((25600000 / 8 - 8000) / 54) +- + #define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */ + #define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */ + +--- ref/drivers/atm/suni.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/suni.c Mon Feb 28 21:59:52 2000 +@@ -1,4 +1,4 @@ +-/* drivers/atm/suni.c - PMC SUNI (PHY) driver */ ++/* drivers/atm/suni.c - PMC PM5346 SUNI (PHY) driver */ + + /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + +@@ -31,7 +31,7 @@ + + struct suni_priv { + struct sonet_stats sonet_stats; /* link diagnostics */ +- unsigned char loop_mode; /* loopback mode */ ++ int loop_mode; /* loopback mode */ + struct atm_dev *dev; /* device back-pointer */ + struct suni_priv *next; /* next SUNI */ + }; +@@ -158,6 +158,29 @@ + } + + ++static int set_loopback(struct atm_dev *dev,int mode) ++{ ++ unsigned char control; ++ ++ control = GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE); ++ switch (mode) { ++ case ATM_LM_NONE: ++ break; ++ case ATM_LM_LOC_PHY: ++ control |= SUNI_MCT_DLE; ++ break; ++ case ATM_LM_RMT_PHY: ++ control |= SUNI_MCT_LLE; ++ break; ++ default: ++ return -EINVAL; + } -+ return ret; ++ PUT(control,MCT); ++ PRIV(dev)->loop_mode = mode; ++ return 0; +} + + - static int atm_tc_drop(struct Qdisc *sch) + static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) { - struct atm_qdisc_data *p = PRIV(sch); -@@ -616,7 +649,7 @@ + switch (cmd) { +@@ -172,7 +195,6 @@ + case SONET_GETDIAG: + return get_diag(dev,arg); + case SONET_SETFRAMING: +- if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (arg != SONET_FRAME_SONET) return -EINVAL; + return 0; + case SONET_GETFRAMING: +@@ -180,21 +202,9 @@ + -EFAULT : 0; + case SONET_GETFRSENSE: + return -EINVAL; +- case SUNI_SETLOOP: +- { +- int int_arg = (int) (long) arg; +- +- if (!capable(CAP_NET_ADMIN)) return -EPERM; +- if (int_arg < 0 || int_arg > SUNI_LM_LOOP) +- return -EINVAL; +- PUT((GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE)) +- | (int_arg == SUNI_LM_DIAG ? SUNI_MCT_DLE : +- 0) | (int_arg == SUNI_LM_LOOP ? +- SUNI_MCT_LLE : 0),MCT); +- PRIV(dev)->loop_mode = int_arg; +- return 0; +- } +- case SUNI_GETLOOP: ++ case ATM_SETLOOP: ++ return set_loopback(dev,(int) (long) arg); ++ case ATM_GETLOOP: + return put_user(PRIV(dev)->loop_mode,(int *) arg) ? + -EFAULT : 0; + default: +@@ -237,7 +247,7 @@ + if (dev->signal == ATM_PHY_SIG_LOST) + printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, + dev->number); +- PRIV(dev)->loop_mode = SUNI_LM_NONE; ++ PRIV(dev)->loop_mode = ATM_LM_NONE; + suni_hz(0); /* clear SUNI counters */ + (void) fetch_stats(dev,NULL,1); /* clear kernel counters */ + cli(); +@@ -259,9 +269,9 @@ - atm_tc_enqueue, /* enqueue */ - atm_tc_dequeue, /* dequeue */ -- atm_tc_enqueue, /* requeue; we're cheating a little */ -+ atm_tc_requeue, /* requeue */ - atm_tc_drop, /* drop */ - - atm_tc_init, /* init */ ---- ref/net/atm/atm_misc.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/atm_misc.c Wed Feb 2 20:33:05 2000 -@@ -10,13 +10,11 @@ - #include - #include --#include "tunable.h" -- + static const struct atmphy_ops suni_ops = { +- suni_start, +- suni_ioctl, +- suni_int ++ start: suni_start, ++ ioctl: suni_ioctl, ++ interrupt: suni_int, + }; - int atm_charge(struct atm_vcc *vcc,int truesize) - { - atm_force_charge(vcc,truesize); -- if (atomic_read(&vcc->rx_inuse) <= vcc->rx_quota) return 1; -+ if (atomic_read(&vcc->rx_inuse) <= vcc->sk->rcvbuf) return 1; - atm_return(vcc,truesize); - vcc->stats->rx_drop++; - return 0; -@@ -29,7 +27,7 @@ - int guess = atm_guess_pdu2truesize(pdu_size); - atm_force_charge(vcc,guess); -- if (atomic_read(&vcc->rx_inuse) <= vcc->rx_quota) { -+ if (atomic_read(&vcc->rx_inuse) <= vcc->sk->rcvbuf) { - struct sk_buff *skb = alloc_skb(pdu_size,gfp_flags); - - if (skb) { ---- ref/net/atm/clip.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/clip.c Wed Feb 2 20:33:05 2000 +--- ref/drivers/atm/suni.h Mon Aug 23 18:56:31 1999 ++++ work/drivers/atm/suni.h Mon Feb 28 22:24:36 2000 @@ -1,6 +1,6 @@ - /* net/atm/clip.c - RFC1577 Classical IP over ATM */ - --/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ +-/* drivers/atm/suni.h - PMC SUNI (PHY) declarations */ ++/* drivers/atm/suni.h - PMC PM5346 SUNI (PHY) declarations */ + +-/* Written 1995,1998 by Werner Almesberger, EPFL LRC/ICA */ +/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + + + #ifndef DRIVER_ATM_SUNI_H +--- ref/drivers/atm/uPD98402.c Wed Feb 9 03:23:13 2000 ++++ work/drivers/atm/uPD98402.c Mon Feb 28 21:59:55 2000 +@@ -25,6 +25,7 @@ + struct uPD98402_priv { + struct sonet_stats sonet_stats; /* link diagnostics */ + unsigned char framing; /* SONET/SDH framing */ ++ int loop_mode; /* loopback mode */ + }; - #include -@@ -30,7 +30,6 @@ - #include - - #include "common.h" --#include "tunable.h" - #include "resources.h" - #include "ipcommon.h" - #include -@@ -219,6 +218,18 @@ +@@ -102,6 +103,39 @@ } -+static void clip_pop(struct atm_vcc *vcc,struct sk_buff *skb) ++static int set_loopback(struct atm_dev *dev,int mode) +{ -+ DPRINTK("clip_pop(vcc %p)\n",vcc); -+ CLIP_VCC(vcc)->old_pop(vcc,skb); -+ /* skb->dev == NULL in outbound ARP packets */ -+ if (atm_may_send(vcc,0) && skb->dev) { -+ skb->dev->tbusy = 0; -+ mark_bh(NET_BH); ++ unsigned char mode_reg; ++ ++ mode_reg = GET(MDR) & ~(uPD98402_MDR_TPLP | uPD98402_MDR_ALP | ++ uPD98402_MDR_RPLP); ++ switch (__ATM_LM_XTLOC(mode)) { ++ case __ATM_LM_NONE: ++ break; ++ case __ATM_LM_PHY: ++ mode_reg |= uPD98402_MDR_TPLP; ++ break; ++ case __ATM_LM_ATM: ++ mode_reg |= uPD98402_MDR_ALP; ++ break; ++ default: ++ return -EINVAL; ++ } ++ switch (__ATM_LM_XTRMT(mode)) { ++ case __ATM_LM_NONE: ++ break; ++ case __ATM_LM_PHY: ++ mode_reg |= uPD98402_MDR_RPLP; ++ break; ++ default: ++ return -EINVAL; + } ++ PUT(mode_reg,MDR); ++ PRIV(dev)->loop_mode = mode; ++ return 0; +} + + - static void clip_neigh_destroy(struct neighbour *neigh) + static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) { - DPRINTK("clip_neigh_destroy (neigh %p)\n",neigh); -@@ -346,6 +357,7 @@ - static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev) - { - struct atmarp_entry *entry; -+ struct atm_vcc *vcc; - - DPRINTK("clip_start_xmit (skb %p)\n",skb); - if (!skb->dst) { -@@ -381,9 +393,8 @@ - return 0; - } - DPRINTK("neigh %p, vccs %p\n",entry,entry->vccs); -- ATM_SKB(skb)->vcc = entry->vccs->vcc; -- DPRINTK("using neighbour %p, vcc %p\n",skb->dst->neighbour, -- ATM_SKB(skb)->vcc); -+ ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; -+ DPRINTK("using neighbour %p, vcc %p\n",skb->dst->neighbour,vcc); - if (entry->vccs->encap) { - void *here; - -@@ -391,15 +402,15 @@ - memcpy(here,llc_oui,sizeof(llc_oui)); - ((u16 *) here)[3] = skb->protocol; + switch (cmd) { +@@ -117,8 +151,13 @@ + -EFAULT : 0; + case SONET_GETFRSENSE: + return get_sense(dev,arg); ++ case ATM_SETLOOP: ++ return set_loopback(dev,(int) (long) arg); ++ case ATM_GETLOOP: ++ return put_user(PRIV(dev)->loop_mode,(int *) arg) ? ++ -EFAULT : 0; + default: +- return -ENOIOCTLCMD; ++ return -ENOIOCTLCMD; } -- atomic_add(skb->truesize,&ATM_SKB(skb)->vcc->tx_inuse); -+ atomic_add(skb->truesize,&vcc->tx_inuse); -+ dev->tbusy = !atm_may_send(vcc,0); - ATM_SKB(skb)->iovcnt = 0; -- ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options; -+ ATM_SKB(skb)->atm_options = vcc->atm_options; - entry->vccs->last_use = jiffies; -- DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,ATM_SKB(skb)->vcc, -- ATM_SKB(skb)->vcc->dev); -+ DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev); - PRIV(dev)->stats.tx_packets++; - PRIV(dev)->stats.tx_bytes += skb->len; -- (void) ATM_SKB(skb)->vcc->dev->ops->send(ATM_SKB(skb)->vcc,skb); -+ (void) vcc->dev->ops->send(vcc,skb); - return 0; } -@@ -428,9 +439,11 @@ - clip_vcc->last_use = jiffies; - clip_vcc->idle_timeout = timeout*HZ; - clip_vcc->old_push = vcc->push; -+ clip_vcc->old_pop = vcc->pop; - save_flags(flags); - cli(); - vcc->push = clip_push; -+ vcc->pop = clip_pop; - skb_migrate(&vcc->recvq,©); - restore_flags(flags); - /* re-process everything received between connection setup and MKIP */ -@@ -511,7 +524,12 @@ - dev->hard_header_len = RFC1483LLC_LEN; - dev->mtu = RFC1626_MTU; - dev->addr_len = 0; -- dev->tx_queue_len = 0; -+ dev->tx_queue_len = 100; /* "normal" queue */ -+ /* When using a "real" qdisc, the qdisc determines the queue */ -+ /* length. tx_queue_len is only used for the default case, */ -+ /* without any more elaborate queuing. 100 is a reasonable */ -+ /* compromise between decent burst-tolerance and protection */ -+ /* against memory hogs. */ - dev->flags = 0; - dev_init_buffers(dev); /* is this ever supposed to be used ? */ - return 0; -@@ -641,20 +659,7 @@ +@@ -190,9 +229,9 @@ - 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, + static const struct atmphy_ops uPD98402_ops = { +- uPD98402_start, +- uPD98402_ioctl, /* no ioctl yet */ +- uPD98402_int ++ start: uPD98402_start, ++ ioctl: uPD98402_ioctl, ++ interrupt: uPD98402_int, }; ---- ref/net/atm/common.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/common.c Wed Feb 2 20:33:05 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 - --#ifdef CONFIG_MMU_HACKS --#include --#include --#endif -- - #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) - #include - #include "lec.h" -@@ -62,7 +57,6 @@ - #include "resources.h" /* atm_find_dev */ - #include "common.h" /* prototypes */ - #include "protocols.h" /* atm_init_ */ --#include "tunable.h" /* tunable parameters */ - #include "addr.h" /* address registry */ - #ifdef CONFIG_ATM_CLIP - #include /* for clip_create */ -@@ -81,10 +75,9 @@ - { - struct sk_buff *skb; +--- ref/drivers/net/wd.c Fri Oct 29 22:20:35 1999 ++++ work/drivers/net/wd.c Mon Feb 28 22:50:15 2000 +@@ -309,6 +309,7 @@ + outb(inb(ioaddr+4)|0x80, ioaddr+4); + #endif -- if (atomic_read(&vcc->tx_inuse) && size+atomic_read(&vcc->tx_inuse)+ -- ATM_PDU_OVHD > vcc->tx_quota) { -- DPRINTK("Sorry: tx_inuse = %d, size = %d, tx_quota = %ld\n", -- atomic_read(&vcc->tx_inuse),size,vcc->tx_quota); -+ if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) { -+ DPRINTK("Sorry: tx_inuse = %d, size = %d, sndbuf = %d\n", -+ atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf); - return NULL; - } - while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule(); -@@ -103,15 +96,13 @@ - if (sock->type == SOCK_STREAM) return -EINVAL; - if (!(sk = alloc_atm_vcc_sk(family))) return -ENOMEM; - vcc = sk->protinfo.af_atm; -- vcc->flags = ATM_VF_SCRX | ATM_VF_SCTX; -+ vcc->flags = 0; - vcc->dev = NULL; - vcc->family = sock->ops->family; - vcc->alloc_tx = alloc_tx; - vcc->callback = NULL; - memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); - memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); -- vcc->tx_quota = ATM_TXBQ_DEF; -- vcc->rx_quota = ATM_RXBQ_DEF; - atomic_set(&vcc->tx_inuse,0); - atomic_set(&vcc->rx_inuse,0); - vcc->push = NULL; -@@ -382,19 +373,9 @@ - else vcc->dev->ops->free_rx_skb(vcc, skb); - return error ? error : eff_len; - } --#ifdef CONFIG_MMU_HACKS -- if (vcc->flags & ATM_VF_SCRX) { -- mmucp_tofs((unsigned long) buff,eff_len,skb, -- (unsigned long) skb->data); -- return eff_len; -- } -- else --#endif -- { -- error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0; -- if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb); -- else vcc->dev->ops->free_rx_skb(vcc, skb); -- } -+ error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0; -+ if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb); -+ else vcc->dev->ops->free_rx_skb(vcc, skb); - return error ? error : eff_len; ++ netif_device_attach(dev); /* EVIL HACK, FIXME ! - WA */ + return 0; } -@@ -419,39 +400,6 @@ - if (!(vcc->flags & ATM_VF_READY)) return -EPIPE; - if (!size) return 0; - /* verify_area is done by net/socket.c */ --#ifdef CONFIG_MMU_HACKS -- if ((vcc->flags & ATM_VF_SCTX) && vcc->dev->ops->sg_send && -- vcc->dev->ops->sg_send(vcc,(unsigned long) buff,size)) { -- int res,max_iov; -- -- max_iov = 2+size/PAGE_SIZE; -- /* -- * Doesn't use alloc_tx yet - this will change later. @@@ -- */ -- while (!(skb = alloc_skb(sizeof(struct iovec)*max_iov, -- GFP_KERNEL))) { -- if (m->msg_flags & MSG_DONTWAIT) return -EAGAIN; -- interruptible_sleep_on(&vcc->wsleep); -- if (signal_pending(current)) return -ERESTARTSYS; -- } -- skb_put(skb,size); -- res = lock_user((unsigned long) buff,size,max_iov, -- (struct iovec *) skb->data); -- if (res < 0) { -- kfree_skb(skb); -- if (res != -EAGAIN) return res; -- } -- else { -- DPRINTK("res is %d\n",res); -- DPRINTK("Asnd %d += %d\n",vcc->tx_inuse,skb->truesize); -- atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); -- ATM_SKB(skb)->iovcnt = res; -- error = vcc->dev->ops->send(vcc,skb); -- /* FIXME: security: may send up to 3 "garbage" bytes */ -- return error ? error : size; -- } -- } --#endif - eff = (size+3) & ~3; /* align to word boundary */ - while (!(skb = vcc->alloc_tx(vcc,eff))) { - if (m->msg_flags & MSG_DONTWAIT) return -EAGAIN; -@@ -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)+ -- ATM_PDU_OVHD <= vcc->tx_quota) -+ ATM_PDU_OVHD <= vcc->sk->sndbuf) - mask |= POLLOUT | POLLWRNORM; - } - else if (vcc->reply != WAITING) { -@@ -527,13 +476,13 @@ +--- ref/include/linux/atm_idt77105.h Wed Feb 9 03:23:13 2000 ++++ work/include/linux/atm_idt77105.h Mon Feb 28 22:24:39 2000 +@@ -9,6 +9,7 @@ - vcc = ATM_SD(sock); - switch (cmd) { -- case TIOCOUTQ: -+ case SIOCOUTQ: - if (sock->state != SS_CONNECTED || - !(vcc->flags & ATM_VF_READY)) return -EINVAL; -- return put_user(vcc->tx_quota- -+ return put_user(vcc->sk->sndbuf- - atomic_read(&vcc->tx_inuse)-ATM_PDU_OVHD, - (int *) arg) ? -EFAULT : 0; -- case TIOCINQ: -+ case SIOCINQ: - { - struct sk_buff *skb; - -@@ -569,30 +518,13 @@ - return copy_to_user((void *) arg,&vcc->timestamp, - sizeof(struct timeval)) ? -EFAULT : 0; - case ATM_SETSC: -- if (arg & ~(ATM_VF_SCRX | ATM_VF_SCTX)) return -EINVAL; -- /* @@@ race condition - should split flags into -- "volatile" and non-volatile part */ -- vcc->flags = (vcc->flags & ~(ATM_VF_SCRX | -- ATM_VF_SCTX)) | arg; -+ printk(KERN_WARNING "ATM_SETSC is obsolete\n"); - return 0; - case ATMSIGD_CTRL: - if (!capable(CAP_NET_ADMIN)) return -EPERM; - 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) { -- case SO_SNDBUF: -- if (get_user(value,(unsigned long *) optval)) -- return -EFAULT; -- if (!value) value = ATM_TXBQ_DEF; -- if (value < ATM_TXBQ_MIN) value = ATM_TXBQ_MIN; -- if (value > ATM_TXBQ_MAX) value = ATM_TXBQ_MAX; -- vcc->tx_quota = value; -- return 0; -- case SO_RCVBUF: -- if (get_user(value,(unsigned long *) optval)) -- return -EFAULT; -- if (!value) value = ATM_RXBQ_DEF; -- if (value < ATM_RXBQ_MIN) value = ATM_RXBQ_MIN; -- if (value > ATM_RXBQ_MAX) value = ATM_RXBQ_MAX; -- vcc->rx_quota = value; -- return 0; - case SO_ATMQOS: - { - struct atm_qos qos; -@@ -859,18 +776,6 @@ - - vcc = ATM_SD(sock); - switch (optname) { -- case SO_SNDBUF: -- return put_user(vcc->tx_quota,(unsigned long *) optval) -- ? -EFAULT : 0; -- case SO_RCVBUF: -- return put_user(vcc->rx_quota,(unsigned long *) optval) -- ? -EFAULT : 0; -- case SO_BCTXOPT: -- /* fall through */ -- case SO_BCRXOPT: -- printk(KERN_WARNING "Warning: SO_BCTXOPT/SO_BCRXOPT " -- "are obsolete\n"); -- break; - case SO_ATMQOS: - 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 Wed Feb 2 20:33:05 2000 -@@ -39,7 +39,6 @@ - - #include "lec.h" - #include "lec_arpc.h" --#include "tunable.h" - #include "resources.h" /* for bind_vcc() */ + #include + #include ++#include - #if 0 -@@ -60,7 +59,7 @@ - static int lec_send_packet(struct sk_buff *skb, struct net_device *dev); - static int lec_close(struct net_device *dev); - static struct net_device_stats *lec_get_stats(struct net_device *dev); --static int lec_init(struct net_device *dev); -+static void lec_init(struct net_device *dev); - static __inline__ struct lec_arp_table* lec_arp_find(struct lec_priv *priv, - unsigned char *mac_addr); - static __inline__ int lec_arp_remove(struct lec_arp_table **lec_arp_tables, -@@ -79,9 +78,6 @@ - NULL /* associate indicator, spec 3.1.5 */ - }; + /* + * Structure for IDT77105_GETSTAT and IDT77105_GETSTATZ ioctls. +@@ -21,20 +22,7 @@ + __u32 rx_hec_errors; /* Header Error Check errors on receive */ + }; + +-#define IDT77105_GETLOOP _IOW('a',ATMIOC_PHYPRV,struct atmif_sioc) /* get loopback mode */ +-#define IDT77105_SETLOOP _IOW('a',ATMIOC_PHYPRV+1,struct atmif_sioc) /* set loopback mode */ + #define IDT77105_GETSTAT _IOW('a',ATMIOC_PHYPRV+2,struct atmif_sioc) /* get stats */ + #define IDT77105_GETSTATZ _IOW('a',ATMIOC_PHYPRV+3,struct atmif_sioc) /* get stats and zero */ +- +- +-/* +- * TODO: what we need is a global loopback mode get/set ioctl for +- * all devices, not these device-specific hacks -- Greg Banks +- */ +-#define IDT77105_LM_NONE 0 /* no loopback */ +-#define IDT77105_LM_DIAG 1 /* diagnostic (i.e. loop TX to RX) +- * (a.k.a. local loopback) */ +-#define IDT77105_LM_LOOP 2 /* line (i.e. loop RX to TX) +- * (a.k.a. remote loopback) */ --/* will be lec0, lec1, lec2 etc. */ --static char myname[] = "lecxx"; -- - static unsigned char bus_mac[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + #endif +--- ref/include/linux/atm_suni.h Mon Aug 23 18:56:31 1999 ++++ work/include/linux/atm_suni.h Mon Feb 28 20:54:26 2000 +@@ -1,19 +1,12 @@ + /* atm_suni.h - Driver-specific declarations of the SUNI driver (for use by + driver-specific utilities) */ - /* Device structures */ -@@ -262,6 +258,17 @@ - lec_h = (struct lecdatahdr_8023*)skb->data; - lec_h->le_header = htons(priv->lecid); - -+#ifdef CONFIG_TR -+ /* Ugly. Use this to realign Token Ring packets for -+ * e.g. PCA-200E driver. */ -+ if (priv->is_trdev) { -+ skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); -+ kfree_skb(skb); -+ if (skb2 == NULL) return 0; -+ skb = skb2; -+ } -+#endif -+ - #if DUMP_PACKETS > 0 - printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name, - skb->len, priv->lecid); -@@ -466,6 +473,7 @@ - if (dev->change_mtu(dev, mesg->content.config.mtu)) - printk("%s: change_mtu to %d failed\n", dev->name, - mesg->content.config.mtu); -+ priv->is_proxy = mesg->content.config.is_proxy; - break; - case l_flush_tran_id: - lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr, -@@ -540,24 +548,8 @@ - } +-/* Written 1998 by Werner Almesberger, EPFL ICA */ ++/* Written 1998,2000 by Werner Almesberger, EPFL ICA */ - 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; - } + #ifndef LINUX_ATM_SUNI_H + #define LINUX_ATM_SUNI_H --static int -+static void - lec_init(struct net_device *dev) - { -- struct lec_priv *priv; +-#include - -- priv = (struct lec_priv *)dev->priv; -- if (priv->is_trdev) { --#ifdef CONFIG_TR -- init_trdev(dev, 0); --#endif -- } else ether_setup(dev); - dev->change_mtu = lec_change_mtu; - dev->open = lec_open; - dev->stop = lec_close; -@@ -646,7 +630,7 @@ - dev->set_multicast_list = NULL; - dev->do_ioctl = NULL; - printk("%s: Initialized!\n",dev->name); -- return 0; -+ return; - } - - static unsigned char lec_ctrl_magic[] = { -@@ -660,7 +644,6 @@ - { - struct net_device *dev = (struct net_device *)vcc->proto_data; - struct lec_priv *priv = (struct lec_priv *)dev->priv; -- struct lecdatahdr_8023 *hdr; - - #if DUMP_PACKETS >0 - int i=0; -@@ -696,9 +679,10 @@ - skb_queue_tail(&vcc->recvq, skb); - wake_up(&vcc->sleep); - } else { /* Data frame, queue to protocol handlers */ -+ unsigned char *dst; -+ - atm_return(vcc,skb->truesize); -- hdr = (struct lecdatahdr_8023 *)skb->data; -- if (hdr->le_header == htons(priv->lecid) || -+ if (*(uint16_t *)skb->data == htons(priv->lecid) || - !priv->lecd) { - /* Probably looping back, or if lecd is missing, - lecd has gone down */ -@@ -706,7 +690,19 @@ - dev_kfree_skb(skb); - return; - } -- if (priv->lec_arp_empty_ones) { /* FILTER DATA!!!! */ -+#ifdef CONFIG_TR -+ if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest; -+ else -+#endif -+ dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; -+ -+ if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */ -+ !priv->is_proxy && /* Proxy wants all the packets */ -+ memcmp(dst, dev->dev_addr, sizeof(dev->dev_addr))) { -+ dev_kfree_skb(skb); -+ return; -+ } -+ if (priv->lec_arp_empty_ones) { - lec_arp_check_empties(priv, vcc, skb); - } - skb->dev = dev; -@@ -757,7 +753,7 @@ - int - lecd_attach(struct atm_vcc *vcc, int arg) - { -- int i, result; -+ int i; - struct lec_priv *priv; - - if (arg<0) -@@ -772,30 +768,28 @@ - return -EINVAL; - #endif - if (!dev_lec[i]) { -- dev_lec[i] = (struct net_device*) -- kmalloc(sizeof(struct net_device)+sizeof(myname)+1, -- GFP_KERNEL); -- if (!dev_lec[i]) -- return -ENOMEM; -- memset(dev_lec[i],0,sizeof(struct net_device)+sizeof(myname)+1); +-#define SUNI_GETLOOP _IOR('a',ATMIOC_PHYPRV,int) /* get loopback mode */ +-#define SUNI_SETLOOP _IO('a',ATMIOC_PHYPRV+1) /* set loopback mode */ - -- dev_lec[i]->priv = kmalloc(sizeof(struct lec_priv), GFP_KERNEL); -- if (!dev_lec[i]->priv) -- return -ENOMEM; -- memset(dev_lec[i]->priv,0,sizeof(struct lec_priv)); -- priv = (struct lec_priv *)dev_lec[i]->priv; -+ int is_trdev, size; - -+ is_trdev = 0; - 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) -+ dev_lec[i] = init_trdev(NULL, size); -+ else -+#endif -+ dev_lec[i] = init_etherdev(NULL, size); -+ if (!dev_lec[i]) -+ return -ENOMEM; -+ -+ priv = dev_lec[i]->priv; -+ priv->is_trdev = is_trdev; -+ sprintf(dev_lec[i]->name, "lec%d", i); -+ lec_init(dev_lec[i]); - } else { -- priv = (struct lec_priv *)dev_lec[i]->priv; -+ priv = dev_lec[i]->priv; - if (priv->lecd) - return -EADDRINUSE; - } -@@ -874,7 +868,6 @@ - #endif - } else - unregister_netdev(dev_lec[i]); -- kfree(dev_lec[i]->priv); - 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 Wed Feb 2 20:33:05 2000 -@@ -27,7 +27,6 @@ - - #include "lec.h" - #include "mpc.h" --#include "tunable.h" - #include "resources.h" /* for bind_vcc() */ - - /* -@@ -326,7 +325,7 @@ - return; - } - --static const char *mpoa_device_type_string (char type) -+static const char * __attribute__ ((unused)) mpoa_device_type_string(char type) - { - switch(type) { - case NON_MPOA: -@@ -623,7 +622,8 @@ - dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name); - in_entry = mpc->in_ops->search_by_vcc(vcc, mpc); - if (in_entry) { -- unsigned char *ip = (unsigned char *)&in_entry->ctrl_info.in_dst_ip; -+ unsigned char *ip __attribute__ ((unused)) = -+ (unsigned char *)&in_entry->ctrl_info.in_dst_ip; - 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; -@@ -726,21 +726,8 @@ - } +-#define SUNI_LM_NONE 0 /* no loopback */ +-#define SUNI_LM_DIAG 1 /* diagnostic (i.e. loop TX to RX) */ +-#define SUNI_LM_LOOP 2 /* line (i.e. loop RX to TX) */ ++/* everything obsoleted */ - 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 - }; + #endif +--- ref/include/linux/atmdev.h Sun Feb 27 05:55:41 2000 ++++ work/include/linux/atmdev.h Mon Feb 28 22:24:33 2000 +@@ -20,6 +20,8 @@ + SONET overhead: /270*260 (9 section, 1 path) + bits per cell: /8/53 + max cell rate: 353207.547 cells/sec */ ++#define ATM_25_PCR ((25600000/8-8000)/54) ++ /* 25 Mbps ATM cell rate (59111) */ + + #define ATM_PDU_OVHD 0 /* number of bytes to charge against buffer + quota per PDU */ +@@ -69,12 +71,50 @@ + /* get AAL layer statistics */ + #define ATM_GETSTATZ _IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc) + /* get AAL layer statistics and zero */ ++#define ATM_GETLOOP _IOW('a',ATMIOC_SARCOM+2,struct atmif_sioc) ++ /* get loopback mode */ ++#define ATM_SETLOOP _IOW('a',ATMIOC_SARCOM+3,struct atmif_sioc) ++ /* set loopback mode */ + #define ATM_SETSC _IOW('a',ATMIOC_SPECIAL+1,int) + /* enable or disable single-copy */ - 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; -- unsigned char *ip = (unsigned char *)&dst_ip; -+ unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip; - struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip); - 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 Wed Feb 2 20:33:05 2000 -@@ -87,7 +87,7 @@ - struct mpoa_client *client) - { - unsigned long flags; -- unsigned char *ip = (unsigned char *)&dst_ip; -+ unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip; - in_cache_entry* entry = kmalloc(sizeof(in_cache_entry), GFP_KERNEL); - - if (entry == NULL) { -@@ -149,7 +149,8 @@ - - if( entry->count > mpc->parameters.mpc_p1 && - entry->entry_state == INGRESS_INVALID){ -- unsigned char *ip = (unsigned char *)&entry->ctrl_info.in_dst_ip; -+ unsigned char *ip __attribute__ ((unused)) = -+ (unsigned char *)&entry->ctrl_info.in_dst_ip; - - 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/mpoa_proc.c Fri Nov 19 05:02:02 1999 -+++ work/net/atm/mpoa_proc.c Wed Feb 2 20:33:05 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 Wed Feb 2 20:33:05 2000 -@@ -1,6 +1,6 @@ - /* net/atm/proc.c - ATM /proc interface */ + /* for ATM_GETTYPE */ + #define ATM_ITFTYP_LEN 8 /* maximum length of interface type name */ --/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ ++/* ++ * Loopback modes for ATM_{PHY,SAR}_{GET,SET}LOOP ++ */ ++ ++/* Point of loopback CPU-->SAR-->PHY-->line--> ... */ ++#define __ATM_LM_NONE 0 /* no loop back ^ ^ ^ ^ */ ++#define __ATM_LM_AAL 1 /* loop back PDUs --' | | | */ ++#define __ATM_LM_ATM 2 /* loop back ATM cells ---' | | */ ++#define __ATM_LM_PHY 3 /* loop back bits (digital) ----' | */ ++#define __ATM_LM_ANALOG 4 /* loop back the analog signal --------' */ ++ ++/* Direction of loopback */ ++#define __ATM_LM_MKLOC(n) ((n)) /* Local (i.e. loop TX to RX) */ ++#define __ATM_LM_MKRMT(n) ((n) << 8) /* Remote (i.e. loop RX to TX) */ ++ ++#define __ATM_LM_XTLOC(n) ((n) & 0xff) ++#define __ATM_LM_XTRMT(n) (((n) >> 8) & 0xff) ++ ++#define ATM_LM_NONE 0 /* no loopback */ ++ ++#define ATM_LM_LOC_AAL __ATM_LM_MKLOC(__ATM_LM_AAL) ++#define ATM_LM_LOC_ATM __ATM_LM_MKLOC(__ATM_LM_ATM) ++#define ATM_LM_LOC_PHY __ATM_LM_MKLOC(__ATM_LM_PHY) ++#define ATM_LM_LOC_ANALOG __ATM_LM_MKLOC(__ATM_LM_ANALOG) ++ ++#define ATM_LM_RMT_AAL __ATM_LM_MKRMT(__ATM_LM_AAL) ++#define ATM_LM_RMT_ATM __ATM_LM_MKRMT(__ATM_LM_ATM) ++#define ATM_LM_RMT_PHY __ATM_LM_MKRMT(__ATM_LM_PHY) ++#define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG) ++ ++/* ++ * Note: ATM_LM_LOC_* and ATM_LM_RMT_* can be combined, provided that ++ * __ATM_LM_XTLOC(x) <= __ATM_LM_XTRMT(x) ++ */ - /* - * 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) - { -- sprintf(strchr(buf,0),"%s ( %ld %ld %ld %ld %ld )",aal,stats->tx, -+ sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal,stats->tx, - stats->tx_err,stats->rx,stats->rx_err,stats->rx_drop); + struct atm_iobuf { +@@ -207,6 +247,7 @@ + /* modified by protocol or by driver.*/ + /* NOTE: this interface will change */ + int (*push_oam)(struct atm_vcc *vcc,void *cell); ++ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); + void *dev_data; /* per-device data */ + void *proto_data; /* per-protocol data */ + struct timeval timestamp; /* AAL timestamps */ +@@ -307,6 +348,7 @@ + int (*start)(struct atm_dev *dev); + int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg); + void (*interrupt)(struct atm_dev *dev); ++ int (*stop)(struct atm_dev *dev); + }; + + struct atm_skb_data { +--- ref/net/sched/sch_atm.c Tue Feb 22 01:32:27 2000 ++++ work/net/sched/sch_atm.c Mon Feb 28 23:23:02 2000 +@@ -276,7 +276,7 @@ + goto err_out; + } + /* @@@ should check if the socket is really operational or we'll crash +- on vcc->dev->ops->send */ ++ on vcc->send */ + if (classid) { + if (TC_H_MAJ(classid ^ sch->handle)) { + DPRINTK("atm_tc_change: classid mismatch\n"); +@@ -449,8 +449,22 @@ + sch->stats.packets++; + flow->stats.bytes += skb->len; + flow->stats.packets++; +- sch->q.qlen++; +- return 0; ++ /* ++ * Okay, this may seem weird. We pretend we've dropped the packet if ++ * it goes via ATM. The reason for this is that the outer qdisc ++ * expects to be able to q->dequeue the packet later on if we return ++ * success at this place. Also, sch->q.qdisc needs to reflect whether ++ * there is a packet egligible for dequeuing or not. Note that the ++ * statistics of the outer qdisc are necessarily wrong because of all ++ * this. There's currently no correct solution for this. ++ */ ++ if (flow == &p->link) { ++ sch->q.qlen++; ++ return 0; ++ } ++ tasklet_schedule(&p->task); ++ return NET_XMIT_CN; ++ /* must use NET_XMIT_CN - TCP retransmits on any other error ... */ } -@@ -112,7 +113,7 @@ - len = strlen(addr->sas_addr.pub); - buf += len; - if (*addr->sas_addr.pub) { -- *buf += '+'; -+ *buf++ = '+'; - len++; + +@@ -477,11 +491,9 @@ + */ + while ((skb = flow->q->dequeue(flow->q))) { + if (!atm_may_send(flow->vcc,skb->truesize)) { +- if (flow->q->ops->requeue(skb,flow->q)) +- sch->q.qlen--; ++ (void) flow->q->ops->requeue(skb,flow->q); + break; + } +- sch->q.qlen--; + D2PRINTK("atm_tc_deqeueue: sending on class %p\n",flow); + /* remove any LL header somebody else has attached */ + skb_pull(skb,(char *) skb->nh.iph-(char *) skb->data); +@@ -501,7 +513,7 @@ + atomic_add(skb->truesize,&flow->vcc->tx_inuse); + ATM_SKB(skb)->iovcnt = 0; + /* atm.atm_options are already set by atm_tc_enqueue */ +- (void) flow->vcc->dev->ops->send(flow->vcc,skb); ++ (void) flow->vcc->send(flow->vcc,skb); } - } -@@ -209,12 +210,39 @@ } - -+static void vc_info(struct atm_vcc *vcc,char *buf) -+{ -+ char *here; -+ -+ here = buf+sprintf(buf,"%p ",vcc); -+ if (!vcc->dev) here += sprintf(here,"Unassigned "); -+ else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi, -+ vcc->vci); -+ switch (vcc->family) { -+ case AF_ATMPVC: -+ here += sprintf(here,"PVC"); -+ break; -+ case AF_ATMSVC: -+ here += sprintf(here,"SVC"); -+ break; -+ default: -+ here += sprintf(here,"%3d",vcc->family); +--- ref/net/atm/clip.c Tue Feb 22 01:32:27 2000 ++++ work/net/atm/clip.c Mon Feb 28 21:18:14 2000 +@@ -431,7 +431,7 @@ + } + clip_priv->stats.tx_packets++; + clip_priv->stats.tx_bytes += skb->len; +- (void) vcc->dev->ops->send(vcc,skb); ++ (void) vcc->send(vcc,skb); + if (atm_may_send(vcc,0)) { + entry->vccs->xoff = 0; + return 0; +--- ref/net/atm/common.c Wed Feb 9 03:23:13 2000 ++++ work/net/atm/common.c Mon Feb 28 21:59:19 2000 +@@ -204,6 +204,7 @@ + if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) + return -EPERM; + error = 0; ++ bind_vcc(vcc,dev); + switch (vcc->qos.aal) { + case ATM_AAL0: + error = atm_init_aal0(vcc); +@@ -226,8 +227,10 @@ + } + if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal); + if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal); +- if (error) return error; +- bind_vcc(vcc,dev); ++ if (error) { ++ bind_vcc(vcc,NULL); ++ return error; + } -+ here += sprintf(here," %04x %5d %7d/%7d %7d/%7d\n",vcc->flags, -+ vcc->reply, -+ atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf, -+ atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf); -+} -+ -+ - static void svc_info(struct atm_vcc *vcc,char *buf) - { - char *here; - int i; - -- 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; - } + DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal); + DPRINTK(" TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class, + vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu); +@@ -522,6 +525,14 @@ + return 0; + case ATMSIGD_CTRL: + if (!capable(CAP_NET_ADMIN)) return -EPERM; ++ /* ++ * The user/kernel protocol for exchanging signalling ++ * info uses kernel pointers as opaque references, ++ * so the holder of the file descriptor can scribble ++ * on the kernel... so we should make sure that we ++ * have the same privledges that /proc/kcore needs ++ */ ++ if (!capable(CAP_SYS_RAWIO)) return -EPERM; + error = sigd_attach(vcc); + if (!error) sock->state = SS_CONNECTED; + return error; +@@ -668,6 +679,12 @@ + write the length" */ + return put_user(size, + &((struct atmif_sioc *) arg)->length) ? -EFAULT : 0; ++ case ATM_SETLOOP: ++ if (__ATM_LM_XTRMT((int) (long) buf) && ++ __ATM_LM_XTLOC((int) (long) buf) > ++ __ATM_LM_XTRMT((int) (long) buf)) ++ return -EINVAL; ++ /* fall through */ + case ATM_SETCIRANGE: + case SONET_GETSTATZ: + case SONET_SETDIAG: +@@ -689,6 +706,14 @@ -+ -+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) + int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) { - 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; - } ++ /* ++ * Don't let the QoS change the already connected AAL type nor the ++ * traffic class. ++ */ ++ if (qos->aal != vcc->qos.aal || ++ qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class || ++ qos->txtp.traffic_class != vcc->qos.txtp.traffic_class) ++ return -EINVAL; + if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP; + if (vcc->family == AF_ATMPVC) + return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET); +--- ref/net/atm/lec.c Tue Feb 22 01:32:27 2000 ++++ work/net/atm/lec.c Mon Feb 28 21:18:29 2000 +@@ -339,7 +339,7 @@ + send_vcc->vpi, send_vcc->vci); + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb2->len; +- send_vcc->dev->ops->send(send_vcc, skb2); ++ send_vcc->send(send_vcc, skb2); + } -+ - 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; - } + ATM_SKB(skb)->vcc = send_vcc; +@@ -348,7 +348,7 @@ + ATM_SKB(skb)->atm_options = send_vcc->atm_options; + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb->len; +- send_vcc->dev->ops->send(send_vcc, skb); ++ send_vcc->send(send_vcc, skb); -+ - struct proc_dir_entry *atm_proc_root; - EXPORT_SYMBOL(atm_proc_root); + #if 0 + /* Should we wait for card's device driver to notify us? */ +--- ref/net/atm/mpc.c Wed Feb 9 03:23:13 2000 ++++ work/net/atm/mpc.c Mon Feb 28 21:18:39 2000 +@@ -522,7 +522,7 @@ + atomic_add(skb->truesize, &entry->shortcut->tx_inuse); + ATM_SKB(skb)->iovcnt = 0; /* just to be safe ... */ + ATM_SKB(skb)->atm_options = entry->shortcut->atm_options; +- entry->shortcut->dev->ops->send(entry->shortcut, skb); ++ entry->shortcut->send(entry->shortcut, skb); + entry->packets_fwded++; -+ - int atm_proc_dev_register(struct atm_dev *dev) - { - int digits,num; -@@ -520,48 +581,41 @@ - kfree(dev->proc_name); - } + return 0; +--- ref/net/atm/proc.c Sun Feb 27 05:33:10 2000 ++++ work/net/atm/proc.c Mon Feb 28 20:54:27 2000 +@@ -583,7 +583,7 @@ + struct proc_dir_entry *devices = NULL,*pvc = NULL,*svc = NULL; + struct proc_dir_entry *arp = NULL,*lec = NULL,*vc = NULL; -+ -+#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); +- atm_proc_root = proc_mkdir("atm", &proc_root); ++ atm_proc_root = proc_mkdir("net/atm",NULL); 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 -- 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); + CREATE_ENTRY(devices); +@@ -605,6 +605,6 @@ 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); + if (vc) remove_proc_entry("vc",atm_proc_root); +- remove_proc_entry("atm",&proc_root); ++ remove_proc_entry("net/atm",NULL); return -ENOMEM; } ---- ref/net/atm/raw.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/raw.c Wed Feb 2 20:33:05 2000 -@@ -11,14 +11,8 @@ - #include - #include - --#ifdef CONFIG_MMU_HACKS --#include --#include --#endif -- - #include "common.h" - #include "protocols.h" --#include "tunable.h" /* tunable parameters */ - - - #if 0 -@@ -43,10 +37,6 @@ - - static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb) +--- ref/net/atm/raw.c Tue Feb 22 01:32:27 2000 ++++ work/net/atm/raw.c Mon Feb 28 21:07:08 2000 +@@ -38,16 +38,34 @@ { --#ifdef CONFIG_MMU_HACKS -- if (ATM_SKB(skb)->iovcnt) -- unlock_user(ATM_SKB(skb)->iovcnt,(struct iovec *) skb->data); --#endif DPRINTK("APopR (%d) %d -= %d\n",vcc->vci,vcc->tx_inuse,skb->truesize); 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 Feb 2 20:33:05 2000 -@@ -145,8 +145,10 @@ - sk_free(sk); - return NULL; - } -+ sock_init_data(NULL,sk); - sk->destruct = atm_free_sock; - memset(vcc,0,sizeof(*vcc)); -+ vcc->sk = sk; - if (nodev_vccs) nodev_vccs->prev = vcc; - vcc->prev = NULL; - vcc->next = nodev_vccs; ---- ref/net/atm/signaling.c Mon Aug 23 18:56:32 1999 -+++ work/net/atm/signaling.c Wed Feb 2 20:33:05 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 - --#include "tunable.h" - #include "resources.h" - #include "signaling.h" +- dev_kfree_skb_irq(skb); ++ dev_kfree_skb_any(skb); + wake_up(&vcc->wsleep); + } -@@ -92,8 +91,9 @@ - msg = (struct atmsvc_msg *) skb->data; - atomic_sub(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); -- DPRINTK("sigd_send %d (0x%lx)\n",(int) msg->type,msg->vcc); -- vcc = (struct atm_vcc *) msg->vcc; -+ DPRINTK("sigd_send %d (0x%lx)\n",(int) msg->type, -+ (unsigned long) msg->vcc); -+ vcc = *(struct atm_vcc **) &msg->vcc; - switch (msg->type) { - case as_okay: - vcc->reply = msg->reply; -@@ -118,7 +118,7 @@ - vcc->reply = msg->reply; - break; - case as_indicate: -- vcc = (struct atm_vcc *) 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); -@@ -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) ++static int atm_send_aal0(struct atm_vcc *vcc,struct sk_buff *skb) ++{ ++ /* ++ * Note that if vpi/vci are _ANY or _UNSPEC the below will ++ * still work ++ */ ++ if (!capable(CAP_NET_ADMIN) && ++ (((u32 *) skb->data)[0] & (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)) != ++ ((vcc->vpi << ATM_HDR_VPI_SHIFT) | (vcc->vci << ATM_HDR_VCI_SHIFT))) ++ { ++ kfree_skb(skb); ++ return -EADDRNOTAVAIL; ++ } ++ return vcc->dev->ops->send(vcc,skb); ++} ++ ++ + int atm_init_aal0(struct atm_vcc *vcc) { - 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; -+ *(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 Wed Feb 2 20:47:25 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/svc.c Wed Sep 8 20:14:32 1999 -+++ work/net/atm/svc.c Wed Feb 2 20:33:05 2000 -@@ -1,6 +1,6 @@ - /* net/atm/svc.c - ATM SVC sockets */ + vcc->push = atm_push_raw; + vcc->pop = atm_pop_raw; + vcc->push_oam = NULL; ++ vcc->send = atm_send_aal0; + return 0; + } --/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ +@@ -57,6 +75,7 @@ + vcc->push = atm_push_raw; + vcc->pop = atm_pop_raw; + vcc->push_oam = NULL; ++ vcc->send = vcc->dev->ops->send; + return 0; + } +@@ -66,6 +85,7 @@ + vcc->push = atm_push_raw; + vcc->pop = atm_pop_raw; + vcc->push_oam = NULL; ++ vcc->send = vcc->dev->ops->send; + return 0; + } - #include -@@ -253,6 +253,7 @@ - new_vcc->qos = msg->qos; - new_vcc->flags |= ATM_VF_HASQOS; - new_vcc->remote = msg->svc; -+ new_vcc->local = msg->local; - new_vcc->sap = msg->sap; - error = atm_connect(newsock,msg->pvc.sap_addr.itf, - msg->pvc.sap_addr.vpi,msg->pvc.sap_addr.vci); ---- ref/net/atm/tunable.h Wed Sep 8 20:14:32 1999 -+++ work/net/atm/tunable.h Wed Feb 2 20:33:05 2000 -@@ -1,16 +0,0 @@ --/* net/atm/tunable.h - Tunable parameters of ATM support */ -- --/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */ -- -- --#ifndef NET_ATM_TUNABLE_H --#define NET_ATM_TUNABLE_H -- --#define ATM_RXBQ_DEF ( 64*1024) /* default RX buffer quota, in bytes */ --#define ATM_TXBQ_DEF ( 64*1024) /* default TX buffer quota, in bytes */ --#define ATM_RXBQ_MIN ( 1*1024) /* RX buffer minimum, in bytes */ --#define ATM_TXBQ_MIN ( 1*1024) /* TX buffer minimum, in bytes */ --#define ATM_RXBQ_MAX (1024*1024) /* RX buffer quota limit, in bytes */ --#define ATM_TXBQ_MAX (1024*1024) /* TX buffer quota limit, in bytes */ -- --#endif diff -ur --new-file old/atm/debug/Makefile new/atm/debug/Makefile --- old/atm/debug/Makefile Tue Aug 24 00:02:30 1999 +++ new/atm/debug/Makefile Thu Feb 24 17:09:47 2000 @@ -1,4 +1,4 @@ -SYSPGMS=delay svctor # ed encopy endump zndump znth +PGMS=delay svctor # ed encopy endump zndump znth # Remove the # for more hardware-specific debugging programs. # I'll need those only if you're fiddling with the guts of drivers. diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex --- old/atm/doc/usage.tex Wed Feb 2 20:55:46 2000 +++ new/atm/doc/usage.tex Mon Feb 28 23:42:14 2000 @@ -1,7 +1,7 @@ %%def%:= %:\begin{verbatim} -%:Usage instructions - ATM on Linux, release 0.67 +%:Usage instructions - ATM on Linux, release 0.68 %:------------------------------------------------- %: %:\end{verbatim} @@ -38,14 +38,14 @@ \title{ATM on Linux \\ User's guide \\ - Release 0.67 (beta)} + Release 0.68 (beta)} \author{Werner Almesberger \\ {\tt Werner.Almesberger@epfl.ch} \\ \\ Institute for computer Communications and Applications (ICA) \\ EPFL, CH-1015 Lausanne, Switzerland} -\date{February 2, 2000} +\date{February 28, 2000} \begin{document} \maketitle @@ -82,9 +82,9 @@ In order to install this package, you need \begin{itemize} \item the package itself - \url{ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.67.tar.gz} - \item the Linux kernel, version 2.3.42, e.g. from - \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.42.tar.gz} + \url{ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.68.tar.gz} + \item the Linux kernel, version 2.3.48, e.g. from + \url{ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.48.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.67.tar.gz +tar xfz atm-0.68.tar.gz \end{verbatim} and the kernel source: \begin{verbatim} -tar xfz linux-2.3.42.tar.gz +tar xfz linux-2.3.48.tar.gz \end{verbatim} Finally, you can extract the ATM-related patches: @@ -126,8 +126,9 @@ \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{enitune}, \name{esi}, - \name{sonetdiag}, \name{saaldump}, \name{sunimode}, and \name{zntune} + \name{atmdiag}, \name{atmdump}, \name{atmloop}, \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}, \name{ttcp\_atm}, \name{window} @@ -142,7 +143,8 @@ \item[\path{atm/lib/}] Libraries for applications and demons \item[\path{atm/doc/}] Documentation in \LaTeX\ and conversion tools \item[\path{atm/man/}] Miscellaneous man pages - \item[\path{atm/extra/}] Extra packages (\name{tcpdump} and \name{ans}) + \item[\path{atm/extra/}] Extra packages (\name{tc}, \name{tcpdump}, and + \name{ans}) \item[\path{atm/config/}] Configuration file examples \item[\path{atm/switch/}] Switch fabric control (under construction) \end{description} @@ -430,13 +432,13 @@ Use the \raw{-z} option to reset the ``Alarm'' and ``Under'' counters. -\subsection{Files in \path{/proc/atm}} +\subsection{Files in \path{/proc/net/atm}} Some status information about the ATM subsystem can be obtained through files -in \path{/proc/atm}. \path{/proc/atm/arp} contains information specific to -Classical IP over ATM, see section \ref{clip}. +in \path{/proc/net/atm}. \path{/proc/net/atm/arp} contains information +specific to Classical IP over ATM, see section \ref{clip}. -\path{/proc/atm/devices} lists all active ATM devices. For each device, +\path{/proc/net/atm/devices} lists all active ATM devices. For each device, the interface number, the type label, the end system identifier (ESI), and statistics are shown. The statistics correspond to the ones available via \name{atmdiag}. @@ -445,7 +447,8 @@ \raw{\meta{type}:\meta{number}} (e.g. \raw{eni:0}) which contain device-specific information. -\path{/proc/atm/pvc} and \path{/proc/atm/svc} list all PVC and SVC sockets. +\path{/proc/net/atm/pvc} and \path{/proc/net/atm/svc} list all PVC and SVC +sockets. For both types of sockets, the interface, VPI and VCI numbers are shown. For PVCs, this is followed by the AAL and the traffic class and the selected PCR for the receive and the transmit direction. For SVCs, the SVC state @@ -453,6 +456,9 @@ number 999 are used for special control purposes as indicated in the ``State'' column. +Furthermore, \path{/proc/net/atm/vc} shows buffer sizes and additional +internal information for all ATM sockets. + \subsection{ATM diagnostics} @@ -948,8 +954,8 @@ Note that the ATMARP server currently has to be started and configured before any clients are configured. -The kernel ATMARP table can be read via \path{/proc/atm/arp}. The table used -by \name{atmarpd} is regularly printed on standard error if \name{atmarpd} +The kernel ATMARP table can be read via \path{/proc/net/atm/arp}. The table +used by \name{atmarpd} is regularly printed on standard error if \name{atmarpd} is started with the \raw{-d} option. If \name{atmarpd} is invoked without \raw{-d}, the table is written to the file \path{atmarpd.table} in the dump directory (by default \path{/var/run}; can be changed with \raw{-D}), and @@ -1017,7 +1023,7 @@ ELAN. The state of the LANE ARP cache entries can be monitored through -\path{/proc/atm/lec}. For each entry the MAC and ATM addresses and status +\path{/proc/net/atm/lec}. For each entry the MAC and ATM addresses and status is listed. If the entry has an active connection, the connection identifiers are also listed. @@ -1074,16 +1080,16 @@ The contents of MPOA ingress and egress caches can be monitored -through \path{/proc/atm/mpc} file. +through \path{/proc/net/atm/mpc} file. The Linux MPOA client also supports CBR traffic class for shortcuts SVCs instead of default UBR. The QoS specifications for future -shortcuts can be set and modified using \path{/proc/atm/mpc}. +shortcuts can be set and modified using \path{/proc/net/atm/mpc}. \begin{verbatim} -# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/atm/mpc +# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/net/atm/mpc # # generate enough traffic to trigger a shortcut -# cat /proc/atm/mpc +# cat /proc/net/atm/mpc QoS entries for shortcuts: IP address TX:max_pcr pcr min_pcr max_cdv max_sdu diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt --- old/atm/doc/usage.txt Wed Feb 2 22:53:12 2000 +++ new/atm/doc/usage.txt Mon Feb 28 23:42:24 2000 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.67 +Usage instructions - ATM on Linux, release 0.68 ------------------------------------------------- For updates of ATM on Linux, please check the Web page at @@ -17,9 +17,9 @@ In order to install this package, you need - the package itself - ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.67.tar.gz - - the Linux kernel, version 2.3.42, e.g. from - ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.42.tar.gz + ftp://icaftp.epfl.ch/pub/linux/atm/dist/atm-0.68.tar.gz + - the Linux kernel, version 2.3.48, e.g. from + ftp://ftp.kernel.org/pub/linux/kernel/v2.3/linux-2.3.48.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 @@ -33,11 +33,11 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.67.tar.gz +tar xfz atm-0.68.tar.gz and the kernel source: -tar xfz linux-2.3.42.tar.gz +tar xfz linux-2.3.48.tar.gz Finally, you can extract the ATM-related patches: @@ -52,8 +52,8 @@ atm/saal/ Signaling AAL library (SSCOP, SSCF, and SAAL) atm/qgen/ Q.2931-style message handling atm/ilmid/ ILMI address registration demon: ilmid - atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmtcp, - enitune, esi, sonetdiag, saaldump, sunimode, and zntune + atm/maint/ ATM maintenance programs: atmaddr, atmdiag, atmdump, atmloop, + atmtcp, 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 @@ -65,7 +65,7 @@ atm/lib/ Libraries for applications and demons atm/doc/ Documentation in LaTeX and conversion tools atm/man/ Miscellaneous man pages - atm/extra/ Extra packages (tcpdump and ans) + atm/extra/ Extra packages (tc, tcpdump, and ans) atm/config/ Configuration file examples atm/switch/ Switch fabric control (under construction) @@ -311,14 +311,14 @@ Use the -z option to reset the "Alarm" and "Under" counters. -Files in /proc/atm ------------------- +Files in /proc/net/atm +---------------------- Some status information about the ATM subsystem can be obtained through -files in /proc/atm. /proc/atm/arp contains information specific to +files in /proc/net/atm. /proc/net/atm/arp contains information specific to Classical IP over ATM, see section "CLIP". -/proc/atm/devices lists all active ATM devices. For each device, the +/proc/net/atm/devices lists all active ATM devices. For each device, the interface number, the type label, the end system identifier (ESI), and statistics are shown. The statistics correspond to the ones available via atmdiag. @@ -326,12 +326,16 @@ Individual ATM devices may register entries of the form : (e.g. eni:0 ) which contain device-specific information. -/proc/atm/pvc and /proc/atm/svc list all PVC and SVC sockets. For both -types of sockets, the interface, VPI and VCI numbers are shown. For PVCs, -this is followed by the AAL and the traffic class and the selected PCR for -the receive and the transmit direction. For SVCs, the SVC state and the -address of the remote party are shown. SVCs with the interface number 999 -are used for special control purposes as indicated in the "State" column. +/proc/net/atm/pvc and /proc/net/atm/svc list all PVC and SVC sockets. For +both types of sockets, the interface, VPI and VCI numbers are shown. For +PVCs, this is followed by the AAL and the traffic class and the selected +PCR for the receive and the transmit direction. For SVCs, the SVC state and +the address of the remote party are shown. SVCs with the interface number +999 are used for special control purposes as indicated in the "State" +column. + +Furthermore, /proc/net/atm/vc shows buffer sizes and additional internal +information for all ATM sockets. ATM diagnostics @@ -774,11 +778,11 @@ Note that the ATMARP server currently has to be started and configured before any clients are configured. -The kernel ATMARP table can be read via /proc/atm/arp. The table used by -atmarpd is regularly printed on standard error if atmarpd is started with -the -d option. If atmarpd is invoked without -d , the table is written -to the file atmarpd.table in the dump directory (by default /var/run; can -be changed with -D ), and it can be read with atmarp -a . +The kernel ATMARP table can be read via /proc/net/atm/arp. The table used +by atmarpd is regularly printed on standard error if atmarpd is started +with the -d option. If atmarpd is invoked without -d , the table is +written to the file atmarpd.table in the dump directory (by default +/var/run; can be changed with -D ), and it can be read with atmarp -a . LAN Emulation @@ -837,7 +841,7 @@ according to the MTU of the current ELAN. The state of the LANE ARP cache entries can be monitored through -/proc/atm/lec. For each entry the MAC and ATM addresses and status is +/proc/net/atm/lec. For each entry the MAC and ATM addresses and status is listed. If the entry has an active connection, the connection identifiers are also listed. @@ -889,15 +893,15 @@ the available options. The contents of MPOA ingress and egress caches can be monitored through -/proc/atm/mpc file. +/proc/net/atm/mpc file. The Linux MPOA client also supports CBR traffic class for shortcuts SVCs instead of default UBR. The QoS specifications for future shortcuts can be -set and modified using /proc/atm/mpc. +set and modified using /proc/net/atm/mpc. -# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/atm/mpc +# echo add 130.230.54.146 tx=80000,1600 rx=tx > /proc/net/atm/mpc # # generate enough traffic to trigger a shortcut -# cat /proc/atm/mpc +# cat /proc/net/atm/mpc QoS entries for shortcuts: IP address TX:max_pcr pcr min_pcr max_cdv max_sdu diff -ur --new-file old/atm/extra/tc/Makefile.patch new/atm/extra/tc/Makefile.patch --- old/atm/extra/tc/Makefile.patch Thu Jul 23 23:42:43 1998 +++ new/atm/extra/tc/Makefile.patch Thu Jan 1 01:00:00 1970 @@ -1,19 +0,0 @@ ---- iproute2/tc/Makefile Sat May 9 18:46:58 1998 -+++ wa/tc/Makefile Thu Jul 23 22:00:10 1998 -@@ -7,6 +7,7 @@ - TCMODULES += q_prio.o - TCMODULES += q_tbf.o - TCMODULES += q_cbq.o -+TCMODULES += q_atm.o - TCMODULES += f_rsvp.o - TCMODULES += f_u32.o - #TCMODULES += q_csz.o -@@ -20,7 +21,7 @@ - TCLIB += tc_cbq.o - TCLIB += tc_estimator.o - --LDLIBS += -L. -ltc -lm -ldl -+LDLIBS += -L. -ltc -lm -ldl -latm - LDFLAGS += -Wl,-export-dynamic - - all: libtc.a tc diff -ur --new-file old/atm/extra/tc/README new/atm/extra/tc/README --- old/atm/extra/tc/README Mon Mar 1 15:48:55 1999 +++ new/atm/extra/tc/README Mon Feb 28 23:07:31 2000 @@ -13,37 +13,32 @@ 2. Build the kernel. -3. Download iproute2-2.1.99-now-ss990203.tar.gz either from +3. Download iproute2-2.2.4-now-ss000225.tar.gz either from ftp://ftp.inr.ac.ru/ip-routing/ or one of its mirrors, or from - ftp://lrcftp.epfl.ch/pub/people/almesber/misc/ + ftp://icaftp.epfl.ch/pub/people/almesber/misc/ -4. Add the ATM queuing discipline to "tc" (assuming that we're in - atm/extra/tc): - - tar xvfz iproute2-2.1.99-now-ss990203.tar.gz - - cd iproute2/tc - - patch -s -p2 <../../Makefile.patch - - cp ../../q_atm.c . - -5. Build tc: - - cd .. - - edit Makefile to adjust KERNEL_INCLUDE, and maybe also to change the - library definitions +4. Extract iproute2: + - tar xvfz iproute2-2.2.4-now-ss000225.tar.gz + +5. Build and install iproute2: + - cd iproute2 + - edit Config to enable the ATM queuing discipline: TC_CONFIG_ATM=y - make - - cd tc + - cp tc/tc ip/ip /sbin 6. Run a little example. We first set up the ATM queuing discipline to intercept selected traffic through our Ethernet interface "eth0" and to forward this traffic over a PVC 0.100: - # ./tc qdisc add dev eth0 handle 1: root atm - # ./tc class add dev eth0 classid 1:1 atm pvc 0.100 + # tc qdisc add dev eth0 handle 1: root atm + # tc class add dev eth0 classid 1:1 atm pvc 0.100 Verify that the operation succeeded: - % ./tc qdisc show dev eth0 - qdisc atm 1: root refcnt 0 - % ./tc class show dev eth0 + % tc qdisc show dev eth0 + qdisc atm 1: + % tc class show dev eth0 class atm 1: parent 1: hdr . excess clp class atm 1:1 parent 1: pvc 0.0.100 hdr aa.aa.03.00.00.00.08.00 excess clp CONNECTED @@ -56,8 +51,8 @@ have enabled other filters, you can also try to select flows via firewall rules, etc. - # ./tc filter add dev eth0 parent 1:1 protocol ip route - # ../ip/ip route add 10.0.0.0/8 dev eth0 flow 0x10001 + # tc filter add dev eth0 protocol ip route to 1 flowid 1:1 + # ip route add 10.0.0.0/8 dev eth0 realm 1 Test the redirection to ATM: @@ -65,11 +60,11 @@ Remove the ATM queuing discipline again: - # ./tc qdisc del dev eth0 root + # tc qdisc del dev eth0 root Verify that the PVC has been removed: - % cat /proc/atm/pvc + % cat /proc/net/atm/pvc Policing (UNTESTED !) @@ -100,6 +95,6 @@ CLP=1 reclassify (default) excess clp Example: - # ./tc filter add dev eth0 parent 1:1 protocol ip route \ + # tc filter add dev eth0 parent 1:1 protocol ip route \ burst 100 rate 100 - # ./tc class add dev eth0 classid 1:1 atm pvc 0.100 excess 1:0 + # tc class add dev eth0 classid 1:1 atm pvc 0.100 excess 1:0 diff -ur --new-file old/atm/extra/tc/mkpatch new/atm/extra/tc/mkpatch --- old/atm/extra/tc/mkpatch Thu Jan 1 01:00:00 1970 +++ new/atm/extra/tc/mkpatch Sun Feb 20 00:42:03 2000 @@ -0,0 +1,15 @@ +#!/bin/sh +[ -d iproute2 ] || { echo iproute2/ is missing; exit; } +>iproute2.patch +for n in `awk '$1 !~ /^#/ {print$1}' <>iproute2.patch +done diff -ur --new-file old/atm/extra/tc/q_atm.c new/atm/extra/tc/q_atm.c --- old/atm/extra/tc/q_atm.c Tue Nov 30 22:05:51 1999 +++ new/atm/extra/tc/q_atm.c Thu Jan 1 01:00:00 1970 @@ -1,267 +0,0 @@ -/* - * q_atm.c ATM. - * - * Hacked 1998,1999 by Werner Almesberger, EPFL ICA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "tc_util.h" - - -#define MAX_HDR_LEN 64 - -#define usage() return(-1) - - -static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - if (argc) { - fprintf(stderr,"Usage: atm\n"); - return -1; - } - return 0; -} - - -static void explain(void) -{ - fprintf(stderr, "Usage: ... atm ( pvc ADDR | svc ADDR [ sap SAP ] ) " - "[ qos QOS ] [ sndbuf BYTES ]\n"); - fprintf(stderr, " [ hdr HEX... ] [ excess ( CLASSID | clp ) ] " - "[ clip ]\n"); -} - - -static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - struct sockaddr_atmsvc addr; - struct atm_qos qos; - struct atm_sap sap; - unsigned char hdr[MAX_HDR_LEN]; - __u32 excess = 0; - struct rtattr *tail; - int sndbuf = 0; - int hdr_len = -1; - int set_clip = 0; - int s; - - memset(&addr,0,sizeof(addr)); - (void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0); - (void) text2sap("blli:l2=iso8802",&sap,0); - while (argc > 0) { - if (!strcmp(*argv,"pvc")) { - NEXT_ARG(); - if (text2atm(*argv,(struct sockaddr *) &addr, - sizeof(addr),T2A_PVC | T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"svc")) { - NEXT_ARG(); - if (text2atm(*argv,(struct sockaddr *) &addr, - sizeof(addr),T2A_SVC | T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"qos")) { - NEXT_ARG(); - if (text2qos(*argv,&qos,0) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"sndbuf")) { - char *end; - - NEXT_ARG(); - sndbuf = strtol(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"sap")) { - NEXT_ARG(); - if (addr.sas_family != AF_ATMSVC || - text2sap(*argv,&sap,T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"hdr")) { - unsigned char *ptr; - char *walk; - - NEXT_ARG(); - ptr = hdr; - for (walk = *argv; *walk; walk++) { - int tmp; - - if (ptr == hdr+MAX_HDR_LEN) { - fprintf(stderr,"header is too long\n"); - return -1; - } - if (*walk == '.') continue; - if (!isxdigit(walk[0]) || !walk[1] || - !isxdigit(walk[1])) { - explain(); - return -1; - } - sscanf(walk,"%2x",&tmp); - *ptr++ = tmp; - walk++; - } - hdr_len = ptr-hdr; - } - else if (!strcmp(*argv,"excess")) { - NEXT_ARG(); - if (!strcmp(*argv,"clp")) excess = 0; - else if (get_tc_classid(&excess,*argv)) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"clip")) { - set_clip = 1; - } - else { - explain(); - return 1; - } - argc--; - argv++; - } - s = socket(addr.sas_family,SOCK_DGRAM,0); - if (s < 0) { - perror("socket"); - return -1; - } - if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) { - perror("SO_ATMQOS"); - return -1; - } - if (sndbuf) - if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) { - perror("SO_SNDBUF"); - return -1; - } - if (addr.sas_family == AF_ATMSVC && setsockopt(s,SOL_ATM,SO_ATMSAP, - &sap,sizeof(sap)) < 0) { - perror("SO_ATMSAP"); - return -1; - } - if (connect(s,(struct sockaddr *) &addr,addr.sas_family == AF_ATMPVC ? - sizeof(struct sockaddr_atmpvc) : sizeof(addr)) < 0) { - perror("connect"); - return -1; - } - if (set_clip) - if (ioctl(s,ATMARP_MKIP,0) < 0) { - perror("ioctl ATMARP_MKIP"); - return -1; - } - tail = (struct rtattr *) (((void *) n)+NLMSG_ALIGN(n->nlmsg_len)); - addattr_l(n,1024,TCA_OPTIONS,NULL,0); - addattr_l(n,1024,TCA_ATM_FD,&s,sizeof(s)); - if (excess) addattr_l(n,1024,TCA_ATM_EXCESS,&excess,sizeof(excess)); - if (hdr_len != -1) addattr_l(n,1024,TCA_ATM_HDR,hdr,hdr_len); - tail->rta_len = (((void *) n)+NLMSG_ALIGN(n->nlmsg_len))-(void *) tail; - return 0; -} - - - -static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_ATM_MAX+1]; - char buffer[MAX_ATM_ADDR_LEN+1]; - - if (!opt) return 0; - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, TCA_ATM_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)); - if (tb[TCA_ATM_ADDR]) - if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) < - sizeof(struct sockaddr_atmpvc)) - fprintf(stderr,"ATM: address too short\n"); - else { - if (atm2text(buffer,MAX_ATM_ADDR_LEN, - RTA_DATA(tb[TCA_ATM_ADDR]),A2T_PRETTY | A2T_NAME) < - 0) fprintf(stderr,"atm2text error\n"); - fprintf(f,"pvc %s ",buffer); - } - if (tb[TCA_ATM_HDR]) { - int i; - - fprintf(f,"hdr"); - for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++) - fprintf(f,"%c%02x",i ? '.' : ' ', - ((unsigned char *) RTA_DATA(tb[TCA_ATM_HDR]))[i]); - if (!i) fprintf(f," ."); - fprintf(f," "); - } - if (tb[TCA_ATM_EXCESS]) { - __u32 excess; - - if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess)) - fprintf(stderr,"ATM: excess class ID too short\n"); - else { - excess = *(__u32 *) RTA_DATA(tb[TCA_ATM_EXCESS]); - if (!excess) fprintf(f,"excess clp "); - else { - char buf[64]; - - print_tc_classid(buf,sizeof(buf),excess); - fprintf(f,"excess %s ",buf); - } - } - } - if (tb[TCA_ATM_STATE]) { - static const char *map[] = { ATM_VS2TXT_MAP }; - int state; - - if (RTA_PAYLOAD(tb[TCA_ATM_STATE]) < sizeof(state)) - fprintf(stderr,"ATM: state field too short\n"); - else { - state = *(int *) RTA_DATA(tb[TCA_ATM_STATE]); - fprintf(f,"%s ",map[state]); - } - } - return 0; -} - - -static int atm_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -{ - return 0; -} - - -struct qdisc_util atm_util = { - NULL, - "atm", - atm_parse_opt, - atm_print_opt, - atm_print_xstats, - - atm_parse_class_opt, - atm_print_opt -}; diff -ur --new-file old/atm/maint/Makefile new/atm/maint/Makefile --- old/atm/maint/Makefile Tue Feb 1 21:30:55 2000 +++ new/atm/maint/Makefile Fri Feb 25 18:22:36 2000 @@ -1,9 +1,9 @@ LDLIBS=-latmd INCLUDES=-I../qgen -I../saal BOOTPGMS=atmaddr esi -SYSPGMS=atmtcp enitune zntune loop25 # nstune -USRPGMS=atmdiag atmdump sonetdiag saaldump sunimode -MAN8=atmaddr.8 atmdiag.8 atmdump.8 atmtcp.8 +SYSPGMS=atmloop atmtcp enitune zntune # nstune +USRPGMS=atmdiag atmdump sonetdiag saaldump +MAN8=atmaddr.8 atmdiag.8 atmdump.8 atmtcp.8 esi.8 include ../Rules.make diff -ur --new-file old/atm/maint/atmloop.c new/atm/maint/atmloop.c --- old/atm/maint/atmloop.c Thu Jan 1 01:00:00 1970 +++ new/atm/maint/atmloop.c Mon Feb 28 22:05:05 2000 @@ -0,0 +1,112 @@ +/* atmloop.c - get/set loopback mode of ATM interfaces */ + +/* Written 2000 by Werner Almesberger, EPFL ICA */ + + +#include +#include +#include +#include +#include +#include +#include + + +static void usage(const char *name) +{ + fprintf(stderr,"usage: %s [ -s ] [ -l level ] [ -r level ] [ itf ]\n", + name); + fprintf(stderr,"%7s%s [ itf ]\n","",name); + fprintf(stderr," levels: aal = AAL PDU, atm = ATM cell,\n"); + fprintf(stderr,"%10sphy = line (digital), analog = line (analog)\n",""); + exit(1); +} + + +static int text2level(const char *name,const char *s) +{ + if (!strcmp(s,"aal")) return __ATM_LM_AAL; + if (!strcmp(s,"atm")) return __ATM_LM_ATM; + if (!strcmp(s,"phy")) return __ATM_LM_PHY; + if (!strcmp(s,"analog")) return __ATM_LM_ANALOG; + usage(name); + return 0; /* uh ... */ +} + + +static const char *level2text(int level) +{ + switch (level) { + case __ATM_LM_NONE: + return "(none)"; + case __ATM_LM_AAL: + return "aal"; + case __ATM_LM_ATM: + return "atm"; + case __ATM_LM_PHY: + return "phy"; + case __ATM_LM_ANALOG: + return "analog"; + default: + return "???"; + } +} + + +int main(int argc,char **argv) +{ + int local = ATM_LM_NONE,remote = ATM_LM_NONE,mode; + int set = 0; + struct atmif_sioc req; + int s,c; + + req.number = 0; + while ((c = getopt(argc,argv,"l:r:s")) != EOF) + switch (c) { + case 'l': + if (local) usage(*argv); + local = text2level(*argv,optarg); + break; + case 'r': + if (remote) usage(*argv); + remote = text2level(*argv,optarg); + break; + case 's': + set = 1; + break; + default: + usage(*argv); + } + if (argc > optind+1) usage(*argv); + if (argc == optind+1) { + char *end; + + req.number = strtoul(argv[optind],&end,0); + if (*end) usage(*argv); + } + mode = __ATM_LM_MKLOC(local) | __ATM_LM_MKRMT(remote); + if (mode && !set) usage(*argv); + s = socket(PF_ATMPVC,SOCK_DGRAM,0); + if (s < 0) { + perror("socket"); + return 1; + } + if (set) { + req.arg = (void *) mode; + req.length = 0; + if (ioctl(s,ATM_SETLOOP,&req) < 0) { + perror("ioctl ATM_SETLOOP"); + return 1; + } + return 0; + } + req.arg = &mode; + req.length = sizeof(mode); + if (ioctl(s,ATM_GETLOOP,&req) < 0) { + perror("ioctl ATM_GETLOOP"); + return 1; + } + printf("local: %s\n",level2text(__ATM_LM_XTLOC(mode))); + printf("remote: %s\n",level2text(__ATM_LM_XTRMT(mode))); + return 0; +} diff -ur --new-file old/atm/maint/atmtcp.8 new/atm/maint/atmtcp.8 --- old/atm/maint/atmtcp.8 Fri Jan 21 19:25:09 2000 +++ new/atm/maint/atmtcp.8 Sat Feb 26 09:30:18 2000 @@ -1,4 +1,4 @@ -.TH ATMTCP 8 "January 21, 2000" "Linux" "Maintenance Commands" +.TH ATMTCP 8 "February 26, 2000" "Linux" "Maintenance Commands" .SH NAME atmtcp \- set up ATM over TCP connections .SH SYNOPSIS @@ -11,7 +11,7 @@ .ad b .SH DESCRIPTION The main purpose of \fBatmtcp\fP -is to establish TCP connections and to configures them as virtual ATM devices. +is to establish TCP connections and to configure 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. diff -ur --new-file old/atm/maint/esi.8 new/atm/maint/esi.8 --- old/atm/maint/esi.8 Mon Aug 18 12:43:15 1997 +++ new/atm/maint/esi.8 Fri Feb 25 18:22:00 2000 @@ -1,4 +1,4 @@ -.TH ATMARP 8 "Aug 18, 1997" "Linux" "Maintenance Commands" +.TH ESI 8 "Feb 25, 2000" "Linux" "Maintenance Commands" .SH NAME esi \- get or set the end system identifier (ESI) .SH SYNOPSIS diff -ur --new-file old/atm/maint/esi.c new/atm/maint/esi.c --- old/atm/maint/esi.c Tue Jan 18 22:22:40 2000 +++ new/atm/maint/esi.c Fri Feb 25 17:04:47 2000 @@ -89,7 +89,7 @@ } if (ioctl(s,esi ? op : ATM_GETESI,&req) < 0) { perror(esi ? op == ATM_SETESI ? "ioctl ATM_SETESI" : - "ioctl ATM_SETESIF" : "ioctk ATM_GETESI"); + "ioctl ATM_SETESIF" : "ioctl ATM_GETESI"); return 1; } if (!esi) { diff -ur --new-file old/atm/maint/loop25.c new/atm/maint/loop25.c --- old/atm/maint/loop25.c Mon Nov 22 12:57:56 1999 +++ new/atm/maint/loop25.c Thu Jan 1 01:00:00 1970 @@ -1,161 +0,0 @@ -/* - * loopback: program to control the loopback mode on a ForeRunner LE25 - * ATM NIC. Sadly, due to immaturity of the Linux ATM API, - * this needs to be done via device-specific ioctl()s. - * - * Written by Greg Banks, NEC Australia - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static void -usage(void) -{ - static const char usage_string[] = "\ -Usage: loop25 interface\n\ - loop25 interface mode\n\ - where `mode' is one of:\n\ - none normal operation.\n\ - local Tx looped to Rx. Transmitted cells are immediately\n\ - received as if they had bounced.\n\ - diag Same as local.\n\ - remote Rx teed to Tx. Received cells are received (e.g. for\n\ - analysis) and also retransmitted.\n\ - loop Same as remote.\n\ - `interface' is an ATM interface number, e.g. 0 for first NIC.\n\ -"; - - fputs(usage_string, stderr); - exit(1); -} - -/* Sadly, an equivalent define is in the nicstar.h private header */ -#define PCR_ATM25 59111 - -/* Check for correct ATM device driver */ -static int -check_is_idt77105_phy(int sock, int interface) -{ - int link_rate = -1; - char dev_type[256]; - struct atmif_sioc sioc; - - dev_type[0] = '\0'; - - memset(&sioc, 0, sizeof(sioc)); - sioc.arg = dev_type; - sioc.length = sizeof(dev_type); - sioc.number = interface; - if (ioctl(sock, ATM_GETTYPE, &sioc) < 0) - { - perror("ioctl(ATM_GETTYPE)"); - return -1; - } - if (strcmp(dev_type, "nicstar")) - { - fprintf(stderr, "Interface %d is not a NICStAR (type is \"%s\")\n", - interface, dev_type); - return -1; - } - - - memset(&sioc, 0, sizeof(sioc)); - sioc.arg = &link_rate; - sioc.length = sizeof(link_rate); - sioc.number = interface; - if (ioctl(sock, ATM_GETLINKRATE, &sioc) < 0) - { - perror("ioctl(ATM_GETLINKRATE)"); - return -1; - } - if (link_rate != PCR_ATM25) - { - fprintf(stderr, "Interface %d is not 25 Mbps (PCR is %d not %d)\n", - interface, link_rate, PCR_ATM25); - return -1; - } - - return 0; -} - - -int -main(int argc, char **argv) -{ - int sock; - int mode; - int interface; - const char *modestr = 0; - struct atmif_sioc sioc; - - if (argc <2 || argc > 3) - usage(); - interface = atoi(argv[1]); - modestr = (argc > 2 ? argv[2] : 0); - - sock = socket(PF_ATMPVC, SOCK_DGRAM, 0); - if (sock < 0) - { - perror("socket(PF_ATMPVC)"); - exit(3); - } - - if (check_is_idt77105_phy(sock, interface) < 0) - exit(1); - - memset(&sioc, 0, sizeof(sioc)); - sioc.number = interface; - - if (modestr == 0) - { - /* get and print the current loopback mode */ - mode = -1; - sioc.arg = &mode; - if (ioctl(sock, IDT77105_GETLOOP, &sioc) < 0) - { - perror("ioctl(IDT77105_GETLOOP)"); - exit(1); - } - switch (mode) - { - case IDT77105_LM_NONE: printf("none\n"); break; - case IDT77105_LM_DIAG: printf("local\n"); break; - case IDT77105_LM_LOOP: printf("remote\n"); break; - default: printf("unknown (%d)\n", mode); break; - } - } - else - { - /* set a new loopback mode */ - if (!strcmp(modestr, "none")) - mode = IDT77105_LM_NONE; - else if (!strcmp(modestr, "local")) - mode = IDT77105_LM_DIAG; - else if (!strcmp(modestr, "diag")) - mode = IDT77105_LM_DIAG; - else if (!strcmp(modestr, "remote")) - mode = IDT77105_LM_LOOP; - else if (!strcmp(modestr, "line")) - mode = IDT77105_LM_LOOP; - else - usage(); - - sioc.arg = (void*)mode; - if (ioctl(sock, IDT77105_SETLOOP, &sioc) < 0) - { - perror("ioctl(IDT77105_SETLOOP)"); - exit(1); - } - } - - return 0; -} diff -ur --new-file old/atm/maint/sunimode.c new/atm/maint/sunimode.c --- old/atm/maint/sunimode.c Sat Jan 22 16:29:25 2000 +++ new/atm/maint/sunimode.c Thu Jan 1 01:00:00 1970 @@ -1,112 +0,0 @@ -/* - $Id: $ - - sunimode.c - get/set S/UNI loopback mode - - Christophe Lizzi (lizzi@cnam.fr), December 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 -#include -#include -#include -#include -#include -#include - - -static const char* suni_mode[] = { - "normal operation", - "diagnostic loopback", - "line loopback" -}; - -char* progname; - -void usage(void) -{ - fprintf(stderr, "%s [{-n, -d, -l}] [itf]\n" - "\t-n: normal operation\n" - "\t-d: diagnostic loopback (tx -> rx)\n" - "\t-l: line loopback (rx -> tx)\n", progname); - exit(-1); -} - - -int main(int argc, char** argv) -{ - int sock, normal_op, diag_loop, line_loop, loop_mode, itf; - struct atmif_sioc req; - - normal_op = diag_loop = line_loop = itf = 0; - - progname = *(argv++); - - while (argc > 1) { - if ((*argv)[0] == '-') { - switch ((*argv)[1]) { - case 'n': - normal_op = 1; - loop_mode = SUNI_LM_NONE; - break; - case 'd': - diag_loop = 1; - loop_mode = SUNI_LM_DIAG; - break; - case 'l': - line_loop = 1; - loop_mode = SUNI_LM_LOOP; - break; - default: - usage(); - } - } - else { - itf = atoi(*argv); - if (itf < 0) - usage(); - } - argc--; - argv++; - } - - if ((sock = socket(PF_ATMPVC, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - exit(-1); - } - - switch(normal_op + diag_loop + line_loop) { - - case 0: /* get the current loopback mode */ - req.number = itf; - req.length = sizeof(loop_mode); - req.arg = (void*) &loop_mode; - - if (ioctl(sock, SUNI_GETLOOP, &req) < 0) - perror("ioctl SUNI_GETLOOP"); - else - printf("itf %d: %s\n", itf, suni_mode[ loop_mode ]); - - exit(loop_mode); - - case 1: /* set a new loopback mode */ - req.number = itf; - req.length = 0; - req.arg = (void*) loop_mode; - - if (ioctl(sock, SUNI_SETLOOP, &req) < 0) - perror("ioctl SUNI_SETLOOP"); - - exit(0); - - default: /* more than one mode was supplied */ - usage(); - } - - return 0; -} diff -ur --new-file old/atm/mkdiff new/atm/mkdiff --- old/atm/mkdiff Thu Jun 3 04:23:25 1999 +++ new/atm/mkdiff Mon Feb 28 23:57:12 2000 @@ -55,19 +55,40 @@ read version read version } &2 + echo "no kernel $kernel ($version) found in $KPATH" 1>&2 exit 1 + fi + if [ ! -z "$patch" ]; then + for m in `echo $KPATH | tr : ' '`; do + if [ -r $m/$patch.gz -o -r $m/$patch.bz2 ]; then + break + fi + done + if [ -r $m/$patch.gz ]; then + zcat $m/$patch.gz | patch -p0 -s || exit 1 + elif [ -r $m/$patch.bz2 ]; then + bunzip2 < $m/$patch.bz2 | patch -p0 -s || exit 1 + else + echo "no patch $patch ($version) found in $KPATH" 1>&2 + exit 1 + fi fi cd linux patch -s -p1 <../atm/atm*.patch || exit 1 diff -ur --new-file old/atm/mkdist new/atm/mkdist --- old/atm/mkdist Tue Feb 1 21:31:16 2000 +++ new/atm/mkdist Mon Feb 28 20:39:28 2000 @@ -70,10 +70,10 @@ 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/sonetdiag.c atm/maint/loop25.c \ + atm/maint/sonetdiag.c atm/maint/atmloop.c \ atm/maint/atmaddr.8 atm/maint/atmdiag.8 atm/maint/atmdump.8 \ atm/maint/atmtcp.8 atm/maint/zntune.c atm/maint/enitune.c atm/maint/esi.c \ - atm/maint/esi.8 atm/maint/sunimode.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 \ @@ -128,7 +128,7 @@ atm/extra/extra.html atm/extra/Makefile \ atm/extra/tcpdump-3.4.patch atm/extra/tcpdump-3.4.patch.sunrpc \ atm/extra/bind-4.9.5-REL.patch atm/extra/hosts2ans.pl \ - atm/extra/tc/README atm/extra/tc/Makefile.patch atm/extra/tc/q_atm.c \ + atm/extra/tc/README atm/extra/tc/mkpatch \ atm/config/README atm/config/Makefile \ atm/config/common/README atm/config/common/Makefile \ atm/config/common/hosts.atm atm/config/common/e164_cc \ diff -ur --new-file old/atm/mkpatch new/atm/mkpatch --- old/atm/mkpatch Tue Jan 18 20:37:13 2000 +++ new/atm/mkpatch Mon Feb 28 22:56:41 2000 @@ -37,6 +37,7 @@ drivers/atm/eni.h drivers/atm/fore200e.c drivers/atm/fore200e.h +drivers/atm/fore200e_firmware_copyright drivers/atm/fore200e_mkfirm.c drivers/atm/horizon.c drivers/atm/horizon.h @@ -60,6 +61,9 @@ drivers/atm/zatm.c drivers/atm/zatm.h drivers/atm/zeprom.h +#--- drivers/net-------------------------------------------------------------- +# okay, this is evil ... +drivers/net/wd.c #--- include/linux ------------------------------------------------------------ include/linux/atm.h include/linux/atm_eni.h diff -ur --new-file old/atm/switch/Makefile new/atm/switch/Makefile --- old/atm/switch/Makefile Thu Oct 1 19:43:25 1998 +++ new/atm/switch/Makefile Thu Feb 24 17:13:11 2000 @@ -2,7 +2,7 @@ LIBDEPS=../lib/libatmd.a SW_OBJS=control.o dispatch.o proto.o relay.o route.o sig.o lex.yy.o y.tab.o SUBDIRS=debug tcp -SYSPGMS=swc +PGMS=swc all: diff -ur --new-file old/atm/switch/debug/Makefile new/atm/switch/debug/Makefile --- old/atm/switch/debug/Makefile Tue Aug 4 19:55:05 1998 +++ new/atm/switch/debug/Makefile Thu Feb 24 17:11:09 2000 @@ -2,7 +2,7 @@ LIBDEPS=../../lib/libatmd.a ../libsw.a INCLUDES=-I../../qgen OBJS=debug.o -SYSPGMS=sw_debug +PGMS=sw_debug include ../Rules.make diff -ur --new-file old/atm/switch/tcp/Makefile new/atm/switch/tcp/Makefile --- old/atm/switch/tcp/Makefile Thu Oct 1 22:45:27 1998 +++ new/atm/switch/tcp/Makefile Thu Feb 24 17:11:31 2000 @@ -2,7 +2,7 @@ LIBDEPS=../../lib/libatmd.a ../libsw.a INCLUDES=-I../../qgen OBJS=tcpsw.o -SYSPGMS=sw_tcp +PGMS=sw_tcp include ../Rules.make diff -ur --new-file old/atm/test/Makefile new/atm/test/Makefile --- old/atm/test/Makefile Fri Jan 21 16:09:34 2000 +++ new/atm/test/Makefile Thu Feb 24 17:08:54 2000 @@ -1,5 +1,6 @@ ISP_OBJS=isp.o lex.yy.o y.tab.o -USRPGMS=align aping aread awrite br bw isp ttcp_atm window +USRPGMS=aread awrite ttcp_atm +PGMS=align aping br bw isp window MAN1= TRASH=errnos.inc .