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( ®d );
+ 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]