From: Jan Kiszka <jan.kis...@siemens.com>

This was once (2004) added to cater a special x86 platform with ISA
interface. That one is long dead, and now the driver stops building on
5.15, reminding of its old Frankenstein logic. Time to bury it.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---
 .gitlab-ci.yml                           |    1 -
 kernel/drivers/net/drivers/Kconfig       |    5 -
 kernel/drivers/net/drivers/Makefile      |    4 -
 kernel/drivers/net/drivers/rt_smc91111.h |  566 ----
 kernel/drivers/net/drivers/smc91111.c    | 3531 ----------------------
 5 files changed, 4107 deletions(-)
 delete mode 100644 kernel/drivers/net/drivers/rt_smc91111.h
 delete mode 100644 kernel/drivers/net/drivers/smc91111.c

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e4f35f2c45..859a12b89b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -130,7 +130,6 @@ variables:
     - ./scripts/config -m XENO_DRIVERS_NET_DRV_VIA_RHINE
     - ./scripts/config -m XENO_DRIVERS_NET_DRV_IGB
     - ./scripts/config -m XENO_DRIVERS_NET_DRV_R8169
-    - ./scripts/config -m XENO_DRIVERS_NET_DRV_SMC91111
     - ./scripts/config -e XENO_DRIVERS_NET_EXP_DRIVERS
     - ./scripts/config -m XENO_DRIVERS_NET_DRV_3C59X
     - ./scripts/config -m XENO_DRIVERS_NET_DRV_E1000_NEW
diff --git a/kernel/drivers/net/drivers/Kconfig 
b/kernel/drivers/net/drivers/Kconfig
index 7a9d27e386..3a90dd8abe 100644
--- a/kernel/drivers/net/drivers/Kconfig
+++ b/kernel/drivers/net/drivers/Kconfig
@@ -84,11 +84,6 @@ config XENO_DRIVERS_NET_DRV_LOOPBACK
     tristate "Loopback"
     default y
 
-
-config XENO_DRIVERS_NET_DRV_SMC91111
-    depends on XENO_DRIVERS_NET
-    tristate "SMSC LAN91C111"
-
 if ARM
 
 config XENO_DRIVERS_NET_DRV_AT91_ETHER
diff --git a/kernel/drivers/net/drivers/Makefile 
b/kernel/drivers/net/drivers/Makefile
index 6c715abc00..97cf0c3b12 100644
--- a/kernel/drivers/net/drivers/Makefile
+++ b/kernel/drivers/net/drivers/Makefile
@@ -36,10 +36,6 @@ obj-$(CONFIG_XENO_DRIVERS_NET_DRV_PCNET32) += rt_pcnet32.o
 
 rt_pcnet32-y := pcnet32.o
 
-obj-$(CONFIG_XENO_DRIVERS_NET_DRV_SMC91111) += rt_smc91111.o
-
-rt_smc91111-y := smc91111.o
-
 obj-$(CONFIG_XENO_DRIVERS_NET_DRV_MACB) += rt_macb.o
 
 rt_macb-y := macb.o
diff --git a/kernel/drivers/net/drivers/rt_smc91111.h 
b/kernel/drivers/net/drivers/rt_smc91111.h
deleted file mode 100644
index da39e17238..0000000000
--- a/kernel/drivers/net/drivers/rt_smc91111.h
+++ /dev/null
@@ -1,566 +0,0 @@
-/*------------------------------------------------------------------------
- . smc91111.h - macros for the LAN91C111 Ethernet Driver
- .
- . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- .       Developed by Simple Network Magic Corporation (SNMC)
- . Copyright (C) 1996 by Erik Stahlman (ES)
- .
- . 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
- .
- . This file contains register information and access macros for 
- . the LAN91C111 single chip ethernet controller.  It is a modified
- . version of the smc9194.h file.
- . 
- . Information contained in this file was obtained from the LAN91C111
- . manual from SMC.  To get a copy, if you really want one, you can find 
- . information under www.smsc.com.
- . 
- . Authors
- .     Erik Stahlman                           ( e...@vt.edu )
- .     Daris A Nevil                           ( dne...@snmc.com )
- .
- . History
- . 03/16/01            Daris A Nevil   Modified for use with LAN91C111 device
- .
- ---------------------------------------------------------------------------*/
-#ifndef _SMC91111_H_
-#define _SMC91111_H_
-
-/* I want some simple types */
-
-typedef unsigned char                  byte;
-typedef unsigned short                 word;
-typedef unsigned long int              dword;
-
-
-/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
-
-#define SMC_IO_EXTENT  16
-
-
-/*---------------------------------------------------------------
- .  
- . A description of the SMSC registers is probably in order here,
- . although for details, the SMC datasheet is invaluable.  
- . 
- . Basically, the chip has 4 banks of registers ( 0 to 3 ), which
- . are accessed by writing a number into the BANK_SELECT register
- . ( I also use a SMC_SELECT_BANK macro for this ).
- . 
- . The banks are configured so that for most purposes, bank 2 is all
- . that is needed for simple run time tasks.  
- -----------------------------------------------------------------------*/
-
-/*
- . Bank Select Register: 
- .
- .             yyyy yyyy 0000 00xx  
- .             xx              = bank number
- .             yyyy yyyy       = 0x33, for identification purposes.
-*/
-#define        BANK_SELECT             14
-
-// Transmit Control Register
-/* BANK 0  */
-#define        TCR_REG         0x0000  // transmit control register 
-#define TCR_ENABLE     0x0001  // When 1 we can transmit
-#define TCR_LOOP       0x0002  // Controls output pin LBK
-#define TCR_FORCOL     0x0004  // When 1 will force a collision
-#define TCR_PAD_EN     0x0080  // When 1 will pad tx frames < 64 bytes w/0
-#define TCR_NOCRC      0x0100  // When 1 will not append CRC to tx frames
-#define TCR_MON_CSN    0x0400  // When 1 tx monitors carrier
-#define TCR_FDUPLX     0x0800  // When 1 enables full duplex operation
-#define TCR_STP_SQET   0x1000  // When 1 stops tx if Signal Quality Error
-#define        TCR_EPH_LOOP    0x2000  // When 1 enables EPH block loopback
-#define        TCR_SWFDUP      0x8000  // When 1 enables Switched Full Duplex 
mode
-
-#define        TCR_CLEAR       0       /* do NOTHING */
-/* the default settings for the TCR register : */ 
-/* QUESTION: do I want to enable padding of short packets ? */
-#define        TCR_DEFAULT     TCR_ENABLE 
-
-
-// EPH Status Register
-/* BANK 0  */
-#define EPH_STATUS_REG 0x0002
-#define ES_TX_SUC      0x0001  // Last TX was successful
-#define ES_SNGL_COL    0x0002  // Single collision detected for last tx
-#define ES_MUL_COL     0x0004  // Multiple collisions detected for last tx
-#define ES_LTX_MULT    0x0008  // Last tx was a multicast
-#define ES_16COL       0x0010  // 16 Collisions Reached
-#define ES_SQET                0x0020  // Signal Quality Error Test
-#define ES_LTXBRD      0x0040  // Last tx was a broadcast
-#define ES_TXDEFR      0x0080  // Transmit Deferred
-#define ES_LATCOL      0x0200  // Late collision detected on last tx
-#define ES_LOSTCARR    0x0400  // Lost Carrier Sense
-#define ES_EXC_DEF     0x0800  // Excessive Deferral
-#define ES_CTR_ROL     0x1000  // Counter Roll Over indication
-#define ES_LINK_OK     0x4000  // Driven by inverted value of nLNK pin
-#define ES_TXUNRN      0x8000  // Tx Underrun
-
-
-// Receive Control Register
-/* BANK 0  */
-#define        RCR_REG         0x0004
-#define        RCR_RX_ABORT    0x0001  // Set if a rx frame was aborted
-#define        RCR_PRMS        0x0002  // Enable promiscuous mode
-#define        RCR_ALMUL       0x0004  // When set accepts all multicast frames
-#define RCR_RXEN       0x0100  // IFF this is set, we can receive packets
-#define        RCR_STRIP_CRC   0x0200  // When set strips CRC from rx packets
-#define        RCR_ABORT_ENB   0x0200  // When set will abort rx on collision 
-#define        RCR_FILT_CAR    0x0400  // When set filters leading 12 bit s of 
carrier
-#define RCR_SOFTRST    0x8000  // resets the chip
-
-/* the normal settings for the RCR register : */
-#define        RCR_DEFAULT     (RCR_STRIP_CRC | RCR_RXEN)
-#define RCR_CLEAR      0x0     // set it to a base state
-
-// Counter Register
-/* BANK 0  */
-#define        COUNTER_REG     0x0006
-
-// Memory Information Register
-/* BANK 0  */
-#define        MIR_REG         0x0008
-
-// Receive/Phy Control Register
-/* BANK 0  */
-#define        RPC_REG         0x000A
-#define        RPC_SPEED       0x2000  // When 1 PHY is in 100Mbps mode.
-#define        RPC_DPLX        0x1000  // When 1 PHY is in Full-Duplex Mode
-#define        RPC_ANEG        0x0800  // When 1 PHY is in Auto-Negotiate Mode
-#define        RPC_LSXA_SHFT   5       // Bits to shift LS2A,LS1A,LS0A to lsb
-#define        RPC_LSXB_SHFT   2       // Bits to get LS2B,LS1B,LS0B to lsb
-#define RPC_LED_100_10 (0x00)  // LED = 100Mbps OR's with 10Mbps link detect
-#define RPC_LED_RES    (0x01)  // LED = Reserved
-#define RPC_LED_10     (0x02)  // LED = 10Mbps link detect
-#define RPC_LED_FD     (0x03)  // LED = Full Duplex Mode
-#define RPC_LED_TX_RX  (0x04)  // LED = TX or RX packet occurred
-#define RPC_LED_100    (0x05)  // LED = 100Mbps link dectect
-#define RPC_LED_TX     (0x06)  // LED = TX packet occurred
-#define RPC_LED_RX     (0x07)  // LED = RX packet occurred
-#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD 
<< RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
-
-/* Bank 0 0x000C is reserved */
-
-// Bank Select Register
-/* All Banks */
-#define BSR_REG        0x000E
-
-
-// Configuration Reg
-/* BANK 1 */
-#define CONFIG_REG     0x0000
-#define CONFIG_EXT_PHY 0x0200  // 1=external MII, 0=internal Phy
-#define CONFIG_GPCNTRL 0x0400  // Inverse value drives pin nCNTRL
-#define CONFIG_NO_WAIT 0x1000  // When 1 no extra wait states on ISA bus
-#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
-
-// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
-#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
-
-
-// Base Address Register
-/* BANK 1 */
-#define        BASE_REG        0x0002
-
-
-// Individual Address Registers
-/* BANK 1 */
-#define        ADDR0_REG       0x0004
-#define        ADDR1_REG       0x0006
-#define        ADDR2_REG       0x0008
-
-
-// General Purpose Register
-/* BANK 1 */
-#define        GP_REG          0x000A
-
-
-// Control Register
-/* BANK 1 */
-#define        CTL_REG         0x000C
-#define CTL_RCV_BAD    0x4000 // When 1 bad CRC packets are received
-#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
-#define        CTL_LE_ENABLE   0x0080 // When 1 enables Link Error interrupt
-#define        CTL_CR_ENABLE   0x0040 // When 1 enables Counter Rollover 
interrupt
-#define        CTL_TE_ENABLE   0x0020 // When 1 enables Transmit Error 
interrupt
-#define        CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
-#define        CTL_RELOAD      0x0002 // When set reads EEPROM into registers
-#define        CTL_STORE       0x0001 // When set stores registers into EEPROM
-
-
-// MMU Command Register
-/* BANK 2 */
-#define MMU_CMD_REG    0x0000
-#define MC_BUSY                1       // When 1 the last release has not 
completed
-#define MC_NOP         (0<<5)  // No Op
-#define        MC_ALLOC        (1<<5)  // OR with number of 256 byte packets
-#define        MC_RESET        (2<<5)  // Reset MMU to initial state
-#define        MC_REMOVE       (3<<5)  // Remove the current rx packet
-#define MC_RELEASE     (4<<5)  // Remove and release the current rx packet
-#define MC_FREEPKT     (5<<5)  // Release packet in PNR register
-#define MC_ENQUEUE     (6<<5)  // Enqueue the packet for transmit
-#define MC_RSTTXFIFO   (7<<5)  // Reset the TX FIFOs
-
-
-// Packet Number Register
-/* BANK 2 */
-#define        PN_REG          0x0002
-
-
-// Allocation Result Register
-/* BANK 2 */
-#define        AR_REG          0x0003
-#define AR_FAILED      0x80    // Alocation Failed
-
-
-// RX FIFO Ports Register
-/* BANK 2 */
-#define RXFIFO_REG     0x0004  // Must be read as a word
-#define RXFIFO_REMPTY  0x8000  // RX FIFO Empty
-
-
-// TX FIFO Ports Register
-/* BANK 2 */
-#define TXFIFO_REG     RXFIFO_REG      // Must be read as a word
-#define TXFIFO_TEMPTY  0x80    // TX FIFO Empty
-
-
-// Pointer Register
-/* BANK 2 */
-#define PTR_REG                0x0006
-#define        PTR_RCV         0x8000 // 1=Receive area, 0=Transmit area
-#define        PTR_AUTOINC     0x4000 // Auto increment the pointer on each 
access
-#define PTR_READ       0x2000 // When 1 the operation is a read
-
-
-// Data Register
-/* BANK 2 */
-#define        DATA_REG        0x0008
-
-
-// Interrupt Status/Acknowledge Register
-/* BANK 2 */
-#define        INT_REG         0x000C
-
-
-// Interrupt Mask Register
-/* BANK 2 */
-#define IM_REG         0x000D
-#define        IM_MDINT        0x80 // PHY MI Register 18 Interrupt
-#define        IM_ERCV_INT     0x40 // Early Receive Interrupt
-#define        IM_EPH_INT      0x20 // Set by Etheret Protocol Handler section
-#define        IM_RX_OVRN_INT  0x10 // Set by Receiver Overruns
-#define        IM_ALLOC_INT    0x08 // Set when allocation request is completed
-#define        IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty
-#define        IM_TX_INT       0x02 // Transmit Interrrupt
-#define IM_RCV_INT     0x01 // Receive Interrupt
-
-
-// Multicast Table Registers
-/* BANK 3 */
-#define        MCAST_REG1      0x0000
-#define        MCAST_REG2      0x0002
-#define        MCAST_REG3      0x0004
-#define        MCAST_REG4      0x0006
-
-
-// Management Interface Register (MII)
-/* BANK 3 */
-#define        MII_REG         0x0008
-#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup
-#define MII_MDOE       0x0008 // MII Output Enable
-#define MII_MCLK       0x0004 // MII Clock, pin MDCLK
-#define MII_MDI                0x0002 // MII Input, pin MDI
-#define MII_MDO                0x0001 // MII Output, pin MDO
-
-
-// Revision Register
-/* BANK 3 */
-#define        REV_REG         0x000A /* ( hi: chip id   low: rev # ) */
-
-
-// Early RCV Register
-/* BANK 3 */
-/* this is NOT on SMC9192 */
-#define        ERCV_REG        0x000C
-#define ERCV_RCV_DISCRD        0x0080 // When 1 discards a packet being 
received
-#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
-
-// External Register
-/* BANK 7 */
-#define        EXT_REG         0x0000
-
-
-#define CHIP_9192      3
-#define CHIP_9194      4
-#define CHIP_9195      5
-#define CHIP_9196      6
-#define CHIP_91100     7
-#define CHIP_91100FD   8
-#define CHIP_91111FD   9
-
-static const char * chip_ids[ 15 ] =  { 
-       NULL, NULL, NULL, 
-       /* 3 */ "SMC91C90/91C92",
-       /* 4 */ "SMC91C94",
-       /* 5 */ "SMC91C95",
-       /* 6 */ "SMC91C96",
-       /* 7 */ "SMC91C100", 
-       /* 8 */ "SMC91C100FD", 
-       /* 9 */ "SMC91C11xFD", 
-       NULL, NULL, 
-       NULL, NULL, NULL};  
-
-/* 
- . Transmit status bits 
-*/
-#define TS_SUCCESS 0x0001
-#define TS_LOSTCAR 0x0400
-#define TS_LATCOL  0x0200
-#define TS_16COL   0x0010
-
-/*
- . Receive status bits
-*/
-#define RS_ALGNERR     0x8000
-#define RS_BRODCAST    0x4000
-#define RS_BADCRC      0x2000
-#define RS_ODDFRAME    0x1000  // bug: the LAN91C111 never sets this on receive
-#define RS_TOOLONG     0x0800
-#define RS_TOOSHORT    0x0400
-#define RS_MULTICAST   0x0001
-#define RS_ERRORS      (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) 
-
-
-// PHY Types
-enum {
-       PHY_LAN83C183 = 1,      // LAN91C111 Internal PHY
-       PHY_LAN83C180
-};
-
-
-// PHY Register Addresses (LAN91C111 Internal PHY)
-
-// PHY Control Register
-#define PHY_CNTL_REG           0x00
-#define PHY_CNTL_RST           0x8000  // 1=PHY Reset
-#define PHY_CNTL_LPBK          0x4000  // 1=PHY Loopback
-#define PHY_CNTL_SPEED         0x2000  // 1=100Mbps, 0=10Mpbs
-#define PHY_CNTL_ANEG_EN       0x1000 // 1=Enable Auto negotiation
-#define PHY_CNTL_PDN           0x0800  // 1=PHY Power Down mode
-#define PHY_CNTL_MII_DIS       0x0400  // 1=MII 4 bit interface disabled
-#define PHY_CNTL_ANEG_RST      0x0200 // 1=Reset Auto negotiate
-#define PHY_CNTL_DPLX          0x0100  // 1=Full Duplex, 0=Half Duplex
-#define PHY_CNTL_COLTST                0x0080  // 1= MII Colision Test
-
-// PHY Status Register
-#define PHY_STAT_REG           0x01
-#define PHY_STAT_CAP_T4                0x8000  // 1=100Base-T4 capable
-#define PHY_STAT_CAP_TXF       0x4000  // 1=100Base-X full duplex capable
-#define PHY_STAT_CAP_TXH       0x2000  // 1=100Base-X half duplex capable
-#define PHY_STAT_CAP_TF                0x1000  // 1=10Mbps full duplex capable
-#define PHY_STAT_CAP_TH                0x0800  // 1=10Mbps half duplex capable
-#define PHY_STAT_CAP_SUPR      0x0040  // 1=recv mgmt frames with not preamble
-#define PHY_STAT_ANEG_ACK      0x0020  // 1=ANEG has completed
-#define PHY_STAT_REM_FLT       0x0010  // 1=Remote Fault detected
-#define PHY_STAT_CAP_ANEG      0x0008  // 1=Auto negotiate capable
-#define PHY_STAT_LINK          0x0004  // 1=valid link
-#define PHY_STAT_JAB           0x0002  // 1=10Mbps jabber condition
-#define PHY_STAT_EXREG         0x0001  // 1=extended registers implemented
-
-// PHY Identifier Registers
-#define PHY_ID1_REG            0x02    // PHY Identifier 1
-#define PHY_ID2_REG            0x03    // PHY Identifier 2
-
-// PHY Auto-Negotiation Advertisement Register
-#define PHY_AD_REG             0x04
-#define PHY_AD_NP              0x8000  // 1=PHY requests exchange of Next Page
-#define PHY_AD_ACK             0x4000  // 1=got link code word from remote
-#define PHY_AD_RF              0x2000  // 1=advertise remote fault
-#define PHY_AD_T4              0x0200  // 1=PHY is capable of 100Base-T4
-#define PHY_AD_TX_FDX          0x0100  // 1=PHY is capable of 100Base-TX FDPLX
-#define PHY_AD_TX_HDX          0x0080  // 1=PHY is capable of 100Base-TX HDPLX
-#define PHY_AD_10_FDX          0x0040  // 1=PHY is capable of 10Base-T FDPLX
-#define PHY_AD_10_HDX          0x0020  // 1=PHY is capable of 10Base-T HDPLX
-#define PHY_AD_CSMA            0x0001  // 1=PHY is capable of 802.3 CMSA
-
-// PHY Auto-negotiation Remote End Capability Register
-#define PHY_RMT_REG            0x05
-// Uses same bit definitions as PHY_AD_REG
-
-// PHY Configuration Register 1
-#define PHY_CFG1_REG           0x10
-#define PHY_CFG1_LNKDIS                0x8000  // 1=Rx Link Detect Function 
disabled
-#define PHY_CFG1_XMTDIS                0x4000  // 1=TP Transmitter Disabled
-#define PHY_CFG1_XMTPDN                0x2000  // 1=TP Transmitter Powered Down
-#define PHY_CFG1_BYPSCR                0x0400  // 1=Bypass 
scrambler/descrambler
-#define PHY_CFG1_UNSCDS                0x0200  // 1=Unscramble Idle Reception 
Disable
-#define PHY_CFG1_EQLZR         0x0100  // 1=Rx Equalizer Disabled
-#define PHY_CFG1_CABLE         0x0080  // 1=STP(150ohm), 0=UTP(100ohm)
-#define PHY_CFG1_RLVL0         0x0040  // 1=Rx Squelch level reduced by 4.5db
-#define PHY_CFG1_TLVL_SHIFT    2       // Transmit Output Level Adjust
-#define PHY_CFG1_TLVL_MASK     0x003C
-#define PHY_CFG1_TRF_MASK      0x0003  // Transmitter Rise/Fall time
-
-
-// PHY Configuration Register 2
-#define PHY_CFG2_REG           0x11
-#define PHY_CFG2_APOLDIS       0x0020  // 1=Auto Polarity Correction disabled
-#define PHY_CFG2_JABDIS                0x0010  // 1=Jabber disabled
-#define PHY_CFG2_MREG          0x0008  // 1=Multiple register access (MII mgt)
-#define PHY_CFG2_INTMDIO       0x0004  // 1=Interrupt signaled with MDIO pulseo
-
-// PHY Status Output (and Interrupt status) Register
-#define PHY_INT_REG            0x12    // Status Output (Interrupt Status)
-#define PHY_INT_INT            0x8000  // 1=bits have changed since last read
-#define        PHY_INT_LNKFAIL         0x4000  // 1=Link Not detected
-#define PHY_INT_LOSSSYNC       0x2000  // 1=Descrambler has lost sync
-#define PHY_INT_CWRD           0x1000  // 1=Invalid 4B5B code detected on rx
-#define PHY_INT_SSD            0x0800  // 1=No Start Of Stream detected on rx
-#define PHY_INT_ESD            0x0400  // 1=No End Of Stream detected on rx
-#define PHY_INT_RPOL           0x0200  // 1=Reverse Polarity detected
-#define PHY_INT_JAB            0x0100  // 1=Jabber detected
-#define PHY_INT_SPDDET         0x0080  // 1=100Base-TX mode, 0=10Base-T mode
-#define PHY_INT_DPLXDET                0x0040  // 1=Device in Full Duplex
-
-// PHY Interrupt/Status Mask Register
-#define PHY_MASK_REG           0x13    // Interrupt Mask
-// Uses the same bit definitions as PHY_INT_REG
-
-
-
-/*-------------------------------------------------------------------------
- .  I define some macros to make it easier to do somewhat common
- . or slightly complicated, repeated tasks. 
- --------------------------------------------------------------------------*/
-
-/* select a register bank, 0 to 3  */
-
-#define SMC_SELECT_BANK(x)  { outw( x, ioaddr + BANK_SELECT ); } 
-
-/* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = inb( ioaddr + IM_REG );\
-               mask |= (x);\
-               outb( mask, ioaddr + IM_REG ); \
-}
-
-/* this disables an interrupt from the interrupt mask register */
-
-#define SMC_DISABLE_INT(x) {\
-               unsigned char mask;\
-               SMC_SELECT_BANK(2);\
-               mask = inb( ioaddr + IM_REG );\
-               mask &= ~(x);\
-               outb( mask, ioaddr + IM_REG ); \
-}
-
-/*----------------------------------------------------------------------
- . Define the interrupts that I want to receive from the card
- . 
- . I want: 
- .  IM_EPH_INT, for nasty errors
- .  IM_RCV_INT, for happy received packets
- .  IM_RX_OVRN_INT, because I have to kick the receiver
- .  IM_MDINT, for PHY Register 18 Status Changes
- --------------------------------------------------------------------------*/
-#define SMC_INTERRUPT_MASK   (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
-       IM_MDINT) 
-
-
-#ifdef CONFIG_SYSCTL
-
-
-/*
- * Declarations for the sysctl interface, which allows users the ability to
- * control the finer aspects of the LAN91C111 chip.  Since the smc
- * module currently registers its sysctl table dynamically, the sysctl path
- * for module FOO is /proc/sys/dev/ethX/FOO
- */
-#define CTL_SMC         (CTL_BUS+1389)      // arbitrary and hopefully unused
-
-enum {
-       CTL_SMC_INFO = 1,       // Sysctl files information
-       CTL_SMC_SWVER,          // Driver Software Version Info
-       CTL_SMC_SWFDUP,         // Switched Full Duplex Mode
-       CTL_SMC_EPHLOOP,        // EPH Block Internal Loopback
-       CTL_SMC_MIIOP,          // MII Operation
-       CTL_SMC_AUTONEG,        // Auto-negotiate Mode
-       CTL_SMC_RFDUPLX,        // Request Full Duplex Mode
-       CTL_SMC_RSPEED,         // Request Speed Selection
-       CTL_SMC_AFDUPLX,        // Actual Full Duplex Mode
-       CTL_SMC_ASPEED,         // Actual Speed Selection
-       CTL_SMC_LNKFAIL,        // Link Failed
-       CTL_SMC_FORCOL,         // Force a Collision
-       CTL_SMC_FILTCAR,        // Filter Carrier
-       CTL_SMC_FREEMEM,        // Free Buffer Memory
-       CTL_SMC_TOTMEM,         // Total Buffer Memory
-       CTL_SMC_LEDA,           // Output of LED-A
-       CTL_SMC_LEDB,           // Output of LED-B
-       CTL_SMC_CHIPREV,        // LAN91C111 Chip Revision ID
-#ifdef SMC_DEBUG
-       // Register access for debugging
-       CTL_SMC_REG_BSR,        // Bank Select
-       CTL_SMC_REG_TCR,        // Transmit Control
-       CTL_SMC_REG_ESR,        // EPH Status
-       CTL_SMC_REG_RCR,        // Receive Control
-       CTL_SMC_REG_CTRR,       // Counter
-       CTL_SMC_REG_MIR,        // Memory Information
-       CTL_SMC_REG_RPCR,       // Receive/Phy Control
-       CTL_SMC_REG_CFGR,       // Configuration
-       CTL_SMC_REG_BAR,        // Base Address
-       CTL_SMC_REG_IAR0,       // Individual Address 0
-       CTL_SMC_REG_IAR1,       // Individual Address 1 
-       CTL_SMC_REG_IAR2,       // Individual Address 2
-       CTL_SMC_REG_GPR,        // General Purpose
-       CTL_SMC_REG_CTLR,       // Control
-       CTL_SMC_REG_MCR,        // MMU Command
-       CTL_SMC_REG_PNR,        // Packet Number
-       CTL_SMC_REG_FPR,        // FIFO Ports
-       CTL_SMC_REG_PTR,        // Pointer
-       CTL_SMC_REG_DR,         // Data 
-       CTL_SMC_REG_ISR,        // Interrupt Status
-       CTL_SMC_REG_MTR1,       // Multicast Table Entry 1
-       CTL_SMC_REG_MTR2,       // Multicast Table Entry 2
-       CTL_SMC_REG_MTR3,       // Multicast Table Entry 3
-       CTL_SMC_REG_MTR4,       // Multicast Table Entry 4
-       CTL_SMC_REG_MIIR,       // Management Interface
-       CTL_SMC_REG_REVR,       // Revision
-       CTL_SMC_REG_ERCVR,      // Early RCV
-       CTL_SMC_REG_EXTR,       // External
-       CTL_SMC_PHY_CTRL,       // PHY Control
-       CTL_SMC_PHY_STAT,       // PHY Status
-       CTL_SMC_PHY_ID1,        // PHY ID1
-       CTL_SMC_PHY_ID2,        // PHY ID2
-       CTL_SMC_PHY_ADC,        // PHY Advertise Capability
-       CTL_SMC_PHY_REMC,       // PHY Advertise Capability
-       CTL_SMC_PHY_CFG1,       // PHY Configuration 1
-       CTL_SMC_PHY_CFG2,       // PHY Configuration 2
-       CTL_SMC_PHY_INT,        // PHY Interrupt/Status Output
-       CTL_SMC_PHY_MASK,       // PHY Interrupt/Status Mask
-#endif
-       // ---------------------------------------------------
-       CTL_SMC_LAST_ENTRY      // Add new entries above the line
-};
-
-#endif // CONFIG_SYSCTL
- 
-#endif  /* _SMC_91111_H_ */
-
-
diff --git a/kernel/drivers/net/drivers/smc91111.c 
b/kernel/drivers/net/drivers/smc91111.c
deleted file mode 100644
index 07e1596b62..0000000000
--- a/kernel/drivers/net/drivers/smc91111.c
+++ /dev/null
@@ -1,3531 +0,0 @@
-/*------------------------------------------------------------------------
- . smc91111.c
- . This is a driver for SMSC's 91C111 single-chip Ethernet device.
- .
- . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- .       Developed by Simple Network Magic Corporation (SNMC)
- . Copyright (C) 1996 by Erik Stahlman (ES)
- .
- . 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
- .
- . Information contained in this file was obtained from the LAN91C111
- . manual from SMC.  To get a copy, if you really want one, you can find
- . information under www.smsc.com.
- .
- .
- . "Features" of the SMC chip:
- .   Integrated PHY/MAC for 10/100BaseT Operation
- .   Supports internal and external MII
- .   Integrated 8K packet memory
- .   EEPROM interface for configuration
- .
- . Arguments:
- .     io      = for the base address
- .     irq     = for the IRQ
- .     nowait  = 0 for normal wait states, 1 eliminates additional wait states
- .
- . author:
- .     Erik Stahlman                           ( e...@vt.edu )
- .     Daris A Nevil                           ( dne...@snmc.com )
- .     Pramod B Bhardwaj                       (pramod.bhard...@smsc.com)
- .
- .
- . Hardware multicast code from Peter Cammaert ( p...@denkart.be )
- .
- . Sources:
- .    o   SMSC LAN91C111 databook (www.smsc.com)
- .    o   smc9194.c by Erik Stahlman
- .    o   skeleton.c by Donald Becker ( bec...@cesdis.gsfc.nasa.gov )
- .
- . History:
- .    09/24/01  Pramod B Bhardwaj, Added the changes for Kernel 2.4
- .    08/21/01  Pramod B Bhardwaj Added support for RevB of LAN91C111
- .     04/25/01  Daris A Nevil  Initial public release through SMSC
- .     03/16/01  Daris A Nevil  Modified smc9194.c for use with LAN91C111
-
-       Ported to RTnet: March 2004, Jan Kiszka <jan.kis...@web.de>
- ----------------------------------------------------------------------------*/
-
-// Use power-down feature of the chip
-#define POWER_DOWN     1
-
-
-static const char version[] =
-       "SMSC LAN91C111 Driver (v2.0-rt), RTnet version - Jan Kiszka 
(jan.kis...@web.de)\n\n";
-
-#ifdef MODULE
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h> //#include <linux/malloc.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-//#include <linux/kcomp.h>
-
-#ifdef DISABLED____CONFIG_SYSCTL
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#endif
-
-#include <rtnet_port.h>
-
-#include "rt_smc91111.h"
-/*------------------------------------------------------------------------
- .
- . Configuration options, for the experienced user to change.
- .
- -------------------------------------------------------------------------*/
-
-/*
- . Do you want to use 32 bit xfers?  This should work on all chips, as
- . the chipset is designed to accommodate them.
-*/
-#define USE_32_BIT 1
-
-
-/*
- .the LAN91C111 can be at any of the following port addresses.  To change,
- .for a slightly different card, you can add it to the array.  Keep in
- .mind that the array must end in zero.
-*/
-static unsigned int smc_portlist[] __initdata =
-   { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
-        0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0};
-
-
-/*
- . Wait time for memory to be free.  This probably shouldn't be
- . tuned that much, as waiting for this means nothing else happens
- . in the system
-*/
-#define MEMORY_WAIT_TIME 16
-
-
-/*
- . Timeout in us for waiting on the completion of a previous MMU command
- . in smc_rcv().
-*/
-#define MMU_CMD_TIMEOUT 5
-
-
-/*
- . DEBUGGING LEVELS
- .
- . 0 for normal operation
- . 1 for slightly more details
- . >2 for various levels of increasingly useless information
- .    2 for interrupt tracking, status flags
- .    3 for packet info
- .    4 for complete packet dumps
-*/
-//#define SMC_DEBUG 3 // Must be defined in makefile
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2)
-#define PRINTK3(args...) rtdm_printk(args)
-#else
-#define PRINTK3(args...)
-#endif
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 1)
-#define PRINTK2(args...) rtdm_printk(args)
-#else
-#define PRINTK2(args...)
-#endif
-
-#ifdef SMC_DEBUG
-#define PRINTK(args...) rtdm_printk(args)
-#else
-#define PRINTK(args...)
-#endif
-
-
-/*------------------------------------------------------------------------
- .
- . The internal workings of the driver.  If you are changing anything
- . here with the SMC stuff, you should have the datasheet and know
- . what you are doing.
- .
- -------------------------------------------------------------------------*/
-#define CARDNAME "LAN91C111"
-
-// Memory sizing constant
-#define LAN91C111_MEMORY_MULTIPLIER    (1024*2)
-
-/* store this information for the driver.. */
-struct smc_local {
-
-// these are things that the kernel wants me to keep, so users
-       // can find out semi-useless statistics of how well the card is
-       // performing
-       struct net_device_stats stats;
-
-       // If I have to wait until memory is available to send
-       // a packet, I will store the skbuff here, until I get the
-       // desired memory.  Then, I'll send it out and free it.
-       struct rtskb * saved_skb;
-
-       // This keeps track of how many packets that I have
-       // sent out.  When an TX_EMPTY interrupt comes, I know
-       // that all of these have been sent.
-       int     packets_waiting;
-
-       // Set to true during the auto-negotiation sequence
-       int     autoneg_active;
-
-       // Address of our PHY port
-       word    phyaddr;
-
-       // Type of PHY
-       word    phytype;
-
-       // Last contents of PHY Register 18
-       word    lastPhy18;
-
-       // Contains the current active transmission mode
-       word    tcr_cur_mode;
-
-       // Contains the current active receive mode
-       word    rcr_cur_mode;
-
-       // Contains the current active receive/phy mode
-       word    rpc_cur_mode;
-
-       /* => Pramod, Odd Byte issue */
-       // Contains the Current ChipID
-       unsigned short ChipID;
-
-       //Contains the Current ChipRevision
-       unsigned short ChipRev;
-       /* <= Pramod, Odd Byte issue */
-
-#ifdef DISABLED____CONFIG_SYSCTL
-
-       // Root directory /proc/sys/dev
-       // Second entry must be null to terminate the table
-       ctl_table root_table[2];
-
-       // Directory for this device /proc/sys/dev/ethX
-       // Again the second entry must be zero to terminate
-       ctl_table eth_table[2];
-
-       // This is the parameters (file) table
-       ctl_table param_table[CTL_SMC_LAST_ENTRY];
-
-       // Saves the sysctl header returned by register_sysctl_table()
-       // we send this to unregister_sysctl_table()
-       struct ctl_table_header *sysctl_header;
-
-       // Parameter variables (files) go here
-       char ctl_info[1024];
-       int ctl_swfdup;
-       int ctl_ephloop;
-       int ctl_miiop;
-       int ctl_autoneg;
-       int ctl_rfduplx;
-       int ctl_rspeed;
-       int ctl_afduplx;
-       int ctl_aspeed;
-       int ctl_lnkfail;
-       int ctl_forcol;
-       int ctl_filtcar;
-       int ctl_freemem;
-       int ctl_totmem;
-       int ctl_leda;
-       int ctl_ledb;
-       int ctl_chiprev;
-#ifdef SMC_DEBUG
-       int ctl_reg_bsr;
-       int ctl_reg_tcr;
-       int ctl_reg_esr;
-       int ctl_reg_rcr;
-       int ctl_reg_ctrr;
-       int ctl_reg_mir;
-       int ctl_reg_rpcr;
-       int ctl_reg_cfgr;
-       int ctl_reg_bar;
-       int ctl_reg_iar0;
-       int ctl_reg_iar1;
-       int ctl_reg_iar2;
-       int ctl_reg_gpr;
-       int ctl_reg_ctlr;
-       int ctl_reg_mcr;
-       int ctl_reg_pnr;
-       int ctl_reg_fpr;
-       int ctl_reg_ptr;
-       int ctl_reg_dr;
-       int ctl_reg_isr;
-       int ctl_reg_mtr1;
-       int ctl_reg_mtr2;
-       int ctl_reg_mtr3;
-       int ctl_reg_mtr4;
-       int ctl_reg_miir;
-       int ctl_reg_revr;
-       int ctl_reg_ercvr;
-       int ctl_reg_extr;
-       int ctl_phy_ctrl;
-       int ctl_phy_stat;
-       int ctl_phy_id1;
-       int ctl_phy_id2;
-       int ctl_phy_adc;
-       int ctl_phy_remc;
-       int ctl_phy_cfg1;
-       int ctl_phy_cfg2;
-       int ctl_phy_int;
-       int ctl_phy_mask;
-#endif // SMC_DEBUG
-
-#endif // CONFIG_SYSCTL
-
-       rtdm_irq_t irq_handle;
-};
-
-
-/*-----------------------------------------------------------------
- .
- .  The driver can be entered at any of the following entry points.
- .
- .------------------------------------------------------------------  */
-
-/*
- . This is called by  register_netdev().  It is responsible for
- . checking the portlist for the SMC9000 series chipset.  If it finds
- . one, then it will initialize the device, find the hardware information,
- . and sets up the appropriate device parameters.
- . NOTE: Interrupts are *OFF* when this procedure is called.
- .
- . NB:This shouldn't be static since it is referred to externally.
-*/
-int smc_init(struct rtnet_device *dev);
-
-/*
- . This is called by  unregister_netdev().  It is responsible for
- . cleaning up before the driver is finally unregistered and discarded.
-*/
-//void smc_destructor(struct net_device *dev);
-
-/*
- . The kernel calls this function when someone wants to use the net_device,
- . typically 'ifconfig ethX up'.
-*/
-static int smc_open(struct rtnet_device *dev);
-
-/*
- . This is called by the kernel to send a packet out into the net.  it's
- . responsible for doing a best-effort send, but if it's simply not possible
- . to send it, the packet gets dropped.
-*/
-//static void smc_timeout (struct net_device *dev);*/
-/*
- . This is called by the kernel in response to 'ifconfig ethX down'.  It
- . is responsible for cleaning up everything that the open routine
- . does, and maybe putting the card into a powerdown state.
-*/
-static int smc_close(struct rtnet_device *dev);
-
-/*
- . This routine allows the proc file system to query the driver's
- . statistics.
-*/
-static struct net_device_stats *smc_query_statistics(struct rtnet_device 
*rtdev);
-
-/*
- . Finally, a call to set promiscuous mode ( for TCPDUMP and related
- . programs ) and multicast modes.
-*/
-static void smc_set_multicast_list(struct rtnet_device *dev);
-
-/*
- . Configures the PHY through the MII Management interface
-*/
-static void smc_phy_configure(struct rtnet_device* dev);
-
-/*---------------------------------------------------------------
- .
- . Interrupt level calls..
- .
- ----------------------------------------------------------------*/
-
-/*
- . Handles the actual interrupt
-*/
-static int smc_interrupt(rtdm_irq_t *irq_handle);
-/*
- . This is a separate procedure to handle the receipt of a packet, to
- . leave the interrupt code looking slightly cleaner
-*/
-inline static void smc_rcv( struct rtnet_device *dev );
-/*
- . This handles a TX interrupt, which is only called when an error
- . relating to a packet is sent.
-*/
-//inline static void smc_tx( struct net_device * dev );
-
-/*
- . This handles interrupts generated from PHY register 18
-*/
-//static void smc_phy_interrupt(struct net_device* dev);
-
-/*
- ------------------------------------------------------------
- .
- . Internal routines
- .
- ------------------------------------------------------------
-*/
-
-/*
- . Test if a given location contains a chip, trying to cause as
- . little damage as possible if it's not a SMC chip.
-*/
-static int smc_probe(struct rtnet_device *dev, int ioaddr);
-
-/*
- . A rather simple routine to print out a packet for debugging purposes.
-*/
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2)
-static void print_packet( byte *, int );
-#endif
-
-#define tx_done(dev) 1
-
-/* this is called to actually send the packet to the chip */
-static void smc_hardware_send_packet( struct rtnet_device * dev );
-
-/* Since I am not sure if I will have enough room in the chip's ram
- . to store the packet, I call this routine, which either sends it
- . now, or generates an interrupt when the card is ready for the
- . packet */
-static int  smc_wait_to_send_packet( struct rtskb * skb, struct rtnet_device 
*dev );
-
-/* this does a soft reset on the device */
-static void smc_reset( struct rtnet_device* dev );
-
-/* Enable Interrupts, Receive, and Transmit */
-static void smc_enable( struct rtnet_device *dev );
-
-/* this puts the device in an inactive state */
-static void smc_shutdown( int ioaddr );
-
-#ifndef NO_AUTOPROBE
-/* This routine will find the IRQ of the driver if one is not
- . specified in the input to the device.  */
-static int smc_findirq( int ioaddr );
-#endif
-
-/* Routines to Read and Write the PHY Registers across the
-   MII Management Interface
-*/
-
-static word smc_read_phy_register(int ioaddr, byte phyaddr, byte phyreg);
-static void smc_write_phy_register(int ioaddr, byte phyaddr, byte phyreg, word 
phydata);
-
-/* Initilizes our device's sysctl proc filesystem */
-
-#ifdef DISABLED____CONFIG_SYSCTL
-static void smc_sysctl_register(struct rtnet_device *);
-static void smc_sysctl_unregister(struct rtnet_device *);
-#endif /* CONFIG_SYSCTL */
-
-/*
- . Function: smc_reset( struct device* dev )
- . Purpose:
- .     This sets the SMC91111 chip to its normal state, hopefully from whatever
- .     mess that any other DOS driver has put it in.
- .
- . Maybe I should reset more registers to defaults in here?  SOFTRST  should
- . do that for me.
- .
- . Method:
- .     1.  send a SOFT RESET
- .     2.  wait for it to finish
- .     3.  enable autorelease mode
- .     4.  reset the memory management unit
- .     5.  clear all interrupts
- .
-*/
-static void smc_reset( struct rtnet_device* dev )
-{
-       //struct smc_local *lp  = (struct smc_local *)dev->priv;
-       int     ioaddr = dev->base_addr;
-
-       PRINTK2("%s:smc_reset\n", dev->name);
-
-       /* This resets the registers mostly to defaults, but doesn't
-          affect EEPROM.  That seems unnecessary */
-       SMC_SELECT_BANK( 0 );
-       outw( RCR_SOFTRST, ioaddr + RCR_REG );
-
-       /* Setup the Configuration Register */
-       /* This is necessary because the CONFIG_REG is not affected */
-       /* by a soft reset */
-
-       SMC_SELECT_BANK( 1 );
-       outw( CONFIG_DEFAULT, ioaddr + CONFIG_REG);
-
-       /* Setup for fast accesses if requested */
-       /* If the card/system can't handle it then there will */
-       /* be no recovery except for a hard reset or power cycle */
-
-       if (dev->dma)
-               outw( inw( ioaddr + CONFIG_REG ) | CONFIG_NO_WAIT,
-                       ioaddr + CONFIG_REG );
-
-#ifdef POWER_DOWN
-       /* Release from possible power-down state */
-       /* Configuration register is not affected by Soft Reset */
-       SMC_SELECT_BANK( 1 );
-       outw( inw( ioaddr + CONFIG_REG ) | CONFIG_EPH_POWER_EN,
-               ioaddr + CONFIG_REG  );
-#endif
-
-       SMC_SELECT_BANK( 0 );
-
-       /* this should pause enough for the chip to be happy */
-       mdelay(10);
-
-       /* Disable transmit and receive functionality */
-       outw( RCR_CLEAR, ioaddr + RCR_REG );
-       outw( TCR_CLEAR, ioaddr + TCR_REG );
-
-       /* set the control register to automatically
-          release successfully transmitted packets, to make the best
-          use out of our limited memory */
-       SMC_SELECT_BANK( 1 );
-       outw( inw( ioaddr + CTL_REG ) | CTL_AUTO_RELEASE , ioaddr + CTL_REG );
-
-       /* Reset the MMU */
-       SMC_SELECT_BANK( 2 );
-       outw( MC_RESET, ioaddr + MMU_CMD_REG );
-
-       /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
-          but this is a place where future chipsets _COULD_ break.  Be wary
-          of issuing another MMU command right after this */
-
-       /* Disable all interrupts */
-       outb( 0, ioaddr + IM_REG );
-}
-
-/*
- . Function: smc_enable
- . Purpose: let the chip talk to the outside work
- . Method:
- .     1.  Enable the transmitter
- .     2.  Enable the receiver
- .     3.  Enable interrupts
-*/
-static void smc_enable( struct rtnet_device *dev )
-{
-       unsigned short ioaddr   = dev->base_addr;
-       struct smc_local *lp    = (struct smc_local *)dev->priv;
-
-       PRINTK2("%s:smc_enable\n", dev->name);
-
-       SMC_SELECT_BANK( 0 );
-       /* see the header file for options in TCR/RCR DEFAULT*/
-       outw( lp->tcr_cur_mode, ioaddr + TCR_REG );
-       outw( lp->rcr_cur_mode, ioaddr + RCR_REG );
-
-       /* now, enable interrupts */
-       SMC_SELECT_BANK( 2 );
-       outb( SMC_INTERRUPT_MASK, ioaddr + IM_REG );
-}
-
-/*
- . Function: smc_shutdown
- . Purpose:  closes down the SMC91xxx chip.
- . Method:
- .     1. zero the interrupt mask
- .     2. clear the enable receive flag
- .     3. clear the enable xmit flags
- .
- . TODO:
- .   (1) maybe utilize power down mode.
- .     Why not yet?  Because while the chip will go into power down mode,
- .     the manual says that it will wake up in response to any I/O requests
- .     in the register space.   Empirical results do not show this working.
-*/
-static void smc_shutdown( int ioaddr )
-{
-       PRINTK2("CARDNAME:smc_shutdown\n");
-
-       /* no more interrupts for me */
-       SMC_SELECT_BANK( 2 );
-       outb( 0, ioaddr + IM_REG );
-
-       /* and tell the card to stay away from that nasty outside world */
-       SMC_SELECT_BANK( 0 );
-       outb( RCR_CLEAR, ioaddr + RCR_REG );
-       outb( TCR_CLEAR, ioaddr + TCR_REG );
-
-#ifdef POWER_DOWN
-       /* finally, shut the chip down */
-       SMC_SELECT_BANK( 1 );
-       outw( inw( ioaddr + CONFIG_REG ) & ~CONFIG_EPH_POWER_EN,
-               ioaddr + CONFIG_REG  );
-#endif
-}
-
-
-/*
- . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * )
- . Purpose:
- .    Attempt to allocate memory for a packet, if chip-memory is not
- .    available, then tell the card to generate an interrupt when it
- .    is available.
- .
- . Algorithm:
- .
- . o   if the saved_skb is not currently null, then drop this packet
- .     on the floor.  This should never happen, because of TBUSY.
- . o   if the saved_skb is null, then replace it with the current packet,
- . o   See if I can sending it now.
- . o   (NO): Enable interrupts and let the interrupt handler deal with it.
- . o   (YES):Send it now.
-*/
-static int smc_wait_to_send_packet( struct rtskb * skb, struct rtnet_device * 
dev )
-{
-       struct smc_local *lp    = (struct smc_local *)dev->priv;
-       unsigned short ioaddr   = dev->base_addr;
-       word                    length;
-       unsigned short          numPages;
-       word                    time_out;
-       word                    status;
-
-       PRINTK3("%s:smc_wait_to_send_packet\n", dev->name);
-
-       rtnetif_stop_queue(dev);
-
-       if ( lp->saved_skb) {
-               /* THIS SHOULD NEVER HAPPEN. */
-               lp->stats.tx_aborted_errors++;
-               rtdm_printk("%s: Bad Craziness - sent packet while busy.\n",
-                       dev->name);
-               return 1;
-       }
-       lp->saved_skb = skb;
-
-       length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
-
-       /*
-       ** The MMU wants the number of pages to be the number of 256 bytes
-       ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
-       **
-       ** The 91C111 ignores the size bits, but the code is left intact
-       ** for backwards and future compatibility.
-       **
-       ** Pkt size for allocating is data length +6 (for additional status
-       ** words, length and ctl!)
-       **
-       ** If odd size then last byte is included in this header.
-       */
-       numPages =   ((length & 0xfffe) + 6);
-       numPages >>= 8; // Divide by 256
-
-       if (numPages > 7 ) {
-               rtdm_printk("%s: Far too big packet error. \n", dev->name);
-               /* freeing the packet is a good thing here... but should
-                . any packets of this size get down here?   */
-               kfree_rtskb(skb);
-               lp->saved_skb = NULL;
-               /* this IS an error, but, i don't want the skb saved */
-               rtnetif_wake_queue(dev);
-               return 0;
-       }
-       /* either way, a packet is waiting now */
-       lp->packets_waiting++;
-
-       /* now, try to allocate the memory */
-       SMC_SELECT_BANK( 2 );
-       outw( MC_ALLOC | numPages, ioaddr + MMU_CMD_REG );
-       /*
-       . Performance Hack
-       .
-       . wait a short amount of time.. if I can send a packet now, I send
-       . it now.  Otherwise, I enable an interrupt and wait for one to be
-       . available.
-       .
-       . I could have handled this a slightly different way, by checking to
-       . see if any memory was available in the FREE MEMORY register.  However,
-       . either way, I need to generate an allocation, and the allocation works
-       . no matter what, so I saw no point in checking free memory.
-       */
-       time_out = MEMORY_WAIT_TIME;
-       do {
-               status = inb( ioaddr + INT_REG );
-               if ( status & IM_ALLOC_INT ) {
-                       /* acknowledge the interrupt */
-                       outb( IM_ALLOC_INT, ioaddr + INT_REG );
-                       break;
-               }
-       } while ( -- time_out );
-
-       if ( !time_out ) {
-               kfree_rtskb(skb);
-               lp->saved_skb = NULL;
-               rtnetif_wake_queue(dev);
-
-               rtdm_printk("%s: ERROR: unable to allocate card memory for "
-                       "packet transmission.\n", dev->name);
-               return 0;
-       }
-       /* or YES! I can send the packet now.. */
-       smc_hardware_send_packet(dev);
-       rtnetif_wake_queue(dev);
-       return 0;
-}
-
-/*
- . Function:  smc_hardware_send_packet(struct device * )
- . Purpose:
- .     This sends the actual packet to the SMC9xxx chip.
- .
- . Algorithm:
- .     First, see if a saved_skb is available.
- .             ( this should NOT be called if there is no 'saved_skb'
- .     Now, find the packet number that the chip allocated
- .     Point the data pointers at it in memory
- .     Set the length word in the chip's memory
- .     Dump the packet to chip memory
- .     Check if a last byte is needed ( odd length packet )
- .             if so, set the control flag right
- .     Tell the card to send it
- .     Enable the transmit interrupt, so I know if it failed
- .     Free the kernel data if I actually sent it.
-*/
-static void smc_hardware_send_packet( struct rtnet_device * dev )
-{
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       byte                    packet_no;
-       struct rtskb *  skb = lp->saved_skb;
-       word                    length;
-       unsigned short          ioaddr;
-       void                    * buf;
-       rtdm_lockctx_t          context;
-
-       PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
-
-       ioaddr = dev->base_addr;
-
-       if ( !skb ) {
-               PRINTK("%s: In XMIT with no packet to send \n", dev->name);
-               return;
-       }
-       length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-       buf = skb->data;
-
-       /* If I get here, I _know_ there is a packet slot waiting for me */
-       packet_no = inb( ioaddr + AR_REG );
-       if ( packet_no & AR_FAILED ) {
-               /* or isn't there?  BAD CHIP! */
-               rtdm_printk(KERN_DEBUG "%s: Memory allocation failed. \n",
-                       dev->name);
-               kfree_rtskb(skb);
-               lp->saved_skb = NULL;
-               rtnetif_wake_queue(dev);
-               return;
-       }
-
-       /* we have a packet address, so tell the card to use it */
-       outb( packet_no, ioaddr + PN_REG );
-
-       /* point to the beginning of the packet */
-       outw( PTR_AUTOINC , ioaddr + PTR_REG );
-
-       PRINTK3("%s: Trying to xmit packet of length %x\n",
-               dev->name, length);
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2)
-       rtdm_printk("Transmitting Packet\n");
-       print_packet( buf, length );
-#endif
-
-       /* send the packet length ( +6 for status, length and ctl byte )
-          and the status word ( set to zeros ) */
-#ifdef USE_32_BIT
-       outl(  (length +6 ) << 16 , ioaddr + DATA_REG );
-#else
-       outw( 0, ioaddr + DATA_REG );
-       /* send the packet length ( +6 for status words, length, and ctl*/
-       outb( (length+6) & 0xFF,ioaddr + DATA_REG );
-       outb( (length+6) >> 8 , ioaddr + DATA_REG );
-#endif
-
-       /* send the actual data
-        . I _think_ it's faster to send the longs first, and then
-        . mop up by sending the last word.  It depends heavily
-        . on alignment, at least on the 486.  Maybe it would be
-        . a good idea to check which is optimal?  But that could take
-        . almost as much time as is saved?
-       */
-#ifdef USE_32_BIT
-       outsl(ioaddr + DATA_REG, buf,  length >> 2 );
-       if ( length & 0x2  )
-               outw(*((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_REG);
-#else
-       outsw(ioaddr + DATA_REG , buf, (length ) >> 1);
-#endif // USE_32_BIT
-
-       /* Send the last byte, if there is one.   */
-       if ( (length & 1) == 0 ) {
-               outw( 0, ioaddr + DATA_REG );
-       } else {
-               outb( ((char *)buf)[length -1 ], ioaddr + DATA_REG );
-               outb( 0x20, ioaddr + DATA_REG); // Set odd bit in CONTROL BYTE
-       }
-
-       rtdm_lock_irqsave(context);
-
-       /* get and patch time stamp just before the transmission */
-       if (skb->xmit_stamp) {
-               nanosecs_abs_t xmit_stamp =
-                       cpu_to_be64(rtdm_clock_read() + *skb->xmit_stamp);
-
-               /* point to the patch address */
-               outw(PTR_AUTOINC |
-                       (4 + (char *)skb->xmit_stamp - (char *)skb->data),
-                       ioaddr + PTR_REG);
-               /* we don't check alignments, we just write bytes */
-               outsb(ioaddr + DATA_REG, (char *)&xmit_stamp,
-                       sizeof(xmit_stamp));
-       }
-
-       /* enable the interrupts */
-       SMC_ENABLE_INT( (IM_TX_INT | IM_TX_EMPTY_INT) );
-
-       /* and let the chipset deal with it */
-       outw( MC_ENQUEUE , ioaddr + MMU_CMD_REG );
-
-       rtdm_lock_irqrestore(context);
-
-       PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
-
-       lp->saved_skb = NULL;
-       kfree_rtskb(skb);
-
-//     dev->trans_start = jiffies;
-
-       /* we can send another packet */
-       rtnetif_wake_queue(dev);
-
-
-       return;
-}
-
-/*-------------------------------------------------------------------------
- |
- | smc_init( struct device * dev )
- |   Input parameters:
- |     dev->base_addr == 0, try to find all possible locations
- |     dev->base_addr == 1, return failure code
- |     dev->base_addr == 2, always allocate space,  and return success
- |     dev->base_addr == <anything else>   this is the address to check
- |
- |   Output:
- |     0 --> there is a device
- |     anything else, error
- |
- ---------------------------------------------------------------------------
-*/
-int __init smc_init(struct rtnet_device *dev)
-{
-       int i;
-       int base_addr = dev ? dev->base_addr : 0;
-
-       PRINTK2("CARDNAME:smc_init\n");
-
-       /*  try a specific location */
-       if (base_addr > 0x1ff)
-               return smc_probe(dev, base_addr);
-       else if ( 0 != base_addr )
-                       return -ENXIO;
-
-       /* check every ethernet address */
-       for (i = 0; smc_portlist[i]; i++)
-               if ( smc_probe(dev,smc_portlist[i]) ==0)
-                       return 0;
-
-       /* couldn't find anything */
-       return -ENODEV;
-}
-
-
-#ifndef NO_AUTOPROBE
-/*----------------------------------------------------------------------
- . smc_findirq
- .
- . This routine has a simple purpose -- make the SMC chip generate an
- . interrupt, so an auto-detect routine can detect it, and find the IRQ,
- ------------------------------------------------------------------------
-*/
-int __init smc_findirq( int ioaddr )
-{
-       int     timeout = 20;
-       unsigned long cookie;
-
-       PRINTK2("CARDNAME:smc_findirq\n");
-
-       /* I have to do a STI() here, because this is called from
-          a routine that does an CLI during this process, making it
-          rather difficult to get interrupts for auto detection */
-       local_irq_enable();
-
-       cookie = probe_irq_on();
-
-       /*
-        * What I try to do here is trigger an ALLOC_INT. This is done
-        * by allocating a small chunk of memory, which will give an interrupt
-        * when done.
-        */
-
-
-       SMC_SELECT_BANK(2);
-       /* enable ALLOCation interrupts ONLY */
-       outb( IM_ALLOC_INT, ioaddr + IM_REG );
-
-       /*
-        . Allocate 512 bytes of memory.  Note that the chip was just
-        . reset so all the memory is available
-       */
-       outw( MC_ALLOC | 1, ioaddr + MMU_CMD_REG );
-
-       /*
-        . Wait until positive that the interrupt has been generated
-       */
-       while ( timeout ) {
-               byte    int_status;
-
-               int_status = inb( ioaddr + INT_REG );
-
-               if ( int_status & IM_ALLOC_INT )
-                       break;          /* got the interrupt */
-               timeout--;
-       }
-
-       /* there is really nothing that I can do here if timeout fails,
-          as autoirq_report will return a 0 anyway, which is what I
-          want in this case.   Plus, the clean up is needed in both
-          cases.  */
-
-       /* DELAY HERE!
-          On a fast machine, the status might change before the interrupt
-          is given to the processor.  This means that the interrupt was
-          never detected, and autoirq_report fails to report anything.
-          This should fix autoirq_* problems.
-       */
-       mdelay(10);
-
-       /* and disable all interrupts again */
-       outb( 0, ioaddr + IM_REG );
-
-       /* clear hardware interrupts again, because that's how it
-          was when I was called... */
-       local_irq_disable();
-
-       /* and return what I found */
-       return probe_irq_off(cookie);
-}
-#endif
-
-/*----------------------------------------------------------------------
- . Function: smc_probe( int ioaddr )
- .
- . Purpose:
- .     Tests to see if a given ioaddr points to an SMC91111 chip.
- .     Returns a 0 on success
- .
- . Algorithm:
- .     (1) see if the high byte of BANK_SELECT is 0x33
- .     (2) compare the ioaddr with the base register's address
- .     (3) see if I recognize the chip ID in the appropriate register
- .
- .---------------------------------------------------------------------
- */
-/*---------------------------------------------------------------
- . Here I do typical initialization tasks.
- .
- . o  Initialize the structure if needed
- . o  print out my vanity message if not done so already
- . o  print out what type of hardware is detected
- . o  print out the ethernet address
- . o  find the IRQ
- . o  set up my private data
- . o  configure the dev structure with my subroutines
- . o  actually GRAB the irq.
- . o  GRAB the region
- .-----------------------------------------------------------------*/
-
-static int __init smc_probe(struct rtnet_device *dev, int ioaddr )
-{
-       int i, memory, retval;
-       static unsigned version_printed = 0;
-       unsigned int    bank;
-
-       const char *version_string;
-
-       /*registers */
-       word    revision_register;
-       word    base_address_register;
-       word    memory_info_register;
-       /*=> Pramod */
-       struct smc_local *lp;
-       /*<= Pramod */
-
-       PRINTK2("CARDNAME:smc_probe\n");
-
-       /* Grab the region so that no one else tries to probe our ioports. */
-       if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name)) return -EBUSY;
-
-       /* First, see if the high byte is 0x33 */
-       bank = inw( ioaddr + BANK_SELECT );
-       if ( (bank & 0xFF00) != 0x3300 ) return -ENODEV;
-
-       /* The above MIGHT indicate a device, but I need to write to further 
test this.  */
-       outw( 0x0, ioaddr + BANK_SELECT );
-       bank = inw( ioaddr + BANK_SELECT );
-       if ( (bank & 0xFF00 ) != 0x3300 )
-       {
-               retval = -ENODEV;
-               goto err_out;
-       }
-
-       /* well, we've already written once, so hopefully another time won't
-          hurt.  This time, I need to switch the bank register to bank 1,
-          so I can access the base address register */
-       SMC_SELECT_BANK(1);
-       base_address_register = inw( ioaddr + BASE_REG );
-       if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )
-       {
-               printk("CARDNAME: IOADDR %x doesn't match configuration (%x)."
-                       "Probably not a SMC chip\n",
-                       ioaddr, base_address_register >> 3 & 0x3E0 );
-               /* well, the base address register didn't match.  Must not have
-                  been a SMC chip after all. */
-               retval = -ENODEV;
-               goto err_out;
-       }
-
-       /*  check if the revision register is something that I recognize.
-           These might need to be added to later, as future revisions
-           could be added.  */
-       SMC_SELECT_BANK(3);
-       revision_register  = inw( ioaddr + REV_REG );
-       if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] )
-       {
-               /* I don't recognize this chip, so... */
-               printk("CARDNAME: IO %x: Unrecognized revision register:"
-                       " %x, Contact author. \n",
-                       ioaddr, revision_register );
-               retval =  -ENODEV;
-               goto err_out;
-       }
-
-       /* at this point I'll assume that the chip is an SMC9xxx.
-          It might be prudent to check a listing of MAC addresses
-          against the hardware address, or do some other tests. */
-
-       if (version_printed++ == 0)
-               printk("%s", version);
-
-       /* fill in some of the fields */
-       dev->base_addr = ioaddr;
-
-       /*
-        . Get the MAC address ( bank 1, regs 4 - 9 )
-       */
-       SMC_SELECT_BANK( 1 );
-       for ( i = 0; i < 6; i += 2 )
-       {
-               word    address;
-
-               address = inw( ioaddr + ADDR0_REG + i  );
-               dev->dev_addr[ i + 1] = address >> 8;
-               dev->dev_addr[ i ] = address & 0xFF;
-       }
-
-       /* get the memory information */
-
-       SMC_SELECT_BANK( 0 );
-       memory_info_register = inw( ioaddr + MIR_REG );
-       memory = memory_info_register & (word)0x00ff;
-       memory *= LAN91C111_MEMORY_MULTIPLIER;
-
-       /*
-        Now, I want to find out more about the chip.  This is sort of
-        redundant, but it's cleaner to have it in both, rather than having
-        one VERY long probe procedure.
-       */
-       SMC_SELECT_BANK(3);
-       revision_register  = inw( ioaddr + REV_REG );
-       version_string = chip_ids[ ( revision_register  >> 4 ) & 0xF  ];
-       if ( !version_string )
-       {
-               /* I shouldn't get here because this call was done before.... */
-               retval =  -ENODEV;
-               goto err_out;
-       }
-
-       /* now, reset the chip, and put it into a known state */
-       smc_reset( dev );
-
-       /*
-        . If dev->irq is 0, then the device has to be banged on to see
-        . what the IRQ is.
-        .
-        . This banging doesn't always detect the IRQ, for unknown reasons.
-        . a workaround is to reset the chip and try again.
-        .
-        . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
-        . be what is requested on the command line.   I don't do that, mostly
-        . because the card that I have uses a non-standard method of accessing
-        . the IRQs, and because this _should_ work in most configurations.
-        .
-        . Specifying an IRQ is done with the assumption that the user knows
-        . what (s)he is doing.  No checking is done!!!!
-        .
-       */
-       if ( dev->irq < 2 ) {
-               int     trials;
-
-               trials = 3;
-               while ( trials-- ) {
-                       dev->irq = smc_findirq( ioaddr );
-                       if ( dev->irq )
-                               break;
-                       /* kick the card and try again */
-                       smc_reset( dev );
-               }
-       }
-       if (dev->irq == 0 ) {
-               printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
-                       dev->name);
-               retval =  -ENODEV;
-               goto err_out;
-       }
-
-       if (dev->irq == 2) {
-               /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
-                * or don't know which one to set.
-                */
-               dev->irq = 9;
-       }
-
-       /* now, print out the card info, in a short format.. */
-
-       printk("%s: %s(rev:%d) at %#3x IRQ:%d MEMSIZE:%db NOWAIT:%d ",
-               dev->name,
-               version_string, revision_register & 0xF, ioaddr, dev->irq,
-               memory, dev->dma);
-       /*
-        . Print the Ethernet address
-       */
-       printk("ADDR: ");
-       for (i = 0; i < 5; i++)
-               printk("%2.2x:", dev->dev_addr[i] );
-       printk("%2.2x \n", dev->dev_addr[5] );
-
-
-       /* Initialize the private structure. */
-       /*if (dev->priv == NULL) {
-               dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
-               if (dev->priv == NULL) {
-                       retval = -ENOMEM;
-                       goto err_out;
-               }
-       }*/
-       /* set the private data to zero by default */
-       memset(dev->priv, 0, sizeof(struct smc_local));
-
-       /* Fill in the fields of the device structure with ethernet values. */
-//     ether_setup(dev);
-
-       rt_stack_connect(dev, &STACK_manager);
-
-       /* Grab the IRQ */
-    retval = rtdm_irq_request(&((struct smc_local *)dev->priv)->irq_handle,
-                             dev->irq, &smc_interrupt, 0,
-                             "rt_smx91111", dev);
-    if (retval) {
-         printk("%s: unable to get IRQ %d (irqval=%d).\n",
-               dev->name, dev->irq, retval);
-               //kfree (dev->priv);
-               //dev->priv = NULL;
-               goto err_out;
-       }
-
-       dev->open                       = smc_open;
-       dev->stop                       = smc_close;
-       dev->hard_start_xmit    = smc_wait_to_send_packet;
-       dev->get_stats                  = smc_query_statistics;
-//     dev->tx_timeout                 = smc_timeout;
-#ifdef HAVE_MULTICAST
-//     dev->set_multicast_list         = &smc_set_multicast_list;
-#endif
-
-       /* => Store the ChipRevision and ChipID, to be used in resolving the 
Odd-Byte issue in RevB of LAN91C111; Pramod */
-       SMC_SELECT_BANK(3);
-       revision_register  = inw( ioaddr + REV_REG );
-       lp = (struct smc_local *)dev->priv;
-       lp->ChipID = (revision_register >> 4) & 0xF;
-       lp->ChipRev = revision_register & 0xF;
-
-       return 0;
-
-err_out:
-       release_region (ioaddr, SMC_IO_EXTENT);
-       return retval;
-}
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2)
-static void print_packet( byte * buf, int length )
-{
-       int i;
-       int remainder;
-       int lines;
-
-       rtdm_printk("Packet of length %d \n", length );
-
-#if SMC_DEBUG > 3
-       lines = length / 16;
-       remainder = length % 16;
-
-       for ( i = 0; i < lines ; i ++ ) {
-               int cur;
-
-               for ( cur = 0; cur < 8; cur ++ ) {
-                       byte a, b;
-
-                       a = *(buf ++ );
-                       b = *(buf ++ );
-                       rtdm_printk("%02x%02x ", a, b );
-               }
-               rtdm_printk("\n");
-       }
-       for ( i = 0; i < remainder/2 ; i++ ) {
-               byte a, b;
-
-               a = *(buf ++ );
-               b = *(buf ++ );
-               rtdm_printk("%02x%02x ", a, b );
-       }
-       rtdm_printk("\n");
-#endif
-}
-#endif
-
-
-/*
- * Open and Initialize the board
- *
- * Set up everything, reset the card, etc ..
- *
- */
-static int smc_open(struct rtnet_device *dev)
-{
-       struct smc_local *lp    = (struct smc_local *)dev->priv;
-       int     ioaddr = dev->base_addr;
-       int     i;      /* used to set hw ethernet address */
-
-       PRINTK2("%s:smc_open\n", dev->name);
-
-       /* clear out all the junk that was put here before... */
-       memset(dev->priv, 0, (size_t)&((struct smc_local *)0)->irq_handle);
-
-       rtnetif_start_queue(dev);
-
-       // Setup the default Register Modes
-       lp->tcr_cur_mode = TCR_DEFAULT;
-       lp->rcr_cur_mode = RCR_DEFAULT;
-       lp->rpc_cur_mode = RPC_DEFAULT;
-
-#ifdef DISABLED____CONFIG_SYSCTL
-       // Set default parameters (files)
-       lp->ctl_swfdup = 0;
-       lp->ctl_ephloop = 0;
-       lp->ctl_miiop = 0;
-       lp->ctl_autoneg = 1;
-       lp->ctl_rfduplx = 1;
-       lp->ctl_rspeed = 100;
-       lp->ctl_afduplx = 1;
-       lp->ctl_aspeed = 100;
-       lp->ctl_lnkfail = 1;
-       lp->ctl_forcol = 0;
-       lp->ctl_filtcar = 0;
-#endif /* CONFIG_SYSCTL */
-
-       /* reset the hardware */
-
-       smc_reset( dev );
-       smc_enable( dev );
-
-       /* Configure the PHY */
-       smc_phy_configure(dev);
-
-       smc_set_multicast_list(dev);
-
-       /*
-               According to Becker, I have to set the hardware address
-               at this point, because the (l)user can set it with an
-               ioctl.  Easily done...
-       */
-       SMC_SELECT_BANK( 1 );
-       for ( i = 0; i < 6; i += 2 ) {
-               word    address;
-
-               address = dev->dev_addr[ i + 1 ] << 8 ;
-               address  |= dev->dev_addr[ i ];
-               outw( address, ioaddr + ADDR0_REG + i );
-       }
-
-#ifdef DISABLED____CONFIG_SYSCTL
-       smc_sysctl_register(dev);
-#endif /* CONFIG_SYSCTL */
-
-       rtnetif_start_queue(dev);
-       return 0;
-}
-
-/*-------------------------------------------------------------
- .
- . smc_rcv -  receive a packet from the card
- .
- . There is ( at least ) a packet waiting to be read from
- . chip-memory.
- .
- . o Read the status
- . o If an error, record it
- . o otherwise, read in the packet
- --------------------------------------------------------------
-*/
-static inline void smc_rcv(struct rtnet_device *dev)
-{
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       int     ioaddr = dev->base_addr;
-       int     packet_number;
-       word    status;
-       word    packet_length;
-       nanosecs_abs_t  time_stamp = rtdm_clock_read();
-       int             timeout;
-
-       PRINTK3("%s:smc_rcv\n", dev->name);
-
-       /* assume bank 2 */
-
-       packet_number = inw( ioaddr + RXFIFO_REG );
-
-       if ( packet_number & RXFIFO_REMPTY ) {
-
-               /* we got called , but nothing was on the FIFO */
-               PRINTK("%s: WARNING: smc_rcv with nothing on FIFO. \n",
-                       dev->name);
-               /* don't need to restore anything */
-               return;
-       }
-
-       /*  start reading from the start of the packet */
-       outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + PTR_REG );
-       inw( ioaddr + MMU_CMD_REG ); /* min delay to avoid errors... */
-
-       /* First two words are status and packet_length */
-       status          = inw( ioaddr + DATA_REG );
-       packet_length   = inw( ioaddr + DATA_REG );
-
-       packet_length &= 0x07ff;  /* mask off top bits */
-
-       PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
-
-       if ( !(status & RS_ERRORS ) ){
-               /* do stuff to make a new packet */
-               struct rtskb  * skb;
-               void            * data;
-
-               /* set multicast stats */
-               if ( status & RS_MULTICAST )
-                       lp->stats.multicast++;
-
-               // Allocate enough memory for entire receive frame, to be safe
-               skb = rtnetdev_alloc_rtskb(dev, packet_length);
-
-               /* Adjust for having already read the first two words */
-               packet_length -= 4;
-
-               if ( skb == NULL ) {
-                       rtdm_printk(KERN_NOTICE "%s: Low memory, packet 
dropped.\n",
-                               dev->name);
-                       lp->stats.rx_dropped++;
-                       goto done;
-               }
-
-               /*
-                ! This should work without alignment, but it could be
-                ! in the worse case
-               */
-               /* TODO: Should I use 32bit alignment here ? */
-               rtskb_reserve( skb, 2 );   /* 16 bit alignment */
-
-               /* =>
-    ODD-BYTE ISSUE : The odd byte problem has been fixed in the LAN91C111 Rev 
B.
-               So we check if the Chip Revision, stored in 
smsc_local->ChipRev, is = 1.
-               If so then we increment the packet length only if RS_ODDFRAME 
is set.
-               If the Chip's revision is equal to 0, then we blindly increment 
the packet length
-               by 1, thus always assuming that the packet is odd length, 
leaving the higher layer
-               to decide the actual length.
-                       -- Pramod
-               <= */
-               if ((9 == lp->ChipID) && (1 == lp->ChipRev))
-               {
-                       if (status & RS_ODDFRAME)
-                               data = rtskb_put( skb, packet_length + 1 );
-                       else
-                               data = rtskb_put( skb, packet_length);
-
-               }
-               else
-               {
-                       // set odd length for bug in LAN91C111, REV A
-                       // which never sets RS_ODDFRAME
-                       data = rtskb_put( skb, packet_length + 1 );
-               }
-
-#ifdef USE_32_BIT
-               PRINTK3(" Reading %d dwords (and %d bytes) \n",
-                       packet_length >> 2, packet_length & 3 );
-               /* QUESTION:  Like in the TX routine, do I want
-                  to send the DWORDs or the bytes first, or some
-                  mixture.  A mixture might improve already slow PIO
-                  performance  */
-               insl(ioaddr + DATA_REG , data, packet_length >> 2 );
-               /* read the left over bytes */
-               insb( ioaddr + DATA_REG, data + (packet_length & 0xFFFFFC),
-                       packet_length & 0x3  );
-#else
-               PRINTK3(" Reading %d words and %d byte(s) \n",
-                       (packet_length >> 1 ), packet_length & 1 );
-               insw(ioaddr + DATA_REG , data, packet_length >> 1);
-
-#endif // USE_32_BIT
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2)
-               rtdm_printk("Receiving Packet\n");
-               print_packet( data, packet_length );
-#endif
-
-               skb->protocol = rt_eth_type_trans(skb, dev );
-               skb->time_stamp = time_stamp;
-               rtnetif_rx(skb);
-               lp->stats.rx_packets++;
-       } else {
-               /* error ... */
-               lp->stats.rx_errors++;
-
-               if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;
-               if ( status & (RS_TOOSHORT | RS_TOOLONG ) )
-                       lp->stats.rx_length_errors++;
-               if ( status & RS_BADCRC)        lp->stats.rx_crc_errors++;
-       }
-
-       timeout = MMU_CMD_TIMEOUT;
-       while ( inw( ioaddr + MMU_CMD_REG ) & MC_BUSY ) {
-               rtdm_task_busy_sleep(1000); // Wait until not busy
-               if (--timeout == 0) {
-                       rtdm_printk("%s: ERROR: timeout while waiting on 
MMU.\n",
-                               dev->name);
-                       break;
-               }
-       }
-done:
-       /*  error or good, tell the card to get rid of this packet */
-       outw( MC_RELEASE, ioaddr + MMU_CMD_REG );
-
-       return;
-}
-
-/*--------------------------------------------------------------------
- .
- . This is the main routine of the driver, to handle the net_device when
- . it needs some attention.
- .
- . So:
- .   first, save state of the chipset
- .   branch off into routines to handle each case, and acknowledge
- .         each to the interrupt register
- .   and finally restore state.
- .
- ---------------------------------------------------------------------*/
-static int smc_interrupt(rtdm_irq_t *irq_handle)
-{
-       struct rtnet_device *dev = rtdm_irq_get_arg(irq_handle, struct 
rtnet_device);
-       int ioaddr              = dev->base_addr;
-       struct smc_local *lp    = (struct smc_local *)dev->priv;
-
-       byte    status;
-       word    card_stats;
-       byte    mask;
-       int     timeout;
-       /* state registers */
-       word    saved_bank;
-       word    saved_pointer;
-
-       unsigned int old_packet_cnt = lp->stats.rx_packets;
-
-
-
-       PRINTK3("%s: SMC interrupt started \n", dev->name);
-
-/*     if (dev == NULL) {
-               rtdm_printk(KERN_WARNING "%s: irq %d for unknown device.\n",
-                       dev->name, irq);
-               return;
-       }*/
-
-/* will Linux let this happen ??  If not, this costs some speed
-       if ( dev->interrupt ) {
-               printk(KERN_WARNING "%s: interrupt inside interrupt.\n",
-                       dev->name);
-               return;
-       }
-
-       dev->interrupt = 1; */
-
-       saved_bank = inw( ioaddr + BANK_SELECT );
-
-       SMC_SELECT_BANK(2);
-       saved_pointer = inw( ioaddr + PTR_REG );
-
-       /* read the interrupt status register */
-       mask = inb( ioaddr + IM_REG );
-
-       /* disable all interrupts */
-       outb( 0, ioaddr + IM_REG );
-
-       /*
-        * The packet reception will take some time (up to several hundred us).
-        * Re-enable other irqs now so that no critical deadline will be missed.
-        */
-       hard_local_irq_enable();
-
-       /* set a timeout value, so I don't stay here forever */
-       timeout = 4;
-
-       PRINTK2(KERN_WARNING "%s: MASK IS %x \n", dev->name, mask);
-       do {
-               /* read the status flag, and mask it */
-               status = inb( ioaddr + INT_REG ) & mask;
-               if (!status )
-                       break;
-
-               PRINTK3(KERN_WARNING "%s: Handling interrupt status %x \n",
-                       dev->name, status);
-
-               if (status & IM_RCV_INT) {
-                       /* Got a packet(s). */
-                       PRINTK2(KERN_WARNING
-                               "%s: Receive Interrupt\n", dev->name);
-                       smc_rcv(dev);
-               } else if (status & IM_TX_INT ) {
-                       rtdm_printk(KERN_ERR "%s: TX ERROR!\n", dev->name);
-                       //smc_tx(dev);
-                       // Acknowledge the interrupt
-                       outb(IM_TX_INT, ioaddr + INT_REG );
-               } else if (status & IM_TX_EMPTY_INT ) {
-                       /* update stats */
-                       SMC_SELECT_BANK( 0 );
-                       card_stats = inw( ioaddr + COUNTER_REG );
-                       /* single collisions */
-                       lp->stats.collisions += card_stats & 0xF;
-                       card_stats >>= 4;
-                       /* multiple collisions */
-                       lp->stats.collisions += card_stats & 0xF;
-
-                       /* these are for when linux supports these statistics */
-                       SMC_SELECT_BANK( 2 );
-                       PRINTK2(KERN_WARNING "%s: TX_BUFFER_EMPTY handled\n",
-                               dev->name);
-                       // Acknowledge the interrupt
-                       outb( IM_TX_EMPTY_INT, ioaddr + INT_REG );
-                       mask &= ~IM_TX_EMPTY_INT;
-                       lp->stats.tx_packets += lp->packets_waiting;
-                       lp->packets_waiting = 0;
-
-               } else if (status & IM_ALLOC_INT ) {
-                       PRINTK2(KERN_DEBUG "%s: Allocation interrupt \n",
-                               dev->name);
-                       /* clear this interrupt so it doesn't happen again */
-                       mask &= ~IM_ALLOC_INT;
-
-               } else if (status & IM_RX_OVRN_INT ) {
-                       lp->stats.rx_errors++;
-                       lp->stats.rx_fifo_errors++;
-                       // Acknowledge the interrupt
-                       outb( IM_RX_OVRN_INT, ioaddr + INT_REG );
-               } else if (status & IM_EPH_INT ) {
-                       PRINTK("%s: UNSUPPORTED: EPH INTERRUPT \n",
-                               dev->name);
-               } else if (status & IM_MDINT ) {
-                       //smc_phy_interrupt(dev);
-                       PRINTK("%s: UNSUPPORTED: MD INTERRUPT \n",
-                               dev->name);
-                       // Acknowledge the interrupt
-                       outb(IM_MDINT, ioaddr + INT_REG );
-               } else if (status & IM_ERCV_INT ) {
-                       PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n",
-                               dev->name);
-                       // Acknowledge the interrupt
-                       outb( IM_ERCV_INT, ioaddr + INT_REG );
-               }
-       } while ( timeout -- );
-
-
-       /* restore register states */
-
-       SMC_SELECT_BANK( 2 );
-
-       outb( mask, ioaddr + IM_REG );
-
-       PRINTK3( KERN_WARNING "%s: MASK is now %x \n", dev->name, mask);
-       outw( saved_pointer, ioaddr + PTR_REG );
-
-       SMC_SELECT_BANK( saved_bank );
-
-       if (old_packet_cnt != lp->stats.rx_packets)
-               rt_mark_stack_mgr(dev);
-
-       hard_local_irq_disable();
-
-       //dev->interrupt = 0;
-       PRINTK3("%s: Interrupt done\n", dev->name);
-       return RTDM_IRQ_HANDLED;
-}
-
-
-/*----------------------------------------------------
- . smc_close
- .
- . this makes the board clean up everything that it can
- . and not talk to the outside world.   Caused by
- . an 'ifconfig ethX down'
- .
- -----------------------------------------------------*/
-static int smc_close(struct rtnet_device *dev)
-{
-       rtnetif_stop_queue(dev);
-       //dev->start = 0;
-
-       PRINTK2("%s:smc_close\n", dev->name);
-
-#ifdef DISABLED____CONFIG_SYSCTL
-       smc_sysctl_unregister(dev);
-#endif /* CONFIG_SYSCTL */
-
-       /* clear everything */
-       smc_shutdown( dev->base_addr );
-
-       /* Update the statistics here. */
-
-       return 0;
-}
-
-/*------------------------------------------------------------
- . Get the current statistics.
- . This may be called with the card open or closed.
- .-------------------------------------------------------------*/
-static struct net_device_stats* smc_query_statistics(struct rtnet_device 
*rtdev)
-{
-       struct smc_local *lp = (struct smc_local *)rtdev->priv;
-
-       PRINTK2("%s:smc_query_statistics\n", rtdev->name);
-
-       return &lp->stats;
-}
-
-/*-----------------------------------------------------------
- . smc_set_multicast_list
- .
- . This routine will, depending on the values passed to it,
- . either make it accept multicast packets, go into
- . promiscuous mode ( for TCPDUMP and cousins ) or accept
- . a select set of multicast packets
-*/
-static void smc_set_multicast_list(struct rtnet_device *dev)
-{
-       short ioaddr = dev->base_addr;
-
-       PRINTK2("%s:smc_set_multicast_list\n", dev->name);
-
-       SMC_SELECT_BANK(0);
-       if ( dev->flags & IFF_PROMISC )
-               {
-               PRINTK2("%s:smc_set_multicast_list:RCR_PRMS\n", dev->name);
-               outw( inw(ioaddr + RCR_REG ) | RCR_PRMS, ioaddr + RCR_REG );
-               }
-
-/* BUG?  I never disable promiscuous mode if multicasting was turned on.
-   Now, I turn off promiscuous mode, but I don't do anything to multicasting
-   when promiscuous mode is turned on.
-*/
-
-       /* Here, I am setting this to accept all multicast packets.
-          I don't need to zero the multicast table, because the flag is
-          checked before the table is
-       */
-       else if (dev->flags & IFF_ALLMULTI)
-               {
-               outw( inw(ioaddr + RCR_REG ) | RCR_ALMUL, ioaddr + RCR_REG );
-               PRINTK2("%s:smc_set_multicast_list:RCR_ALMUL\n", dev->name);
-               }
-
-       else  {
-               PRINTK2("%s:smc_set_multicast_list:~(RCR_PRMS|RCR_ALMUL)\n",
-                       dev->name);
-               outw( inw( ioaddr + RCR_REG ) & ~(RCR_PRMS | RCR_ALMUL),
-                       ioaddr + RCR_REG );
-
-               /*
-                 since I'm disabling all multicast entirely, I need to
-                 clear the multicast list
-               */
-               SMC_SELECT_BANK( 3 );
-               outw( 0, ioaddr + MCAST_REG1 );
-               outw( 0, ioaddr + MCAST_REG2 );
-               outw( 0, ioaddr + MCAST_REG3 );
-               outw( 0, ioaddr + MCAST_REG4 );
-       }
-}
-
-#ifdef MODULE
-
-static struct rtnet_device *devSMC91111;
-int io = 0;
-int irq = 0;
-int nowait = 0;
-
-module_param(io, int, 0444);
-module_param(irq, int, 0444);
-module_param(nowait, int, 0444);
-
-/*------------------------------------------------------------
- . Module initialization function
- .-------------------------------------------------------------*/
-int __init init_module(void)
-{
-       int result;
-
-       PRINTK2("CARDNAME:init_module\n");
-       if (io == 0)
-               printk(KERN_WARNING
-               CARDNAME": You shouldn't use auto-probing with insmod!\n" );
-
-       devSMC91111 = rt_alloc_etherdev(sizeof(struct smc_local), 4 * 2 + 1);
-       if (devSMC91111 == NULL) {
-               printk (KERN_ERR "init_ethernet failed\n");
-               return -ENODEV;
-       }
-       rtdev_alloc_name(devSMC91111, "rteth%d");
-       rt_rtdev_connect(devSMC91111, &RTDEV_manager);
-       devSMC91111->vers = RTDEV_VERS_2_0;
-
-       /* copy the parameters from insmod into the device structure */
-       devSMC91111->base_addr  = io;
-       devSMC91111->irq                = irq;
-       devSMC91111->dma                = nowait; // Use DMA field for nowait
-       if ((result = smc_init(devSMC91111)) != 0)
-               return result;
-
-       if ((result = rt_register_rtnetdev(devSMC91111)) != 0) {
-               rt_rtdev_disconnect(devSMC91111);
-               release_region(devSMC91111->base_addr, SMC_IO_EXTENT);
-
-               rtdm_irq_free(&((struct smc_local *)devSMC91111)->irq_handle);
-
-               rtdev_free(devSMC91111);
-
-               return result;
-       }
-
-       return 0;
-}
-
-/*------------------------------------------------------------
- . Cleanup when module is removed with rmmod
- .-------------------------------------------------------------*/
-void __exit cleanup_module(void)
-{
-       /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
-       rt_unregister_rtnetdev(devSMC91111);
-       rt_rtdev_disconnect(devSMC91111);
-
-       release_region(devSMC91111->base_addr, SMC_IO_EXTENT);
-
-       if (devSMC91111->priv) {
-               rtdm_irq_free(&((struct smc_local 
*)devSMC91111->priv)->irq_handle);
-       }
-
-       rtdev_free(devSMC91111);
-}
-
-#endif /* MODULE */
-
-
-#ifdef DISABLED____CONFIG_SYSCTL
-
-
-/*------------------------------------------------------------
- . Modify a bit in the LAN91C111 register set
- .-------------------------------------------------------------*/
-static word smc_modify_regbit(int bank, int ioaddr, int reg,
-       unsigned int bit, int val)
-{
-       word regval;
-
-       SMC_SELECT_BANK( bank );
-
-       regval = inw( ioaddr+reg );
-       if (val)
-               regval |= bit;
-       else
-               regval &= ~bit;
-
-       outw( regval, ioaddr );
-       return(regval);
-}
-
-
-/*------------------------------------------------------------
- . Retrieve a bit in the LAN91C111 register set
- .-------------------------------------------------------------*/
-static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit)
-{
-       SMC_SELECT_BANK( bank );
-       if ( inw( ioaddr+reg ) & bit)
-               return(1);
-       else
-               return(0);
-}
-
-
-/*------------------------------------------------------------
- . Modify a LAN91C111 register (word access only)
- .-------------------------------------------------------------*/
-static void smc_modify_reg(int bank, int ioaddr, int reg, word val)
-{
-       SMC_SELECT_BANK( bank );
-       outw( val, ioaddr+reg );
-}
-
-
-/*------------------------------------------------------------
- . Retrieve a LAN91C111 register (word access only)
- .-------------------------------------------------------------*/
-static int smc_get_reg(int bank, int ioaddr, int reg)
-{
-       SMC_SELECT_BANK( bank );
-       return(inw( ioaddr+reg ));
-}
-
-
-static const char smc_info_string[] =
-"\n"
-"info           Provides this information blurb\n"
-"swver          Prints the software version information of this driver\n"
-"autoneg        Auto-negotiate Mode = 1\n"
-"rspeed         Requested Speed, 100=100Mbps, 10=10Mpbs\n"
-"rfduplx        Requested Full Duplex Operation\n"
-"aspeed         Actual Speed, 100=100Mbps, 10=10Mpbs\n"
-"afduplx        Actual Full Duplex Operation\n"
-"lnkfail        PHY Link Failure when 1\n"
-"miiop          External MII when 1, Internal PHY when 0\n"
-"swfdup         Switched Full Duplex Mode (allowed only in MII operation)\n"
-"ephloop        EPH Block Loopback\n"
-"forcol         Force a collision\n"
-"filtcar        Filter leading edge of carrier sense for 12 bit times\n"
-"freemem        Free buffer memory in bytes\n"
-"totmem         Total buffer memory in bytes\n"
-"leda           Output of LED-A (green)\n"
-"ledb           Output of LED-B (yellow)\n"
-"chiprev        Revision ID of the LAN91C111 chip\n"
-"";
-
-/*------------------------------------------------------------
- . Sysctl handler for all integer parameters
- .-------------------------------------------------------------*/
-static int smc_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
-                               void *buffer, size_t *lenp, loff_t *ppos)
-{
-       struct rtnet_device *dev = (struct rtnet_device*)ctl->extra1;
-       struct smc_local *lp = (struct smc_local *)ctl->extra2;
-       int ioaddr = dev->base_addr;
-       int *valp = ctl->data;
-       int val;
-       int ret;
-
-       // Update parameters from the real registers
-       switch (ctl->ctl_name)
-       {
-       case CTL_SMC_FORCOL:
-               *valp = smc_get_regbit(0, ioaddr, TCR_REG, TCR_FORCOL);
-               break;
-
-       case CTL_SMC_FREEMEM:
-               *valp = ( (word)smc_get_reg(0, ioaddr, MIR_REG) >> 8 )
-                       * LAN91C111_MEMORY_MULTIPLIER;
-               break;
-
-
-       case CTL_SMC_TOTMEM:
-               *valp = ( smc_get_reg(0, ioaddr, MIR_REG) & (word)0x00ff )
-                       * LAN91C111_MEMORY_MULTIPLIER;
-               break;
-
-       case CTL_SMC_CHIPREV:
-               *valp = smc_get_reg(3, ioaddr, REV_REG);
-               break;
-
-       case CTL_SMC_AFDUPLX:
-               *valp = (lp->lastPhy18 & PHY_INT_DPLXDET) ? 1 : 0;
-               break;
-
-       case CTL_SMC_ASPEED:
-               *valp = (lp->lastPhy18 & PHY_INT_SPDDET) ? 100 : 10;
-               break;
-
-       case CTL_SMC_LNKFAIL:
-               *valp = (lp->lastPhy18 & PHY_INT_LNKFAIL) ? 1 : 0;
-               break;
-
-       case CTL_SMC_LEDA:
-               *valp = (lp->rpc_cur_mode >> RPC_LSXA_SHFT) & (word)0x0007;
-               break;
-
-       case CTL_SMC_LEDB:
-               *valp = (lp->rpc_cur_mode >> RPC_LSXB_SHFT) & (word)0x0007;
-               break;
-
-       case CTL_SMC_MIIOP:
-               *valp = smc_get_regbit(1, ioaddr, CONFIG_REG, CONFIG_EXT_PHY);
-               break;
-
-#ifdef SMC_DEBUG
-       case CTL_SMC_REG_BSR:   // Bank Select
-               *valp = smc_get_reg(0, ioaddr, BSR_REG);
-               break;
-
-       case CTL_SMC_REG_TCR:   // Transmit Control
-               *valp = smc_get_reg(0, ioaddr, TCR_REG);
-               break;
-
-       case CTL_SMC_REG_ESR:   // EPH Status
-               *valp = smc_get_reg(0, ioaddr, EPH_STATUS_REG);
-               break;
-
-       case CTL_SMC_REG_RCR:   // Receive Control
-               *valp = smc_get_reg(0, ioaddr, RCR_REG);
-               break;
-
-       case CTL_SMC_REG_CTRR:  // Counter
-               *valp = smc_get_reg(0, ioaddr, COUNTER_REG);
-               break;
-
-       case CTL_SMC_REG_MIR:   // Memory Information
-               *valp = smc_get_reg(0, ioaddr, MIR_REG);
-               break;
-
-       case CTL_SMC_REG_RPCR:  // Receive/Phy Control
-               *valp = smc_get_reg(0, ioaddr, RPC_REG);
-               break;
-
-       case CTL_SMC_REG_CFGR:  // Configuration
-               *valp = smc_get_reg(1, ioaddr, CONFIG_REG);
-               break;
-
-       case CTL_SMC_REG_BAR:   // Base Address
-               *valp = smc_get_reg(1, ioaddr, BASE_REG);
-               break;
-
-       case CTL_SMC_REG_IAR0:  // Individual Address
-               *valp = smc_get_reg(1, ioaddr, ADDR0_REG);
-               break;
-
-       case CTL_SMC_REG_IAR1:  // Individual Address
-               *valp = smc_get_reg(1, ioaddr, ADDR1_REG);
-               break;
-
-       case CTL_SMC_REG_IAR2:  // Individual Address
-               *valp = smc_get_reg(1, ioaddr, ADDR2_REG);
-               break;
-
-       case CTL_SMC_REG_GPR:   // General Purpose
-               *valp = smc_get_reg(1, ioaddr, GP_REG);
-               break;
-
-       case CTL_SMC_REG_CTLR:  // Control
-               *valp = smc_get_reg(1, ioaddr, CTL_REG);
-               break;
-
-       case CTL_SMC_REG_MCR:   // MMU Command
-               *valp = smc_get_reg(2, ioaddr, MMU_CMD_REG);
-               break;
-
-       case CTL_SMC_REG_PNR:   // Packet Number
-               *valp = smc_get_reg(2, ioaddr, PN_REG);
-               break;
-
-       case CTL_SMC_REG_FPR:   // Allocation Result/FIFO Ports
-               *valp = smc_get_reg(2, ioaddr, RXFIFO_REG);
-               break;
-
-       case CTL_SMC_REG_PTR:   // Pointer
-               *valp = smc_get_reg(2, ioaddr, PTR_REG);
-               break;
-
-       case CTL_SMC_REG_DR:    // Data
-               *valp = smc_get_reg(2, ioaddr, DATA_REG);
-               break;
-
-       case CTL_SMC_REG_ISR:   // Interrupt Status/Mask
-               *valp = smc_get_reg(2, ioaddr, INT_REG);
-               break;
-
-       case CTL_SMC_REG_MTR1:  // Multicast Table Entry 1
-               *valp = smc_get_reg(3, ioaddr, MCAST_REG1);
-               break;
-
-       case CTL_SMC_REG_MTR2:  // Multicast Table Entry 2
-               *valp = smc_get_reg(3, ioaddr, MCAST_REG2);
-               break;
-
-       case CTL_SMC_REG_MTR3:  // Multicast Table Entry 3
-               *valp = smc_get_reg(3, ioaddr, MCAST_REG3);
-               break;
-
-       case CTL_SMC_REG_MTR4:  // Multicast Table Entry 4
-               *valp = smc_get_reg(3, ioaddr, MCAST_REG4);
-               break;
-
-       case CTL_SMC_REG_MIIR:  // Management Interface
-               *valp = smc_get_reg(3, ioaddr, MII_REG);
-               break;
-
-       case CTL_SMC_REG_REVR:  // Revision
-               *valp = smc_get_reg(3, ioaddr, REV_REG);
-               break;
-
-       case CTL_SMC_REG_ERCVR: // Early RCV
-               *valp = smc_get_reg(3, ioaddr, ERCV_REG);
-               break;
-
-       case CTL_SMC_REG_EXTR:  // External
-               *valp = smc_get_reg(7, ioaddr, EXT_REG);
-               break;
-
-       case CTL_SMC_PHY_CTRL:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_CNTL_REG);
-               break;
-
-       case CTL_SMC_PHY_STAT:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_STAT_REG);
-               break;
-
-       case CTL_SMC_PHY_ID1:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_ID1_REG);
-               break;
-
-       case CTL_SMC_PHY_ID2:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_ID2_REG);
-               break;
-
-       case CTL_SMC_PHY_ADC:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_AD_REG);
-               break;
-
-       case CTL_SMC_PHY_REMC:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_RMT_REG);
-               break;
-
-       case CTL_SMC_PHY_CFG1:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_CFG1_REG);
-               break;
-
-       case CTL_SMC_PHY_CFG2:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_CFG2_REG);
-               break;
-
-       case CTL_SMC_PHY_INT:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_INT_REG);
-               break;
-
-       case CTL_SMC_PHY_MASK:
-               *valp = smc_read_phy_register(ioaddr, lp->phyaddr,
-                       PHY_MASK_REG);
-               break;
-
-#endif // SMC_DEBUG
-
-       default:
-               // Just ignore unsupported parameters
-               break;
-       }
-
-       // Save old state
-       val = *valp;
-
-       // Perform the generic integer operation
-       if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos)) != 0)
-               return(ret);
-
-       // Write changes out to the registers
-       if (write && *valp != val) {
-
-               val = *valp;
-               switch (ctl->ctl_name) {
-
-               case CTL_SMC_SWFDUP:
-                       if (val)
-                               lp->tcr_cur_mode |= TCR_SWFDUP;
-                       else
-                               lp->tcr_cur_mode &= ~TCR_SWFDUP;
-
-                       smc_modify_regbit(0, ioaddr, TCR_REG, TCR_SWFDUP, val);
-                       break;
-
-               case CTL_SMC_EPHLOOP:
-                       if (val)
-                               lp->tcr_cur_mode |= TCR_EPH_LOOP;
-                       else
-                               lp->tcr_cur_mode &= ~TCR_EPH_LOOP;
-
-                       smc_modify_regbit(0, ioaddr, TCR_REG, TCR_EPH_LOOP, 
val);
-                       break;
-
-               case CTL_SMC_FORCOL:
-                       if (val)
-                               lp->tcr_cur_mode |= TCR_FORCOL;
-                       else
-                               lp->tcr_cur_mode &= ~TCR_FORCOL;
-
-                       // Update the EPH block
-                       smc_modify_regbit(0, ioaddr, TCR_REG, TCR_FORCOL, val);
-                       break;
-
-               case CTL_SMC_FILTCAR:
-                       if (val)
-                               lp->rcr_cur_mode |= RCR_FILT_CAR;
-                       else
-                               lp->rcr_cur_mode &= ~RCR_FILT_CAR;
-
-                       // Update the EPH block
-                       smc_modify_regbit(0, ioaddr, RCR_REG, RCR_FILT_CAR, 
val);
-                       break;
-
-               case CTL_SMC_RFDUPLX:
-                       // Disallow changes if in auto-negotiation mode
-                       if (lp->ctl_autoneg)
-                               break;
-
-                       if (val)
-                               {
-                               lp->rpc_cur_mode |= RPC_DPLX;
-                               }
-                       else
-                               {
-                               lp->rpc_cur_mode &= ~RPC_DPLX;
-                               }
-
-                       // Reconfigure the PHY
-                       smc_phy_configure(dev);
-
-                       break;
-
-               case CTL_SMC_RSPEED:
-                       // Disallow changes if in auto-negotiation mode
-                       if (lp->ctl_autoneg)
-                               break;
-
-                       if (val > 10)
-                               lp->rpc_cur_mode |= RPC_SPEED;
-                       else
-                               lp->rpc_cur_mode &= ~RPC_SPEED;
-
-                       // Reconfigure the PHY
-                       smc_phy_configure(dev);
-
-                       break;
-
-               case CTL_SMC_AUTONEG:
-                       if (val)
-                               lp->rpc_cur_mode |= RPC_ANEG;
-                       else
-                               lp->rpc_cur_mode &= ~RPC_ANEG;
-
-                       // Reconfigure the PHY
-                       smc_phy_configure(dev);
-
-                       break;
-
-               case CTL_SMC_LEDA:
-                       val &= 0x07; // Restrict to 3 ls bits
-                       lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXA_SHFT);
-                       lp->rpc_cur_mode |= (word)(val<<RPC_LSXA_SHFT);
-
-                       // Update the Internal PHY block
-                       smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);
-                       break;
-
-               case CTL_SMC_LEDB:
-                       val &= 0x07; // Restrict to 3 ls bits
-                       lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXB_SHFT);
-                       lp->rpc_cur_mode |= (word)(val<<RPC_LSXB_SHFT);
-
-                       // Update the Internal PHY block
-                       smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);
-                       break;
-
-               case CTL_SMC_MIIOP:
-                       // Update the Internal PHY block
-                       smc_modify_regbit(1, ioaddr, CONFIG_REG,
-                               CONFIG_EXT_PHY, val);
-                       break;
-
-#ifdef SMC_DEBUG
-               case CTL_SMC_REG_BSR:   // Bank Select
-                       smc_modify_reg(0, ioaddr, BSR_REG, val);
-                       break;
-
-               case CTL_SMC_REG_TCR:   // Transmit Control
-                       smc_modify_reg(0, ioaddr, TCR_REG, val);
-                       break;
-
-               case CTL_SMC_REG_ESR:   // EPH Status
-                       smc_modify_reg(0, ioaddr, EPH_STATUS_REG, val);
-                       break;
-
-               case CTL_SMC_REG_RCR:   // Receive Control
-                       smc_modify_reg(0, ioaddr, RCR_REG, val);
-                       break;
-
-               case CTL_SMC_REG_CTRR:  // Counter
-                       smc_modify_reg(0, ioaddr, COUNTER_REG, val);
-                       break;
-
-               case CTL_SMC_REG_MIR:   // Memory Information
-                       smc_modify_reg(0, ioaddr, MIR_REG, val);
-                       break;
-
-               case CTL_SMC_REG_RPCR:  // Receive/Phy Control
-                       smc_modify_reg(0, ioaddr, RPC_REG, val);
-                       break;
-
-               case CTL_SMC_REG_CFGR:  // Configuration
-                       smc_modify_reg(1, ioaddr, CONFIG_REG, val);
-                       break;
-
-               case CTL_SMC_REG_BAR:   // Base Address
-                       smc_modify_reg(1, ioaddr, BASE_REG, val);
-                       break;
-
-               case CTL_SMC_REG_IAR0:  // Individual Address
-                       smc_modify_reg(1, ioaddr, ADDR0_REG, val);
-                       break;
-
-               case CTL_SMC_REG_IAR1:  // Individual Address
-                       smc_modify_reg(1, ioaddr, ADDR1_REG, val);
-                       break;
-
-               case CTL_SMC_REG_IAR2:  // Individual Address
-                       smc_modify_reg(1, ioaddr, ADDR2_REG, val);
-                       break;
-
-               case CTL_SMC_REG_GPR:   // General Purpose
-                       smc_modify_reg(1, ioaddr, GP_REG, val);
-                       break;
-
-               case CTL_SMC_REG_CTLR:  // Control
-                       smc_modify_reg(1, ioaddr, CTL_REG, val);
-                       break;
-
-               case CTL_SMC_REG_MCR:   // MMU Command
-                       smc_modify_reg(2, ioaddr, MMU_CMD_REG, val);
-                       break;
-
-               case CTL_SMC_REG_PNR:   // Packet Number
-                       smc_modify_reg(2, ioaddr, PN_REG, val);
-                       break;
-
-               case CTL_SMC_REG_FPR:   // Allocation Result/FIFO Ports
-                       smc_modify_reg(2, ioaddr, RXFIFO_REG, val);
-                       break;
-
-               case CTL_SMC_REG_PTR:   // Pointer
-                       smc_modify_reg(2, ioaddr, PTR_REG, val);
-                       break;
-
-               case CTL_SMC_REG_DR:    // Data
-                       smc_modify_reg(2, ioaddr, DATA_REG, val);
-                       break;
-
-               case CTL_SMC_REG_ISR:   // Interrupt Status/Mask
-                       smc_modify_reg(2, ioaddr, INT_REG, val);
-                       break;
-
-               case CTL_SMC_REG_MTR1:  // Multicast Table Entry 1
-                       smc_modify_reg(3, ioaddr, MCAST_REG1, val);
-                       break;
-
-               case CTL_SMC_REG_MTR2:  // Multicast Table Entry 2
-                       smc_modify_reg(3, ioaddr, MCAST_REG2, val);
-                       break;
-
-               case CTL_SMC_REG_MTR3:  // Multicast Table Entry 3
-                       smc_modify_reg(3, ioaddr, MCAST_REG3, val);
-                       break;
-
-               case CTL_SMC_REG_MTR4:  // Multicast Table Entry 4
-                       smc_modify_reg(3, ioaddr, MCAST_REG4, val);
-                       break;
-
-               case CTL_SMC_REG_MIIR:  // Management Interface
-                       smc_modify_reg(3, ioaddr, MII_REG, val);
-                       break;
-
-               case CTL_SMC_REG_REVR:  // Revision
-                       smc_modify_reg(3, ioaddr, REV_REG, val);
-                       break;
-
-               case CTL_SMC_REG_ERCVR: // Early RCV
-                       smc_modify_reg(3, ioaddr, ERCV_REG, val);
-                       break;
-
-               case CTL_SMC_REG_EXTR:  // External
-                       smc_modify_reg(7, ioaddr, EXT_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_CTRL:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_CNTL_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_STAT:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_STAT_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_ID1:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_ID1_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_ID2:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_ID2_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_ADC:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_AD_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_REMC:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_RMT_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_CFG1:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_CFG1_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_CFG2:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_CFG2_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_INT:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_INT_REG, val);
-                       break;
-
-               case CTL_SMC_PHY_MASK:
-                       smc_write_phy_register(ioaddr, lp->phyaddr,
-                               PHY_MASK_REG, val);
-                       break;
-
-#endif // SMC_DEBUG
-
-               default:
-                       // Just ignore unsupported parameters
-                       break;
-               } // end switch
-
-       } // end if
-
-       return ret;
-}
-
-/*------------------------------------------------------------
- . Sysctl registration function for all parameters (files)
- .-------------------------------------------------------------*/
-static void smc_sysctl_register(struct rtnet_device *dev)
-{
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       static int ctl_name = CTL_SMC;
-       ctl_table* ct;
-       int i;
-
-       // Make sure the ctl_tables start out as all zeros
-       memset(lp->root_table, 0, sizeof lp->root_table);
-       memset(lp->eth_table, 0, sizeof lp->eth_table);
-       memset(lp->param_table, 0, sizeof lp->param_table);
-
-       // Initialize the root table
-       ct = lp->root_table;
-       ct->ctl_name = CTL_DEV;
-       ct->procname = "dev";
-       ct->maxlen = 0;
-       ct->mode = 0555;
-       ct->child = lp->eth_table;
-       // remaining fields are zero
-
-       // Initialize the ethX table (this device's table)
-       ct = lp->eth_table;
-       ct->ctl_name = ctl_name++; // Must be unique
-       ct->procname = dev->name;
-       ct->maxlen = 0;
-       ct->mode = 0555;
-       ct->child = lp->param_table;
-       // remaining fields are zero
-
-       // Initialize the parameter (files) table
-       // Make sure the last entry remains null
-       ct = lp->param_table;
-       for (i = 0; i < (CTL_SMC_LAST_ENTRY-1); ++i)
-               {
-               // Initialize fields common to all table entries
-               ct[i].proc_handler = smc_sysctl_handler;
-               ct[i].extra1 = (void*)dev; // Save our device pointer
-               ct[i].extra2 = (void*)lp;  // Save our smc_local data pointer
-               }
-
-       // INFO - this is our only string parameter
-       i = 0;
-       ct[i].proc_handler = proc_dostring; // use default handler
-       ct[i].ctl_name = CTL_SMC_INFO;
-       ct[i].procname = "info";
-       ct[i].data = (void*)smc_info_string;
-       ct[i].maxlen = sizeof smc_info_string;
-       ct[i].mode = 0444; // Read only
-
-       // SWVER
-       ++i;
-       ct[i].proc_handler = proc_dostring; // use default handler
-       ct[i].ctl_name = CTL_SMC_SWVER;
-       ct[i].procname = "swver";
-       ct[i].data = (void*)version;
-       ct[i].maxlen = sizeof version;
-       ct[i].mode = 0444; // Read only
-
-       // SWFDUP
-       ++i;
-       ct[i].ctl_name = CTL_SMC_SWFDUP;
-       ct[i].procname = "swfdup";
-       ct[i].data = (void*)&(lp->ctl_swfdup);
-       ct[i].maxlen = sizeof lp->ctl_swfdup;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // EPHLOOP
-       ++i;
-       ct[i].ctl_name = CTL_SMC_EPHLOOP;
-       ct[i].procname = "ephloop";
-       ct[i].data = (void*)&(lp->ctl_ephloop);
-       ct[i].maxlen = sizeof lp->ctl_ephloop;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // MIIOP
-       ++i;
-       ct[i].ctl_name = CTL_SMC_MIIOP;
-       ct[i].procname = "miiop";
-       ct[i].data = (void*)&(lp->ctl_miiop);
-       ct[i].maxlen = sizeof lp->ctl_miiop;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // AUTONEG
-       ++i;
-       ct[i].ctl_name = CTL_SMC_AUTONEG;
-       ct[i].procname = "autoneg";
-       ct[i].data = (void*)&(lp->ctl_autoneg);
-       ct[i].maxlen = sizeof lp->ctl_autoneg;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // RFDUPLX
-       ++i;
-       ct[i].ctl_name = CTL_SMC_RFDUPLX;
-       ct[i].procname = "rfduplx";
-       ct[i].data = (void*)&(lp->ctl_rfduplx);
-       ct[i].maxlen = sizeof lp->ctl_rfduplx;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // RSPEED
-       ++i;
-       ct[i].ctl_name = CTL_SMC_RSPEED;
-       ct[i].procname = "rspeed";
-       ct[i].data = (void*)&(lp->ctl_rspeed);
-       ct[i].maxlen = sizeof lp->ctl_rspeed;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // AFDUPLX
-       ++i;
-       ct[i].ctl_name = CTL_SMC_AFDUPLX;
-       ct[i].procname = "afduplx";
-       ct[i].data = (void*)&(lp->ctl_afduplx);
-       ct[i].maxlen = sizeof lp->ctl_afduplx;
-       ct[i].mode = 0444; // Read only
-
-       // ASPEED
-       ++i;
-       ct[i].ctl_name = CTL_SMC_ASPEED;
-       ct[i].procname = "aspeed";
-       ct[i].data = (void*)&(lp->ctl_aspeed);
-       ct[i].maxlen = sizeof lp->ctl_aspeed;
-       ct[i].mode = 0444; // Read only
-
-       // LNKFAIL
-       ++i;
-       ct[i].ctl_name = CTL_SMC_LNKFAIL;
-       ct[i].procname = "lnkfail";
-       ct[i].data = (void*)&(lp->ctl_lnkfail);
-       ct[i].maxlen = sizeof lp->ctl_lnkfail;
-       ct[i].mode = 0444; // Read only
-
-       // FORCOL
-       ++i;
-       ct[i].ctl_name = CTL_SMC_FORCOL;
-       ct[i].procname = "forcol";
-       ct[i].data = (void*)&(lp->ctl_forcol);
-       ct[i].maxlen = sizeof lp->ctl_forcol;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // FILTCAR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_FILTCAR;
-       ct[i].procname = "filtcar";
-       ct[i].data = (void*)&(lp->ctl_filtcar);
-       ct[i].maxlen = sizeof lp->ctl_filtcar;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // FREEMEM
-       ++i;
-       ct[i].ctl_name = CTL_SMC_FREEMEM;
-       ct[i].procname = "freemem";
-       ct[i].data = (void*)&(lp->ctl_freemem);
-       ct[i].maxlen = sizeof lp->ctl_freemem;
-       ct[i].mode = 0444; // Read only
-
-       // TOTMEM
-       ++i;
-       ct[i].ctl_name = CTL_SMC_TOTMEM;
-       ct[i].procname = "totmem";
-       ct[i].data = (void*)&(lp->ctl_totmem);
-       ct[i].maxlen = sizeof lp->ctl_totmem;
-       ct[i].mode = 0444; // Read only
-
-       // LEDA
-       ++i;
-       ct[i].ctl_name = CTL_SMC_LEDA;
-       ct[i].procname = "leda";
-       ct[i].data = (void*)&(lp->ctl_leda);
-       ct[i].maxlen = sizeof lp->ctl_leda;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // LEDB
-       ++i;
-       ct[i].ctl_name = CTL_SMC_LEDB;
-       ct[i].procname = "ledb";
-       ct[i].data = (void*)&(lp->ctl_ledb);
-       ct[i].maxlen = sizeof lp->ctl_ledb;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // CHIPREV
-       ++i;
-       ct[i].ctl_name = CTL_SMC_CHIPREV;
-       ct[i].procname = "chiprev";
-       ct[i].data = (void*)&(lp->ctl_chiprev);
-       ct[i].maxlen = sizeof lp->ctl_chiprev;
-       ct[i].mode = 0444; // Read only
-
-#ifdef SMC_DEBUG
-       // REG_BSR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_BSR;
-       ct[i].procname = "reg_bsr";
-       ct[i].data = (void*)&(lp->ctl_reg_bsr);
-       ct[i].maxlen = sizeof lp->ctl_reg_bsr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_TCR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_TCR;
-       ct[i].procname = "reg_tcr";
-       ct[i].data = (void*)&(lp->ctl_reg_tcr);
-       ct[i].maxlen = sizeof lp->ctl_reg_tcr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_ESR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_ESR;
-       ct[i].procname = "reg_esr";
-       ct[i].data = (void*)&(lp->ctl_reg_esr);
-       ct[i].maxlen = sizeof lp->ctl_reg_esr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_RCR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_RCR;
-       ct[i].procname = "reg_rcr";
-       ct[i].data = (void*)&(lp->ctl_reg_rcr);
-       ct[i].maxlen = sizeof lp->ctl_reg_rcr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_CTRR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_CTRR;
-       ct[i].procname = "reg_ctrr";
-       ct[i].data = (void*)&(lp->ctl_reg_ctrr);
-       ct[i].maxlen = sizeof lp->ctl_reg_ctrr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MIR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MIR;
-       ct[i].procname = "reg_mir";
-       ct[i].data = (void*)&(lp->ctl_reg_mir);
-       ct[i].maxlen = sizeof lp->ctl_reg_mir;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_RPCR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_RPCR;
-       ct[i].procname = "reg_rpcr";
-       ct[i].data = (void*)&(lp->ctl_reg_rpcr);
-       ct[i].maxlen = sizeof lp->ctl_reg_rpcr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_CFGR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_CFGR;
-       ct[i].procname = "reg_cfgr";
-       ct[i].data = (void*)&(lp->ctl_reg_cfgr);
-       ct[i].maxlen = sizeof lp->ctl_reg_cfgr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_BAR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_BAR;
-       ct[i].procname = "reg_bar";
-       ct[i].data = (void*)&(lp->ctl_reg_bar);
-       ct[i].maxlen = sizeof lp->ctl_reg_bar;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_IAR0
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_IAR0;
-       ct[i].procname = "reg_iar0";
-       ct[i].data = (void*)&(lp->ctl_reg_iar0);
-       ct[i].maxlen = sizeof lp->ctl_reg_iar0;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_IAR1
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_IAR1;
-       ct[i].procname = "reg_iar1";
-       ct[i].data = (void*)&(lp->ctl_reg_iar1);
-       ct[i].maxlen = sizeof lp->ctl_reg_iar1;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_IAR2
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_IAR2;
-       ct[i].procname = "reg_iar2";
-       ct[i].data = (void*)&(lp->ctl_reg_iar2);
-       ct[i].maxlen = sizeof lp->ctl_reg_iar2;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_GPR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_GPR;
-       ct[i].procname = "reg_gpr";
-       ct[i].data = (void*)&(lp->ctl_reg_gpr);
-       ct[i].maxlen = sizeof lp->ctl_reg_gpr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_CTLR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_CTLR;
-       ct[i].procname = "reg_ctlr";
-       ct[i].data = (void*)&(lp->ctl_reg_ctlr);
-       ct[i].maxlen = sizeof lp->ctl_reg_ctlr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MCR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MCR;
-       ct[i].procname = "reg_mcr";
-       ct[i].data = (void*)&(lp->ctl_reg_mcr);
-       ct[i].maxlen = sizeof lp->ctl_reg_mcr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_PNR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_PNR;
-       ct[i].procname = "reg_pnr";
-       ct[i].data = (void*)&(lp->ctl_reg_pnr);
-       ct[i].maxlen = sizeof lp->ctl_reg_pnr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_FPR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_FPR;
-       ct[i].procname = "reg_fpr";
-       ct[i].data = (void*)&(lp->ctl_reg_fpr);
-       ct[i].maxlen = sizeof lp->ctl_reg_fpr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_PTR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_PTR;
-       ct[i].procname = "reg_ptr";
-       ct[i].data = (void*)&(lp->ctl_reg_ptr);
-       ct[i].maxlen = sizeof lp->ctl_reg_ptr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_DR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_DR;
-       ct[i].procname = "reg_dr";
-       ct[i].data = (void*)&(lp->ctl_reg_dr);
-       ct[i].maxlen = sizeof lp->ctl_reg_dr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_ISR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_ISR;
-       ct[i].procname = "reg_isr";
-       ct[i].data = (void*)&(lp->ctl_reg_isr);
-       ct[i].maxlen = sizeof lp->ctl_reg_isr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MTR1
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MTR1;
-       ct[i].procname = "reg_mtr1";
-       ct[i].data = (void*)&(lp->ctl_reg_mtr1);
-       ct[i].maxlen = sizeof lp->ctl_reg_mtr1;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MTR2
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MTR2;
-       ct[i].procname = "reg_mtr2";
-       ct[i].data = (void*)&(lp->ctl_reg_mtr2);
-       ct[i].maxlen = sizeof lp->ctl_reg_mtr2;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MTR3
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MTR3;
-       ct[i].procname = "reg_mtr3";
-       ct[i].data = (void*)&(lp->ctl_reg_mtr3);
-       ct[i].maxlen = sizeof lp->ctl_reg_mtr3;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MTR4
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MTR4;
-       ct[i].procname = "reg_mtr4";
-       ct[i].data = (void*)&(lp->ctl_reg_mtr4);
-       ct[i].maxlen = sizeof lp->ctl_reg_mtr4;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_MIIR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_MIIR;
-       ct[i].procname = "reg_miir";
-       ct[i].data = (void*)&(lp->ctl_reg_miir);
-       ct[i].maxlen = sizeof lp->ctl_reg_miir;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_REVR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_REVR;
-       ct[i].procname = "reg_revr";
-       ct[i].data = (void*)&(lp->ctl_reg_revr);
-       ct[i].maxlen = sizeof lp->ctl_reg_revr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_ERCVR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_ERCVR;
-       ct[i].procname = "reg_ercvr";
-       ct[i].data = (void*)&(lp->ctl_reg_ercvr);
-       ct[i].maxlen = sizeof lp->ctl_reg_ercvr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // REG_EXTR
-       ++i;
-       ct[i].ctl_name = CTL_SMC_REG_EXTR;
-       ct[i].procname = "reg_extr";
-       ct[i].data = (void*)&(lp->ctl_reg_extr);
-       ct[i].maxlen = sizeof lp->ctl_reg_extr;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Control
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_CTRL;
-       ct[i].procname = "phy_ctrl";
-       ct[i].data = (void*)&(lp->ctl_phy_ctrl);
-       ct[i].maxlen = sizeof lp->ctl_phy_ctrl;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Status
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_STAT;
-       ct[i].procname = "phy_stat";
-       ct[i].data = (void*)&(lp->ctl_phy_stat);
-       ct[i].maxlen = sizeof lp->ctl_phy_stat;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY ID1
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_ID1;
-       ct[i].procname = "phy_id1";
-       ct[i].data = (void*)&(lp->ctl_phy_id1);
-       ct[i].maxlen = sizeof lp->ctl_phy_id1;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY ID2
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_ID2;
-       ct[i].procname = "phy_id2";
-       ct[i].data = (void*)&(lp->ctl_phy_id2);
-       ct[i].maxlen = sizeof lp->ctl_phy_id2;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Advertise Capabilities
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_ADC;
-       ct[i].procname = "phy_adc";
-       ct[i].data = (void*)&(lp->ctl_phy_adc);
-       ct[i].maxlen = sizeof lp->ctl_phy_adc;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Remote Capabilities
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_REMC;
-       ct[i].procname = "phy_remc";
-       ct[i].data = (void*)&(lp->ctl_phy_remc);
-       ct[i].maxlen = sizeof lp->ctl_phy_remc;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Configuration 1
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_CFG1;
-       ct[i].procname = "phy_cfg1";
-       ct[i].data = (void*)&(lp->ctl_phy_cfg1);
-       ct[i].maxlen = sizeof lp->ctl_phy_cfg1;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Configuration 2
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_CFG2;
-       ct[i].procname = "phy_cfg2";
-       ct[i].data = (void*)&(lp->ctl_phy_cfg2);
-       ct[i].maxlen = sizeof lp->ctl_phy_cfg2;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Interrupt/Status Output
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_INT;
-       ct[i].procname = "phy_int";
-       ct[i].data = (void*)&(lp->ctl_phy_int);
-       ct[i].maxlen = sizeof lp->ctl_phy_int;
-       ct[i].mode = 0644; // Read by all, write by root
-
-       // PHY Interrupt/Status Mask
-       ++i;
-       ct[i].ctl_name = CTL_SMC_PHY_MASK;
-       ct[i].procname = "phy_mask";
-       ct[i].data = (void*)&(lp->ctl_phy_mask);
-       ct[i].maxlen = sizeof lp->ctl_phy_mask;
-       ct[i].mode = 0644; // Read by all, write by root
-
-#endif // SMC_DEBUG
-
-       // Register /proc/sys/dev/ethX
-       lp->sysctl_header = register_sysctl_table(lp->root_table, 1);
-}
-
-
-/*------------------------------------------------------------
- . Sysctl unregistration when driver is closed
- .-------------------------------------------------------------*/
-static void smc_sysctl_unregister(struct rtnet_device *dev)
-{
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-
-       unregister_sysctl_table(lp->sysctl_header);
-}
-
-#endif /* endif CONFIG_SYSCTL */
-
-
-//---PHY CONTROL AND CONFIGURATION-----------------------------------------
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2 )
-
-/*------------------------------------------------------------
- . Debugging function for viewing MII Management serial bitstream
- .-------------------------------------------------------------*/
-static void smc_dump_mii_stream(byte* bits, int size)
-{
-       int i;
-
-       printk("BIT#:");
-       for (i = 0; i < size; ++i)
-               {
-               printk("%d", i%10);
-               }
-
-       printk("\nMDOE:");
-       for (i = 0; i < size; ++i)
-               {
-               if (bits[i] & MII_MDOE)
-                       printk("1");
-               else
-                       printk("0");
-               }
-
-       printk("\nMDO :");
-       for (i = 0; i < size; ++i)
-               {
-               if (bits[i] & MII_MDO)
-                       printk("1");
-               else
-                       printk("0");
-               }
-
-       printk("\nMDI :");
-       for (i = 0; i < size; ++i)
-               {
-               if (bits[i] & MII_MDI)
-                       printk("1");
-               else
-                       printk("0");
-               }
-
-       printk("\n");
-}
-#endif
-
-/*------------------------------------------------------------
- . Reads a register from the MII Management serial interface
- .-------------------------------------------------------------*/
-static word smc_read_phy_register(int ioaddr, byte phyaddr, byte phyreg)
-{
-       int oldBank;
-       int i;
-       byte mask;
-       word mii_reg;
-       byte bits[64];
-       int clk_idx = 0;
-       int input_idx;
-       word phydata;
-
-       // 32 consecutive ones on MDO to establish sync
-       for (i = 0; i < 32; ++i)
-               bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       // Start code <01>
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       // Read command <10>
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-       bits[clk_idx++] = MII_MDOE;
-
-       // Output the PHY address, msb first
-       mask = (byte)0x10;
-       for (i = 0; i < 5; ++i)
-               {
-               if (phyaddr & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               // Shift to next lowest bit
-               mask >>= 1;
-               }
-
-       // Output the phy register number, msb first
-       mask = (byte)0x10;
-       for (i = 0; i < 5; ++i)
-               {
-               if (phyreg & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               // Shift to next lowest bit
-               mask >>= 1;
-               }
-
-       // Tristate and turnaround (2 bit times)
-       bits[clk_idx++] = 0;
-       //bits[clk_idx++] = 0;
-
-       // Input starts at this bit time
-       input_idx = clk_idx;
-
-       // Will input 16 bits
-       for (i = 0; i < 16; ++i)
-               bits[clk_idx++] = 0;
-
-       // Final clock bit
-       bits[clk_idx++] = 0;
-
-       // Save the current bank
-       oldBank = inw( ioaddr+BANK_SELECT );
-
-       // Select bank 3
-       SMC_SELECT_BANK( 3 );
-
-       // Get the current MII register value
-       mii_reg = inw( ioaddr+MII_REG );
-
-       // Turn off all MII Interface bits
-       mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
-
-       // Clock all 64 cycles
-       for (i = 0; i < sizeof bits; ++i)
-               {
-               // Clock Low - output data
-               outw( mii_reg | bits[i], ioaddr+MII_REG );
-               udelay(50);
-
-
-               // Clock Hi - input data
-               outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
-               udelay(50);
-               bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
-               }
-
-       // Return to idle state
-       // Set clock to low, data to low, and output tristated
-       outw( mii_reg, ioaddr+MII_REG );
-       udelay(50);
-
-       // Restore original bank select
-       SMC_SELECT_BANK( oldBank );
-
-       // Recover input data
-       phydata = 0;
-       for (i = 0; i < 16; ++i)
-               {
-               phydata <<= 1;
-
-               if (bits[input_idx++] & MII_MDI)
-                       phydata |= 0x0001;
-               }
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2 )
-       printk("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
-               phyaddr, phyreg, phydata);
-       smc_dump_mii_stream(bits, sizeof bits);
-#endif
-
-       return(phydata);
-}
-
-
-/*------------------------------------------------------------
- . Writes a register to the MII Management serial interface
- .-------------------------------------------------------------*/
-static void smc_write_phy_register(int ioaddr,
-       byte phyaddr, byte phyreg, word phydata)
-{
-       int oldBank;
-       int i;
-       word mask;
-       word mii_reg;
-       byte bits[65];
-       int clk_idx = 0;
-
-       // 32 consecutive ones on MDO to establish sync
-       for (i = 0; i < 32; ++i)
-               bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       // Start code <01>
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       // Write command <01>
-       bits[clk_idx++] = MII_MDOE;
-       bits[clk_idx++] = MII_MDOE | MII_MDO;
-
-       // Output the PHY address, msb first
-       mask = (byte)0x10;
-       for (i = 0; i < 5; ++i)
-               {
-               if (phyaddr & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               // Shift to next lowest bit
-               mask >>= 1;
-               }
-
-       // Output the phy register number, msb first
-       mask = (byte)0x10;
-       for (i = 0; i < 5; ++i)
-               {
-               if (phyreg & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               // Shift to next lowest bit
-               mask >>= 1;
-               }
-
-       // Tristate and turnaround (2 bit times)
-       bits[clk_idx++] = 0;
-       bits[clk_idx++] = 0;
-
-       // Write out 16 bits of data, msb first
-       mask = 0x8000;
-       for (i = 0; i < 16; ++i)
-               {
-               if (phydata & mask)
-                       bits[clk_idx++] = MII_MDOE | MII_MDO;
-               else
-                       bits[clk_idx++] = MII_MDOE;
-
-               // Shift to next lowest bit
-               mask >>= 1;
-               }
-
-       // Final clock bit (tristate)
-       bits[clk_idx++] = 0;
-
-       // Save the current bank
-       oldBank = inw( ioaddr+BANK_SELECT );
-
-       // Select bank 3
-       SMC_SELECT_BANK( 3 );
-
-       // Get the current MII register value
-       mii_reg = inw( ioaddr+MII_REG );
-
-       // Turn off all MII Interface bits
-       mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
-
-       // Clock all cycles
-       for (i = 0; i < sizeof bits; ++i)
-               {
-               // Clock Low - output data
-               outw( mii_reg | bits[i], ioaddr+MII_REG );
-               udelay(50);
-
-
-               // Clock Hi - input data
-               outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
-               udelay(50);
-               bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
-               }
-
-       // Return to idle state
-       // Set clock to low, data to low, and output tristated
-       outw( mii_reg, ioaddr+MII_REG );
-       udelay(50);
-
-       // Restore original bank select
-       SMC_SELECT_BANK( oldBank );
-
-#if defined(SMC_DEBUG) && (SMC_DEBUG > 2 )
-       printk("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
-               phyaddr, phyreg, phydata);
-       smc_dump_mii_stream(bits, sizeof bits);
-#endif
-}
-
-
-/*------------------------------------------------------------
- . Finds and reports the PHY address
- .-------------------------------------------------------------*/
-static int smc_detect_phy(struct rtnet_device* dev)
-{
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       int ioaddr = dev->base_addr;
-       word phy_id1;
-       word phy_id2;
-       int phyaddr;
-       int found = 0;
-
-       PRINTK3("%s:smc_detect_phy()\n", dev->name);
-
-       // Scan all 32 PHY addresses if necessary
-       for (phyaddr = 0; phyaddr < 32; ++phyaddr)
-               {
-               // Read the PHY identifiers
-               phy_id1  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG);
-               phy_id2  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG);
-
-               PRINTK3("%s: phy_id1=%x, phy_id2=%x\n",
-                       dev->name, phy_id1, phy_id2);
-
-               // Make sure it is a valid identifier
-               if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
-                   (phy_id1 > 0x0000) && (phy_id1 < 0xffff))
-                       {
-                       if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000))
-                               {
-                               // Save the PHY's address
-                               lp->phyaddr = phyaddr;
-                               found = 1;
-                               break;
-                               }
-                       }
-               }
-
-       if (!found)
-               {
-               PRINTK("%s: No PHY found\n", dev->name);
-               return(0);
-               }
-
-       // Set the PHY type
-       if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) )
-               {
-               lp->phytype = PHY_LAN83C183;
-               PRINTK("%s: PHY=LAN83C183 (LAN91C111 Internal)\n", dev->name);
-               }
-
-       if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) )
-               {
-               lp->phytype = PHY_LAN83C180;
-               PRINTK("%s: PHY=LAN83C180\n", dev->name);
-               }
-
-       return(1);
-}
-
-/*------------------------------------------------------------
- . Waits the specified number of milliseconds - kernel friendly
- .-------------------------------------------------------------*/
-static void smc_wait_ms(unsigned int ms)
-{
-
-       if (!in_interrupt())
-               {
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout(1 + ms * HZ / 1000);
-               }
-       else
-               {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1 + ms * HZ / 1000);
-               current->state = TASK_RUNNING;
-               }
-}
-
-/*------------------------------------------------------------
- . Sets the PHY to a configuration as determined by the user
- .-------------------------------------------------------------*/
-#ifdef DISABLED____CONFIG_SYSCTL
-static int smc_phy_fixed(struct rtnet_device* dev)
-{
-       int ioaddr = dev->base_addr;
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       byte phyaddr = lp->phyaddr;
-       word my_fixed_caps;
-       word cfg1;
-
-       PRINTK3("%s:smc_phy_fixed()\n", dev->name);
-
-       // Enter Link Disable state
-       cfg1 = smc_read_phy_register(ioaddr, phyaddr, PHY_CFG1_REG);
-       cfg1 |= PHY_CFG1_LNKDIS;
-       smc_write_phy_register(ioaddr, phyaddr, PHY_CFG1_REG, cfg1);
-
-       // Set our fixed capabilities
-       // Disable auto-negotiation
-       my_fixed_caps = 0;
-
-       if (lp->ctl_rfduplx)
-               my_fixed_caps |= PHY_CNTL_DPLX;
-
-       if (lp->ctl_rspeed == 100)
-               my_fixed_caps |= PHY_CNTL_SPEED;
-
-       // Write our capabilities to the phy control register
-       smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, my_fixed_caps);
-
-       // Re-Configure the Receive/Phy Control register
-       outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
-
-       // Success
-       return(1);
-}
-#endif // CONFIG_SYSCTL
-
-
-/*------------------------------------------------------------
- . Configures the specified PHY using Autonegotiation. Calls
- . smc_phy_fixed() if the user has requested a certain config.
- .-------------------------------------------------------------*/
-static void smc_phy_configure(struct rtnet_device* dev)
-{
-       int ioaddr = dev->base_addr;
-       struct smc_local *lp = (struct smc_local *)dev->priv;
-       int timeout;
-       byte phyaddr;
-       word my_phy_caps; // My PHY capabilities
-       word my_ad_caps; // My Advertised capabilities
-       word status;
-       int failed = 0;
-
-       PRINTK3("%s:smc_program_phy()\n", dev->name);
-
-       // Set the blocking flag
-       lp->autoneg_active = 1;
-
-       // Find the address and type of our phy
-       if (!smc_detect_phy(dev))
-               {
-               goto smc_phy_configure_exit;
-               }
-
-       // Get the detected phy address
-       phyaddr = lp->phyaddr;
-
-       // Reset the PHY, setting all other bits to zero
-       smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
-
-       // Wait for the reset to complete, or time out
-       timeout = 6; // Wait up to 3 seconds
-       while (timeout--)
-               {
-               if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
-                   & PHY_CNTL_RST))
-                       {
-                       // reset complete
-                       break;
-                       }
-
-               smc_wait_ms(500); // wait 500 millisecs
-               if (signal_pending(current)) // Exit anyway if signaled
-                       {
-                       PRINTK2("%s:PHY reset interrupted by signal\n",
-                               dev->name);
-                       timeout = 0;
-                       break;
-                       }
-               }
-
-       if (timeout < 1)
-               {
-               PRINTK2("%s:PHY reset timed out\n", dev->name);
-               goto smc_phy_configure_exit;
-               }
-
-       // Read PHY Register 18, Status Output
-       lp->lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
-
-       // Enable PHY Interrupts (for register 18)
-       // Interrupts listed here are disabled
-       smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG,
-               PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
-               PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
-               PHY_INT_SPDDET | PHY_INT_DPLXDET);
-
-       /* Configure the Receive/Phy Control register */
-       SMC_SELECT_BANK( 0 );
-       outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
-
-       // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
-       my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
-       my_ad_caps  = PHY_AD_CSMA; // I am CSMA capable
-
-       if (my_phy_caps & PHY_STAT_CAP_T4)
-               my_ad_caps |= PHY_AD_T4;
-
-       if (my_phy_caps & PHY_STAT_CAP_TXF)
-               my_ad_caps |= PHY_AD_TX_FDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TXH)
-               my_ad_caps |= PHY_AD_TX_HDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TF)
-               my_ad_caps |= PHY_AD_10_FDX;
-
-       if (my_phy_caps & PHY_STAT_CAP_TH)
-               my_ad_caps |= PHY_AD_10_HDX;
-
-#ifdef DISABLED____CONFIG_SYSCTL
-       // Disable capabilities not selected by our user
-       if (lp->ctl_rspeed != 100)
-               {
-               my_ad_caps &= ~(PHY_AD_T4|PHY_AD_TX_FDX|PHY_AD_TX_HDX);
-               }
-
-       if (!lp->ctl_rfduplx)
-               {
-               my_ad_caps &= ~(PHY_AD_TX_FDX|PHY_AD_10_FDX);
-               }
-#endif // CONFIG_SYSCTL
-
-       // Update our Auto-Neg Advertisement Register
-       smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
-
-       PRINTK2("%s:phy caps=%x\n", dev->name, my_phy_caps);
-       PRINTK2("%s:phy advertised caps=%x\n", dev->name, my_ad_caps);
-
-#ifdef DISABLED____CONFIG_SYSCTL
-       // If the user requested no auto neg, then go set his request
-       if (!(lp->ctl_autoneg))
-               {
-               smc_phy_fixed(dev);
-               goto smc_phy_configure_exit;
-               }
-#endif // CONFIG_SYSCTL
-
-       // Restart auto-negotiation process in order to advertise my caps
-       smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
-               PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
-
-       // Wait for the auto-negotiation to complete.  This may take from
-       // 2 to 3 seconds.
-       // Wait for the reset to complete, or time out
-       timeout = 20-1; // Wait up to 10 seconds
-       do
-               {
-               status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
-               if (status & PHY_STAT_ANEG_ACK)
-                       {
-                       // auto-negotiate complete
-                       break;
-                       }
-
-               smc_wait_ms(500); // wait 500 millisecs
-               if (signal_pending(current)) // Exit anyway if signaled
-                       {
-                       printk(KERN_DEBUG
-                               "%s:PHY auto-negotiate interrupted by signal\n",
-                               dev->name);
-                       timeout = 0;
-                       break;
-                       }
-
-               // Restart auto-negotiation if remote fault
-               if (status & PHY_STAT_REM_FLT)
-                       {
-                       PRINTK2("%s:PHY remote fault detected\n", dev->name);
-
-                       // Restart auto-negotiation
-                       PRINTK2("%s:PHY restarting auto-negotiation\n",
-                               dev->name);
-                       smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
-                               PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST |
-                               PHY_CNTL_SPEED | PHY_CNTL_DPLX);
-                       }
-               }
-       while (timeout--);
-
-       if (timeout < 1)
-               {
-               printk(KERN_DEBUG "%s:PHY auto-negotiate timed out\n",
-                       dev->name);
-               PRINTK2("%s:PHY auto-negotiate timed out\n", dev->name);
-               failed = 1;
-               }
-
-       // Fail if we detected an auto-negotiate remote fault
-       if (status & PHY_STAT_REM_FLT)
-               {
-               printk(KERN_DEBUG "%s:PHY remote fault detected\n", dev->name);
-               PRINTK2("%s:PHY remote fault detected\n", dev->name);
-               failed = 1;
-               }
-
-       // The smc_phy_interrupt() routine will be called to update lastPhy18
-
-       // Set our sysctl parameters to match auto-negotiation results
-       if ( lp->lastPhy18 & PHY_INT_SPDDET )
-               {
-               PRINTK2("%s:PHY 100BaseT\n", dev->name);
-               lp->rpc_cur_mode |= RPC_SPEED;
-               }
-       else
-               {
-               PRINTK2("%s:PHY 10BaseT\n", dev->name);
-               lp->rpc_cur_mode &= ~RPC_SPEED;
-               }
-
-       if ( lp->lastPhy18 & PHY_INT_DPLXDET )
-               {
-               PRINTK2("%s:PHY Full Duplex\n", dev->name);
-               lp->rpc_cur_mode |= RPC_DPLX;
-               }
-       else
-               {
-               PRINTK2("%s:PHY Half Duplex\n", dev->name);
-               lp->rpc_cur_mode &= ~RPC_DPLX;
-               }
-
-       // Re-Configure the Receive/Phy Control register
-       outw( lp->rpc_cur_mode, ioaddr + RPC_REG );
-
-  smc_phy_configure_exit:
-
-       // Exit auto-negotiation
-       lp->autoneg_active = 0;
-}
-
-
-
-MODULE_LICENSE("GPL");
-- 
2.31.1


Reply via email to