Hi Greg,

The enclosed patch adds support for RTL8150-based USB network adapters
(such as the Linksys USB100M EtherFast 10/100 Compact USB Network Adapter)
to 2.4.18-pre9.  It is based on [EMAIL PROTECTED]'s old 2.4.0 driver,
which was in turn based on the pegasus driver.

Please apply.

Cheers
Marc

PS: Mr. Wei, if you get this message, please review the new driver,
and send us any updates that might have been done to your version
since 1.0.0.
--- linux-2.4.18-pre9-rtl8150/Documentation/Configure.help      2002/02/10 17:02:48    
 1.1
+++ linux-2.4.18-pre9-rtl8150/Documentation/Configure.help      2002/02/10 17:05:15
@@ -13378,6 +13378,21 @@
   The module will be called pegasus.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+Realtek RTL8150 based USB-Ethernet/HomePNA device support
+CONFIG_USB_RTL8150
+  Say Y here if you know you have a Realtek 8150 or 8151 based adapter,
+  such as the Linksys USB100M EtherFast 10/100 Compact USB Net Adapter.
+  If in doubt then look at linux/drivers/usb/rtl8150.h for the complete
+  list of supported devices.
+  If your particular adapter is not in the list and you are _sure_ it
+  is RTL8150 or RTL8151 based then send me ([EMAIL PROTECTED]) vendor
+  and device IDs.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called rtl8150.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB KLSI KL5USB101-based Ethernet device support
 CONFIG_USB_KAWETH
   Say Y here if you want to use one of the following 10Mbps only
--- linux-2.4.18-pre9-rtl8150/drivers/usb/Config.in     2002/02/10 17:01:03     1.1
+++ linux-2.4.18-pre9-rtl8150/drivers/usb/Config.in     2002/02/10 17:02:01
@@ -86,6 +86,7 @@
    comment '  Networking support is needed for USB Networking device support'
 else
    dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' 
CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Realtek RTL8150-based ethernet device support (EXPERIMENTAL)' 
+CONFIG_USB_RTL8150 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' 
CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' 
CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB Communication Class Ethernet device support (EXPERIMENTAL)' 
CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
--- linux-2.4.18-pre9-rtl8150/drivers/usb/Makefile      2002/02/10 17:01:03     1.1
+++ linux-2.4.18-pre9-rtl8150/drivers/usb/Makefile      2002/02/10 17:02:16
@@ -64,6 +64,7 @@
 obj-$(CONFIG_USB_SE401)                += se401.o
 obj-$(CONFIG_USB_STV680)       += stv680.o
 obj-$(CONFIG_USB_PEGASUS)      += pegasus.o
+obj-$(CONFIG_USB_RTL8150)      += rtl8150.o
 obj-$(CONFIG_USB_CATC)         += catc.o
 obj-$(CONFIG_USB_KAWETH)        += kaweth.o
 obj-$(CONFIG_USB_CDCETHER)     += CDCEther.o
--- linux-2.4.18-pre9-rtl8150/drivers/usb/rtl8150.c     2002/02/10 17:05:37     1.1
+++ linux-2.4.18-pre9-rtl8150/drivers/usb/rtl8150.c     2002/02/10 16:59:55
@@ -0,0 +1,1061 @@
+/*
+**     Realtek RTL8150 USB 10/100 Fast Ethernet / HomePNA Adapter driver
+**
+**     Copyright (c) 2001 Realtek Semiconductor Corp.([EMAIL PROTECTED])
+**     Copyright (c) 2002 Marc Boucher <[EMAIL PROTECTED]>
+**
+**     based on pegasus driver, copyright (c) 1999,2000 Petko Manolov - Petkan
+**
+** Works with the Linksys USB100M EtherFast 10/100 Compact USB Network Adapter
+*/
+
+/*
+ * 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
+ */
+
+ /*
+ **
+ **    ChangeLog of Realtek:
+ **            1.0.0   First release for RTL8150 USB Fast Ethernet NIC
+ **            1.1.0   Polished and updated for 2.4.18 by Marc Boucher <[EMAIL PROTECTED]>
+ **
+ */
+
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/usb.h>
+#include "rtl8150.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.1.0 (2002/02/09)"
+#define DRIVER_AUTHOR "Petko Manolov <[EMAIL PROTECTED]>, Owen Wei 
+<[EMAIL PROTECTED]>, Marc Boucher <[EMAIL PROTECTED]>"
+#define DRIVER_DESC "Realtek RTL8150 USB 10/100 Fast Ethernet Driver"
+
+/// define this to use interrupt endpoint 3
+//#define      RTL8150_USE_INTR        
+
+//static int loopback = 0;
+//static int mii_mode = 0;
+static int multicast_filter_limit = 32;
+
+
+static struct usb_eth_dev usb_dev_id[] = {
+#define        RTL8150_DEV(pn, vid, pid, flags)        \
+       {name:pn, vendor:vid, device:pid, private:flags},
+#include "rtl8150.h"
+#undef RTL8150_DEV
+       {NULL, 0, 0, 0}
+};
+
+static struct usb_device_id rtl8150_ids[] = {
+#define        RTL8150_DEV(pn, vid, pid, flags) \
+       {match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor:vid, idProduct:pid},
+#include "rtl8150.h"
+#undef RTL8150_DEV
+       { }
+};
+
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+//MODULE_PARM(loopback, "i");
+//MODULE_PARM(mii_mode, "i");
+//MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
+//MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
+
+MODULE_DEVICE_TABLE (usb, rtl8150_ids);
+
+static void ctrl_callback( urb_t *urb );
+static int update_rxconfig_async( rtl8150_t *rtl8150 )
+{
+       int     ret;
+
+       rtl8150->dr.requesttype = RTL8150_REQT_WRITE;
+       rtl8150->dr.request = RTL8150_REQ_SET_REGS;
+       rtl8150->dr.index = 0;
+       rtl8150->dr.value =  cpu_to_le16(EthCtrl0);
+       rtl8150->dr.length = cpu_to_le16(3);
+       rtl8150->ctrl_urb.transfer_buffer_length = 3;
+
+       FILL_CONTROL_URB( &rtl8150->ctrl_urb, rtl8150->usb,
+                         usb_sndctrlpipe(rtl8150->usb,0),
+                         (char *)&rtl8150->dr,
+                         &rtl8150->rx_config_content, 
+sizeof(rtl8150->rx_config_content), ctrl_callback, rtl8150 );
+
+       if ( (ret = usb_submit_urb( &rtl8150->ctrl_urb )) )
+               err( __FUNCTION__ " BAD CTRL %d, flags %x",ret,rtl8150->flags );
+
+       return  ret;
+}
+
+static void ctrl_callback( urb_t *urb )
+{
+       rtl8150_t       *rtl8150 = urb->context;
+
+       if ( !rtl8150 )
+               return;
+
+       switch ( urb->status ) {
+               case USB_ST_NOERROR:
+                       if ( rtl8150->flags & ETH_RXCONFIG_CHANGE) {
+                               rtl8150->flags &= ~ETH_RXCONFIG_CHANGE;
+                               rtl8150->flags |= ETH_REGS_CHANGED;
+                               update_rxconfig_async( rtl8150 );
+                               return;
+                       }
+                       break;
+               case USB_ST_URB_PENDING:
+                       dbg( __FUNCTION__ " status USB_PENDING");
+                       return;
+               case USB_ST_URB_KILLED:
+                       warn( __FUNCTION__ " status USB_KILLED");
+                       break;
+               case USB_ST_CRC:
+                       dbg( __FUNCTION__ " status USB_ST_CRC");
+                       break;
+               case USB_ST_TIMEOUT:
+                       dbg( __FUNCTION__ " status USB_ST_TIMEOUT");
+                       break;
+               default:
+                       warn( __FUNCTION__ " status %d", urb->status);
+       }
+       rtl8150->flags &= ~ETH_REGS_CHANGED;
+       wake_up(&rtl8150->ctrl_wait );
+}
+
+
+static int get_registers(rtl8150_t *rtl8150, __u16 indx, __u16 size, void *data)
+{
+       int     ret;
+       unsigned char *buffer;
+       DECLARE_WAITQUEUE(wait, current);
+
+       buffer = kmalloc(size,GFP_KERNEL);
+       if (!buffer) {
+               err("unable to allocate memory for configuration descriptors");
+               return 0;
+       }
+       memcpy(buffer,data,size);
+
+       add_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       while ( rtl8150->flags & ETH_REGS_CHANGED )
+               schedule();
+       remove_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_RUNNING);
+
+       rtl8150->dr.requesttype = RTL8150_REQT_READ;
+       rtl8150->dr.request = RTL8150_REQ_GET_REGS;
+       rtl8150->dr.index = cpu_to_le16 (0);
+       rtl8150->dr.value = cpu_to_le16p(&indx);
+       rtl8150->dr.length = cpu_to_le16p(&size);
+       rtl8150->ctrl_urb.transfer_buffer_length = size;
+
+       FILL_CONTROL_URB( &rtl8150->ctrl_urb, rtl8150->usb,
+                         usb_rcvctrlpipe(rtl8150->usb,0),
+                         (char *)&rtl8150->dr,
+                         buffer, size, ctrl_callback, rtl8150 );
+
+       add_wait_queue( &rtl8150->ctrl_wait, &wait );
+       set_current_state( TASK_UNINTERRUPTIBLE );
+
+       if ( (ret = usb_submit_urb( &rtl8150->ctrl_urb )) ) {
+               err( __FUNCTION__ " BAD CTRLs %d", ret);
+               goto out;
+       }
+
+       schedule();
+out:
+       remove_wait_queue( &rtl8150->ctrl_wait, &wait );
+       memcpy(data,buffer,size);
+       kfree(buffer);
+
+       return ret;
+}
+
+
+static int set_registers(rtl8150_t *rtl8150, __u16 indx, __u16 size, void *data)
+{
+       int     ret;
+       unsigned char *buffer;
+       DECLARE_WAITQUEUE(wait, current);
+
+       buffer = kmalloc(size, GFP_KERNEL);
+       if (!buffer) {
+               err("unable to allocate memory for configuration descriptors");
+               return 0;
+       }
+       memcpy(buffer, data, size);
+
+       add_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       while ( rtl8150->flags & ETH_REGS_CHANGED )
+               schedule();
+       remove_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_RUNNING);
+
+       rtl8150->dr.requesttype = RTL8150_REQT_WRITE;
+       rtl8150->dr.request = RTL8150_REQ_SET_REGS;
+       rtl8150->dr.index = cpu_to_le16 (0);
+       rtl8150->dr.value = cpu_to_le16p( &indx );
+       rtl8150->dr.length = cpu_to_le16p( &size );
+       rtl8150->ctrl_urb.transfer_buffer_length = size;
+
+       FILL_CONTROL_URB( &rtl8150->ctrl_urb, rtl8150->usb,
+                         usb_sndctrlpipe(rtl8150->usb,0),
+                         (char *)&rtl8150->dr,
+                         buffer, size, ctrl_callback, rtl8150 );
+                         
+       add_wait_queue( &rtl8150->ctrl_wait, &wait );
+       set_current_state( TASK_UNINTERRUPTIBLE );
+
+       if ( (ret = usb_submit_urb( &rtl8150->ctrl_urb )) ) {
+               err( __FUNCTION__ " BAD CTRL %d", ret);
+               goto out;
+       }
+       
+       schedule();
+out:
+       remove_wait_queue( &rtl8150->ctrl_wait, &wait );
+       kfree(buffer);
+       
+       return ret;
+}
+
+
+#if 0
+static int set_register( rtl8150_t *rtl8150, __u16 indx, __u8 data )
+{
+       int     ret;
+       unsigned char *buffer;
+       __u16 dat = data;
+       DECLARE_WAITQUEUE(wait, current);
+       
+       buffer = kmalloc(1, GFP_KERNEL);
+       if (!buffer) {
+               err("unable to allocate memory for configuration descriptors");
+               return 0;
+       }
+       memcpy(buffer, &data, 1);
+
+       add_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       while ( rtl8150->flags & ETH_REGS_CHANGED )
+               schedule();
+       remove_wait_queue(&rtl8150->ctrl_wait, &wait);
+       set_current_state(TASK_RUNNING);
+
+       rtl8150->dr.requesttype = RTL8150_REQT_WRITE;
+       rtl8150->dr.request = RTL8150_REQ_SET_REG;
+       rtl8150->dr.index = cpu_to_le16p( &dat);
+       rtl8150->dr.value = cpu_to_le16p( &indx );
+       rtl8150->dr.length = cpu_to_le16( 1 );
+       rtl8150->ctrl_urb.transfer_buffer_length = 1;
+
+       FILL_CONTROL_URB( &rtl8150->ctrl_urb, rtl8150->usb,
+                         usb_sndctrlpipe(rtl8150->usb,0),
+                         (char *)&rtl8150->dr,
+                         buffer, 1, ctrl_callback, rtl8150 );
+
+       add_wait_queue( &rtl8150->ctrl_wait, &wait );
+       set_current_state( TASK_UNINTERRUPTIBLE );
+
+       if ( (ret = usb_submit_urb( &rtl8150->ctrl_urb )) ) {
+               err( __FUNCTION__ " BAD CTRL %d", ret);
+               goto out;
+       }
+
+       schedule();
+out:
+       remove_wait_queue( &rtl8150->ctrl_wait, &wait );
+       kfree(buffer);
+
+       return ret;
+}
+
+
+static int read_phy_word( rtl8150_t *rtl8150, __u8 phy, __u8 indx, __u16 *regd )
+{
+       int     i;
+       __u8    MiiPhyAccessContent;
+
+       /*
+       set_register( rtl8150, MiiPhyAccess, 0 );
+       set_register( rtl8150, MiiPhyAddr, phy );
+       set_register( rtl8150, MiiPhyAccess, (0x40 | indx) );
+       for (i = 0; i < REG_TIMEOUT; i++) 
+       {
+               get_registers( rtl8150, MiiPhyAccess, 1, &MiiPhyAccessContent );
+               if ( (MiiPhyAccessContent & 0x40) == 0)
+                       break;
+       }
+       if ( i < REG_TIMEOUT ) 
+       {
+               get_registers( rtl8150, MiiPhyData, 2, regd );
+               return  0;
+       }
+       warn( __FUNCTION__ " failed" );
+       */
+       
+       return 1;
+}
+
+
+
+static int write_phy_word( rtl8150_t *rtl8150, __u8 phy, __u8 indx, __u16 regd )
+{
+       int     i;
+       __u8    data[2] = { 0, 0 };
+       __u8    MiiPhyAccessContent;
+       
+       dbg( "write_phy_word() =====>" );
+
+       /*
+       *data = cpu_to_le16p( &regd );
+       set_register( rtl8150, MiiPhyAccess, 0 );
+       set_register( rtl8150, MiiPhyAddr, phy );
+       set_registers( rtl8150, MiiPhyData, 2, data );
+       set_register( rtl8150, MiiPhyAccess, (0x60 | indx) );
+       for (i = 0; i < REG_TIMEOUT; i++) 
+       {
+               get_registers( rtl8150, MiiPhyAccess, 1, &MiiPhyAccessContent );
+               if ( (MiiPhyAccessContent & 0x40) == 0)
+                       break;
+       }
+
+       if ( i < REG_TIMEOUT )
+               return  0;
+       
+       warn( __FUNCTION__ " failed" );
+       */
+
+       return 1;
+}
+
+
+
+static int read_eprom_word( rtl8150_t *rtl8150, __u8 index, __u16 *retdata )
+{
+       int     i, tmp;
+
+       dbg( "+read_eprom_word() =====>" );
+
+       get_registers( rtl8150, index, 2, retdata );
+       
+       dbg( "-read_eprom_word() <=====" );
+       return  0;
+}
+
+
+
+static int read_eprom_byte( rtl8150_t *rtl8150, __u16 index, __u8 *retdata )
+{
+       int     i, tmp;
+
+       dbg( "+read_eprom_byte() =====>" );
+
+       get_registers( rtl8150,  index, 1, retdata );
+       
+       dbg( "-read_eprom_byte() <=====");
+
+       return 0;
+}
+
+#ifdef RTL8150_WRITE_EEPROM
+static inline void enable_eprom_write( rtl8150_t *rtl8150 )
+{
+       __u8    tmp;
+
+       dbg( "+enable_eprom_write() =====>" );
+
+       dbg( "-enable_eprom_write() <=====" );
+}
+
+
+static inline void disable_eprom_write( rtl8150_t *rtl8150 )
+{
+       __u8    tmp;
+
+       dbg( "+disable_eprom_write() =====>" );
+       
+       dbg( "-disable_eprom_write() <=====" );
+}
+
+
+static int write_eprom_word( rtl8150_t *rtl8150, __u8 index, __u16 data )
+{
+       int     i, tmp;
+       __u8    d[4] = {0x3f, 0, 0, EPROM_WRITE};
+
+       dbg( "+write_eprom_word() =====>" );
+
+       /*
+       set_registers( rtl8150, EpromOffset, 4, d );
+       enable_eprom_write( rtl8150 );
+       set_register( rtl8150, EpromOffset, index );
+       set_registers( rtl8150, EpromData, 2, &data );
+       set_register( rtl8150, EpromCtrl, EPROM_WRITE );
+
+       for ( i=0; i < REG_TIMEOUT; i++ ) {
+               get_registers( rtl8150, EpromCtrl, 1, &tmp );
+               if ( tmp & EPROM_DONE )
+                       break;
+       }
+       disable_eprom_write( rtl8150 );
+       if ( i < REG_TIMEOUT )
+               return  0;
+       warn( __FUNCTION__ " failed" );
+       */
+       dbg( "-write_eprom_word <=====");
+       return  -1;
+}
+#endif /* RTL8150_WRITE_EEPROM */
+
+#endif
+
+static inline void get_node_id( rtl8150_t *rtl8150, __u8 *id )
+{
+       int     i;
+
+       dbg( "+get_node_id() =====>" );
+       for (i=0; i < 6; i++)
+       {
+               get_registers( rtl8150, IDR0+i, 1, &id[i] );
+       }
+       dbg( "-get_node_id() <=====" );
+}
+
+
+static void set_ethernet_addr( rtl8150_t *rtl8150 )
+{
+       __u8    node_id[6];
+       memset(node_id, 0, sizeof(node_id));
+
+       dbg( "+set_ethernet_addr() =====>" );
+       get_node_id(rtl8150, node_id);
+       memcpy( rtl8150->net->dev_addr, node_id, sizeof(node_id) );
+       dbg( " set_ethernet_addr: node id = %x %x %x %x %x %x",
+               node_id[0], node_id[1], node_id[2], node_id[3], node_id[4], node_id[5] 
+);
+       dbg( "-set_ethernet_addr() <======" );
+}
+
+
+static inline int reset_mac( rtl8150_t *rtl8150 )
+{
+       __u8    data = 0;
+       int     i;
+
+       dbg( "+reset_mac() =====>" );
+       /// software reset
+       data = SOFT_RST;
+
+       set_registers(rtl8150, Command, 1, &data);
+       for (i = 0; i < REG_TIMEOUT; i++)
+       {
+               get_registers(rtl8150, Command, 1, &data);
+               if ( ~(data & SOFT_RST) )
+               {
+                       break;
+               }
+       }
+       if ( i == REG_TIMEOUT )
+       {
+               warn( __FUNCTION__": software reset failed" );
+               return 1;
+       }
+       
+       dbg( "-reset_mac() <=====" );
+       return  0;
+}
+
+
+static int enable_net_traffic( struct net_device *dev, struct usb_device *usb )
+{
+       //__u16 linkpart, bmsr;
+       //__u8  data[4];
+       __u8    byte_tmp = 0;
+       rtl8150_t *rtl8150 = dev->priv;
+
+       dbg("+enable_net_traffic() =====>");
+       
+       /// check if link okay!
+       get_registers( rtl8150, MediaStst, 1, &byte_tmp );
+       dbg(" enable_net_traffic: MediaStst = 0x%x", byte_tmp);
+       if ( byte_tmp & LINK )
+               dbg(" enable_net_traffic: LINK ON");
+       else
+               dbg(" enable_net_traffic: LINK OFF");
+
+       
+       /// software reset
+       /// byte_tmp = SOFT_RST;
+       ///set_register( rtl8150, Command, 1, &byte_tmp );
+       
+       /// set Transmit Configuration Register
+       dbg(" enable_net_traffic: before setting Tx Config");
+       byte_tmp = TXRR1 | TXRR0 | IFG1 | IFG0;
+       set_registers( rtl8150, TxConfig, 1, &byte_tmp);
+       ///get_registers( rtl8150, TxConfig, 1, &byte_tmp );
+       dbg( "enable_net_traffic: TxConfig = 0x%x", byte_tmp );
+       dbg(" enable_net_traffic: after setting Tx Config");
+
+       /// set Receive Configuration Register
+       dbg(" enable_net_traffic: before setting Rx Config");
+       rtl8150->rx_config_content = AM | AB | AD | AAM;
+       set_registers( rtl8150, RxConfig, 2, &rtl8150->rx_config_content );
+       dbg(" enable_net_traffic: after setting Rx Config");
+
+       /// enable Tx and Rx
+       dbg(" enable_net_traffic: before enabling Tx and Rx" );
+       byte_tmp = RE | TE;
+       set_registers( rtl8150, Command, 1, &byte_tmp );
+       dbg(" enable_net_traffic: after enabling Tx and Rx" );
+       
+       //get_register( rtl8150, Command, &byte_tmp);
+       //dbg(" enable_net_traffic: Command = 0x%x", byte_tmp );
+
+       dbg( "-enable_net_traffic() <=====");
+       return 0;
+}
+
+
+static void read_bulk_callback( struct urb *urb )
+{
+       rtl8150_t *rtl8150 = urb->context;
+       struct net_device *net;
+       int count = urb->actual_length, res;
+       struct sk_buff  *skb;
+       __u16 pkt_len;
+
+       dbg( "+read_bulk_callback() =====>" );
+
+       if ( !rtl8150 || !(rtl8150->flags & RTL8150_RUNNING) )
+               return;
+
+       net = rtl8150->net;
+       if ( !netif_device_present(net) )
+               return;
+
+       if ( rtl8150->flags & RTL8150_RX_BUSY ) {
+               rtl8150->stats.rx_errors++;
+               return;
+       }
+       rtl8150->flags |= RTL8150_RX_BUSY;
+
+       switch ( urb->status ) {
+               case USB_ST_NOERROR:
+                       break;
+               case USB_ST_NORESPONSE:
+                       warn( __FUNCTION__": NO RESPONSE (reset MAC)" );
+                       rtl8150->flags &= ~RTL8150_RX_BUSY;
+                       break;
+               default:
+                       info( __FUNCTION__": %s: Rx status = 0x%x", net->name, 
+urb->status);
+                       goto goon;
+       }
+       
+       pkt_len = count - 4;
+       dbg(" read_bulk_callback: packet length = 0x%x", pkt_len );
+       dbg(" read_bulk_callback: packet = %x %x %x %x %x %x %x %x %x %x %x %x", 
+rtl8150->rx_buff[0], rtl8150->rx_buff[1],
+               rtl8150->rx_buff[2], rtl8150->rx_buff[3], rtl8150->rx_buff[4], 
+rtl8150->rx_buff[5],
+               rtl8150->rx_buff[6], rtl8150->rx_buff[7], rtl8150->rx_buff[8], 
+rtl8150->rx_buff[9],
+               rtl8150->rx_buff[10], rtl8150->rx_buff[11] );
+
+       if ( !(skb = dev_alloc_skb(pkt_len+2)) )
+               goto goon;
+
+       skb->dev = net;
+       skb_reserve(skb, 2);
+       eth_copy_and_sum(skb, rtl8150->rx_buff, pkt_len, 0);
+       skb_put(skb, pkt_len);
+
+       skb->protocol = eth_type_trans(skb, net);
+       netif_rx(skb);
+       rtl8150->stats.rx_packets++;
+       rtl8150->stats.rx_bytes += pkt_len;
+
+goon:
+       FILL_BULK_URB( &rtl8150->rx_urb, rtl8150->usb,
+                       usb_rcvbulkpipe(rtl8150->usb, 1),
+                       rtl8150->rx_buff, RTL8150_MAX_MTU, 
+                       read_bulk_callback, rtl8150 );
+       if ( (res = usb_submit_urb(&rtl8150->rx_urb)) )
+               warn( __FUNCTION__ ": failed submit rx_urb %d", res);
+       rtl8150->flags &= ~RTL8150_RX_BUSY;
+       
+       dbg( "-read_bulk_callback() <=====");
+}
+
+
+static void write_bulk_callback( struct urb *urb )
+{
+       rtl8150_t *rtl8150 = urb->context;
+
+       dbg( "+write_bulk_callback() =====>" );
+
+       if ( !rtl8150 || !(rtl8150->flags & RTL8150_RUNNING) )
+               return;
+
+       if ( !netif_device_present(rtl8150->net) )
+               return;
+               
+       if ( urb->status )
+               info("%s: TX status %d", rtl8150->net->name, urb->status);
+
+       rtl8150->net->trans_start = jiffies;
+       netif_wake_queue( rtl8150->net );
+       dbg( "-write_bulk_callback() <=====" );
+}
+
+
+
+#ifdef RTL8150_USE_INTR
+static void intr_callback( struct urb *urb )
+{
+       rtl8150_t *rtl8150 = urb->context;
+       struct net_device *net;
+       __u8    *d;
+
+       dbg( "intr_callback() =====>" );
+
+       if ( !rtl8150 )
+               return;
+       d = urb->transfer_buffer;
+       net = rtl8150->net;
+///    if ( d[0] & 0xfc ) {
+///            rtl8150->stats.tx_errors++;
+///            if ( d[0] & TX_UNDERRUN )
+///                    rtl8150->stats.tx_fifo_errors++;
+///            if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
+///                    rtl8150->stats.tx_aborted_errors++;
+///            if ( d[0] & LATE_COL )
+///                    rtl8150->stats.tx_window_errors++;
+///            if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
+///                    rtl8150->stats.tx_carrier_errors++;
+///    }
+       switch ( urb->status ) 
+       {
+               case USB_ST_NOERROR:
+                       break;
+               case USB_ST_URB_KILLED:
+                       break;
+               default:
+                       dbg("intr status %d", urb->status);
+       }
+}
+#endif
+
+
+
+static void rtl8150_tx_timeout( struct net_device *net )
+{
+       rtl8150_t *rtl8150 = net->priv;
+
+       dbg( "+rtl8150_tx_timeout() =====>" );
+
+       if ( !rtl8150 )
+               return;
+       
+       warn("%s: Tx timed out.", net->name);
+       rtl8150->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
+       usb_unlink_urb( &rtl8150->tx_urb );
+       rtl8150->stats.tx_errors++;
+       dbg( "-rtl8150_tx_timeout() <=====" );
+}
+
+
+
+static int rtl8150_start_xmit( struct sk_buff *skb, struct net_device *net )
+{
+       rtl8150_t       *rtl8150 = net->priv;
+       int     count = ((skb->len) & 0x3f) ? skb->len : skb->len+1;
+               /// increase 64n-length packet by one, because the host controller 
+sometimes doesn't send
+               /// 0-length usb packet to end the 64n-length packet.
+       int     res;
+
+       dbg( "+rtl8150_start_xmit() =====>" );
+
+       netif_stop_queue( net );
+               
+       memcpy( rtl8150->tx_buff, skb->data, skb->len );
+       
+       if(count < RTL8150_MIN_PACKET_LENGTH)
+               count = RTL8150_MIN_PACKET_LENGTH;
+       FILL_BULK_URB( &rtl8150->tx_urb, rtl8150->usb,
+                       usb_sndbulkpipe(rtl8150->usb, 2),
+                       rtl8150->tx_buff, RTL8150_MAX_MTU, 
+                       write_bulk_callback, rtl8150 );
+       rtl8150->tx_urb.transfer_buffer_length = count;
+
+       dbg( " rtl8150_start_xmit: packet length = 0x%x", count);       
+       dbg( " rtl8150_start_xmit: packet = %x %x %x %x %x %x %x %x %x %x %x %x", 
+rtl8150->tx_buff[0], rtl8150->tx_buff[1],
+               rtl8150->tx_buff[2], rtl8150->tx_buff[3], rtl8150->tx_buff[4], 
+rtl8150->tx_buff[5],
+               rtl8150->tx_buff[6], rtl8150->tx_buff[7], rtl8150->tx_buff[8], 
+rtl8150->tx_buff[9],
+               rtl8150->tx_buff[10], rtl8150->tx_buff[11]);
+       if ((res = usb_submit_urb(&rtl8150->tx_urb))) 
+       {
+               warn("failed tx_urb %d", res);
+               rtl8150->stats.tx_errors++;
+               netif_start_queue( net );
+       }
+       else 
+       {
+               rtl8150->stats.tx_packets++;
+               rtl8150->stats.tx_bytes += skb->len;
+               net->trans_start = jiffies;     /// record the time stamp
+       }
+
+       dev_kfree_skb(skb);
+       
+       dbg( "-rtl8150_start_xmit() <=====" );  
+       return 0;
+}
+
+
+static struct net_device_stats *rtl8150_netdev_stats( struct net_device *dev )
+{
+       return &((rtl8150_t *)dev->priv)->stats;
+}
+
+
+
+static inline void disable_net_traffic( rtl8150_t *rtl8150 )
+{
+       __u8    tmp = 0;
+
+       dbg( "+disable_net_traffic() =====>" );
+       set_registers( rtl8150, Command, 1, &tmp );
+       dbg( "-disable_net_traffic() <=====" );
+}
+
+
+
+#ifdef RTL8150_USE_INTR
+static inline void get_interrupt_interval( rtl8150_t *rtl8150 )
+{
+       __u8    data;
+
+       dbg( "+get_interrupt_interval() =====>" );
+
+       read_eprom_byte( rtl8150, EPROM_Interv, &data );
+       rtl8150->intr_interval = data;
+       dbg( "-get_interrupt_interval() <=====" );
+}
+#endif
+
+
+/// this function is called when "ifconfig ethx xxx ....."
+static int rtl8150_open(struct net_device *net)
+{
+       rtl8150_t *rtl8150 = (rtl8150_t *)net->priv;
+       int     res;
+
+       dbg( "+rtl8150_open() =====>" );
+
+       dbg( " rtl8150_open: before enable_net_traffic()" );
+       if ( (res = enable_net_traffic(net, rtl8150->usb)) ) 
+       {
+               err(__FUNCTION__": enable_net_traffic failed (%d)", res);
+               return -EIO;
+       }
+
+       /// initiate the rx operation
+       dbg( " rtl8150_open: initiate the rx operation" );
+       FILL_BULK_URB( &rtl8150->rx_urb, rtl8150->usb,
+                       usb_rcvbulkpipe(rtl8150->usb, 1),
+                       rtl8150->rx_buff, RTL8150_MAX_MTU, 
+                       read_bulk_callback, rtl8150 );
+       if ( (res = usb_submit_urb(&rtl8150->rx_urb)) )
+               warn( __FUNCTION__ " failed rx_urb %d", res );
+
+#ifdef RTL8150_USE_INTR
+       /*
+       /// initiate the interrupt operation
+       FILL_INT_URB( &rtl8150->intr_urb, rtl8150->usb,
+                       usb_rcvintpipe(rtl8150->usb, 3),
+                       rtl8150->intr_buff, sizeof(rtl8150->intr_buff),
+                       intr_callback, rtl8150, rtl8150->intr_interval );
+       if ( (res = usb_submit_urb(&rtl8150->intr_urb)) )
+               warn( __FUNCTION__ " failed intr_urb %d", res);
+       */
+#endif
+       netif_start_queue( net );
+       rtl8150->flags |= RTL8150_RUNNING;
+
+       dbg( "-rt8150_open() <=====" );
+       
+       return 0;
+}
+
+
+
+/// this function is called when "ifconfig ethx down"
+static int rtl8150_close( struct net_device *net )
+{
+       rtl8150_t       *rtl8150 = net->priv;
+
+       dbg( "+rtl8150_close() =====>" );
+
+       rtl8150->flags &= ~RTL8150_RUNNING;
+       netif_stop_queue( net );
+       if ( !(rtl8150->flags & RTL8150_UNPLUG) )
+               disable_net_traffic( rtl8150 );
+
+       usb_unlink_urb( &rtl8150->rx_urb );
+       usb_unlink_urb( &rtl8150->tx_urb );
+       usb_unlink_urb( &rtl8150->ctrl_urb );
+#ifdef RTL8150_USE_INTR
+       usb_unlink_urb( &rtl8150->intr_urb );
+#endif
+
+       dbg( "-rtl8150_close() <=====" );
+       return 0;
+}
+
+
+
+static int rtl8150_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
+{
+#if 1
+       info( "+rtl8150_ioctl() =====> return -EOPNOTSUPP directly" );
+
+       return -EOPNOTSUPP;
+
+#else
+
+       __u16 *data = (__u16 *)&rq->ifr_data;
+       rtl8150_t       *rtl8150 = net->priv;
+
+       switch(cmd) {
+               case SIOCDEVPRIVATE:
+                       data[0] = rtl8150->phy;
+               case SIOCDEVPRIVATE+1:
+                       read_phy_word(rtl8150, data[0], data[1]&0x1f, &data[3]);
+                       return 0;
+               case SIOCDEVPRIVATE+2:
+                       if ( !capable(CAP_NET_ADMIN) )
+                               return -EPERM;
+                       write_phy_word(rtl8150, rtl8150->phy, data[1] & 0x1f, data[2]);
+                       return 0;
+               default:
+                       return -EOPNOTSUPP;
+       }
+#endif
+}
+
+
+static void rtl8150_set_multicast( struct net_device *net )
+{
+       rtl8150_t *rtl8150 = net->priv;
+
+       dbg( "+rtl8150_set_multicast() =====>" );
+
+       netif_stop_queue(net);
+
+       if (net->flags & IFF_PROMISC) 
+       {
+               rtl8150->rx_config_content |= AAP;
+               dbg("%s: Promiscuous mode enabled", net->name);
+       } 
+       else if( (net->mc_count > multicast_filter_limit) || (net->flags & 
+IFF_ALLMULTI) ) 
+       {
+               rtl8150->rx_config_content |= AAM;
+               rtl8150->rx_config_content &= ~AAP;
+               dbg("%s: set allmulti", net->name);
+       } 
+       else 
+       {
+               rtl8150->rx_config_content &= ~AAM;
+               rtl8150->rx_config_content &= ~AAP;
+               dbg("%s: No Promiscuous and All Multicast", net->name);
+               /// added by Owen, please refer to 14.14.2 of Linux Device Drivers
+               /// if( net->mc_count==0 )
+               ///     ff_get_only_own_packets();
+               /// else
+               /// {
+               ///     struct dev_mc_list      *mcptr;
+               ///     ff_clear_mc_list();
+               ///     for( mc_ptr = net->mc_list; mc_ptr; mc_ptr = mc_ptr->next )
+               ///             ff_store_mc_address( mc_ptr->dmi_addr );
+               //      ff_get_packets_in_multicast_list();
+               /// }
+       }
+
+       rtl8150->flags |= ETH_RXCONFIG_CHANGE;
+       ctrl_callback( &rtl8150->ctrl_urb );
+
+       netif_wake_queue(net);  
+       dbg( "-rtl8150_set_multicast() <=====" );       
+}
+
+static void mii_HPNA_phy_probe( rtl8150_t *rtl8150 )
+{
+#if 0
+       int     i;
+       __u16   tmp;
+
+       for ( i=0; i < 32; i++ ) 
+       {
+               read_phy_word( rtl8150, i, MII_PHY_ID2, &tmp );
+               tmp = tmp & 0xfff0;
+               if( tmp == AMD_PHY_ID ) 
+               {
+                       rtl8150->hpna_phy = AMD_PHY;
+                       rtl8150->phy = i;
+                       return;
+               }
+               else if( tmp == NS_PHY_ID )
+               {
+                       rtl8150->hpna_phy = NS_PHY;
+                       rtl8150->phy = i;
+                       return;
+               }
+               else
+                       continue;       
+       }
+
+       rtl8150->phy = 0;
+       rtl8150->hpna_phy = UNKNOWN_PHY;
+#endif
+}
+
+
+
+static void * rtl8150_probe( struct usb_device *dev, unsigned int ifnum, const struct 
+usb_device_id *id)
+{
+       struct net_device *net;
+       rtl8150_t *rtl8150;
+       int     dev_indx = id - rtl8150_ids;
+
+       dbg( "+rtl8150_probe() =====>" );
+
+       /// the following is for fixing the bug of 1st-cut, and must be removed in 
+2nd-cut
+       dev->config[0].bConfigurationValue = 1;
+       ////////////////////////////////////////////////
+       if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) 
+       {
+               err(__FUNCTION__": usb_set_configuration() failed");
+               return NULL;
+       }
+
+       if(!(rtl8150 = kmalloc(sizeof(struct rtl8150), GFP_KERNEL))) 
+       {
+               err(__FUNCTION__": out of memory allocating device structure");
+               return NULL;
+       }
+       
+       usb_inc_dev_use( dev );
+       memset(rtl8150, 0, sizeof(struct rtl8150));
+       
+       init_MUTEX( &rtl8150-> ctrl_sem );
+       
+       init_waitqueue_head( &rtl8150->ctrl_wait );
+
+       net = init_etherdev( NULL, 0 );
+       if ( !net ) 
+       {
+               kfree( rtl8150 );
+               info( " rtl8150_probe: init_etherdev() failed" );
+               return  NULL;
+       }
+       
+       rtl8150->usb = dev;
+       rtl8150->net = net;
+       SET_MODULE_OWNER(net);
+       net->priv = rtl8150;
+       net->open = rtl8150_open;
+       net->stop = rtl8150_close;
+       net->watchdog_timeo = RTL8150_TX_TIMEOUT;
+       net->tx_timeout = rtl8150_tx_timeout;
+       net->do_ioctl = rtl8150_ioctl;
+       net->hard_start_xmit = rtl8150_start_xmit;
+       net->set_multicast_list = rtl8150_set_multicast;
+       net->get_stats = rtl8150_netdev_stats;
+       net->mtu = RTL8150_MTU;     //  1500
+
+       rtl8150->features = usb_dev_id[dev_indx].private;
+#ifdef RTL8150_USE_INTR
+       get_interrupt_interval( rtl8150 );
+#endif
+       if ( reset_mac(rtl8150) ) {
+               err(__FUNCTION__": can't reset MAC");
+               unregister_netdev( rtl8150->net );
+               kfree(rtl8150->net);
+               kfree(rtl8150);
+               return NULL;
+       }
+
+       info( "%s: %s", net->name, usb_dev_id[dev_indx].name );
+
+       set_ethernet_addr( rtl8150 );
+       
+       if( rtl8150->features & FEATURE_HAS_HOME_PNA )
+               mii_HPNA_phy_probe( rtl8150 );
+       
+       dbg( "-rtl8150_probe() <=====" );
+       return rtl8150;
+}
+
+
+static void rtl8150_disconnect( struct usb_device *dev, void *ptr )
+{
+       struct rtl8150 *rtl8150 = ptr;
+
+       dbg( "+rtl8150_disconnect() =====>" );
+
+       if ( !rtl8150 ) {
+               warn(__FUNCTION__": unregistering non-existant device");
+               return;
+       }
+
+       rtl8150->flags |= RTL8150_UNPLUG;
+       unregister_netdev( rtl8150->net );
+       usb_dec_dev_use( dev );
+       kfree(rtl8150->net);
+       kfree( rtl8150 );
+       rtl8150 = NULL;
+       dbg( "-rtl8150_disconnect() <=====" );
+}
+
+
+static struct usb_driver rtl8150_driver = {
+       name:           "rtl8150",
+       probe:          rtl8150_probe,
+       disconnect:     rtl8150_disconnect,
+       id_table:       rtl8150_ids,
+};
+
+int __init rtl8150_init(void)
+{
+       info(DRIVER_VERSION ":" DRIVER_DESC);
+       return usb_register( &rtl8150_driver );
+}
+
+void __exit rtl8150_exit(void)
+{
+       usb_deregister( &rtl8150_driver );
+}
+
+module_init( rtl8150_init );
+module_exit( rtl8150_exit );
--- linux-2.4.18-pre9-rtl8150/drivers/usb/rtl8150.h     2002/02/10 17:05:37     1.1
+++ linux-2.4.18-pre9-rtl8150/drivers/usb/rtl8150.h     2002/02/10 16:59:55
@@ -0,0 +1,296 @@
+/*
+ * 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
+ */
+
+#ifndef RTL8150_DEV
+
+#define        RTL8150_MTU                     1500
+#define        RTL8150_MAX_MTU                 1536
+#define RTL8150_MIN_PACKET_LENGTH      60
+
+
+/// phy registers index
+#define MII_PHY_ID1    0x02
+#define MII_PHY_ID2    0x03
+
+
+/// manufacture ID of HPNA PHY 
+#define AMD_PHY_ID     0x6b90
+#define NS_PHY_ID      0x5c20
+
+
+/// rtl8150->features
+#define        FEATURE_DEFAULT         0x00
+#define        FEATURE_HAS_HOME_PNA    0x01
+
+
+/// rtl8150 states
+#define        RTL8150_PRESENT         0x00000001
+#define        RTL8150_RUNNING         0x00000002
+#define        RTL8150_TX_BUSY         0x00000004
+#define        RTL8150_RX_BUSY         0x00000008
+#define        RTL8150_UNPLUG          0x00000040
+
+#define        ETH_RXCONFIG_CHANGE     0x40000000
+#define        ETH_REGS_CHANGED        0x80000000
+
+#define        REG_TIMEOUT             (HZ)
+#define        RTL8150_TX_TIMEOUT      (HZ*10)
+
+
+/// vendor memory read & write
+#define        RTL8150_REQT_READ       0xc0
+#define        RTL8150_REQT_WRITE      0x40
+#define        RTL8150_REQ_GET_REGS    0x05
+#define        RTL8150_REQ_SET_REG     0x05
+#define        RTL8150_REQ_SET_REGS RTL8150_REQ_SET_REG
+
+
+#define        NUM_CTRL_URBS           0x10
+#define        ALIGN(x)                x __attribute__((aligned(L1_CACHE_BYTES)))
+
+
+#define SIZE32_BIT0            0x00000001
+#define SIZE32_BIT1            0x00000002
+#define SIZE32_BIT2            0x00000004
+#define SIZE32_BIT3            0x00000008
+#define SIZE32_BIT4            0x00000010
+#define SIZE32_BIT5            0x00000020
+#define SIZE32_BIT6            0x00000040
+#define SIZE32_BIT7            0x00000080
+#define SIZE32_BIT8            0x00000100
+#define SIZE32_BIT9            0x00000200
+#define SIZE32_BIT10           0x00000400
+#define SIZE32_BIT11           0x00000800
+#define SIZE32_BIT12           0x00001000
+#define SIZE32_BIT13           0x00002000
+#define SIZE32_BIT14           0x00004000
+#define SIZE32_BIT15           0x00008000
+#define SIZE32_BIT16           0x00010000
+#define SIZE32_BIT17           0x00020000
+#define SIZE32_BIT18           0x00040000
+#define SIZE32_BIT19           0x00080000
+#define SIZE32_BIT20           0x00100000
+#define SIZE32_BIT21           0x00200000
+#define SIZE32_BIT22           0x00400000
+#define SIZE32_BIT23           0x00800000
+#define SIZE32_BIT24           0x01000000
+#define SIZE32_BIT25           0x02000000
+#define SIZE32_BIT26           0x04000000
+#define SIZE32_BIT27           0x08000000
+#define SIZE32_BIT28           0x10000000
+#define SIZE32_BIT29           0x20000000
+#define SIZE32_BIT30           0x40000000
+#define SIZE32_BIT31           0x80000000
+
+
+#define SIZE16_BIT0            0x0001
+#define SIZE16_BIT1            0x0002
+#define SIZE16_BIT2            0x0004
+#define SIZE16_BIT3            0x0008
+#define SIZE16_BIT4            0x0010
+#define SIZE16_BIT5            0x0020
+#define SIZE16_BIT6            0x0040
+#define SIZE16_BIT7            0x0080
+#define SIZE16_BIT8            0x0100
+#define SIZE16_BIT9            0x0200
+#define SIZE16_BIT10           0x0400
+#define SIZE16_BIT11           0x0800
+#define SIZE16_BIT12           0x1000
+#define SIZE16_BIT13           0x2000
+#define SIZE16_BIT14           0x4000
+#define SIZE16_BIT15           0x8000
+
+
+#define SIZE8_BIT0             0x01
+#define SIZE8_BIT1             0x02
+#define SIZE8_BIT2             0x04
+#define SIZE8_BIT3             0x08
+#define SIZE8_BIT4             0x10
+#define SIZE8_BIT5             0x20
+#define SIZE8_BIT6             0x40
+#define SIZE8_BIT7             0x80
+
+
+/// registers index
+#define IDR0                   0x0120
+#define Command                        0x012e
+#define TxConfig               0x012f
+#define RxConfig               0x0130
+#define TxStst                 0x0132
+#define RxStst                 0x0133
+#define Config                 0x0135
+#define Config1                        0x0136
+#define MediaStst              0x0137
+#define MiiPhyAddr             0x0138
+#define MiiPhyData             0x0139
+#define MiiPhyAccess           0x013b
+#define GPPCtrl                        0x013d
+#define WakeUpEventCtrl                0x013e
+#define BasicModeCtrl          0x0140
+#define BasicModeStst          0x0142
+#define AutoNegoAdver          0x0144
+#define AutoNegoLinkPartner    0x0146
+#define AutoNegoExpan          0x0148
+#define NwayTst                        0x014a
+#define CSConfig               0x014c
+
+
+/// which HPNA PHY
+enum hpna_phy {
+       UNKNOWN_PHY = 0,
+       AMD_PHY = 1,
+       NS_PHY = 2,
+};
+
+
+/// loopback mode
+enum loopback_mode{
+       NORMAL_OPERATION = 0,
+       DIGITAL_LOOPBACK = 1,
+       ANALOG_LOOPBACK = 2,
+};
+
+
+/// EEPROM index
+#define                EPROM_IDR0              0x1202
+#define        EPROM_Config0           0x1208
+#define                EPROM_MSR               0x1209
+#define        EPROM_GPCP              0x120a
+#define                EPROM_UDP               0x120b
+#define                EPROM_ATTR              0x120c
+#define                EPROM_PHY2_PARM         0x120d
+#define                EPROM_PHY1_PARM         0x120e
+#define                EPROM_TW1_PARM          0x1212
+#define                EPROM_MAXPOR            0x1216
+#define                EPROM_Interv            0x1217
+#define                EPROM_LanguageID        0x1218
+#define                EPROM_ManufactureID     0x121a
+#define        EPROM_ProductID         0x121c
+#define                EPROM_SerialNumber      0x121e
+#define                EPROM_ManufactureString 0x1228
+#define                EPROM_ProductString     0x1250
+
+
+/// Command Register
+#define        WEPROM                  SIZE8_BIT5
+#define        SOFT_RST                SIZE8_BIT4
+#define                RE                      SIZE8_BIT3
+#define                TE                      SIZE8_BIT2
+#define        EP3CLEAR                SIZE8_BIT1
+#define        AUTOLOAD                SIZE8_BIT0
+
+
+/// Transmit Configuration Register
+#define                TXRR1                   SIZE8_BIT7
+#define                TXRR0                   SIZE8_BIT6
+#define        IFG1                    SIZE8_BIT4
+#define                IFG0                    SIZE8_BIT3
+#define        LBK1                    SIZE8_BIT2
+#define        LBK0                    SIZE8_BIT1
+#define                NOCRC                   SIZE8_BIT0
+
+
+/// Receive Configuration Register
+#define        EARRX                   SIZE16_BIT10
+#define                TAIL                    SIZE16_BIT7
+#define                AER                     SIZE16_BIT6
+#define                AR                      SIZE16_BIT5
+#define                AM                      SIZE16_BIT4
+#define                AB                      SIZE16_BIT3
+#define                AD                      SIZE16_BIT2
+#define                AAM                     SIZE16_BIT1
+#define                AAP                     SIZE16_BIT0
+
+/// Transmit Status Register
+#define        ECOL                    SIZE8_BIT5
+#define                LCOL                    SIZE8_BIT4
+#define        LOSS_CRS                SIZE8_BIT3
+#define                JBR                     SIZE8_BIT2
+#define        TX_BUF_EMPTY            SIZE8_BIT1
+#define                TX_BUF_FULL             SIZE8_BIT0
+
+/// Receive Status Register
+#define                WEVENT                  SIZE8_BIT7
+#define                RX_BUF_FULL             SIZE8_BIT6
+#define                LKCHG                   SIZE8_BIT5
+#define        RUNT                    SIZE8_BIT4
+#define                LONG                    SIZE8_BIT3
+#define        CRC                     SIZE8_BIT2
+#define                FAE                     SIZE8_BIT1
+#define                ROK                     SIZE8_BIT0
+
+/// Configuration Register0
+#define                SUSLED                  SIZE8_BIT7
+#define                PARM_EN                 SIZE8_BIT6
+#define                LDPS                    SIZE8_BIT3
+#define                MSEL                    SIZE8_BIT2
+#define                LEDS1                   SIZE8_BIT1
+#define        LEDS0                   SIZE8_BIT0
+
+/// Configuration Register1
+#define        BWF                     SIZE8_BIT6
+#define                MWF                     SIZE8_BIT5
+#define                UWF                     SIZE8_BIT4
+#define                LONGWF1                 SIZE8_BIT1
+#define                LONGWF0                 SIZE8_BIT0
+
+/// Media Status Register
+#define                TXFCE                   SIZE8_BIT7
+#define                RXFCE                   SIZE8_BIT6
+#define                DUPLEX                  SIZE8_BIT4
+#define                SPEED_100               SIZE8_BIT3
+#define        LINK                    SIZE8_BIT2
+#define                TXPF                    SIZE8_BIT1
+#define                RXPF                    SIZE8_BIT0
+
+#define EthCtrl0 0
+
+typedef struct rtl8150 {
+       struct usb_device       *usb; // store "dev" passed in rtl8150_probe( struct 
+usb_device *dev...)
+       struct net_device       *net; // store "net" returned by init_etherdev()
+       struct net_device_stats stats;
+       unsigned                flags;
+       unsigned                features;
+       int                     intr_interval;
+       struct urb              ctrl_urb, rx_urb, tx_urb, intr_urb;
+       devrequest              dr;
+       wait_queue_head_t       ctrl_wait;
+       struct semaphore        ctrl_sem;
+       unsigned char           ALIGN(rx_buff[RTL8150_MAX_MTU]);
+       unsigned char           ALIGN(tx_buff[RTL8150_MAX_MTU]);
+       unsigned char           ALIGN(intr_buff[8]);
+       __u16                   rx_config_content;
+       __u8                    phy;
+       __u8                    hpna_phy;
+       __u8                    gpio_res;
+} rtl8150_t;
+
+
+struct usb_eth_dev {
+       char    *name;
+       __u16   vendor;
+       __u16   device;
+       __u32   private; /* LSB is gpio reset value */
+};
+
+#else
+
+RTL8150_DEV( "Realtek RTL8150 USB 10/100 Fast Ethernet Adapter", 0x0bda, 0x8150,
+                       FEATURE_DEFAULT)
+RTL8150_DEV( "Realtek RTL8151 USB 1Mbps HomePNA Adapter", 0x0bda, 0x8151,
+                       FEATURE_DEFAULT | FEATURE_HAS_HOME_PNA)
+
+#endif /* RTL8150_DEV */
--- linux-2.4.18-pre9-rtl8150/MAINTAINERS       2002/02/10 17:27:36     1.1
+++ linux-2.4.18-pre9-rtl8150/MAINTAINERS       2002/02/10 17:28:19
@@ -1631,6 +1631,13 @@
 L:     [EMAIL PROTECTED]
 S:     Maintained
 
+USB RTL8150 DRIVER
+P:     Marc Boucher
+M:     [EMAIL PROTECTED]
+L:     [EMAIL PROTECTED]
+L:     [EMAIL PROTECTED]
+S:     Maintained
+
 USB PRINTER DRIVER
 P:     Vojtech Pavlik
 M:     [EMAIL PROTECTED]

Reply via email to