S3C2440实现dm9000网卡驱动程序移植

20150419 S3C2440实现dm9000网卡驱动程序移植

2015-04-19 Lover雪儿

首先附上厂家提供的完整的dm9000程序:

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

其实总结一下移植,很简单,总共就以下四步:

①开启入口函数,②配置网卡io内存,③配置网卡中断,④配置内存控制器读写时序。

接下来我们一步一步来实现dm9000的驱动移植:

 

1.开启入口函数,修改入口函数名字

在源程序中,我们的module_init()等函数被  #ifdef MODULE  这一个条件所包围,所以,此时我们要将其注释,同样也包括最后面的#end if,

同时修改入口函数名字为dm9000c_init,如图所示

2.开启入口函数,修改入口函数名字

在入口函数dm9000_init中添加映射网卡的内存地址,同样在exit出口函数中进行iounmap操作:

3.在dmfe_probe1去除版本版本检测,防止因为版本不同而导致程序退出

4.配置网卡中断

在入口函数中设置中断线

在open函数中设置中断触发方式:

5.增加头文件包含

6.在入口函数中设置芯片的内存读写时序

 1 int __init dm9000c_init(void)
 2 {
 3     volatile unsigned long *bwscon;     // 0x48000000
 4     volatile unsigned long *bankcon4;     // 0x48000014
 5     unsigned long val;
 6     
 7     iobase = (int)ioremap(0x20000000,1024);    /* 添加内存映射 */
 8 
 9     //2440使用的中断引脚为外部中断7,此处我们设置中断号
10     irq = IRQ_EINT7;
11     
12         /* 设置S3C2440的memory controller */
13     bwscon   = ioremap(0x48000000, 4);
14     bankcon4 = ioremap(0x48000014, 4);
15 
16     /* DW4[17:16]: 01-16bit
17      * WS4[18]   : 0-WAIT disable
18      * ST4[19]   : 0 = Not using UB/LB (The pins are dedicated nWBE[3:0])
19      */
20     val = *bwscon;
21     val &= ~(0xf<<16);
22     val |= (1<<16);
23     *bwscon = val;
24 
25     /*
26      * Tacs[14:13]: 发出片选信号之前,多长时间内要先发出地址信号
27      *              DM9000C的片选信号和CMD信号可以同时发出,
28      *              所以它设为0
29      * Tcos[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE
30      *              DM9000C的T1>=0ns, 
31      *              所以它设为0
32      * Tacc[10:8] : 读写信号的脉冲长度, 
33      *              DM9000C的T2>=10ns, 
34      *              所以它设为1, 表示2个hclk周期,hclk=100MHz,就是20ns
35      * Tcoh[7:6]  : 当读信号nOE变为高电平后,片选信号还要维持多长时间
36      *              DM9000C进行写操作时, nWE变为高电平之后, 数据线上的数据还要维持最少3ns
37      *              DM9000C进行读操作时, nOE变为高电平之后, 数据线上的数据在6ns之内会消失
38      *              我们取一个宽松值: 让片选信号在nOE放为高电平后,再维持10ns, 
39      *              所以设为01
40      * Tcah[5:4]  : 当片选信号变为高电平后, 地址信号还要维持多长时间
41      *              DM9000C的片选信号和CMD信号可以同时出现,同时消失
42      *              所以设为0
43      * PMC[1:0]   : 00-正常模式
44      *
45      */
46     //*bankcon4 = (1<<8)|(1<<6);    /* 对于DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7  */
47     *bankcon4 = (7<<8)|(1<<6);  /* TQ2440和MINI2440使用DM9000E,Tacc要设大一点  正常来说1也可以 */
48 
49     iounmap(bwscon);
50     iounmap(bankcon4);
51     
52     
53     switch(mode) {
54         case DM9KS_10MHD:
55         case DM9KS_100MHD:
56         case DM9KS_10MFD:
57         case DM9KS_100MFD:
58             media_mode = mode;
59             break;
60         default:
61             media_mode = DM9KS_AUTO;
62     }
63     dmfe_dev = dmfe_probe();
64     if(IS_ERR(dmfe_dev))
65         return PTR_ERR(dmfe_dev);
66     return 0;
67 }

 

7.测试驱动程序

/*

1把文件放入内核的drivers/net目录下
2修改drivers/net/Makefile
3把 obj-$(CONFIG_DM9000) += dm9000.o
    改为obj-$(CONFIG_DM9000) += dm9dev9000c.o
4使用网络文件系统启动的话,说明已经能用了

不用网络文件系统的话,
就 ifconfig eth0 xxx.xxx.xxx.xxx    
    ping xxx.xxx.xxx.xxn

*/

 

附上修改好的dm9000c网卡驱动程序:

   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 /* 主要就是修改基地址,位宽,中断引脚等 */
  60 
  61 //#define CHECKSUM
  62 //#define TDBUG        /* check TX FIFO pointer */
  63 //#define RDBUG   /* check RX FIFO pointer */
  64 //#define DM8606
  65 
  66 #define DRV_NAME    "dm9KS"
  67 #define DRV_VERSION    "2.09"
  68 #define DRV_RELDATE    "2007-11-22"
  69 
  70 #ifdef MODVERSIONS
  71 #include <linux/modversions.h>
  72 #endif
  73 
  74 //#include <linux/config.h>
  75 #include <linux/init.h>                
  76 #include <linux/delay.h>
  77 #include <linux/module.h>
  78 #include <linux/ioport.h>
  79 #include <linux/netdevice.h>
  80 #include <linux/etherdevice.h>
  81 #include <linux/skbuff.h>
  82 #include <linux/version.h>
  83 #include <asm/dma.h>
  84 #include <linux/spinlock.h>
  85 #include <linux/crc32.h>
  86 #include <linux/mii.h>
  87 #include <linux/ethtool.h>
  88 #include <asm/uaccess.h>
  89 
  90 #ifdef CONFIG_ARCH_MAINSTONE
  91 #include <asm/io.h>
  92 #include <asm/hardware.h>
  93 #include <asm/irq.h>
  94 #endif
  95 
  96 #include <asm/delay.h>
  97 #include <asm/irq.h>
  98 #include <asm/io.h>
  99 #include <asm/arch-s3c2410/regs-mem.h>
 100 
 101 /* Board/System/Debug information/definition ---------------- */
 102 
 103 #define DM9KS_ID        0x90000A46
 104 #define DM9010_ID        0x90100A46
 105 /*-------register name-----------------------*/
 106 #define DM9KS_NCR        0x00    /* Network control Reg.*/
 107 #define DM9KS_NSR        0x01    /* Network Status Reg.*/
 108 #define DM9KS_TCR        0x02    /* TX control Reg.*/
 109 #define DM9KS_RXCR        0x05    /* RX control Reg.*/
 110 #define DM9KS_BPTR        0x08
 111 #define DM9KS_FCTR        0x09
 112 #define DM9KS_FCR            0x0a
 113 #define DM9KS_EPCR        0x0b
 114 #define DM9KS_EPAR        0x0c
 115 #define DM9KS_EPDRL        0x0d
 116 #define DM9KS_EPDRH        0x0e
 117 #define DM9KS_GPR            0x1f    /* General purpose register */
 118 #define DM9KS_CHIPR        0x2c
 119 #define DM9KS_TCR2        0x2d
 120 #define DM9KS_SMCR        0x2f     /* Special Mode Control Reg.*/
 121 #define DM9KS_ETXCSR    0x30    /* Early Transmit control/status Reg.*/
 122 #define    DM9KS_TCCR        0x31    /* Checksum cntrol Reg. */
 123 #define DM9KS_RCSR        0x32    /* Receive Checksum status Reg.*/
 124 #define DM9KS_BUSCR        0x38
 125 #define DM9KS_MRCMDX    0xf0
 126 #define DM9KS_MRCMD        0xf2
 127 #define DM9KS_MDRAL        0xf4
 128 #define DM9KS_MDRAH        0xf5
 129 #define DM9KS_MWCMD        0xf8
 130 #define DM9KS_MDWAL        0xfa
 131 #define DM9KS_MDWAH        0xfb
 132 #define DM9KS_TXPLL        0xfc
 133 #define DM9KS_TXPLH        0xfd
 134 #define DM9KS_ISR            0xfe
 135 #define DM9KS_IMR            0xff
 136 /*---------------------------------------------*/
 137 #define DM9KS_REG05        0x30    /* SKIP_CRC/SKIP_LONG */ 
 138 #define DM9KS_REGFF        0xA3    /* IMR */
 139 #define DM9KS_DISINTR    0x80
 140 
 141 #define DM9KS_PHY            0x40    /* PHY address 0x01 */
 142 #define DM9KS_PKT_RDY        0x01    /* Packet ready to receive */
 143 
 144 /* Added for PXA of MAINSTONE */
 145 #ifdef CONFIG_ARCH_MAINSTONE
 146 #include <asm/arch/mainstone.h>
 147 #define DM9KS_MIN_IO        (MST_ETH_PHYS + 0x300)
 148 #define DM9KS_MAX_IO            (MST_ETH_PHYS + 0x370)
 149 #define DM9K_IRQ        MAINSTONE_IRQ(3)
 150 #else
 151 #define DM9KS_MIN_IO        0x300
 152 #define DM9KS_MAX_IO        0x370
 153 #define DM9KS_IRQ        3
 154 #endif
 155 
 156 #define DM9KS_VID_L        0x28
 157 #define DM9KS_VID_H        0x29
 158 #define DM9KS_PID_L        0x2A
 159 #define DM9KS_PID_H        0x2B
 160 
 161 #define DM9KS_RX_INTR        0x01
 162 #define DM9KS_TX_INTR        0x02
 163 #define DM9KS_LINK_INTR        0x20
 164 
 165 #define DM9KS_DWORD_MODE    1
 166 #define DM9KS_BYTE_MODE        2
 167 #define DM9KS_WORD_MODE        0
 168 
 169 #define TRUE            1
 170 #define FALSE            0
 171 /* Number of continuous Rx packets */
 172 #define CONT_RX_PKT_CNT        0xFFFF
 173 
 174 #define DMFE_TIMER_WUT  jiffies+(HZ*5)    /* timer wakeup time : 5 second */
 175 
 176 #ifdef DM9KS_DEBUG
 177 #define DMFE_DBUG(dbug_now, msg, vaule)\
 178 if (dmfe_debug||dbug_now) printk(KERN_ERR "dmfe: %s %x\n", msg, vaule)
 179 #else
 180 #define DMFE_DBUG(dbug_now, msg, vaule)\
 181 if (dbug_now) printk(KERN_ERR "dmfe: %s %x\n", msg, vaule)
 182 #endif
 183 
 184 #ifndef CONFIG_ARCH_MAINSTONE
 185 #pragma pack(push, 1)
 186 #endif
 187 
 188 typedef struct _RX_DESC
 189 {
 190     u8 rxbyte;
 191     u8 status;
 192     u16 length;
 193 }RX_DESC;
 194 
 195 typedef union{
 196     u8 buf[4];
 197     RX_DESC desc;
 198 } rx_t;
 199 #ifndef CONFIG_ARCH_MAINSTONE
 200 #pragma pack(pop)
 201 #endif
 202 
 203 enum DM9KS_PHY_mode {
 204     DM9KS_10MHD   = 0, 
 205     DM9KS_100MHD  = 1, 
 206     DM9KS_10MFD   = 4,
 207     DM9KS_100MFD  = 5, 
 208     DM9KS_AUTO    = 8, 
 209 };
 210 
 211 /* Structure/enum declaration ------------------------------- */
 212 typedef struct board_info { 
 213     u32 io_addr;/* Register I/O base address */
 214     u32 io_data;/* Data I/O address */
 215     u8 op_mode;/* PHY operation mode */
 216     u8 io_mode;/* 0:word, 2:byte */
 217     u8 Speed;    /* current speed */
 218     u8 chip_revision;
 219     int rx_csum;/* 0:disable, 1:enable */
 220     
 221     u32 reset_counter;/* counter: RESET */ 
 222     u32 reset_tx_timeout;/* RESET caused by TX Timeout */
 223     int tx_pkt_cnt;
 224     int cont_rx_pkt_cnt;/* current number of continuos rx packets  */
 225     struct net_device_stats stats;
 226     
 227     struct timer_list timer;
 228     unsigned char srom[128];
 229     spinlock_t lock;
 230     struct mii_if_info mii;
 231 } board_info_t;
 232 /* Global variable declaration ----------------------------- */
 233 /*static int dmfe_debug = 0;*/
 234 static struct net_device * dmfe_dev = NULL;
 235 static struct ethtool_ops dmfe_ethtool_ops;
 236 /* For module input parameter */
 237 static int mode       = DM9KS_AUTO;  
 238 static int media_mode = DM9KS_AUTO;
 239 static int  irq        = DM9KS_IRQ;
 240 static int iobase     = DM9KS_MIN_IO;
 241 
 242 #if 0  // use physical address; Not virtual address
 243 #ifdef outb
 244     #undef outb
 245 #endif
 246 #ifdef outw
 247     #undef outw
 248 #endif
 249 #ifdef outl
 250     #undef outl
 251 #endif
 252 #ifdef inb
 253     #undef inb
 254 #endif
 255 #ifdef inw
 256     #undef inw
 257 #endif
 258 #ifdef inl
 259     #undef inl
 260 #endif
 261 void outb(u8 reg, u32 ioaddr)
 262 {
 263     (*(volatile u8 *)(ioaddr)) = reg;
 264 }
 265 void outw(u16 reg, u32 ioaddr)
 266 {
 267     (*(volatile u16 *)(ioaddr)) = reg;
 268 }
 269 void outl(u32 reg, u32 ioaddr)
 270 {
 271     (*(volatile u32 *)(ioaddr)) = reg;
 272 }
 273 u8 inb(u32 ioaddr)
 274 {
 275     return (*(volatile u8 *)(ioaddr));
 276 }
 277 u16 inw(u32 ioaddr)
 278 {
 279     return (*(volatile u16 *)(ioaddr));
 280 }
 281 u32 inl(u32 ioaddr)
 282 {
 283     return (*(volatile u32 *)(ioaddr));
 284 }
 285 #endif
 286 
 287 /* function declaration ------------------------------------- */
 288 int dmfe_probe1(struct net_device *);
 289 static int dmfe_open(struct net_device *);
 290 static int dmfe_start_xmit(struct sk_buff *, struct net_device *);
 291 static void dmfe_tx_done(unsigned long);
 292 static void dmfe_packet_receive(struct net_device *);
 293 static int dmfe_stop(struct net_device *);
 294 static struct net_device_stats * dmfe_get_stats(struct net_device *); 
 295 static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int);
 296 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 297 static void dmfe_interrupt(int , void *, struct pt_regs *); 
 298 #else
 299     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
 300     static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *);
 301     #else
 302     static irqreturn_t dmfe_interrupt(int , void *);/* for kernel 2.6.20 */
 303     #endif
 304 #endif
 305 static void dmfe_timer(unsigned long);
 306 static void dmfe_init_dm9000(struct net_device *);
 307 static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
 308 u8 ior(board_info_t *, int);
 309 void iow(board_info_t *, int, u8);
 310 static u16 phy_read(board_info_t *, int);
 311 static void phy_write(board_info_t *, int, u16);
 312 static u16 read_srom_word(board_info_t *, int);
 313 static void dm9000_hash_table(struct net_device *);
 314 static void dmfe_timeout(struct net_device *);
 315 static void dmfe_reset(struct net_device *);
 316 static int mdio_read(struct net_device *, int, int);
 317 static void mdio_write(struct net_device *, int, int, int);
 318 static void dmfe_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
 319 static int dmfe_get_settings(struct net_device *, struct ethtool_cmd *);
 320 static int dmfe_set_settings(struct net_device *, struct ethtool_cmd *);
 321 static u32 dmfe_get_link(struct net_device *);
 322 static int dmfe_nway_reset(struct net_device *);
 323 static uint32_t dmfe_get_rx_csum(struct net_device *);
 324 static uint32_t dmfe_get_tx_csum(struct net_device *);
 325 static int dmfe_set_rx_csum(struct net_device *, uint32_t );
 326 static int dmfe_set_tx_csum(struct net_device *, uint32_t );
 327 
 328 #ifdef DM8606
 329 #include "dm8606.h"
 330 #endif
 331 
 332 //DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);
 333 
 334 /* DM9000 network baord routine ---------------------------- */
 335 
 336 /*
 337   Search DM9000 board, allocate space and register it
 338 */
 339 
 340 struct net_device * __init dmfe_probe(void)
 341 {
 342     struct net_device *dev;   
 343     int err;
 344     
 345     DMFE_DBUG(0, "dmfe_probe()",0);
 346 
 347 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 348     dev = init_etherdev(NULL, sizeof(struct board_info));
 349     //ether_setup(dev);        
 350 #else
 351     dev= alloc_etherdev(sizeof(struct board_info));        //分配一个net_device结构体
 352 #endif
 353 
 354     if(!dev)
 355         return ERR_PTR(-ENOMEM);
 356 
 357          SET_MODULE_OWNER(dev);
 358     err = dmfe_probe1(dev);
 359     if (err)
 360         goto out;
 361 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 362     err = register_netdev(dev);
 363     if (err)
 364         goto out1;
 365 #endif
 366     return dev;
 367 out1:
 368     release_region(dev->base_addr,2);
 369 out:
 370 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 371     kfree(dev);
 372 #else
 373     free_netdev(dev);
 374 #endif
 375     return ERR_PTR(err);
 376 }
 377 
 378 int __init dmfe_probe1(struct net_device *dev)
 379 {
 380     struct board_info *db;    /* Point a board information structure */
 381     u32 id_val;
 382     u16 i, dm9000_found = FALSE;
 383     u8 MAC_addr[6]={0x00,0x60,0x6E,0x33,0x44,0x55};
 384     u8 HasEEPROM=0,chip_info;
 385     DMFE_DBUG(0, "dmfe_probe1()",0);
 386 
 387     /* Search All DM9000 serial NIC   对网卡芯片,与读内存差不多,读某个地址就可以了*/
 388     do {
 389         outb(DM9KS_VID_L, iobase);       /* DM9000C的索引寄存器  cmd = 0*/
 390         id_val = inb(iobase + 4);        /* 读DM9000C的数据寄存器  cmd = 1*/
 391         outb(DM9KS_VID_H, iobase);
 392         id_val |= inb(iobase + 4) << 8;
 393         outb(DM9KS_PID_L, iobase);
 394         id_val |= inb(iobase + 4) << 16;
 395         outb(DM9KS_PID_H, iobase);
 396         id_val |= inb(iobase + 4) << 24;
 397 
 398         if (id_val == DM9KS_ID || id_val == DM9010_ID) {
 399             
 400             /* Request IO from system */
 401             if(!request_region(iobase, 2, dev->name))
 402                 return -ENODEV;
 403 
 404             printk(KERN_ERR"<DM9KS> I/O: %x, VID: %x \n",iobase, id_val);
 405             dm9000_found = TRUE;
 406 
 407             /* Allocated board information structure */
 408             memset(dev->priv, 0, sizeof(struct board_info));
 409             db = (board_info_t *)dev->priv;
 410             dmfe_dev    = dev;
 411             db->io_addr  = iobase;
 412             db->io_data = iobase + 4;   
 413             db->chip_revision = ior(db, DM9KS_CHIPR);
 414             
 415             chip_info = ior(db,0x43);
 416             //防止应为版本不匹配而导致的出错,版本不同,也可以用
 417             //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) 
 418             //    return -ENODEV;
 419                         
 420             /* driver system function   硬件相关的设置*/                
 421             dev->base_addr         = iobase;
 422             dev->irq         = irq;
 423             dev->open         = &dmfe_open;
 424             dev->hard_start_xmit     = &dmfe_start_xmit;  //硬件启动传输
 425             dev->watchdog_timeo    = 5*HZ;    
 426             dev->tx_timeout        = dmfe_timeout;
 427             dev->stop         = &dmfe_stop;
 428             dev->get_stats         = &dmfe_get_stats;
 429             dev->set_multicast_list = &dm9000_hash_table;
 430             dev->do_ioctl         = &dmfe_do_ioctl;
 431 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28)
 432             dev->ethtool_ops = &dmfe_ethtool_ops;
 433 #endif
 434 #ifdef CHECKSUM
 435             //dev->features |=  NETIF_F_IP_CSUM;
 436             dev->features |=  NETIF_F_IP_CSUM|NETIF_F_SG;
 437 #endif
 438             db->mii.dev = dev;
 439             db->mii.mdio_read = mdio_read;
 440             db->mii.mdio_write = mdio_write;
 441             db->mii.phy_id = 1;
 442 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
 443             db->mii.phy_id_mask = 0x1F; 
 444             db->mii.reg_num_mask = 0x1F; 
 445 #endif
 446             //db->msg_enable =(debug == 0 ? DMFE_DEF_MSG_ENABLE : ((1 << debug) - 1));
 447             
 448             /* Read SROM content */
 449             for (i=0; i<64; i++)
 450                 ((u16 *)db->srom)[i] = read_srom_word(db, i);
 451 
 452             /* Get the PID and VID from EEPROM to check */
 453             id_val = (((u16 *)db->srom)[4])|(((u16 *)db->srom)[5]<<16); 
 454             printk("id_val=%x\n", id_val);
 455             if (id_val == DM9KS_ID || id_val == DM9010_ID) 
 456                 HasEEPROM =1;
 457             
 458             /* Set Node Address */
 459             for (i=0; i<6; i++)
 460             {
 461                 if (HasEEPROM) /* use EEPROM */
 462                     dev->dev_addr[i] = db->srom[i];
 463                 else    /* No EEPROM */
 464                     dev->dev_addr[i] = MAC_addr[i];
 465             }
 466         }//end of if()
 467         iobase += 0x10;
 468     }while(!dm9000_found && iobase <= DM9KS_MAX_IO);
 469 
 470     return dm9000_found ? 0:-ENODEV;
 471 }
 472 
 473 
 474 /*
 475   Open the interface.
 476   The interface is opened whenever "ifconfig" actives it.
 477 */
 478 static int dmfe_open(struct net_device *dev)
 479 {
 480     board_info_t *db = (board_info_t *)dev->priv;
 481     u8 reg_nsr;
 482     int i;
 483     DMFE_DBUG(0, "dmfe_open", 0);
 484     //对于2440来说,可以设置它为上升沿触发
 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\n",dm8606_read(db,0));
 493     printk("[8606]reg1=0x%04x\n",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\n",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\n");
 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\n");
 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\n");
 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("\nRX FIFO OVERFLOW %lx\n", db->stats.rx_fifo_errors);
 877     printk("RX CRC %lx\n", db->stats.rx_crc_errors);
 878     printk("RX LEN Err %lx\n", db->stats.rx_length_errors);
 879     printk("RESET %x\n", db->reset_counter);
 880     printk("RESET: TX Timeout %x\n", db->reset_tx_timeout);
 881     printk("g_TX_nsr %x\n", 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!!\n");
 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\n",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().\n");
1075     db->reset_tx_timeout++;
1076     db->stats.tx_errors++;
1077     
1078 #if FALSE
1079     printk("TX packet count = %d\n", db->tx_pkt_cnt);    
1080     printk("TX timeout = %d\n", db->reset_tx_timeout);    
1081     printk("22H=0x%02x  23H=0x%02x\n",ior(db,0x22),ior(db,0x23));
1082     printk("faH=0x%02x  fbH=0x%02x\n",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!\n");
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!\n");
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>\n");
1240             }
1241             if (rx.desc.status & 0x02) 
1242             {
1243                 db->stats.rx_crc_errors++;
1244                 printk(KERN_INFO"<RX CRC error>\n");
1245             }
1246             if (rx.desc.status & 0x80) 
1247             {
1248                 db->stats.rx_length_errors++;
1249                 printk(KERN_INFO"<RX Length error>\n");
1250             }
1251             if (rx.desc.status & 0x08)
1252                 printk(KERN_INFO"<Physical Layer error>\n");
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.\n", 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\n");
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\n");
1390         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<1));
1391         return;
1392     }else{
1393         //printk(KERN_INFO "DM9KS:disable promiscuous mode\n");
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\n");
1400         iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<3));
1401     }else{
1402         //printk(KERN_INFO "DM9KS:Disable pass all multicast\n");
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\n");
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\n");
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);    /* 添加内存映射 */
1645 
1646     //2440使用的中断引脚为外部中断7,此处我们设置中断号
1647     irq = IRQ_EINT7;
1648     
1649         /* 设置S3C2440的memory controller */
1650     bwscon   = ioremap(0x48000000, 4);
1651     bankcon4 = ioremap(0x48000014, 4);
1652 
1653     /* DW4[17:16]: 01-16bit
1654      * WS4[18]   : 0-WAIT disable
1655      * ST4[19]   : 0 = Not using UB/LB (The pins are dedicated nWBE[3:0])
1656      */
1657     val = *bwscon;
1658     val &= ~(0xf<<16);
1659     val |= (1<<16);
1660     *bwscon = val;
1661 
1662     /*
1663      * Tacs[14:13]: 发出片选信号之前,多长时间内要先发出地址信号
1664      *              DM9000C的片选信号和CMD信号可以同时发出,
1665      *              所以它设为0
1666      * Tcos[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE
1667      *              DM9000C的T1>=0ns, 
1668      *              所以它设为0
1669      * Tacc[10:8] : 读写信号的脉冲长度, 
1670      *              DM9000C的T2>=10ns, 
1671      *              所以它设为1, 表示2个hclk周期,hclk=100MHz,就是20ns
1672      * Tcoh[7:6]  : 当读信号nOE变为高电平后,片选信号还要维持多长时间
1673      *              DM9000C进行写操作时, nWE变为高电平之后, 数据线上的数据还要维持最少3ns
1674      *              DM9000C进行读操作时, nOE变为高电平之后, 数据线上的数据在6ns之内会消失
1675      *              我们取一个宽松值: 让片选信号在nOE放为高电平后,再维持10ns, 
1676      *              所以设为01
1677      * Tcah[5:4]  : 当片选信号变为高电平后, 地址信号还要维持多长时间
1678      *              DM9000C的片选信号和CMD信号可以同时出现,同时消失
1679      *              所以设为0
1680      * PMC[1:0]   : 00-正常模式
1681      *
1682      */
1683     //*bankcon4 = (1<<8)|(1<<6);    /* 对于DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7  */
1684     *bankcon4 = (7<<8)|(1<<6);  /* TQ2440和MINI2440使用DM9000E,Tacc要设大一点  正常来说1也可以 */
1685 
1686     iounmap(bwscon);
1687     iounmap(bankcon4);
1688     
1689     
1690     switch(mode) {
1691         case DM9KS_10MHD:
1692         case DM9KS_100MHD:
1693         case DM9KS_10MFD:
1694         case DM9KS_100MFD:
1695             media_mode = mode;
1696             break;
1697         default:
1698             media_mode = DM9KS_AUTO;
1699     }
1700     dmfe_dev = dmfe_probe();
1701     if(IS_ERR(dmfe_dev))
1702         return PTR_ERR(dmfe_dev);
1703     return 0;
1704 }
1705 /* Description: 
1706    when user used rmmod to delete module, system invoked clean_module()
1707    to  un-register DEVICE.
1708 */
1709 void __exit dm9000c_exit(void)
1710 {
1711     struct net_device *dev = dmfe_dev;
1712     DMFE_DBUG(0, "clean_module()", 0);
1713 
1714     unregister_netdev(dmfe_dev);
1715     release_region(dev->base_addr, 2);
1716 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1717     kfree(dev);
1718 #else
1719     free_netdev(dev);
1720 #endif
1721     iounmap((void *)iobase);
1722     DMFE_DBUG(0, "clean_module() exit", 0);
1723 }
1724 
1725 module_init(dm9000c_init);
1726 module_exit(dm9000c_exit);
1727 
1728 //#endif
1729 
1730 
1731 /*
1732 
1733 1把文件放入内核的drivers/net目录下
1734 2修改drivers/net/Makefile
1735 3把 obj-$(CONFIG_DM9000) += dm9000.o
1736     改为obj-$(CONFIG_DM9000) += dm9dev9000c.o
1737 4使用网络文件系统启动的话,说明已经能用了
1738 
1739 不用网络文件系统的话,
1740 就 ifconfig eth0 xxx.xxx.xxx.xxx    
1741     ping xxx.xxx.xxx.xxn
1742 
1743 */
dm9000c.c

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

"小夜猫&小懒虫&小财迷"的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值