• DM9000C网卡驱动程序编写与测试


    • 一般网卡驱动程序厂商会给我们提供一份模板驱动,我们的工作就是需要根据自己的需要更改这个模板驱动

    1、DM9000C的硬件连接

    硬件连接图如下所示:它接在S3C2440的BANK4内存控制器上,它只占用8个字节的长度,并且是16bit的位宽。

    下面介绍一下DM9000C的主要引脚的功能:SD0-SD15位16bit的数据引脚接口;IOR为读使能信号,低电平有效;IOW为写使能信号,低电平有效;CS为片选信号,低电平有效;CMD为数据与索引选择信号,高电平表数据,低电平表索引,它连接到S3C2440的LADDR2地址引脚;INT表示中断引脚数据发送成功或接收到数据可以产生中断,高电平有效,所以对于S3C2440来说需要设置上升沿触发来触发中断。

    2、DM9000C的驱动代码编写

    直接贴上修改好的代码:此代码是在厂家提供的驱动源码基础上依照S3C2440的应用修改的。

       1 /*
       2 
       3   dm9ks.c: Version 2.08 2007/02/12 
       4   
       5         A Davicom DM9000/DM9010 ISA NIC fast Ethernet driver for Linux.
       6 
       7     This program is free software; you can redistribute it and/or
       8     modify it under the terms of the GNU General Public License
       9     as published by the Free Software Foundation; either version 2
      10     of the License, or (at your option) any later version.
      11 
      12     This program is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15     GNU General Public License for more details.
      16 
      17 
      18   (C)Copyright 1997-2007 DAVICOM Semiconductor,Inc. All Rights Reserved.
      19 
      20 V2.00 Spenser - 01/10/2005
      21             - Modification for PXA270 MAINSTONE.
      22             - Modified dmfe_tx_done().
      23             - Add dmfe_timeout().
      24 V2.01    10/07/2005    -Modified dmfe_timer()
      25             -Dected network speed 10/100M
      26 V2.02    10/12/2005    -Use link change to chage db->Speed
      27             -dmfe_open() wait for Link OK  
      28 V2.03    11/22/2005    -Power-off and Power-on PHY in dmfe_init_dm9000()
      29             -support IOL
      30 V2.04    12/13/2005    -delay 1.6s between power-on and power-off in 
      31              dmfe_init_dm9000()
      32             -set LED mode 1 in dmfe_init_dm9000()
      33             -add data bus driving capability in dmfe_init_dm9000()
      34              (optional)
      35 10/3/2006    -Add DM8606 read/write function by MDC and MDIO
      36 V2.06    01/03/2007    -CONT_RX_PKT_CNT=0xFFFF
      37             -modify dmfe_tx_done function
      38             -check RX FIFO pointer
      39             -if using physical address, re-define I/O function
      40             -add db->cont_rx_pkt_cnt=0 at the front of dmfe_packet_receive()
      41 V2.08    02/12/2007    -module parameter macro
      42             2.4  MODULE_PARM
      43             2.6  module_param
      44             -remove #include <linux/config>
      45               -fix dmfe_interrupt for kernel 2.6.20                  
      46 V2.09 05/24/2007    -support ethtool and mii-tool
      47 05/30/2007    -fix the driver bug when ifconfig eth0 (-)promisc and (-)allmulti.
      48 06/05/2007    -fix dm9000b issue(ex. 10M TX idle=65mA, 10M harmonic)
      49             -add flow control function (option)
      50 10/01/2007  -Add #include <asm/uaccess.h>
      51             -Modyfy dmfe_do_ioctl for kernel 2.6.7
      52 11/23/2007    -Add TDBUG to check TX FIFO pointer shift
      53             - Remove check_rx_ready() 
      54           - Add #define CHECKSUM to modify CHECKSUM function    
      55 12/20/2007  -Modify TX timeout routine(+)check TCR&0x01 
      56 
      57 */
      58 
      59 //#define CHECKSUM
      60 //#define TDBUG        /* check TX FIFO pointer */
      61 //#define RDBUG   /* check RX FIFO pointer */
      62 //#define DM8606
      63 
      64 #define DRV_NAME    "dm9KS"
      65 #define DRV_VERSION    "2.09"
      66 #define DRV_RELDATE    "2007-11-22"
      67 
      68 #ifdef MODVERSIONS
      69 #include <linux/modversions.h>
      70 #endif
      71 
      72 //#include <linux/config.h>
      73 #include <linux/init.h>                
      74 #include <linux/delay.h>
      75 #include <linux/module.h>
      76 #include <linux/ioport.h>
      77 #include <linux/netdevice.h>
      78 #include <linux/etherdevice.h>
      79 #include <linux/skbuff.h>
      80 #include <linux/version.h>
      81 #include <asm/dma.h>
      82 #include <linux/spinlock.h>
      83 #include <linux/crc32.h>
      84 #include <linux/mii.h>
      85 #include <linux/ethtool.h>
      86 #include <asm/uaccess.h>
      87 
      88 #ifdef CONFIG_ARCH_MAINSTONE
      89 #include <asm/io.h>
      90 #include <asm/hardware.h>
      91 #include <asm/irq.h>
      92 #endif
      93 
      94 #include <asm/delay.h>
      95 #include <asm/irq.h>
      96 #include <asm/io.h>
      97 #include <asm/arch-s3c2410/regs-mem.h>
      98 
      99 
     100 /* Board/System/Debug information/definition ---------------- */
     101 
     102 #define DM9KS_ID        0x90000A46
     103 #define DM9010_ID        0x90100A46
     104 /*-------register name-----------------------*/
     105 #define DM9KS_NCR        0x00    /* Network control Reg.*/
     106 #define DM9KS_NSR        0x01    /* Network Status Reg.*/
     107 #define DM9KS_TCR        0x02    /* TX control Reg.*/
     108 #define DM9KS_RXCR        0x05    /* RX control Reg.*/
     109 #define DM9KS_BPTR        0x08
     110 #define DM9KS_FCTR        0x09
     111 #define DM9KS_FCR            0x0a
     112 #define DM9KS_EPCR        0x0b
     113 #define DM9KS_EPAR        0x0c
     114 #define DM9KS_EPDRL        0x0d
     115 #define DM9KS_EPDRH        0x0e
     116 #define DM9KS_GPR            0x1f    /* General purpose register */
     117 #define DM9KS_CHIPR        0x2c
     118 #define DM9KS_TCR2        0x2d
     119 #define DM9KS_SMCR        0x2f     /* Special Mode Control Reg.*/
     120 #define DM9KS_ETXCSR    0x30    /* Early Transmit control/status Reg.*/
     121 #define    DM9KS_TCCR        0x31    /* Checksum cntrol Reg. */
     122 #define DM9KS_RCSR        0x32    /* Receive Checksum status Reg.*/
     123 #define DM9KS_BUSCR        0x38
     124 #define DM9KS_MRCMDX    0xf0
     125 #define DM9KS_MRCMD        0xf2
     126 #define DM9KS_MDRAL        0xf4
     127 #define DM9KS_MDRAH        0xf5
     128 #define DM9KS_MWCMD        0xf8
     129 #define DM9KS_MDWAL        0xfa
     130 #define DM9KS_MDWAH        0xfb
     131 #define DM9KS_TXPLL        0xfc
     132 #define DM9KS_TXPLH        0xfd
     133 #define DM9KS_ISR            0xfe
     134 #define DM9KS_IMR            0xff
     135 /*---------------------------------------------*/
     136 #define DM9KS_REG05        0x30    /* SKIP_CRC/SKIP_LONG */ 
     137 #define DM9KS_REGFF        0xA3    /* IMR */
     138 #define DM9KS_DISINTR    0x80
     139 
     140 #define DM9KS_PHY            0x40    /* PHY address 0x01 */
     141 #define DM9KS_PKT_RDY        0x01    /* Packet ready to receive */
     142 
     143 /* Added for PXA of MAINSTONE */
     144 #ifdef CONFIG_ARCH_MAINSTONE
     145 #include <asm/arch/mainstone.h>
     146 #define DM9KS_MIN_IO        (MST_ETH_PHYS + 0x300)
     147 #define DM9KS_MAX_IO            (MST_ETH_PHYS + 0x370)
     148 #define DM9K_IRQ        MAINSTONE_IRQ(3)
     149 #else
     150 #define DM9KS_MIN_IO        0x300
     151 #define DM9KS_MAX_IO        0x370
     152 #define DM9KS_IRQ        3
     153 #endif
     154 
     155 #define DM9KS_VID_L        0x28
     156 #define DM9KS_VID_H        0x29
     157 #define DM9KS_PID_L        0x2A
     158 #define DM9KS_PID_H        0x2B
     159 
     160 #define DM9KS_RX_INTR        0x01
     161 #define DM9KS_TX_INTR        0x02
     162 #define DM9KS_LINK_INTR        0x20
     163 
     164 #define DM9KS_DWORD_MODE    1
     165 #define DM9KS_BYTE_MODE        2
     166 #define DM9KS_WORD_MODE        0
     167 
     168 #define TRUE            1
     169 #define FALSE            0
     170 /* Number of continuous Rx packets */
     171 #define CONT_RX_PKT_CNT        0xFFFF
     172 
     173 #define DMFE_TIMER_WUT  jiffies+(HZ*5)    /* timer wakeup time : 5 second */
     174 
     175 #ifdef DM9KS_DEBUG
     176 #define DMFE_DBUG(dbug_now, msg, vaule)
     177 if (dmfe_debug||dbug_now) printk(KERN_ERR "dmfe: %s %x
    ", msg, vaule)
     178 #else
     179 #define DMFE_DBUG(dbug_now, msg, vaule)
     180 if (dbug_now) printk(KERN_ERR "dmfe: %s %x
    ", msg, vaule)
     181 #endif
     182 
     183 #ifndef CONFIG_ARCH_MAINSTONE
     184 #pragma pack(push, 1)
     185 #endif
     186 
     187 typedef struct _RX_DESC
     188 {
     189     u8 rxbyte;
     190     u8 status;
     191     u16 length;
     192 }RX_DESC;
     193 
     194 typedef union{
     195     u8 buf[4];
     196     RX_DESC desc;
     197 } rx_t;
     198 #ifndef CONFIG_ARCH_MAINSTONE
     199 #pragma pack(pop)
     200 #endif
     201 
     202 enum DM9KS_PHY_mode {
     203     DM9KS_10MHD   = 0, 
     204     DM9KS_100MHD  = 1, 
     205     DM9KS_10MFD   = 4,
     206     DM9KS_100MFD  = 5, 
     207     DM9KS_AUTO    = 8, 
     208 };
     209 
     210 /* Structure/enum declaration ------------------------------- */
     211 typedef struct board_info { 
     212     u32 io_addr;/* Register I/O base address */
     213     u32 io_data;/* Data I/O address */
     214     u8 op_mode;/* PHY operation mode */
     215     u8 io_mode;/* 0:word, 2:byte */
     216     u8 Speed;    /* current speed */
     217     u8 chip_revision;
     218     int rx_csum;/* 0:disable, 1:enable */
     219     
     220     u32 reset_counter;/* counter: RESET */ 
     221     u32 reset_tx_timeout;/* RESET caused by TX Timeout */
     222     int tx_pkt_cnt;
     223     int cont_rx_pkt_cnt;/* current number of continuos rx packets  */
     224     struct net_device_stats stats;
     225     
     226     struct timer_list timer;
     227     unsigned char srom[128];
     228     spinlock_t lock;
     229     struct mii_if_info mii;
     230 } board_info_t;
     231 /* Global variable declaration ----------------------------- */
     232 /*static int dmfe_debug = 0;*/
     233 static struct net_device * dmfe_dev = NULL;
     234 static struct ethtool_ops dmfe_ethtool_ops;
     235 /* For module input parameter */
     236 static int mode       = DM9KS_AUTO;  
     237 static int media_mode = DM9KS_AUTO;
     238 static int  irq        = DM9KS_IRQ;
     239 static int iobase     = DM9KS_MIN_IO;
     240 
     241 #if 0  // use physical address; Not virtual address
     242 #ifdef outb
     243     #undef outb
     244 #endif
     245 #ifdef outw
     246     #undef outw
     247 #endif
     248 #ifdef outl
     249     #undef outl
     250 #endif
     251 #ifdef inb
     252     #undef inb
     253 #endif
     254 #ifdef inw
     255     #undef inw
     256 #endif
     257 #ifdef inl
     258     #undef inl
     259 #endif
     260 void outb(u8 reg, u32 ioaddr)
     261 {
     262     (*(volatile u8 *)(ioaddr)) = reg;
     263 }
     264 void outw(u16 reg, u32 ioaddr)
     265 {
     266     (*(volatile u16 *)(ioaddr)) = reg;
     267 }
     268 void outl(u32 reg, u32 ioaddr)
     269 {
     270     (*(volatile u32 *)(ioaddr)) = reg;
     271 }
     272 u8 inb(u32 ioaddr)
     273 {
     274     return (*(volatile u8 *)(ioaddr));
     275 }
     276 u16 inw(u32 ioaddr)
     277 {
     278     return (*(volatile u16 *)(ioaddr));
     279 }
     280 u32 inl(u32 ioaddr)
     281 {
     282     return (*(volatile u32 *)(ioaddr));
     283 }
     284 #endif
     285 
     286 /* function declaration ------------------------------------- */
     287 int dmfe_probe1(struct net_device *);
     288 static int dmfe_open(struct net_device *);
     289 static int dmfe_start_xmit(struct sk_buff *, struct net_device *);
     290 static void dmfe_tx_done(unsigned long);
     291 static void dmfe_packet_receive(struct net_device *);
     292 static int dmfe_stop(struct net_device *);
     293 static struct net_device_stats * dmfe_get_stats(struct net_device *); 
     294 static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int);
     295 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
     296 static void dmfe_interrupt(int , void *, struct pt_regs *); 
     297 #else
     298     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
     299     static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *);
     300     #else
     301     static irqreturn_t dmfe_interrupt(int , void *);/* for kernel 2.6.20 */
     302     #endif
     303 #endif
     304 static void dmfe_timer(unsigned long);
     305 static void dmfe_init_dm9000(struct net_device *);
     306 static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
     307 u8 ior(board_info_t *, int);
     308 void iow(board_info_t *, int, u8);
     309 static u16 phy_read(board_info_t *, int);
     310 static void phy_write(board_info_t *, int, u16);
     311 static u16 read_srom_word(board_info_t *, int);
     312 static void dm9000_hash_table(struct net_device *);
     313 static void dmfe_timeout(struct net_device *);
     314 static void dmfe_reset(struct net_device *);
     315 static int mdio_read(struct net_device *, int, int);
     316 static void mdio_write(struct net_device *, int, int, int);
     317 static void dmfe_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
     318 static int dmfe_get_settings(struct net_device *, struct ethtool_cmd *);
     319 static int dmfe_set_settings(struct net_device *, struct ethtool_cmd *);
     320 static u32 dmfe_get_link(struct net_device *);
     321 static int dmfe_nway_reset(struct net_device *);
     322 static uint32_t dmfe_get_rx_csum(struct net_device *);
     323 static uint32_t dmfe_get_tx_csum(struct net_device *);
     324 static int dmfe_set_rx_csum(struct net_device *, uint32_t );
     325 static int dmfe_set_tx_csum(struct net_device *, uint32_t );
     326 
     327 #ifdef DM8606
     328 #include "dm8606.h"
     329 #endif
     330 
     331 //DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);
     332 
     333 /* DM9000 network baord routine ---------------------------- */
     334 
     335 /*
     336   Search DM9000 board, allocate space and register it
     337 */
     338 
     339 struct net_device * __init dmfe_probe(void)
     340 {
     341     struct net_device *dev;
     342     int err;
     343     
     344     DMFE_DBUG(0, "dmfe_probe()",0);
     345 
     346 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
     347     dev = init_etherdev(NULL, sizeof(struct board_info));
     348     //ether_setup(dev);        
     349 #else
     350     dev= alloc_etherdev(sizeof(struct board_info));
     351 #endif
     352 
     353     if(!dev)
     354         return ERR_PTR(-ENOMEM);
     355 
     356          SET_MODULE_OWNER(dev);
     357     err = dmfe_probe1(dev);
     358     if (err)
     359         goto out;
     360 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
     361     err = register_netdev(dev);
     362     if (err)
     363         goto out1;
     364 #endif
     365     return dev;
     366 out1:
     367     release_region(dev->base_addr,2);
     368 out:
     369 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
     370     kfree(dev);
     371 #else
     372     free_netdev(dev);
     373 #endif
     374     return ERR_PTR(err);
     375 }
     376 
     377 int __init dmfe_probe1(struct net_device *dev)
     378 {
     379     struct board_info *db;    /* Point a board information structure */
     380     u32 id_val;
     381     u16 i, dm9000_found = FALSE;
     382     u8 MAC_addr[6]={0x00,0x60,0x6E,0x33,0x44,0x55};
     383     u8 HasEEPROM=0,chip_info;
     384     DMFE_DBUG(0, "dmfe_probe1()",0);
     385 
     386     /* Search All DM9000 serial NIC */
     387     do {
     388         outb(DM9KS_VID_L, iobase); /* DM9000C的索引寄存器(cmd引脚为0)   */
     389         id_val = inb(iobase + 4);  /* 读DM9000C的数据寄存器(cmd引脚为1) */
     390         outb(DM9KS_VID_H, iobase);
     391         id_val |= inb(iobase + 4) << 8;
     392         outb(DM9KS_PID_L, iobase);
     393         id_val |= inb(iobase + 4) << 16;
     394         outb(DM9KS_PID_H, iobase);
     395         id_val |= inb(iobase + 4) << 24;
     396 
     397         if (id_val == DM9KS_ID || id_val == DM9010_ID) {
     398             
     399             /* Request IO from system */
     400             if(!request_region(iobase, 2, dev->name))
     401                 return -ENODEV;
     402 
     403             printk(KERN_ERR"<DM9KS> I/O: %x, VID: %x 
    ",iobase, id_val);
     404             dm9000_found = TRUE;
     405 
     406             /* Allocated board information structure */
     407             memset(dev->priv, 0, sizeof(struct board_info));
     408             db = (board_info_t *)dev->priv;
     409             dmfe_dev    = dev;
     410             db->io_addr  = iobase;
     411             db->io_data = iobase + 4;   
     412             db->chip_revision = ior(db, DM9KS_CHIPR);
     413             
     414             chip_info = ior(db,0x43);
     415             
     416             /* andy */
     417             //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) return -ENODEV;
     418                         
     419             /* driver system function */                
     420             dev->base_addr         = iobase;
     421             dev->irq         = irq;
     422             dev->open         = &dmfe_open;
     423             dev->hard_start_xmit     = &dmfe_start_xmit;
     424             dev->watchdog_timeo    = 5*HZ;    
     425             dev->tx_timeout        = dmfe_timeout;
     426             dev->stop         = &dmfe_stop;
     427             dev->get_stats         = &dmfe_get_stats;
     428             dev->set_multicast_list = &dm9000_hash_table;
     429             dev->do_ioctl         = &dmfe_do_ioctl;
     430 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28)
     431             dev->ethtool_ops = &dmfe_ethtool_ops;
     432 #endif
     433 #ifdef CHECKSUM
     434             //dev->features |=  NETIF_F_IP_CSUM;
     435             dev->features |=  NETIF_F_IP_CSUM|NETIF_F_SG;
     436 #endif
     437             db->mii.dev = dev;
     438             db->mii.mdio_read = mdio_read;
     439             db->mii.mdio_write = mdio_write;
     440             db->mii.phy_id = 1;
     441 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
     442             db->mii.phy_id_mask = 0x1F; 
     443             db->mii.reg_num_mask = 0x1F; 
     444 #endif
     445             //db->msg_enable =(debug == 0 ? DMFE_DEF_MSG_ENABLE : ((1 << debug) - 1));
     446             
     447             /* Read SROM content */
     448             for (i=0; i<64; i++)
     449                 ((u16 *)db->srom)[i] = read_srom_word(db, i);
     450 
     451             /* Get the PID and VID from EEPROM to check */
     452             id_val = (((u16 *)db->srom)[4])|(((u16 *)db->srom)[5]<<16); 
     453             printk("id_val=%x
    ", id_val);
     454             if (id_val == DM9KS_ID || id_val == DM9010_ID) 
     455                 HasEEPROM =1;
     456             
     457             /* Set Node Address */
     458             for (i=0; i<6; i++)
     459             {
     460                 if (HasEEPROM) /* use EEPROM */
     461                     dev->dev_addr[i] = db->srom[i];
     462                 else    /* No EEPROM */
     463                     dev->dev_addr[i] = MAC_addr[i];
     464             }
     465         }//end of if()
     466         iobase += 0x10;
     467     }while(!dm9000_found && iobase <= DM9KS_MAX_IO);
     468 
     469     return dm9000_found ? 0:-ENODEV;
     470 }
     471 
     472 
     473 /*
     474   Open the interface.
     475   The interface is opened whenever "ifconfig" actives it.
     476 */
     477 static int dmfe_open(struct net_device *dev)
     478 {
     479     board_info_t *db = (board_info_t *)dev->priv;
     480     u8 reg_nsr;
     481     int i;
     482     DMFE_DBUG(0, "dmfe_open", 0);
     483     
     484     /* andy */
     485     if (request_irq(dev->irq,&dmfe_interrupt,IRQF_TRIGGER_RISING,dev->name,dev)) 
     486         return -EAGAIN;
     487 
     488     /* Initilize DM910X board */
     489     dmfe_init_dm9000(dev);
     490 #ifdef DM8606
     491     // control DM8606
     492     printk("[8606]reg0=0x%04x
    ",dm8606_read(db,0));
     493     printk("[8606]reg1=0x%04x
    ",dm8606_read(db,0x1));
     494 #endif 
     495     /* Init driver variable */
     496     db->reset_counter     = 0;
     497     db->reset_tx_timeout     = 0;
     498     db->cont_rx_pkt_cnt    = 0;
     499     
     500     /* check link state and media speed */
     501     db->Speed =10;
     502     i=0;
     503     do {
     504         reg_nsr = ior(db,DM9KS_NSR);
     505         if(reg_nsr & 0x40) /* link OK!! */
     506         {
     507             /* wait for detected Speed */
     508             mdelay(200);
     509             reg_nsr = ior(db,DM9KS_NSR);
     510             if(reg_nsr & 0x80)
     511                 db->Speed =10;
     512             else
     513                 db->Speed =100;
     514             break;
     515         }
     516         i++;
     517         mdelay(1);
     518     }while(i<3000);    /* wait 3 second  */
     519     //printk("i=%d  Speed=%d
    ",i,db->Speed);    
     520     /* set and active a timer process */
     521     init_timer(&db->timer);
     522     db->timer.expires     = DMFE_TIMER_WUT;
     523     db->timer.data         = (unsigned long)dev;
     524     db->timer.function     = &dmfe_timer;
     525     add_timer(&db->timer);    //Move to DM9000 initiallization was finished.
     526      
     527     netif_start_queue(dev);
     528 
     529     return 0;
     530 }
     531 
     532 /* Set PHY operationg mode
     533 */
     534 static void set_PHY_mode(board_info_t *db)
     535 {
     536 #ifndef DM8606
     537     u16 phy_reg0 = 0x1000;/* Auto-negotiation*/
     538     u16 phy_reg4 = 0x01e1;
     539 
     540     if ( !(db->op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */
     541     { 
     542         switch(db->op_mode) {
     543             case DM9KS_10MHD:  phy_reg4 = 0x21; 
     544                                        phy_reg0 = 0x1000;
     545                        break;
     546             case DM9KS_10MFD:  phy_reg4 = 0x41; 
     547                        phy_reg0 = 0x1100;
     548                                        break;
     549             case DM9KS_100MHD: phy_reg4 = 0x81; 
     550                        phy_reg0 = 0x3000;
     551                            break;
     552             case DM9KS_100MFD: phy_reg4 = 0x101; 
     553                        phy_reg0 = 0x3100;
     554                           break;
     555             default: 
     556                        break;
     557         } // end of switch
     558     } // end of if
     559 #ifdef FLOW_CONTROL
     560     phy_write(db, 4, phy_reg4|(1<<10));
     561 #else
     562     phy_write(db, 4, phy_reg4);
     563 #endif //end of FLOW_CONTROL
     564     phy_write(db, 0, phy_reg0|0x200);
     565 #else
     566     /* Fiber mode */
     567     phy_write(db, 16, 0x4014);
     568     phy_write(db, 0, 0x2100);
     569 #endif //end of DM8606
     570 
     571     if (db->chip_revision == 0x1A)
     572     {
     573         //set 10M TX idle =65mA (TX 100% utility is 160mA)
     574         phy_write(db,20, phy_read(db,20)|(1<<11)|(1<<10));
     575         
     576         //:fix harmonic
     577         //For short code:
     578         //PHY_REG 27 (1Bh) <- 0000h
     579         phy_write(db, 27, 0x0000);
     580         //PHY_REG 27 (1Bh) <- AA00h
     581         phy_write(db, 27, 0xaa00);
     582 
     583         //PHY_REG 27 (1Bh) <- 0017h
     584         phy_write(db, 27, 0x0017);
     585         //PHY_REG 27 (1Bh) <- AA17h
     586         phy_write(db, 27, 0xaa17);
     587 
     588         //PHY_REG 27 (1Bh) <- 002Fh
     589         phy_write(db, 27, 0x002f);
     590         //PHY_REG 27 (1Bh) <- AA2Fh
     591         phy_write(db, 27, 0xaa2f);
     592         
     593         //PHY_REG 27 (1Bh) <- 0037h
     594         phy_write(db, 27, 0x0037);
     595         //PHY_REG 27 (1Bh) <- AA37h
     596         phy_write(db, 27, 0xaa37);
     597         
     598         //PHY_REG 27 (1Bh) <- 0040h
     599         phy_write(db, 27, 0x0040);
     600         //PHY_REG 27 (1Bh) <- AA40h
     601         phy_write(db, 27, 0xaa40);
     602         
     603         //For long code:
     604         //PHY_REG 27 (1Bh) <- 0050h
     605         phy_write(db, 27, 0x0050);
     606         //PHY_REG 27 (1Bh) <- AA50h
     607         phy_write(db, 27, 0xaa50);
     608         
     609         //PHY_REG 27 (1Bh) <- 006Bh
     610         phy_write(db, 27, 0x006b);
     611         //PHY_REG 27 (1Bh) <- AA6Bh
     612         phy_write(db, 27, 0xaa6b);
     613         
     614         //PHY_REG 27 (1Bh) <- 007Dh
     615         phy_write(db, 27, 0x007d);
     616         //PHY_REG 27 (1Bh) <- AA7Dh
     617         phy_write(db, 27, 0xaa7d);
     618         
     619         //PHY_REG 27 (1Bh) <- 008Dh
     620         phy_write(db, 27, 0x008d);
     621         //PHY_REG 27 (1Bh) <- AA8Dh
     622         phy_write(db, 27, 0xaa8d);
     623         
     624         //PHY_REG 27 (1Bh) <- 009Ch
     625         phy_write(db, 27, 0x009c);
     626         //PHY_REG 27 (1Bh) <- AA9Ch
     627         phy_write(db, 27, 0xaa9c);
     628         
     629         //PHY_REG 27 (1Bh) <- 00A3h
     630         phy_write(db, 27, 0x00a3);
     631         //PHY_REG 27 (1Bh) <- AAA3h
     632         phy_write(db, 27, 0xaaa3);
     633         
     634         //PHY_REG 27 (1Bh) <- 00B1h
     635         phy_write(db, 27, 0x00b1);
     636         //PHY_REG 27 (1Bh) <- AAB1h
     637         phy_write(db, 27, 0xaab1);
     638         
     639         //PHY_REG 27 (1Bh) <- 00C0h
     640         phy_write(db, 27, 0x00c0);
     641         //PHY_REG 27 (1Bh) <- AAC0h
     642         phy_write(db, 27, 0xaac0);
     643         
     644         //PHY_REG 27 (1Bh) <- 00D2h
     645         phy_write(db, 27, 0x00d2);
     646         //PHY_REG 27 (1Bh) <- AAD2h
     647         phy_write(db, 27, 0xaad2);
     648         
     649         //PHY_REG 27 (1Bh) <- 00E0h
     650         phy_write(db, 27, 0x00e0);
     651         //PHY_REG 27 (1Bh) <- AAE0h
     652         phy_write(db, 27, 0xaae0);
     653         //PHY_REG 27 (1Bh) <- 0000h
     654         phy_write(db, 27, 0x0000);
     655     }
     656 }
     657 
     658 /* 
     659     Initilize dm9000 board
     660 */
     661 static void dmfe_init_dm9000(struct net_device *dev)
     662 {
     663     board_info_t *db = (board_info_t *)dev->priv;
     664     DMFE_DBUG(0, "dmfe_init_dm9000()", 0);
     665 
     666     spin_lock_init(&db->lock);
     667     
     668     iow(db, DM9KS_GPR, 0);    /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
     669     mdelay(20);        /* wait for PHY power-on ready */
     670 
     671     /* do a software reset and wait 20us */
     672     iow(db, DM9KS_NCR, 3);
     673     udelay(20);        /* wait 20us at least for software reset ok */
     674     iow(db, DM9KS_NCR, 3);    /* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on */
     675     udelay(20);        /* wait 20us at least for software reset ok */
     676 
     677     /* I/O mode */
     678     db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
     679 
     680     /* Set PHY */
     681     db->op_mode = media_mode;
     682     set_PHY_mode(db);
     683 
     684     /* Program operating register */
     685     iow(db, DM9KS_NCR, 0);
     686     iow(db, DM9KS_TCR, 0);        /* TX Polling clear */
     687     iow(db, DM9KS_BPTR, 0x3f);    /* Less 3kb, 600us */
     688     iow(db, DM9KS_SMCR, 0);        /* Special Mode */
     689     iow(db, DM9KS_NSR, 0x2c);    /* clear TX status */
     690     iow(db, DM9KS_ISR, 0x0f);     /* Clear interrupt status */
     691     iow(db, DM9KS_TCR2, 0x80);    /* Set LED mode 1 */
     692     if (db->chip_revision == 0x1A){ 
     693         /* Data bus current driving/sinking capability  */
     694         iow(db, DM9KS_BUSCR, 0x01);    /* default: 2mA */
     695     }
     696 #ifdef FLOW_CONTROL
     697     iow(db, DM9KS_BPTR, 0x37);
     698     iow(db, DM9KS_FCTR, 0x38);
     699     iow(db, DM9KS_FCR, 0x29);
     700 #endif
     701 
     702 #ifdef DM8606
     703     iow(db,0x34,1);
     704 #endif
     705 
     706     if (dev->features & NETIF_F_HW_CSUM){
     707         printk(KERN_INFO "DM9KS:enable TX checksum
    ");
     708         iow(db, DM9KS_TCCR, 0x07);    /* TX UDP/TCP/IP checksum enable */
     709     }
     710     if (db->rx_csum){
     711         printk(KERN_INFO "DM9KS:enable RX checksum
    ");
     712         iow(db, DM9KS_RCSR, 0x02);    /* RX checksum enable */
     713     }
     714 
     715 #ifdef ETRANS
     716     /*If TX loading is heavy, the driver can try to anbel "early transmit".
     717     The programmer can tune the "Early Transmit Threshold" to get 
     718     the optimization. (DM9KS_ETXCSR.[1-0])
     719     
     720     Side Effect: It will happen "Transmit under-run". When TX under-run
     721     always happens, the programmer can increase the value of "Early 
     722     Transmit Threshold". */
     723     iow(db, DM9KS_ETXCSR, 0x83);
     724 #endif
     725  
     726     /* Set address filter table */
     727     dm9000_hash_table(dev);
     728 
     729     /* Activate DM9000/DM9010 */
     730     iow(db, DM9KS_IMR, DM9KS_REGFF); /* Enable TX/RX interrupt mask */
     731     iow(db, DM9KS_RXCR, DM9KS_REG05 | 1);    /* RX enable */
     732     
     733     /* Init Driver variable */
     734     db->tx_pkt_cnt         = 0;
     735         
     736     netif_carrier_on(dev);
     737 
     738 }
     739 
     740 /*
     741   Hardware start transmission.
     742   Send a packet to media from the upper layer.
     743 */
     744 static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
     745 {
     746     board_info_t *db = (board_info_t *)dev->priv;
     747     char * data_ptr;
     748     int i, tmplen;
     749     u16 MDWAH, MDWAL;
     750     
     751     #ifdef TDBUG /* check TX FIFO pointer */
     752             u16 MDWAH1, MDWAL1;
     753             u16 tx_ptr;
     754     #endif
     755     
     756     DMFE_DBUG(0, "dmfe_start_xmit", 0);
     757     if (db->chip_revision != 0x1A)
     758     {    
     759         if(db->Speed == 10)
     760             {if (db->tx_pkt_cnt >= 1) return 1;}
     761         else
     762             {if (db->tx_pkt_cnt >= 2) return 1;}
     763     }else
     764         if (db->tx_pkt_cnt >= 2) return 1;
     765     
     766     /* packet counting */
     767     db->tx_pkt_cnt++;
     768 
     769     db->stats.tx_packets++;
     770     db->stats.tx_bytes+=skb->len;
     771     if (db->chip_revision != 0x1A)
     772     {
     773         if (db->Speed == 10)
     774             {if (db->tx_pkt_cnt >= 1) netif_stop_queue(dev);}
     775         else
     776             {if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);}
     777     }else
     778         if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);        
     779 
     780     /* Disable all interrupt */
     781     iow(db, DM9KS_IMR, DM9KS_DISINTR);
     782 
     783     MDWAH = ior(db,DM9KS_MDWAH);
     784     MDWAL = ior(db,DM9KS_MDWAL);
     785 
     786     /* Set TX length to reg. 0xfc & 0xfd */
     787     iow(db, DM9KS_TXPLL, (skb->len & 0xff));
     788     iow(db, DM9KS_TXPLH, (skb->len >> 8) & 0xff);
     789 
     790     /* Move data to TX SRAM */
     791     data_ptr = (char *)skb->data;
     792     
     793     outb(DM9KS_MWCMD, db->io_addr); // Write data into SRAM trigger
     794     switch(db->io_mode)
     795     {
     796         case DM9KS_BYTE_MODE:
     797             for (i = 0; i < skb->len; i++)
     798                 outb((data_ptr[i] & 0xff), db->io_data);
     799             break;
     800         case DM9KS_WORD_MODE:
     801             tmplen = (skb->len + 1) / 2;
     802             for (i = 0; i < tmplen; i++)
     803         outw(((u16 *)data_ptr)[i], db->io_data);
     804       break;
     805     case DM9KS_DWORD_MODE:
     806       tmplen = (skb->len + 3) / 4;            
     807             for (i = 0; i< tmplen; i++)
     808                 outl(((u32 *)data_ptr)[i], db->io_data);
     809             break;
     810     }
     811     
     812 #ifndef ETRANS
     813     /* Issue TX polling command */
     814     iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/
     815 #endif
     816 
     817     #ifdef TDBUG /* check TX FIFO pointer */
     818             MDWAH1 = ior(db,DM9KS_MDWAH);
     819             MDWAL1 = ior(db,DM9KS_MDWAL);
     820             tx_ptr = (MDWAH<<8)|MDWAL;
     821             switch (db->io_mode)
     822             {
     823                 case DM9KS_BYTE_MODE:
     824                     tx_ptr += skb->len;
     825                     break;
     826                 case DM9KS_WORD_MODE:
     827                     tx_ptr += ((skb->len + 1) / 2)*2;
     828                     break;
     829                 case DM9KS_DWORD_MODE:
     830                     tx_ptr += ((skb->len+3)/4)*4;
     831                     break;
     832             }
     833             if (tx_ptr > 0x0bff)
     834                     tx_ptr -= 0x0c00;
     835             if (tx_ptr != ((MDWAH1<<8)|MDWAL1))
     836                     printk("[dm9ks:TX FIFO ERROR
    ");
     837     #endif
     838     /* Saved the time stamp */
     839     dev->trans_start = jiffies;
     840     db->cont_rx_pkt_cnt =0;
     841 
     842     /* Free this SKB */
     843     dev_kfree_skb(skb);
     844 
     845     /* Re-enable interrupt */
     846     iow(db, DM9KS_IMR, DM9KS_REGFF);
     847 
     848     return 0;
     849 }
     850 
     851 /*
     852   Stop the interface.
     853   The interface is stopped when it is brought.
     854 */
     855 static int dmfe_stop(struct net_device *dev)
     856 {
     857     board_info_t *db = (board_info_t *)dev->priv;
     858     DMFE_DBUG(0, "dmfe_stop", 0);
     859 
     860     /* deleted timer */
     861     del_timer(&db->timer);
     862 
     863     netif_stop_queue(dev); 
     864 
     865     /* free interrupt */
     866     free_irq(dev->irq, dev);
     867 
     868     /* RESET devie */
     869     phy_write(db, 0x00, 0x8000);    /* PHY RESET */
     870     //iow(db, DM9KS_GPR, 0x01);     /* Power-Down PHY */
     871     iow(db, DM9KS_IMR, DM9KS_DISINTR);    /* Disable all interrupt */
     872     iow(db, DM9KS_RXCR, 0x00);    /* Disable RX */
     873 
     874     /* Dump Statistic counter */
     875 #if FALSE
     876     printk("
    RX FIFO OVERFLOW %lx
    ", db->stats.rx_fifo_errors);
     877     printk("RX CRC %lx
    ", db->stats.rx_crc_errors);
     878     printk("RX LEN Err %lx
    ", db->stats.rx_length_errors);
     879     printk("RESET %x
    ", db->reset_counter);
     880     printk("RESET: TX Timeout %x
    ", db->reset_tx_timeout);
     881     printk("g_TX_nsr %x
    ", g_TX_nsr);
     882 #endif
     883 
     884     return 0;
     885 }
     886 
     887 static void dmfe_tx_done(unsigned long unused)
     888 {
     889     struct net_device *dev = dmfe_dev;
     890     board_info_t *db = (board_info_t *)dev->priv;
     891     int  nsr;
     892 
     893     DMFE_DBUG(0, "dmfe_tx_done()", 0);
     894     
     895     nsr = ior(db, DM9KS_NSR);
     896     if (nsr & 0x0c)
     897     {
     898         if(nsr & 0x04) db->tx_pkt_cnt--;
     899         if(nsr & 0x08) db->tx_pkt_cnt--;
     900         if(db->tx_pkt_cnt < 0)
     901         {
     902             printk(KERN_DEBUG "DM9KS:tx_pkt_cnt ERROR!!
    ");
     903             while(ior(db,DM9KS_TCR) & 0x1){}
     904             db->tx_pkt_cnt = 0;
     905         }
     906             
     907     }else{
     908         while(ior(db,DM9KS_TCR) & 0x1){}
     909         db->tx_pkt_cnt = 0;
     910     }
     911         
     912     netif_wake_queue(dev);
     913     
     914     return;
     915 }
     916 
     917 /*
     918   DM9000 insterrupt handler
     919   receive the packet to upper layer, free the transmitted packet
     920 */
     921 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
     922 static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     923 #else
     924     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
     925     static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     926     #else
     927     static irqreturn_t dmfe_interrupt(int irq, void *dev_id) /* for kernel 2.6.20*/
     928     #endif
     929 #endif
     930 {
     931     struct net_device *dev = dev_id;
     932     board_info_t *db;
     933     int int_status,i;
     934     u8 reg_save;
     935 
     936     DMFE_DBUG(0, "dmfe_interrupt()", 0);
     937 
     938     /* A real interrupt coming */
     939     db = (board_info_t *)dev->priv;
     940     spin_lock(&db->lock);
     941 
     942     /* Save previous register address */
     943     reg_save = inb(db->io_addr);
     944 
     945     /* Disable all interrupt */
     946     iow(db, DM9KS_IMR, DM9KS_DISINTR); 
     947 
     948     /* Got DM9000/DM9010 interrupt status */
     949     int_status = ior(db, DM9KS_ISR);        /* Got ISR */
     950     iow(db, DM9KS_ISR, int_status);        /* Clear ISR status */ 
     951 
     952     /* Link status change */
     953     if (int_status & DM9KS_LINK_INTR) 
     954     {
     955         netif_stop_queue(dev);
     956         for(i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
     957         {
     958             phy_read(db,0x1);
     959             if(phy_read(db,0x1) & 0x4) /*Link OK*/
     960             {
     961                 /* wait for detected Speed */
     962                 for(i=0; i<200;i++)
     963                     udelay(1000);
     964                 /* set media speed */
     965                 if(phy_read(db,0)&0x2000) db->Speed =100;
     966                 else db->Speed =10;
     967                 break;
     968             }
     969             udelay(1000);
     970         }
     971         netif_wake_queue(dev);
     972         //printk("[INTR]i=%d speed=%d
    ",i, (int)(db->Speed));    
     973     }
     974     /* Received the coming packet */
     975     if (int_status & DM9KS_RX_INTR) 
     976         dmfe_packet_receive(dev);
     977 
     978     /* Trnasmit Interrupt check */
     979     if (int_status & DM9KS_TX_INTR)
     980         dmfe_tx_done(0);
     981     
     982     if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
     983     {
     984         iow(db, DM9KS_IMR, 0xa2);
     985     }
     986     else
     987     {
     988         /* Re-enable interrupt mask */ 
     989         iow(db, DM9KS_IMR, DM9KS_REGFF);
     990     }
     991     
     992     /* Restore previous register address */
     993     outb(reg_save, db->io_addr); 
     994 
     995     spin_unlock(&db->lock); 
     996 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
     997     return IRQ_HANDLED;
     998 #endif
     999 }
    1000 
    1001 /*
    1002   Get statistics from driver.
    1003 */
    1004 static struct net_device_stats * dmfe_get_stats(struct net_device *dev)
    1005 {
    1006     board_info_t *db = (board_info_t *)dev->priv;
    1007     DMFE_DBUG(0, "dmfe_get_stats", 0);
    1008     return &db->stats;
    1009 }
    1010 /*
    1011  *    Process the ethtool ioctl command
    1012  */
    1013 static int dmfe_ethtool_ioctl(struct net_device *dev, void *useraddr)
    1014 {
    1015     //struct dmfe_board_info *db = dev->priv;
    1016     struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
    1017     u32 ethcmd;
    1018 
    1019     if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
    1020         return -EFAULT;
    1021 
    1022     switch (ethcmd) 
    1023     {
    1024         case ETHTOOL_GDRVINFO:
    1025             strcpy(info.driver, DRV_NAME);
    1026             strcpy(info.version, DRV_VERSION);
    1027 
    1028             sprintf(info.bus_info, "ISA 0x%lx %d",dev->base_addr, dev->irq);
    1029             if (copy_to_user(useraddr, &info, sizeof(info)))
    1030                 return -EFAULT;
    1031             return 0;
    1032     }
    1033 
    1034     return -EOPNOTSUPP;
    1035 }
    1036 /*
    1037   Process the upper socket ioctl command
    1038 */
    1039 static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
    1040 {
    1041     board_info_t *db = (board_info_t *)dev->priv;
    1042     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
    1043     struct mii_ioctl_data *data=(struct mii_ioctl_data *)&ifr->ifr_data; 
    1044     #endif
    1045   int rc=0;
    1046         
    1047     DMFE_DBUG(0, "dmfe_do_ioctl()", 0);
    1048     
    1049         if (!netif_running(dev))
    1050             return -EINVAL;
    1051 
    1052         if (cmd == SIOCETHTOOL)
    1053         rc = dmfe_ethtool_ioctl(dev, (void *) ifr->ifr_data);
    1054     else {
    1055         spin_lock_irq(&db->lock);
    1056         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
    1057             rc = generic_mii_ioctl(&db->mii, data, cmd, NULL);
    1058         #else
    1059             rc = generic_mii_ioctl(&db->mii, if_mii(ifr), cmd, NULL);
    1060         #endif
    1061         spin_unlock_irq(&db->lock);
    1062     }
    1063 
    1064     return rc;
    1065 }
    1066 
    1067 /* Our watchdog timed out. Called by the networking layer */
    1068 static void dmfe_timeout(struct net_device *dev)
    1069 {
    1070     board_info_t *db = (board_info_t *)dev->priv;
    1071     int i;
    1072     
    1073     DMFE_DBUG(0, "dmfe_TX_timeout()", 0);
    1074     printk("TX time-out -- dmfe_timeout().
    ");
    1075     db->reset_tx_timeout++;
    1076     db->stats.tx_errors++;
    1077     
    1078 #if FALSE
    1079     printk("TX packet count = %d
    ", db->tx_pkt_cnt);    
    1080     printk("TX timeout = %d
    ", db->reset_tx_timeout);    
    1081     printk("22H=0x%02x  23H=0x%02x
    ",ior(db,0x22),ior(db,0x23));
    1082     printk("faH=0x%02x  fbH=0x%02x
    ",ior(db,0xfa),ior(db,0xfb));
    1083 #endif
    1084 
    1085     i=0;
    1086 
    1087     while((i++<100)&&(ior(db,DM9KS_TCR) & 0x01))
    1088     {
    1089         udelay(30);
    1090     }
    1091         
    1092     if(i<100)
    1093     {
    1094             db->tx_pkt_cnt = 0;
    1095             netif_wake_queue(dev);
    1096     }
    1097     else
    1098     {
    1099             dmfe_reset(dev);
    1100     }
    1101 
    1102 }
    1103 
    1104 static void dmfe_reset(struct net_device * dev)
    1105 {
    1106     board_info_t *db = (board_info_t *)dev->priv;
    1107     u8 reg_save;
    1108     int i;
    1109     /* Save previous register address */
    1110     reg_save = inb(db->io_addr);
    1111 
    1112     netif_stop_queue(dev); 
    1113     db->reset_counter++;
    1114     dmfe_init_dm9000(dev);
    1115     
    1116     db->Speed =10;
    1117     for(i=0; i<1000; i++) /*wait link OK, waiting time=1 second */
    1118     {
    1119         if(phy_read(db,0x1) & 0x4) /*Link OK*/
    1120         {
    1121             if(phy_read(db,0)&0x2000) db->Speed =100;
    1122             else db->Speed =10;
    1123             break;
    1124         }
    1125         udelay(1000);
    1126     }
    1127     
    1128     netif_wake_queue(dev);
    1129     
    1130     /* Restore previous register address */
    1131     outb(reg_save, db->io_addr);
    1132 
    1133 }
    1134 /*
    1135   A periodic timer routine
    1136 */
    1137 static void dmfe_timer(unsigned long data)
    1138 {
    1139     struct net_device * dev = (struct net_device *)data;
    1140     board_info_t *db = (board_info_t *)dev->priv;
    1141     DMFE_DBUG(0, "dmfe_timer()", 0);
    1142     
    1143     if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
    1144     {
    1145         db->cont_rx_pkt_cnt=0;
    1146         iow(db, DM9KS_IMR, DM9KS_REGFF);
    1147     }
    1148     /* Set timer again */
    1149     db->timer.expires = DMFE_TIMER_WUT;
    1150     add_timer(&db->timer);
    1151     
    1152     return;
    1153 }
    1154 
    1155 
    1156 /*
    1157   Received a packet and pass to upper layer
    1158 */
    1159 static void dmfe_packet_receive(struct net_device *dev)
    1160 {
    1161     board_info_t *db = (board_info_t *)dev->priv;
    1162     struct sk_buff *skb;
    1163     u8 rxbyte;
    1164     u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;
    1165     u32 tmpdata;
    1166 
    1167     rx_t rx;
    1168 
    1169     u16 * ptr = (u16*)&rx;
    1170     u8* rdptr;
    1171 
    1172     DMFE_DBUG(0, "dmfe_packet_receive()", 0);
    1173 
    1174     db->cont_rx_pkt_cnt=0;
    1175     
    1176     do {
    1177         /*store the value of Memory Data Read address register*/
    1178         MDRAH=ior(db, DM9KS_MDRAH);
    1179         MDRAL=ior(db, DM9KS_MDRAL);
    1180         
    1181         ior(db, DM9KS_MRCMDX);        /* Dummy read */
    1182         rxbyte = inb(db->io_data);    /* Got most updated data */
    1183 
    1184 #ifdef CHECKSUM    
    1185         if (rxbyte&0x2)            /* check RX byte */
    1186         {    
    1187       printk("dm9ks: abnormal!
    ");
    1188             dmfe_reset(dev); 
    1189             break;    
    1190     }else { 
    1191       if (!(rxbyte&0x1))
    1192                 break;    
    1193     }        
    1194 #else
    1195         if (rxbyte==0)
    1196             break;
    1197         
    1198         if (rxbyte>1)
    1199         {    
    1200       printk("dm9ks: Rxbyte error!
    ");
    1201           dmfe_reset(dev);
    1202       break;    
    1203     }
    1204 #endif
    1205 
    1206         /* A packet ready now  & Get status/length */
    1207         GoodPacket = TRUE;
    1208         outb(DM9KS_MRCMD, db->io_addr);
    1209 
    1210         /* Read packet status & length */
    1211         switch (db->io_mode) 
    1212             {
    1213               case DM9KS_BYTE_MODE: 
    1214                      *ptr = inb(db->io_data) + 
    1215                                (inb(db->io_data) << 8);
    1216                     *(ptr+1) = inb(db->io_data) + 
    1217                         (inb(db->io_data) << 8);
    1218                     break;
    1219               case DM9KS_WORD_MODE:
    1220                     *ptr = inw(db->io_data);
    1221                     *(ptr+1)    = inw(db->io_data);
    1222                     break;
    1223               case DM9KS_DWORD_MODE:
    1224                     tmpdata  = inl(db->io_data);
    1225                     *ptr = tmpdata;
    1226                     *(ptr+1)    = tmpdata >> 16;
    1227                     break;
    1228               default:
    1229                     break;
    1230             }
    1231 
    1232         /* Packet status check */
    1233         if (rx.desc.status & 0xbf)
    1234         {
    1235             GoodPacket = FALSE;
    1236             if (rx.desc.status & 0x01) 
    1237             {
    1238                 db->stats.rx_fifo_errors++;
    1239                 printk(KERN_INFO"<RX FIFO error>
    ");
    1240             }
    1241             if (rx.desc.status & 0x02) 
    1242             {
    1243                 db->stats.rx_crc_errors++;
    1244                 printk(KERN_INFO"<RX CRC error>
    ");
    1245             }
    1246             if (rx.desc.status & 0x80) 
    1247             {
    1248                 db->stats.rx_length_errors++;
    1249                 printk(KERN_INFO"<RX Length error>
    ");
    1250             }
    1251             if (rx.desc.status & 0x08)
    1252                 printk(KERN_INFO"<Physical Layer error>
    ");
    1253         }
    1254 
    1255         if (!GoodPacket)
    1256         {
    1257             // drop this packet!!!
    1258             switch (db->io_mode)
    1259             {
    1260                 case DM9KS_BYTE_MODE:
    1261                      for (i=0; i<rx.desc.length; i++)
    1262                         inb(db->io_data);
    1263                     break;
    1264                 case DM9KS_WORD_MODE:
    1265                     tmplen = (rx.desc.length + 1) / 2;
    1266                     for (i = 0; i < tmplen; i++)
    1267                         inw(db->io_data);
    1268                     break;
    1269                 case DM9KS_DWORD_MODE:
    1270                     tmplen = (rx.desc.length + 3) / 4;
    1271                     for (i = 0; i < tmplen; i++)
    1272                         inl(db->io_data);
    1273                     break;
    1274             }
    1275             continue;/*next the packet*/
    1276         }
    1277         
    1278         skb = dev_alloc_skb(rx.desc.length+4);
    1279         if (skb == NULL )
    1280         {    
    1281             printk(KERN_INFO "%s: Memory squeeze.
    ", dev->name);
    1282             /*re-load the value into Memory data read address register*/
    1283             iow(db,DM9KS_MDRAH,MDRAH);
    1284             iow(db,DM9KS_MDRAL,MDRAL);
    1285             return;
    1286         }
    1287         else
    1288         {
    1289             /* Move data from DM9000 */
    1290             skb->dev = dev;
    1291             skb_reserve(skb, 2);
    1292             rdptr = (u8*)skb_put(skb, rx.desc.length - 4);
    1293             
    1294             /* Read received packet from RX SARM */
    1295             switch (db->io_mode)
    1296             {
    1297                 case DM9KS_BYTE_MODE:
    1298                      for (i=0; i<rx.desc.length; i++)
    1299                         rdptr[i]=inb(db->io_data);
    1300                     break;
    1301                 case DM9KS_WORD_MODE:
    1302                     tmplen = (rx.desc.length + 1) / 2;
    1303                     for (i = 0; i < tmplen; i++)
    1304                         ((u16 *)rdptr)[i] = inw(db->io_data);
    1305                     break;
    1306                 case DM9KS_DWORD_MODE:
    1307                     tmplen = (rx.desc.length + 3) / 4;
    1308                     for (i = 0; i < tmplen; i++)
    1309                         ((u32 *)rdptr)[i] = inl(db->io_data);
    1310                     break;
    1311             }
    1312         
    1313             /* Pass to upper layer */
    1314             skb->protocol = eth_type_trans(skb,dev);
    1315 
    1316 #ifdef CHECKSUM
    1317         if((rxbyte&0xe0)==0)    /* receive packet no checksum fail */
    1318                 skb->ip_summed = CHECKSUM_UNNECESSARY;
    1319 #endif
    1320         
    1321             netif_rx(skb);
    1322             dev->last_rx=jiffies;
    1323             db->stats.rx_packets++;
    1324             db->stats.rx_bytes += rx.desc.length;
    1325             db->cont_rx_pkt_cnt++;
    1326 #ifdef RDBG /* check RX FIFO pointer */
    1327             u16 MDRAH1, MDRAL1;
    1328             u16 tmp_ptr;
    1329             MDRAH1 = ior(db,DM9KS_MDRAH);
    1330             MDRAL1 = ior(db,DM9KS_MDRAL);
    1331             tmp_ptr = (MDRAH<<8)|MDRAL;
    1332             switch (db->io_mode)
    1333             {
    1334                 case DM9KS_BYTE_MODE:
    1335                     tmp_ptr += rx.desc.length+4;
    1336                     break;
    1337                 case DM9KS_WORD_MODE:
    1338                     tmp_ptr += ((rx.desc.length+1)/2)*2+4;
    1339                     break;
    1340                 case DM9KS_DWORD_MODE:
    1341                     tmp_ptr += ((rx.desc.length+3)/4)*4+4;
    1342                     break;
    1343             }
    1344             if (tmp_ptr >=0x4000)
    1345                 tmp_ptr = (tmp_ptr - 0x4000) + 0xc00;
    1346             if (tmp_ptr != ((MDRAH1<<8)|MDRAL1))
    1347                 printk("[dm9ks:RX FIFO ERROR
    ");
    1348 #endif
    1349                 
    1350             if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
    1351             {
    1352                 dmfe_tx_done(0);
    1353                 break;
    1354             }
    1355         }
    1356             
    1357     }while((rxbyte & 0x01) == DM9KS_PKT_RDY);
    1358     DMFE_DBUG(0, "[END]dmfe_packet_receive()", 0);
    1359     
    1360 }
    1361 
    1362 /*
    1363   Read a word data from SROM
    1364 */
    1365 static u16 read_srom_word(board_info_t *db, int offset)
    1366 {
    1367     iow(db, DM9KS_EPAR, offset);
    1368     iow(db, DM9KS_EPCR, 0x4);
    1369     while(ior(db, DM9KS_EPCR)&0x1);    /* Wait read complete */
    1370     iow(db, DM9KS_EPCR, 0x0);
    1371     return (ior(db, DM9KS_EPDRL) + (ior(db, DM9KS_EPDRH) << 8) );
    1372 }
    1373 
    1374 /*
    1375   Set DM9000/DM9010 multicast address
    1376 */
    1377 static void dm9000_hash_table(struct net_device *dev)
    1378 {
    1379     board_info_t *db = (board_info_t *)dev->priv;
    1380     struct dev_mc_list *mcptr = dev->mc_list;
    1381     int mc_cnt = dev->mc_count;
    1382     u32 hash_val;
    1383     u16 i, oft, hash_table[4];
    1384 
    1385     DMFE_DBUG(0, "dm9000_hash_table()", 0);
    1386 
    1387     /* enable promiscuous mode */
    1388     if (dev->flags & IFF_PROMISC){
    1389         //printk(KERN_INFO "DM9KS:enable promiscuous mode
    ");
    1390         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<1));
    1391         return;
    1392     }else{
    1393         //printk(KERN_INFO "DM9KS:disable promiscuous mode
    ");
    1394         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<1)));
    1395     }
    1396         
    1397     /* Receive all multicast packets */
    1398     if (dev->flags & IFF_ALLMULTI){
    1399         //printk(KERN_INFO "DM9KS:Pass all multicast
    ");
    1400         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<3));
    1401     }else{
    1402         //printk(KERN_INFO "DM9KS:Disable pass all multicast
    ");
    1403         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<3)));
    1404     }
    1405     
    1406     /* Set Node address */
    1407     for (i = 0, oft = 0x10; i < 6; i++, oft++)
    1408         iow(db, oft, dev->dev_addr[i]);
    1409 
    1410     /* Clear Hash Table */
    1411     for (i = 0; i < 4; i++)
    1412         hash_table[i] = 0x0;
    1413 
    1414     /* broadcast address */
    1415     hash_table[3] = 0x8000;
    1416 
    1417     /* the multicast address in Hash Table : 64 bits */
    1418     for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
    1419         hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f; 
    1420         hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
    1421     }
    1422 
    1423     /* Write the hash table to MAC MD table */
    1424     for (i = 0, oft = 0x16; i < 4; i++) {
    1425         iow(db, oft++, hash_table[i] & 0xff);
    1426         iow(db, oft++, (hash_table[i] >> 8) & 0xff);
    1427     }
    1428 }
    1429 
    1430 /*
    1431   Calculate the CRC valude of the Rx packet
    1432   flag = 1 : return the reverse CRC (for the received packet CRC)
    1433          0 : return the normal CRC (for Hash Table index)
    1434 */
    1435 static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
    1436 {    
    1437     u32 crc = ether_crc_le(Len, Data);
    1438 
    1439     if (flag) 
    1440         return ~crc;
    1441         
    1442     return crc;     
    1443 }
    1444 
    1445 static int mdio_read(struct net_device *dev, int phy_id, int location)
    1446 {
    1447     board_info_t *db = (board_info_t *)dev->priv;
    1448     return phy_read(db, location);
    1449 }
    1450 
    1451 static void mdio_write(struct net_device *dev, int phy_id, int location, int val)
    1452 {
    1453     board_info_t *db = (board_info_t *)dev->priv;
    1454     phy_write(db, location, val);
    1455 }
    1456 
    1457 /*
    1458    Read a byte from I/O port
    1459 */
    1460 u8 ior(board_info_t *db, int reg)
    1461 {
    1462     outb(reg, db->io_addr);
    1463     return inb(db->io_data);
    1464 }
    1465 
    1466 /*
    1467    Write a byte to I/O port
    1468 */
    1469 void iow(board_info_t *db, int reg, u8 value)
    1470 {
    1471     outb(reg, db->io_addr);
    1472     outb(value, db->io_data);
    1473 }
    1474 
    1475 /*
    1476    Read a word from phyxcer
    1477 */
    1478 static u16 phy_read(board_info_t *db, int reg)
    1479 {
    1480     /* Fill the phyxcer register into REG_0C */
    1481     iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
    1482 
    1483     iow(db, DM9KS_EPCR, 0xc);     /* Issue phyxcer read command */
    1484     while(ior(db, DM9KS_EPCR)&0x1);    /* Wait read complete */
    1485     iow(db, DM9KS_EPCR, 0x0);     /* Clear phyxcer read command */
    1486 
    1487     /* The read data keeps on REG_0D & REG_0E */
    1488     return ( ior(db, DM9KS_EPDRH) << 8 ) | ior(db, DM9KS_EPDRL);
    1489     
    1490 }
    1491 
    1492 /*
    1493    Write a word to phyxcer
    1494 */
    1495 static void phy_write(board_info_t *db, int reg, u16 value)
    1496 {
    1497     /* Fill the phyxcer register into REG_0C */
    1498     iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
    1499 
    1500     /* Fill the written data into REG_0D & REG_0E */
    1501     iow(db, DM9KS_EPDRL, (value & 0xff));
    1502     iow(db, DM9KS_EPDRH, ( (value >> 8) & 0xff));
    1503 
    1504     iow(db, DM9KS_EPCR, 0xa);    /* Issue phyxcer write command */
    1505     while(ior(db, DM9KS_EPCR)&0x1);    /* Wait read complete */
    1506     iow(db, DM9KS_EPCR, 0x0);    /* Clear phyxcer write command */
    1507 }
    1508 //====dmfe_ethtool_ops member functions====
    1509 static void dmfe_get_drvinfo(struct net_device *dev,
    1510                    struct ethtool_drvinfo *info)
    1511 {
    1512     //board_info_t *db = (board_info_t *)dev->priv;
    1513     strcpy(info->driver, DRV_NAME);
    1514     strcpy(info->version, DRV_VERSION);
    1515     sprintf(info->bus_info, "ISA 0x%lx irq=%d",dev->base_addr, dev->irq);
    1516 }
    1517 static int dmfe_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
    1518 {
    1519     board_info_t *db = (board_info_t *)dev->priv;
    1520     spin_lock_irq(&db->lock);
    1521     mii_ethtool_gset(&db->mii, cmd);
    1522     spin_unlock_irq(&db->lock);
    1523     return 0;
    1524 }
    1525 static int dmfe_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
    1526 {
    1527     board_info_t *db = (board_info_t *)dev->priv;
    1528     int rc;
    1529 
    1530     spin_lock_irq(&db->lock);
    1531     rc = mii_ethtool_sset(&db->mii, cmd);
    1532     spin_unlock_irq(&db->lock);
    1533     return rc;
    1534 }
    1535 /*
    1536 * Check the link state
    1537 */
    1538 static u32 dmfe_get_link(struct net_device *dev)
    1539 {
    1540     board_info_t *db = (board_info_t *)dev->priv;
    1541     return mii_link_ok(&db->mii);
    1542 }
    1543 
    1544 /*
    1545 * Reset Auto-negitiation
    1546 */
    1547 static int dmfe_nway_reset(struct net_device *dev)
    1548 {
    1549     board_info_t *db = (board_info_t *)dev->priv;
    1550     return mii_nway_restart(&db->mii);
    1551 }
    1552 /*
    1553 * Get RX checksum offload state
    1554 */
    1555 static uint32_t dmfe_get_rx_csum(struct net_device *dev)
    1556 {
    1557     board_info_t *db = (board_info_t *)dev->priv;
    1558     return db->rx_csum;
    1559 }
    1560 /*
    1561 * Get TX checksum offload state
    1562 */
    1563 static uint32_t dmfe_get_tx_csum(struct net_device *dev)
    1564 {
    1565     return (dev->features & NETIF_F_HW_CSUM) != 0;
    1566 }
    1567 /* 
    1568 * Enable/Disable RX checksum offload
    1569 */
    1570 static int dmfe_set_rx_csum(struct net_device *dev, uint32_t data)
    1571 {
    1572 #ifdef CHECKSUM
    1573     board_info_t *db = (board_info_t *)dev->priv;
    1574     db->rx_csum = data;
    1575 
    1576     if(netif_running(dev)) {
    1577         dmfe_stop(dev);
    1578         dmfe_open(dev);
    1579     } else
    1580         dmfe_init_dm9000(dev);
    1581 #else
    1582     printk(KERN_ERR "DM9:Don't support checksum
    ");
    1583 #endif
    1584     return 0;
    1585 }
    1586 /* 
    1587 * Enable/Disable TX checksum offload
    1588 */
    1589 static int dmfe_set_tx_csum(struct net_device *dev, uint32_t data)
    1590 {
    1591 #ifdef CHECKSUM
    1592     if (data)
    1593         dev->features |= NETIF_F_HW_CSUM;
    1594     else
    1595         dev->features &= ~NETIF_F_HW_CSUM;
    1596 #else
    1597     printk(KERN_ERR "DM9:Don't support checksum
    ");
    1598 #endif
    1599 
    1600     return 0;
    1601 }
    1602 //=========================================
    1603 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28)  /* for kernel 2.4.28 */
    1604 static struct ethtool_ops dmfe_ethtool_ops = {
    1605     .get_drvinfo        = dmfe_get_drvinfo,
    1606     .get_settings        = dmfe_get_settings,
    1607     .set_settings        = dmfe_set_settings,
    1608     .get_link            = dmfe_get_link,
    1609     .nway_reset        = dmfe_nway_reset,
    1610     .get_rx_csum        = dmfe_get_rx_csum,
    1611     .set_rx_csum        = dmfe_set_rx_csum,
    1612     .get_tx_csum        = dmfe_get_tx_csum,
    1613     .set_tx_csum        = dmfe_set_tx_csum,
    1614 };
    1615 #endif
    1616 
    1617 //#ifdef MODULE
    1618 
    1619 MODULE_LICENSE("GPL");
    1620 MODULE_DESCRIPTION("Davicom DM9000/DM9010 ISA/uP Fast Ethernet Driver");
    1621 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
    1622 MODULE_PARM(mode, "i");
    1623 MODULE_PARM(irq, "i");
    1624 MODULE_PARM(iobase, "i");
    1625 #else
    1626 module_param(mode, int, 0);
    1627 module_param(irq, int, 0);
    1628 module_param(iobase, int, 0);
    1629 #endif           
    1630 MODULE_PARM_DESC(mode,"Media Speed, 0:10MHD, 1:10MFD, 4:100MHD, 5:100MFD");
    1631 MODULE_PARM_DESC(irq,"EtherLink IRQ number");
    1632 MODULE_PARM_DESC(iobase, "EtherLink I/O base address");
    1633 
    1634 /* Description: 
    1635    when user used insmod to add module, system invoked init_module()
    1636    to initilize and register.
    1637 */
    1638 int __init dm9000c_init(void)
    1639 {
    1640     volatile unsigned long *bwscon;   // 0x48000000
    1641     volatile unsigned long *bankcon4; // 0x48000014
    1642     unsigned long val;
    1643     
    1644     iobase = (int)ioremap(0x20000000, 1024); /* andy */
    1645     irq = IRQ_EINT7;                    /* andy */
    1646     
    1647     /* 设置S3C2440的memory control */
    1648     bwscon   = ioremap(0x48000000,4);
    1649     bankcon4 = ioremap(0x48000014,4);
    1650     
    1651     /* DW4[17:16] :01-16bit
    1652      * WS4[18]    :0-wait disable
    1653      * ST4[19]    :0
    1654      */
    1655     val = *bwscon;
    1656     val &= ~(0xf<<16);
    1657     val |= (1<<16);
    1658     *bwscon = val;
    1659     
    1660     /*
    1661      *    Tacs[14:13] : 发出片选信号之前,多长时间内要先发出地址信号
    1662      *                  DM9000C的片选信号和CMD信号可以同时发出
    1663      *                  所以它设为0            
    1664      *  Tcons[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE
    1665      *                   DM9000C的T1>=0ns,所以它设为0
    1666      *    Tacc[10:8]  : 读写信号的脉冲长度,
    1667      *                  DM9000C的T2>=20ns,所以它设为001,表示2个hclk周期,hclk=100Mhz,就是20ns
    1668      *  Tcoh[7:6]   : 当读信号nOE变为高电平后,片选信号还要维持多长时间
    1669                       DM9000C进行写操作时,nWE变为高电平之后,数据线上的数据还要最少维持3ns
    1670                       DM9000C进行读操作时,nOE变为高电平之后,数据线上的数据在6ns之后会消失
    1671      *                  我们取一个宽松值:让片选信号在nOE为高电平之后,再维持10ns
    1672      *                  所以设为01
    1673      *  Tcch[5:4]   : 当片选信号变为高电平之后,地址信号还要维持多长时间
    1674      *                  DM9000C的片选信号和CMD信号可以同时出现,同时消失
    1675      *                  所以设为0
    1676      *  PMC{1:0]    : 00-正常模式
    1677      */
    1678      *bankcon4 = (1<<6) | (1<<8);
    1679      
    1680          
    1681         
    1682     iounmap(bwscon);
    1683     iounmap(bankcon4);
    1684     
    1685     switch(mode) {
    1686         case DM9KS_10MHD:
    1687         case DM9KS_100MHD:
    1688         case DM9KS_10MFD:
    1689         case DM9KS_100MFD:
    1690             media_mode = mode;
    1691             break;
    1692         default:
    1693             media_mode = DM9KS_AUTO;
    1694     }
    1695     dmfe_dev = dmfe_probe();
    1696     if(IS_ERR(dmfe_dev))
    1697         return PTR_ERR(dmfe_dev);
    1698     return 0;
    1699 }
    1700 /* Description: 
    1701    when user used rmmod to delete module, system invoked clean_module()
    1702    to  un-register DEVICE.
    1703 */
    1704 void __exit dm9000c_exit(void)
    1705 {
    1706     struct net_device *dev = dmfe_dev;
    1707     DMFE_DBUG(0, "clean_module()", 0);
    1708 
    1709     unregister_netdev(dmfe_dev);
    1710     release_region(dev->base_addr, 2);
    1711 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    1712     kfree(dev);
    1713 #else
    1714     free_netdev(dev);
    1715 #endif
    1716     
    1717     iounmap((void *)iobase);
    1718     DMFE_DBUG(0, "clean_module() exit", 0);
    1719 }
    1720 
    1721 module_init(dm9000c_init);
    1722 module_exit(dm9000c_exit);
    1723 
    1724 //#endif

    下面分析主要修改的几个部分:

    • 1、将入口函数与出口函数改为模块,增加1721行与1722行,增加协议。去掉模块的宏定义1617、1724行
    • 2、看到dm9000c_init->dmfe_probe->dmfe_probe1中的416行,由于所有使用的dm9000c芯片版本号不满足此条件,所以直接去掉这一行注释掉。
    • 3、看到dmfe_open函数,这个函数在ifconfig后会被调用。里面的485行,更改中断方式为上升沿触发;看到dm9000c_init的1645行,更改中断引脚IRQ_EINT7
    • 4、更改网卡芯片数据地址,看到dm9000c_init的1644行,将实际地址0x20000000转换为虚拟地址后赋给iobase ,存储控制器的BANK4所控制的存储地址为0x20000000

    • 5、最后设置bwscon、bankcon4两个寄存器的值,他们可以控制BANK4的位宽、时序等信息。它的设置全部在dm9000c_init中。这里以读数据的Tacc时间参数做一下介绍,时序的参数是怎么设置的。直接贴图,其中左边为S3C2440的可以设置时间,右边是DM9000C需要设置的时间,可以看到Tacc时间对应的是DM9000C的T2参数,它主要至少10ns,那么我们设它为20ns,HCLK为100Mhz,那么设置20ns需要2个时钟周期,所以Tacc[10:8]=001b。

     

     3、DM9000C的驱动测试

    1、把dm9dev9000c.c放到内核的drivers/net目录下
    2、修改drivers/net/Makefile

    obj-$(CONFIG_DM9000) += dm9000.o
    改为
    obj-$(CONFIG_DM9000) += dm9dev9000c.o
    3、make uImage
    使用新内核启动
    4、
    使用NFS启动
    或挂接块设备文件系统的话,那么需要再内核启动后
    ifconfig eth0 192.168.1.17
    ping 192.168.1.1

    到这里,DM9000C的代码测试成功。

  • 相关阅读:
    Java String.format 方法使用介绍
    Android获取SD卡中选中图片的路径(URL)
    第三届蓝桥杯Java高职组决赛第一题
    Source Insight使用小技巧小结
    用android代码显示图片的一部分源码
    Liferay的架构:缓存(第一部分)
    Linux登录ssh携带密码
    about flashback_transaction_query
    数据库系统概念读书笔记——实体-联系模型
    Android Phone和Pad UA区别
  • 原文地址:https://www.cnblogs.com/andyfly/p/11259515.html
Copyright © 2020-2023  润新知