iinfi
mekalodu
i have a USB to ethernet device which i want to use in linux.
i downloaded the driver files from the net for the same but am unable to understand the instructions.
the instructions in the readme go as follows.
contents of the file named "Makefile"
contents of the file named "dm9601.c"
contents of the file named "dm9601.h"
do the above code make any sense ??
atleast i dont understand the instructions.
1st step RUN make command!! how do i do this???
i downloaded the driver files from the net for the same but am unable to understand the instructions.
the instructions in the readme go as follows.
DAVICOM Semiconductor Inc. 11/24/2006
A Davicom DM9601 USB Fast Ethernet driver for Linux.
Copyright (C) 1997 Sten Wang
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.
A. Compiler command:
Run make command <<< how do i run this?
B. The following steps teach you how to activate NIC:
B-1: A simple and temporary method
1. Used the upper compiler command to compile dm9601.c
2. Insert DM9601 module into kernel
"insmod dm9601.ko" ;;Auto Detection Mode (Suggest)
"insmod dm9601.ko mode=0" ;;Force 10M Half Duplex
"insmod dm9601.ko mode=1" ;;Force 100M Half Duplex
"insmod dm9601.ko mode=4" ;;Force 10M Full Duplex
"insmod dm9601.ko mode=5" ;;Force 100M Full Duplex
NOTE: You can type "man insmod" to see more description.
3. Config a DM9601 network interface
"ifconfig eth0 172.22.3.18"
^^^^^^^^^^^ Your IP address
NOTE: 1. You can type "man ifconfig" to see more description.
2. If eth0 has been used, you should use eth1 instead.
4. Activate the IP routing table. For some distributions, it is not
necessary. You can type "route" to check.
"route add default netmask 255.255.255.0 eth0"
NOTE: 1. You can type "man route" to see more description.
2. If eth0 has been used, you should use eth1 instead.
5. Well done. Your DM9601 adapter actived now.
Note. This is a temporary method. After you reboot the system, you
will lost the setting.
B-2: For Redhat, You can use the following to Activate NIC
1. login your system used the superuser.
2. copy dm9601.ko into /lib/modules/2.6.x/kernel/drivers/net/
3. add the new line with "alias eth0 dm9601" in "/etc/module.conf".
4. execute "netconfig -d eth0".
5. Fill your IP address, netmask and gateway
6. press <ok> to confirm and exit this setting
7 reboot
Note. If eth0 has been used, you should use eth1 instead.
DAVICOM Web-Site: www.davicom.com.tw
contents of the file named "Makefile"
Code:
##================================================================
## Davicom Semiconductor Inc. For DM9601 V0.00
## --------------------------------------------------------
## Description:
## Compile driver dm9601.c to dm9601.o
##
## Modification List:
## 09/05/2000 Fixed SMPFALGS wrong on smp & smp_mod
## 08/02/2000 Changed some description string & include file path
## 07/25/2000 Append smp_mod and changed some descriptions
## 01/25/2000 by Sten Wang
##================================================================
# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y
# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
CFLAGS += $(DEBFLAGS) -I$(LDDINCDIR)
ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m := dm9601.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINCDIR=$(PWD)/../include modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
contents of the file named "dm9601.c"
Code:
/*
** DM9601: USB 10/100Mbps/HomePNA (1Mbps) Fast Ethernet
**
** Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
**
**
** ChangeLog:
** v0.01 Work for DM9601 now.
** v0.02 rename to dm9601.
** v0.03 Debug TX full to cause TX hang problem.
** v0.04 Support MAC/Hash address
** REG5 get better RX performance when bit4=0
** Power-Down PHY when driver close
** v0.05 Support dynamic reset
** Support automatically switch IntPHY/EXT MII
** Support REG_8, REG_9, REG_A for flow control
** V0.06 06/14/01 Dynamic select INT/EXT MII by REG1 bit 4
** Support Force and Auto mode
** V0.07 06/14/01 Program HPNA chip E3/E4/E5
** V0.08 06/15/01 Enable REG_F4 bit5 to force "INT always return"
** V0.09 06/19/01 Default set REG_0A bit3 to enable BP with DA match
** 06/22/01 Modify DM9801 progrmming
** E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
** E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
** R17 = (R17 & 0xfff0) | NF + 3
** E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
** R17 = (R17 & 0xfff0) | NF
**
** V1.00 03/05/03 Weilun Huang <weilun_huang@davicom.com.tw>:
** Added semaphore mechanism to solve the problem.
** While device is being plugged, it makes kernel
** hang on VIA chipset. Removed the devrequest typedef
** use "struct usb_ctrlrequest".
** v1.01 06/01/12 Michael shen <michaelshen@davicom.com.cn>:
** modify argument of try_module_get and module_put
** to be THIS_MODULE to pass compiling for kernel 2.6.9
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.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 <linux/module.h>
#include <linux/crc32.h>
#include "dm9601.h"
extern int usb_set_configuration(struct usb_device *dev, int configuration);
#define DM9601_USE_INTR
static const char *version = __FILE__ ": v0.0.6 2001/05/24 (C) 1999-2000 Petko Manolov (petkan@dce.bg)";
static struct usb_eth_dev usb_dev_id[] = {
#define DM9601_DEV(pn, vid, pid, flags) \
{name:pn, vendor:vid, device:pid, private:flags},
#include "dm9601.h"
#undef DM9601_DEV
{NULL, 0, 0, 0}
};
static struct usb_device_id dm9601_ids[] = {
#define DM9601_DEV(pn, vid, pid, flags) \
{match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor:vid, idProduct:pid},
#include "dm9601.h"
#undef DM9601_DEV
{ }
};
/* For module input parameter */
static int mode = DM9601_AUTO, dm9601_mode;
static u8 reg5 = DM9601_REG5, reg8 = DM9601_REG8, reg9 = DM9601_REG9,
rega = DM9601_REGA, nfloor = 0;
MODULE_AUTHOR("Petko Manolov <petkan@dce.bg>");
MODULE_DESCRIPTION("DAVICOM DM9601 USB Fast Ethernet driver");
MODULE_LICENSE("Dual BSD/GPL");
/*
* USB-status codes: not defined in 2.6
* USB_ST* maps to -E* and should go away in the future
*/
#define USB_ST_NOERROR 0
#define USB_ST_CRC (-EILSEQ)
#define USB_ST_BITSTUFF (-EPROTO)
#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */
#define USB_ST_DATAOVERRUN (-EOVERFLOW)
#define USB_ST_DATAUNDERRUN (-EREMOTEIO)
#define USB_ST_BUFFEROVERRUN (-ECOMM)
#define USB_ST_BUFFERUNDERRUN (-ENOSR)
#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */
#define USB_ST_SHORT_PACKET (-EREMOTEIO)
#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */
#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */
#define USB_ST_URB_PENDING (-EINPROGRESS)
#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */
#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/
#define USB_ST_NOTSUPPORTED (-ENOSYS)
#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */
#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */
#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */
#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/
module_param(mode, int,0644);
module_param(reg5,int,0644);
module_param(reg8,int,0644);
module_param(reg9,int,0644);
module_param(rega,int,0644);
module_param(nfloor,int,0644);
MODULE_PARM_DESC(mode, "Media mode select: 0:10MH 1:100MHF 4:10MF 5:100MF 8:AUTO");
MODULE_DEVICE_TABLE (usb, dm9601_ids);
static int write_eprom_word(dm9601_board_info_t *, __u8, __u16);
static int update_eth_regs_async(dm9601_board_info_t *);
/* Aargh!!! I _really_ hate such tweaks */
static void ctrl_callback(struct urb *urb, struct pt_regs* regs)
{
dm9601_board_info_t *dbi = urb->context;
if (!dbi)
return;
switch (urb->status & 0xff) {
case USB_ST_NOERROR:
case 0x92:
if (dbi->flags & ALL_REGS_CHANGE) {
update_eth_regs_async(dbi);
return;
}
break;
case USB_ST_URB_PENDING:
case 0x8d:
return;
case USB_ST_URB_KILLED:
break;
default:
warn("%s: status %x",__FUNCTION__, urb->status);
}
dbi->flags &= ~ALL_REGS_CHANGED;
if (dbi->flags & CTRL_URB_SLEEP) {
dbi->flags &= ~CTRL_URB_SLEEP;
wake_up_interruptible(&dbi->ctrl_wait);
}
}
static int get_registers(dm9601_board_info_t *dbi, __u16 indx, __u16 size, void *data)
{
int ret;
DECLARE_WAITQUEUE(wait, current);
while ( dbi->flags & ALL_REGS_CHANGED ) {
dbi->flags |= CTRL_URB_SLEEP;
interruptible_sleep_on( &dbi->ctrl_wait );
}
dbi->dr.bRequestType = DM9601_REQT_READ;
dbi->dr.bRequest = DM9601_REQ_GET_REGS;
dbi->dr.wValue = cpu_to_le16 (0);
dbi->dr.wIndex = cpu_to_le16p(&indx);
dbi->dr.wLength = cpu_to_le16p(&size);
dbi->ctrl_urb.transfer_buffer_length = size;
usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
usb_rcvctrlpipe(dbi->usb,0),
(char *)&dbi->dr,
data, size, ctrl_callback, dbi );
add_wait_queue( &dbi->ctrl_wait, &wait );
set_current_state( TASK_INTERRUPTIBLE );
dbi->flags |= CTRL_URB_SLEEP;
if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_ATOMIC)) ) {
err("%s: BAD CTRLs %d",__FUNCTION__,ret);
goto out;
}
schedule();
remove_wait_queue( &dbi->ctrl_wait, &wait );
out:
return ret;
}
static int set_registers(dm9601_board_info_t *dbi, __u16 indx, __u16 size, void *data)
{
int ret;
DECLARE_WAITQUEUE(wait, current);
while (dbi->flags & ALL_REGS_CHANGED) {
dbi->flags |= CTRL_URB_SLEEP ;
interruptible_sleep_on(&dbi->ctrl_wait);
}
dbi->dr.bRequestType = DM9601_REQT_WRITE;
dbi->dr.bRequest = DM9601_REQ_SET_REGS;
dbi->dr.wValue = cpu_to_le16(0);
dbi->dr.wIndex = cpu_to_le16p(&indx);
dbi->dr.wLength = cpu_to_le16p(&size);
dbi->ctrl_urb.transfer_buffer_length = size;
usb_fill_control_urb(&dbi->ctrl_urb, dbi->usb,
usb_sndctrlpipe(dbi->usb, 0),
(char *)&dbi->dr,
data, size, ctrl_callback, dbi);
add_wait_queue(&dbi->ctrl_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
dbi->flags |= CTRL_URB_SLEEP;
if ( (ret = usb_submit_urb(&dbi->ctrl_urb,GFP_ATOMIC)) ) {
err("%s: BAD CTRL %d",__FUNCTION__,ret);
return ret;
}
schedule();
remove_wait_queue( &dbi->ctrl_wait, &wait );
return ret;
}
static int set_register( dm9601_board_info_t *dbi, __u16 indx, __u8 data )
{
int ret;
__u16 dat = data;
DECLARE_WAITQUEUE(wait, current);
while ( dbi->flags & ALL_REGS_CHANGED ) {
dbi->flags |= CTRL_URB_SLEEP;
interruptible_sleep_on( &dbi->ctrl_wait );
}
dbi->dr.bRequestType = DM9601_REQT_WRITE;
dbi->dr.bRequest = DM9601_REQ_SET_REG;
dbi->dr.wValue = cpu_to_le16p( &dat);
dbi->dr.wIndex = cpu_to_le16p( &indx );
dbi->dr.wLength = cpu_to_le16( 0 );
dbi->ctrl_urb.transfer_buffer_length = 0;
usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
usb_sndctrlpipe(dbi->usb,0),
(char *)&dbi->dr,
&data, 0, ctrl_callback, dbi );
add_wait_queue( &dbi->ctrl_wait, &wait );
set_current_state( TASK_INTERRUPTIBLE );
dbi->flags |= CTRL_URB_SLEEP;
if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_ATOMIC)) ) {
err("%s: BAD CTRL %d",__FUNCTION__,ret);
return ret;
}
schedule();
remove_wait_queue( &dbi->ctrl_wait, &wait );
return ret;
}
static int update_eth_regs_async( dm9601_board_info_t *dbi )
{
int ret;
if (dbi->flags & HASH_REGS_CHANGE) {
dbi->flags &= ~HASH_REGS_CHANGE;
dbi->flags |= HASH_REGS_CHANGED;
dbi->dr.bRequestType = DM9601_REQT_WRITE;
dbi->dr.bRequest = DM9601_REQ_SET_REGS;
dbi->dr.wValue = cpu_to_le16(0);
dbi->dr.wIndex = cpu_to_le16(0x16);
dbi->dr.wLength = cpu_to_le16(8);
dbi->ctrl_urb.transfer_buffer_length = 8;
usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
usb_sndctrlpipe(dbi->usb,0),
(char *)&dbi->dr,
dbi->hash_table, 8, ctrl_callback, dbi );
} else if (dbi->flags & RX_CTRL_CHANGE) {
dbi->flags &= ~RX_CTRL_CHANGE;
dbi->flags |= RX_CTRL_CHANGED;
dbi->dr.bRequestType = DM9601_REQT_WRITE;
dbi->dr.bRequest = DM9601_REQ_SET_REG;
dbi->dr.wValue = cpu_to_le16(dbi->rx_ctrl_reg);
dbi->dr.wIndex = cpu_to_le16(0x5);
dbi->dr.wLength = cpu_to_le16(0);
dbi->ctrl_urb.transfer_buffer_length = 0;
usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
usb_sndctrlpipe(dbi->usb,0),
(char *)&dbi->dr,
&dbi->rx_ctrl_reg, 0, ctrl_callback, dbi );
} else {
dbi->flags &= ~NET_CTRL_CHANGE;
dbi->flags |= NET_CTRL_CHANGED;
dbi->dr.bRequestType = DM9601_REQT_WRITE;
dbi->dr.bRequest = DM9601_REQ_SET_REG;
dbi->dr.wValue = cpu_to_le16(dbi->net_ctrl_reg);
dbi->dr.wIndex = cpu_to_le16(0x0);
dbi->dr.wLength = cpu_to_le16(0);
dbi->ctrl_urb.transfer_buffer_length = 0;
usb_fill_control_urb( &dbi->ctrl_urb, dbi->usb,
usb_sndctrlpipe(dbi->usb,0),
(char *)&dbi->dr,
&dbi->net_ctrl_reg, 0, ctrl_callback, dbi );
}
if ( (ret = usb_submit_urb( &dbi->ctrl_urb ,GFP_KERNEL)) )
err("%s: BAD CTRL %d, flags %x",__FUNCTION__,ret,dbi->flags );
return ret;
}
static int read_mii_word( dm9601_board_info_t *dbi, __u8 phy, __u8 index, __u16 *regd )
{
set_register( dbi, 0x0c, index | 0x40 );
set_register( dbi, 0x0b, 0x0c );
udelay(100);
set_register( dbi, 0x0b, 0x0 );
get_registers( dbi, 0xd, 2, regd);
return 0;
}
static int write_mii_word( dm9601_board_info_t *dbi, __u8 phy, __u8 index, __u16 regd )
{
set_register( dbi, 0x0c, index | 0x40 );
set_registers( dbi, 0xd, 2, ®d);
set_register( dbi, 0x0b, 0x0a );
udelay(100);
set_register( dbi, 0x0b, 0x0 );
return 0;
}
static int read_eprom_word( dm9601_board_info_t *dbi, __u8 index, __u16 *retdata )
{
set_register( dbi, 0x0c, index );
set_register( dbi, 0x0b, 0x4 );
udelay(100);
set_register( dbi, 0x0b, 0x0 );
get_registers( dbi, 0xd, 2, retdata);
return 0;
}
static int write_eprom_word( dm9601_board_info_t *dbi, __u8 index, __u16 data )
{
set_register(dbi, 0x0c, index);
set_registers(dbi, 0x0d, 2, &data);
set_register(dbi, 0x0b, 0x12);
udelay(100);
set_register(dbi, 0x0b, 0x0);
return 0;
}
static void read_bulk_callback( struct urb *urb, struct pt_regs* reg )
{
dm9601_board_info_t *dbi = urb->context;
struct net_device *net = dbi->net;
int count = urb->actual_length, res;
__u8 rx_status;
struct sk_buff *skb;
__u16 pkt_len;
unsigned char * bufptr;
if ( !dbi || !(dbi->flags & DM9601_RUNNING) )
return;
if ( !netif_device_present(net) )
return;
if ( dbi->flags & DM9601_RX_BUSY ) {
dbi->stats.rx_errors++;
dbg("DM9601 Rx busy");
return;
}
dbi->flags |= DM9601_RX_BUSY;
switch ( urb->status ) {
case USB_ST_NOERROR:
break;
case USB_ST_NORESPONSE:
dbg( "reset MAC" );
dbi->flags &= ~DM9601_RX_BUSY;
break;
default:
#ifdef RX_IMPROVE
dbg("%s: RX status %d",net->name, urb->status );
goto goon;
#endif
;
}
/* For RX improve ---------------------------*/
#ifdef RX_IMPROVE
if (dbi->rx_buf_flag) {
bufptr = dbi->rx_buff;
usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
usb_rcvbulkpipe(dbi->usb, 1),
dbi->rx_buff2, DM9601_MAX_MTU,
read_bulk_callback, dbi );
} else {
bufptr = dbi->rx_buff2;
usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
usb_rcvbulkpipe(dbi->usb, 1),
dbi->rx_buff, DM9601_MAX_MTU,
read_bulk_callback, dbi );
}
if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
warn("%s: failed submint rx_urb %d",__FUNCTION__,res);
dbi->flags &= ~DM9601_RX_BUSY;
dbi->rx_buf_flag = dbi->rx_buf_flag ? 0:1;
#else
bufptr = dbi->rx_buff;
#endif
/* ----------------------------------------------------------*/
if ( !count )
goto goon;
rx_status = *(__u8 *)(bufptr);
pkt_len = *(__u16 *)(bufptr + 1) - 4;
dbi->stats.rx_bytes += pkt_len;
if ( (rx_status & 0xbf) || (pkt_len > 1518) ) {
dbi->stats.rx_errors++;
if (pkt_len > 1518) dbi->rx_longf_errors++;
if (rx_status & 0x80) dbi->rx_runtf_errors++;
if (rx_status & 0x20) dbi->rx_lc_errors++;
if (rx_status & 0x10) dbi->rx_wdt_errors++;
if (rx_status & 0x08) dbi->rx_ple_errors++;
if (rx_status & 0x04) dbi->stats.rx_frame_errors++;
if (rx_status & 0x02) dbi->stats.rx_crc_errors++;
if (rx_status & 0x1) dbi->stats.rx_fifo_errors++;
goto goon;
}
if ( !(skb = dev_alloc_skb(pkt_len + 2)) )
goto goon;
skb->dev = net;
skb_reserve(skb, 2);
memcpy(skb_put(skb, pkt_len), bufptr + 3, pkt_len);
skb->protocol = eth_type_trans(skb, net);
netif_rx(skb);
dbi->stats.rx_packets++;
dbi->stats.rx_bytes += pkt_len;
goon:
#ifndef RX_IMPROVE
usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
usb_rcvbulkpipe(dbi->usb, 1),
dbi->rx_buff, DM9601_MAX_MTU,
read_bulk_callback, dbi );
if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
warn("%s: failed submint rx_urb %d",__FUNCTION__,res);
dbi->flags &= ~DM9601_RX_BUSY;
#endif
}
static void write_bulk_callback( struct urb *urb, struct pt_regs* reg )
{
dm9601_board_info_t *dbi = urb->context;
if ( !dbi || !(dbi->flags & DM9601_RUNNING) )
return;
if ( !netif_device_present(dbi->net) )
return;
if ( urb->status )
info("%s: TX status %d", dbi->net->name, urb->status);
dbi->net->trans_start = jiffies;
netif_wake_queue( dbi->net );
}
#ifdef DM9601_USE_INTR
static void intr_callback( struct urb *urb ,struct pt_regs* pt)
{
dm9601_board_info_t *dbi = urb->context;
struct net_device *net;
__u8 *d;
if ( !dbi )
return;
switch ( urb->status ) {
case USB_ST_NOERROR:
break;
case USB_ST_URB_KILLED:
return;
default:
info("intr status %d", urb->status);
}
d = urb->transfer_buffer;
net = dbi->net;
if ( !(d[6] & 0x04) && (d[0] & 0x10) ) {
printk("<WARN> TX FULL %x %x\n", d[0], d[6]);
dbi->flags |= DM9601_RESET_WAIT;
}
/* Auto Sense Media Policy:
Fast EtherNet NIC: don't need to do.
Force media mode: don't need to do.
HomeRun/LongRun NIC and AUTO_Mode:
INT_MII not link, select EXT_MII
EXT_MII not link, select INT_MII
*/
if ( !(d[0] & 0x40) &&
(dbi->nic_type != FASTETHER_NIC) &&
(dbi->op_mode == DM9601_AUTO) ) {
dbi->net_ctrl_reg ^= 0x80;
netif_stop_queue(net);
dbi->flags |= NET_CTRL_CHANGE;
ctrl_callback(&dbi->ctrl_urb, NULL);
netif_wake_queue(net);
}
if ( (d[1] | d[2]) & 0xf4 ) {
dbi->stats.tx_errors++;
if ( (d[0] | d[1]) & 0x84) /* EXEC & JABBER */
dbi->stats.tx_aborted_errors++;
if ( (d[0] | d[1]) & 0x10 ) /* LATE COL */
dbi->stats.tx_window_errors++;
if ( (d[0] | d[1]) & 0x60 ) /* NO or LOST CARRIER */
dbi->stats.tx_carrier_errors++;
}
}
#endif
static void dm9601_tx_timeout( struct net_device *net )
{
dm9601_board_info_t *dbi = net->priv;
if ( !dbi )
return;
warn("%s: Tx timed out.", net->name);
dbi->tx_urb.transfer_flags |= URB_NO_FSBR;//USB_ASYNC_UNLINK;
usb_unlink_urb( &dbi->tx_urb );
dbi->stats.tx_errors++;
}
//#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,48)
//#endif
static int dm9601_start_xmit( struct sk_buff *skb, struct net_device *net )
{
dm9601_board_info_t *dbi = net->priv;
int count = skb->len + 2;
int res;
__u16 l16 = skb->len;
netif_stop_queue( net );
if (!(count & 0x3f)) { count++; l16++; }
((__u16 *)dbi->tx_buff)[0] = cpu_to_le16(l16);
memcpy(dbi->tx_buff + 2, skb->data, skb->len);
#if 0
FILL_BULK_URB_TO( &dbi->tx_urb, dbi->usb,
usb_sndbulkpipe(dbi->usb, 2),
dbi->tx_buff, count,
write_bulk_callback, dbi, jiffies + HZ );
#else
usb_fill_bulk_urb( &dbi->tx_urb, dbi->usb,
usb_sndbulkpipe(dbi->usb, 2),
dbi->tx_buff, count,
write_bulk_callback, dbi);
#endif
if ((res = usb_submit_urb(&dbi->tx_urb,GFP_KERNEL))) {
warn("failed tx_urb %d", res);
dbi->stats.tx_errors++;
netif_start_queue( net );
} else {
dbi->stats.tx_packets++;
dbi->stats.tx_bytes += skb->len;
net->trans_start = jiffies;
}
dev_kfree_skb(skb);
return 0;
}
static struct net_device_stats *dm9601_netdev_stats( struct net_device *dev )
{
return &((dm9601_board_info_t *)dev->priv)->stats;
}
static inline void disable_net_traffic( dm9601_board_info_t *dbi )
{
__u8 reg5;
write_mii_word(dbi, 1, 0, 0x8000); /* RESET PHY */
get_registers(dbi, 0x5, 1, ®5);
reg5 &= 0xfe;
set_register(dbi, 0x5, reg5); /* RX disable */
set_register(dbi, 0x1f, 0x01); /* PHY power down */
}
static void set_phy_mode(dm9601_board_info_t *dbi)
{
__u16 phy_reg0 = 0x1000, phy_reg4 = 0x01e1;
/* PHY media mode setting */
if ( !(dbi->op_mode & DM9601_AUTO) ) {
switch(dbi->op_mode) {
case DM9601_10MHF:
phy_reg4 = 0x0021; break;
case DM9601_10MFD:
phy_reg4 = 0x0041; break;
case DM9601_100MHF:
phy_reg4 = 0x0081; break;
case DM9601_100MFD:
phy_reg4 = 0x0101; break;
default:
phy_reg0 = 0x8000; break;
}
write_mii_word(dbi, 1, 4, phy_reg4); /* Set PHY capability */
write_mii_word(dbi, 1, 0, phy_reg0);
}
/* Active PHY */
set_register( dbi, 0x1e, 0x01 ); /* Let GPIO0 output */
set_register( dbi, 0x1f, 0x00 ); /* Power_on PHY */
}
/*
Init HomeRun DM9801
*/
static void program_dm9801(dm9601_board_info_t *dbi, u16 HPNA_rev)
{
__u16 reg16, reg17, reg24, reg25;
if ( !nfloor ) nfloor = DM9801_NOISE_FLOOR;
read_mii_word(dbi, 1, 16, ®16);
read_mii_word(dbi, 1, 17, ®17);
read_mii_word(dbi, 1, 24, ®24);
read_mii_word(dbi, 1, 25, ®25);
switch(HPNA_rev) {
case 0xb900: /* DM9801 E3 */
reg16 |= 0x1000;
reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xf000;
break;
case 0xb901: /* DM9801 E4 */
reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xc200;
reg17 = (reg17 & 0xfff0) + nfloor + 3;
break;
case 0xb902: /* DM9801 E5 */
case 0xb903: /* DM9801 E6 */
default:
reg16 |= 0x1000;
reg25 = ( (reg24 + nfloor - 3) & 0x00ff) | 0xc200;
reg17 = (reg17 & 0xfff0) + nfloor;
break;
}
write_mii_word(dbi, 1, 16, reg16);
write_mii_word(dbi, 1, 17, reg17);
write_mii_word(dbi, 1, 25, reg25);
}
/*
Init LongRun DM9802
*/
static void program_dm9802(dm9601_board_info_t *dbi)
{
__u16 reg25;
if ( !nfloor ) nfloor = DM9802_NOISE_FLOOR;
read_mii_word(dbi, 1, 25, ®25);
reg25 = (reg25 & 0xff00) + nfloor;
write_mii_word(dbi, 1, 25, reg25);
}
/*
Identify NIC type
*/
static void identify_nic(dm9601_board_info_t* dbi)
{
__u16 phy_tmp;
/* Select EXT_MII */
dbi->net_ctrl_reg |= 0x80;
set_register(dbi, 0x00, dbi->net_ctrl_reg); /* EXT-MII */
read_mii_word(dbi, 1, 3, &phy_tmp);
switch(phy_tmp & 0xfff0) {
case 0xb900:
read_mii_word(dbi, 1, 31, &phy_tmp);
if (phy_tmp == 0x4404) {
dbi->nic_type = HOMERUN_NIC;
program_dm9801(dbi, phy_tmp);
} else {
dbi->nic_type = LONGRUN_NIC;
program_dm9802(dbi);
}
break;
default:
dbi->nic_type = FASTETHER_NIC;
}
/* Select INT_MII */
dbi->net_ctrl_reg &= ~0x80;
set_register(dbi, 0x00, dbi->net_ctrl_reg);
}
static void init_dm9601(struct net_device *net)
{
dm9601_board_info_t *dbi = (dm9601_board_info_t *)net->priv;
/* User passed argument */
dbi->rx_ctrl_reg = reg5 | 0x01;
dbi->net_ctrl_reg = 0x00;
dbi->reg08 = reg8;
dbi->reg09 = reg9;
dbi->reg0a = rega;
/* RESET device */
set_register(dbi, 0x00, 0x01); /* Reset */
udelay(100);
/* NIC type: FASTETHER, HOMERUN, LONGRUN */
identify_nic(dbi);
/* Set PHY */
dbi->op_mode = dm9601_mode;
set_phy_mode(dbi);
/* MII selection */
if ( (dbi->nic_type != FASTETHER_NIC) &&
(dbi->op_mode == DM9601_1M_HPNA) )
dbi->net_ctrl_reg |= 0x80;
/* Program operating register */
set_register(dbi, 0x00, dbi->net_ctrl_reg);
set_register(dbi, 0x08, dbi->reg08);
set_register(dbi, 0x09, dbi->reg09);
set_register(dbi, 0x0a, dbi->reg0a);
set_register(dbi, 0xf4, 0x26); /* Reset EP1/EP2, INT always return */
set_registers(dbi, 0x10, 0x06, net->dev_addr); /* MAC addr */
dbi->hash_table[3] = 0x8000; /* Broadcast Address */
set_registers(dbi, 0x16, 0x08, dbi->hash_table); /* Hash Table */
set_register(dbi, 0x05, dbi->rx_ctrl_reg); /* Active RX */
}
static int dm9601_open(struct net_device *net)
{
dm9601_board_info_t *dbi = (dm9601_board_info_t *)net->priv;
int res;
int owner;
down(&dbi->ctrl_sem);
// MOD_INC_USE_COUNT;
owner = try_module_get(THIS_MODULE);
usb_fill_bulk_urb( &dbi->rx_urb, dbi->usb,
usb_rcvbulkpipe(dbi->usb, 1),
dbi->rx_buff, DM9601_MAX_MTU,
read_bulk_callback, dbi );
if ( (res = usb_submit_urb(&dbi->rx_urb,GFP_ATOMIC)) )
warn("%s: failed rx_urb %d",__FUNCTION__,res);
dbi->rx_buf_flag = 1;
#ifdef DM9601_USE_INTR
usb_fill_int_urb( &dbi->intr_urb, dbi->usb,
usb_rcvintpipe(dbi->usb, 3),
dbi->intr_buff, sizeof(dbi->intr_buff),
intr_callback, dbi, dbi->intr_interval );
if ( (res = usb_submit_urb(&dbi->intr_urb,GFP_ATOMIC)) )
warn("%s: failed intr_urb %d",__FUNCTION__,res);
#endif
init_dm9601(net);
netif_start_queue( net );
dbi->flags |= DM9601_RUNNING;
up(&dbi->ctrl_sem);
return 0;
}
static int dm9601_close( struct net_device *net )
{
dm9601_board_info_t *dbi = net->priv;
dbi->flags &= ~DM9601_RUNNING;
netif_stop_queue(net);
if ( !(dbi->flags & DM9601_UNPLUG) )
disable_net_traffic(dbi);
usb_unlink_urb(&dbi->rx_urb);
usb_unlink_urb(&dbi->tx_urb);
usb_unlink_urb(&dbi->ctrl_urb);
#ifdef DM9601_USE_INTR
usb_unlink_urb(&dbi->intr_urb);
#endif
//MOD_DEC_USE_COUNT;
module_put(THIS_MODULE);
#ifdef STS_DBUG
printk("<DM9601> rx errors: %lx \n", dbi->stats.rx_errors);
printk("<DM9601> fifo over errors: %lx \n", dbi->stats.rx_fifo_errors);
printk("<DM9601> crc errors: %lx \n", dbi->stats.rx_crc_errors);
printk("<DM9601> alignment errors: %lx \n", dbi->stats.rx_frame_errors);
printk("<DM9601> physical layer errors: %lx \n", dbi->rx_ple_errors);
printk("<DM9601> watchdog errors: %lx \n", dbi->rx_wdt_errors);
printk("<DM9601> late collision errors: %lx \n", dbi->rx_lc_errors);
printk("<DM9601> runt frame errors: %lx \n", dbi->rx_runtf_errors);
printk("<DM9601> long frame errors: %lx \n", dbi->rx_longf_errors);
#endif
return 0;
}
static int dm9601_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
{
__u16 *data = (__u16 *)&rq->ifr_data;
dm9601_board_info_t *dbi = net->priv;
switch(cmd) {
case SIOCDEVPRIVATE:
data[0] = dbi->phy;
case SIOCDEVPRIVATE+1:
read_mii_word(dbi, data[0], data[1]&0x1f, &data[3]);
return 0;
case SIOCDEVPRIVATE+2:
if ( !capable(CAP_NET_ADMIN) )
return -EPERM;
write_mii_word(dbi, dbi->phy, data[1] & 0x1f, data[2]);
return 0;
default:
return -EOPNOTSUPP;
}
}
/*
Calculate the CRC valude of the Rx packet
flag = 1 : return the reverse CRC (for the received packet CRC)
0 : return the normal CRC (for Hash Table index)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{
u32 crc = ether_crc_le(Len, Data);
if (flag)
return ~crc;
return crc;
}
static void dm9601_set_multicast( struct net_device *net )
{
dm9601_board_info_t *dbi = net->priv;
struct dev_mc_list *mcptr = net->mc_list;
int count = net->mc_count, i, hash_val;
netif_stop_queue(net);
if (net->flags & IFF_PROMISC) {
dbi->rx_ctrl_reg |= RX_PROMISCUOUS;
info("%s: Promiscuous mode enabled", net->name);
} else if (net->flags & IFF_ALLMULTI) {
dbi->rx_ctrl_reg |= RX_PASS_MULTICAST;
dbi->rx_ctrl_reg &= ~RX_PROMISCUOUS;
info("%s set allmulti", net->name);
} else {
dbi->rx_ctrl_reg &= ~RX_PASS_MULTICAST;
dbi->rx_ctrl_reg &= ~RX_PROMISCUOUS;
/* Clear Hash Table */
for (i = 0; i < 4; i++) dbi->hash_table[i] = 0;
/* Set Broadcast Address */
dbi->hash_table[3] = 0x8000;
/* the multicast address in Hash Table : 64 bits */
for (i = 0; i < count; i++, mcptr = mcptr->next) {
hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f;
dbi->hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
}
info("%s: set Rx mode", net->name);
}
dbi->flags |= HASH_REGS_CHANGE | RX_CTRL_CHANGE;
ctrl_callback(&dbi->ctrl_urb, NULL);
netif_wake_queue(net);
}
static int dm9601_probe( struct usb_interface *udev, const struct usb_device_id *id)
{
struct net_device *net;
dm9601_board_info_t *dbi;
int dev_index = id - dm9601_ids;
struct usb_device *dev = interface_to_usbdev (udev);
int status;
#if 0
if (usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue)) {
err("usb_set_configuration() failed");
return -ENODEV;
}
#endif
if(!(dbi = kmalloc(sizeof(dm9601_board_info_t), GFP_KERNEL))) {
err("out of memory allocating device structure");
return -ENOMEM;
}
// usb_inc_dev_use( dev );
// printk("dev_index %d dbi %x\n",dev_index,dbi);
usb_get_dev(dev);
memset(dbi, 0, sizeof(dm9601_board_info_t));
// initialize dbi struct
{
usb_init_urb(&dbi->ctrl_urb);
usb_init_urb(&dbi->rx_urb);
usb_init_urb(&dbi->tx_urb);
usb_init_urb(&dbi->intr_urb);
usb_init_urb(&dbi->dump_urb);
}
dbi->dev_index = dev_index;
init_waitqueue_head( &dbi->ctrl_wait );
// net = init_etherdev( NULL, 0 );
net = alloc_etherdev(0);
if ( !net ) {
kfree( dbi );
return -ENOMEM;
}
init_MUTEX(&dbi->ctrl_sem);
down(&dbi->ctrl_sem);
dbi->usb = dev;
dbi->net = net;
net->priv = dbi;
net->open = dm9601_open;
net->stop = dm9601_close;
net->watchdog_timeo = DM9601_TX_TIMEOUT;
net->tx_timeout = dm9601_tx_timeout;
net->do_ioctl = dm9601_ioctl;
net->hard_start_xmit = dm9601_start_xmit;
net->set_multicast_list = dm9601_set_multicast;
net->get_stats = dm9601_netdev_stats;
net->mtu = DM9601_MTU;
dbi->intr_interval = 0xff; /* Default is 0x80 */
/* Get Node Address */
read_eprom_word(dbi, 0, (__u16 *)net->dev_addr);
read_eprom_word(dbi, 1, (__u16 *)(net->dev_addr + 2));
read_eprom_word(dbi, 2, (__u16 *)(net->dev_addr + 4));
dbi->features = usb_dev_id[dev_index].private;
info( "%s: %s", net->name, usb_dev_id[dev_index].name );
usb_set_intfdata (udev, dbi);
SET_NETDEV_DEV(net, &udev->dev);
status = register_netdev (net);
up(&dbi->ctrl_sem);
if (status)
return status;
// start as if the link is up
netif_device_attach (net);
return 0;
}
static void dm9601_disconnect( struct usb_interface *intf/*struct usb_device *dev, void *ptr*/ )
{
struct usb_device *dev = interface_to_usbdev (intf);;
dm9601_board_info_t *dbi = usb_get_intfdata(intf);
if ( !dbi ) {
warn("unregistering non-existant device");
return;
}
dbi->flags |= DM9601_UNPLUG;
unregister_netdev( dbi->net );
// usb_dec_dev_use( dev );
usb_put_dev(dev);
kfree( dbi );
dbi = NULL;
}
static struct usb_driver dm9601_driver = {
name: "dm9601",
probe: dm9601_probe,
disconnect: dm9601_disconnect,
id_table: dm9601_ids,
};
int __init dm9601_init(void)
{
info( "%s", version );
switch(mode) {
case DM9601_10MHF:
case DM9601_100MHF:
case DM9601_10MFD:
case DM9601_100MFD:
case DM9601_1M_HPNA:
dm9601_mode = mode;
break;
default:
dm9601_mode = DM9601_AUTO;
}
nfloor = (nfloor > 15) ? 0:nfloor;
return usb_register( &dm9601_driver );
}
void __exit dm9601_exit(void)
{
usb_deregister( &dm9601_driver );
}
module_init( dm9601_init );
module_exit( dm9601_exit );
contents of the file named "dm9601.h"
Code:
/*
* Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
*
* 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 DM9601_DEV
#define HAS_HOME_PNA 0x40000000
#define DM9601_MTU 1500
#define DM9601_MAX_MTU 1536
#define EPROM_WRITE 0x01
#define EPROM_READ 0x02
#define EPROM_LOAD 0x20
#define MII_BMCR 0x00
#define MII_BMSR 0x01
#define PHY_READ 0x40
#define PHY_WRITE 0x20
#define DM9601_PRESENT 0x00000001
#define DM9601_RUNNING 0x00000002
#define DM9601_TX_BUSY 0x00000004
#define DM9601_RX_BUSY 0x00000008
#define CTRL_URB_RUNNING 0x00000010
#define CTRL_URB_SLEEP 0x00000020
#define DM9601_UNPLUG 0x00000040
#define DM9601_RESET_WAIT 0x00800000
#define NET_CTRL_CHANGE 0x04000000
#define NET_CTRL_CHANGED 0x08000000
#define RX_CTRL_CHANGE 0x10000000
#define RX_CTRL_CHANGED 0x20000000
#define HASH_REGS_CHANGE 0x40000000
#define HASH_REGS_CHANGED 0x80000000
#define ALL_REGS_CHANGE (NET_CTRL_CHANGE | RX_CTRL_CHANGE | HASH_REGS_CHANGE)
#define ALL_REGS_CHANGED (NET_CTRL_CHANGED | RX_CTRL_CHANGED | HASH_REGS_CHANGED)
#define DEFAULT_GPIO_RESET 0x24
#define LINKSYS_GPIO_RESET 0x24
#define DEFAULT_GPIO_SET 0x26
#define RX_PASS_MULTICAST 8
#define RX_PROMISCUOUS 2
#define REG_TIMEOUT (HZ)
#define DM9601_TX_TIMEOUT (HZ*10)
#define TX_UNDERRUN 0x80
#define EXCESSIVE_COL 0x40
#define LATE_COL 0x20
#define NO_CARRIER 0x10
#define LOSS_CARRIER 0x08
#define JABBER_TIMEOUT 0x04
#define DM9601_REQT_READ 0xc0
#define DM9601_REQ_GET_REGS 0x00
#define DM9601_REQ_GET_MEMS 0x02
#define DM9601_REQT_WRITE 0x40
#define DM9601_REQ_SET_REGS 0x01
#define DM9601_REQ_SET_REG 0x03
#define DM9601_REQ_SET_MEMS 0x05
#define DM9601_REQ_SET_MEM 0x07
#define DM9601_10MHF 0
#define DM9601_100MHF 1
#define DM9601_10MFD 4
#define DM9601_100MFD 5
#define DM9601_AUTO 8
#define DM9601_1M_HPNA 0x10
#define DM9601_REG5 0x30
#define DM9601_REG8 0x27
#define DM9601_REG9 0x38
#define DM9601_REGA 0xff
#define DM9801_NOISE_FLOOR 0x08
#define DM9802_NOISE_FLOOR 0x05
enum DM9601_NIC_TYPE {
FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2 };
enum DM9601_MII_TYPE {
MII_TYPE_INT = 0, MII_TYPE_EXT = 1 };
#define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
typedef struct dm9601_board_info {
struct usb_device *usb;
struct net_device *net;
struct net_device_stats stats;
unsigned long rx_longf_errors, rx_runtf_errors, rx_lc_errors,
rx_wdt_errors, rx_ple_errors;
unsigned flags;
unsigned features;
int dev_index;
int intr_interval;
struct urb ctrl_urb, rx_urb, tx_urb, intr_urb, dump_urb;
struct usb_ctrlrequest dr;
wait_queue_head_t ctrl_wait;
struct semaphore ctrl_sem;
unsigned char ALIGN(rx_buff[DM9601_MAX_MTU]);
unsigned char ALIGN(rx_buff2[DM9601_MAX_MTU]);
unsigned char ALIGN(tx_buff[DM9601_MAX_MTU]);
unsigned char ALIGN(intr_buff[8]);
unsigned char ALIGN(dump_buff[8]);
__u16 hash_table[4];
__u8 rx_ctrl_reg, net_ctrl_reg, reg08, reg09, reg0a;
__u8 phy;
__u8 gpio_res;
__u8 rx_buf_flag;
__u8 nic_type;
__u8 op_mode;
} dm9601_board_info_t;
struct usb_eth_dev {
char *name;
__u16 vendor;
__u16 device;
__u32 private; /* LSB is gpio reset value */
};
#define VENDOR_ACCTON 0x083a
#define VENDOR_ADMTEK 0x07a6
#define VENDOR_BILLIONTON 0x08dd
#define VENDOR_COREGA 0x07aa
#define VENDOR_DLINK1 0x2001
#define VENDOR_DLINK2 0x07b8
#define VENDOR_IODATA 0x04bb
#define VENDOR_LANEED 0x056e
#define VENDOR_LINKSYS 0x066b
#define VENDOR_MELCO 0x0411
#define VENDOR_SMC 0x0707
#define VENDOR_SOHOWARE 0x15e8
#else /* DM9601_DEV */
DM9601_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
DEFAULT_GPIO_RESET )
DM9601_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)",
VENDOR_ADMTEK, 0x0986,
DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Davicom USB-100", 0x0a46, 0x9601,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Davicom USB-100", 0x3334, 0x1701,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Corega FEter USB-TXC", VENDOR_COREGA, 0x9601,
DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4001,
LINKSYS_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX", VENDOR_DLINK1, 0x4002,
LINKSYS_GPIO_RESET )
DM9601_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK1, 0x4003,
DEFAULT_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "D-Link DSB-650", VENDOR_DLINK1, 0xabc1,
DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DU-E10", VENDOR_DLINK2, 0xabc1,
DEFAULT_GPIO_RESET )
DM9601_DEV( "D-Link DU-E100", VENDOR_DLINK2, 0x4002,
DEFAULT_GPIO_RESET )
DM9601_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET )
DM9601_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
DEFAULT_GPIO_RESET )
DM9601_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
LINKSYS_GPIO_RESET )
DM9601_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
LINKSYS_GPIO_RESET )
DM9601_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
LINKSYS_GPIO_RESET | HAS_HOME_PNA )
DM9601_DEV( "Linksys USB Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
LINKSYS_GPIO_RESET )
DM9601_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
DEFAULT_GPIO_RESET )
DM9601_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
DEFAULT_GPIO_RESET )
DM9601_DEV( "SOHOware NUB100 Ethernet", 0x0a46, 0x9601,
DEFAULT_GPIO_RESET )
#endif /* _DEV */
do the above code make any sense ??
atleast i dont understand the instructions.
1st step RUN make command!! how do i do this???