• 网卡驱动


    DM9000移植

    uboot下参数设置

       

    原理图及管脚说明

    IOR#          —— Processor Read Command

    IOW#         —— Processor Write Command

    CS#         —— Chip Select

    CMD         —— Command Type

    INT         —— Interrupt Request

    SD0 - SD15     —— Processor Data Bus

       

    LED1         —— Speed LED

    LED2         —— Link/Active LED

       

    RX+,RX-     —— TP RX

       

    TX+,TX-     —— TP TX

       

    PWRST#     —— Power on reset

       

       

       

    根据原理图:

    1、修改基地址、长度

    2、修改中断号

       

    根据芯片手册:

    设置2440的Memory Controller(设置时序)

       

     

     

       

     

     

     

     

       

    原厂提供的源码

    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 ", msg, vaule)
    174 #else
    175 #define DMFE_DBUG(dbug_now, msg, vaule)
    176 if (dbug_now) printk(KERN_ERR "dmfe: %s %x ", 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 ",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 ", 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 ",dm8606_read(db,0));
    486         printk("[8606]reg1=0x%04x ",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 ",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 ");
    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 ");
    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 ");
    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(" RX FIFO OVERFLOW %lx ", db->stats.rx_fifo_errors);
    870         printk("RX CRC %lx ", db->stats.rx_crc_errors);
    871         printk("RX LEN Err %lx ", db->stats.rx_length_errors);
    872         printk("RESET %x ", db->reset_counter);
    873         printk("RESET: TX Timeout %x ", db->reset_tx_timeout);
    874         printk("g_TX_nsr %x ", 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!! ");
    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 ",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(). ");
    1068         db->reset_tx_timeout++;
    1069         db->stats.tx_errors++;
    1070         
    1071 #if FALSE
    1072         printk("TX packet count = %d ", db->tx_pkt_cnt);        
    1073         printk("TX timeout = %d ", db->reset_tx_timeout);        
    1074         printk("22H=0x%02x 23H=0x%02x ",ior(db,0x22),ior(db,0x23));
    1075         printk("faH=0x%02x fbH=0x%02x ",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! ");
    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! ");
    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> ");
    1233                         }
    1234                         if (rx.desc.status & 0x02)
    1235                         {
    1236                                 db->stats.rx_crc_errors++;
    1237                                 printk(KERN_INFO"<RX CRC error> ");
    1238                         }
    1239                         if (rx.desc.status & 0x80)
    1240                         {
    1241                                 db->stats.rx_length_errors++;
    1242                                 printk(KERN_INFO"<RX Length error> ");
    1243                         }
    1244                         if (rx.desc.status & 0x08)
    1245                                 printk(KERN_INFO"<Physical Layer error> ");
    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. ", 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 ");
    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 ");
    1383                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<1));
    1384                 return;
    1385         }else{
    1386                 //printk(KERN_INFO "DM9KS:disable promiscuous mode ");
    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 ");
    1393                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<3));
    1394         }else{
    1395                 //printk(KERN_INFO "DM9KS:Disable pass all multicast ");
    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 ");
    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 ");
    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

       

       

    自己移植的源码

    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 //lhc
    96 #include <asm/delay.h>
    97 #include <asm/irq.h>
    98 #include <asm/io.h>
    99 #if defined(CONFIG_ARCH_S3C2410)
    100 #include <asm/arch-s3c2410/regs-mem.h>
    101 #endif
    102
    103
    104 /* Board/System/Debug information/definition ---------------- */
    105
    106 #define DM9KS_ID                0x90000A46
    107 #define DM9010_ID                0x90100A46
    108 /*-------register name-----------------------*/
    109 #define DM9KS_NCR                0x00        /* Network control Reg.*/
    110 #define DM9KS_NSR                0x01        /* Network Status Reg.*/
    111 #define DM9KS_TCR                0x02        /* TX control Reg.*/
    112 #define DM9KS_RXCR                0x05        /* RX control Reg.*/
    113 #define DM9KS_BPTR                0x08
    114 #define DM9KS_FCTR                0x09
    115 #define DM9KS_FCR                        0x0a
    116 #define DM9KS_EPCR                0x0b
    117 #define DM9KS_EPAR                0x0c
    118 #define DM9KS_EPDRL                0x0d
    119 #define DM9KS_EPDRH                0x0e
    120 #define DM9KS_GPR                        0x1f        /* General purpose register */
    121 #define DM9KS_CHIPR                0x2c
    122 #define DM9KS_TCR2                0x2d
    123 #define DM9KS_SMCR                0x2f         /* Special Mode Control Reg.*/
    124 #define DM9KS_ETXCSR        0x30        /* Early Transmit control/status Reg.*/
    125 #define        DM9KS_TCCR                0x31        /* Checksum cntrol Reg. */
    126 #define DM9KS_RCSR                0x32        /* Receive Checksum status Reg.*/
    127 #define DM9KS_BUSCR                0x38
    128 #define DM9KS_MRCMDX        0xf0
    129 #define DM9KS_MRCMD                0xf2
    130 #define DM9KS_MDRAL                0xf4
    131 #define DM9KS_MDRAH                0xf5
    132 #define DM9KS_MWCMD                0xf8
    133 #define DM9KS_MDWAL                0xfa
    134 #define DM9KS_MDWAH                0xfb
    135 #define DM9KS_TXPLL                0xfc
    136 #define DM9KS_TXPLH                0xfd
    137 #define DM9KS_ISR                        0xfe
    138 #define DM9KS_IMR                        0xff
    139 /*---------------------------------------------*/
    140 #define DM9KS_REG05                0x30        /* SKIP_CRC/SKIP_LONG */
    141 #define DM9KS_REGFF                0xA3        /* IMR */
    142 #define DM9KS_DISINTR        0x80
    143
    144 #define DM9KS_PHY                        0x40        /* PHY address 0x01 */
    145 #define DM9KS_PKT_RDY                0x01        /* Packet ready to receive */
    146
    147 /* Added for PXA of MAINSTONE */
    148 #ifdef CONFIG_ARCH_MAINSTONE
    149 #include <asm/arch/mainstone.h>
    150 #define DM9KS_MIN_IO                (MST_ETH_PHYS + 0x300)
    151 #define DM9KS_MAX_IO (MST_ETH_PHYS + 0x370)
    152 #define DM9K_IRQ                 MAINSTONE_IRQ(3)
    153 #else
    154 #define DM9KS_MIN_IO                0x300
    155 #define DM9KS_MAX_IO                0x370
    156 #define DM9KS_IRQ                3
    157 #endif
    158
    159 #define DM9KS_VID_L                0x28
    160 #define DM9KS_VID_H                0x29
    161 #define DM9KS_PID_L                0x2A
    162 #define DM9KS_PID_H                0x2B
    163
    164 #define DM9KS_RX_INTR                0x01
    165 #define DM9KS_TX_INTR                0x02
    166 #define DM9KS_LINK_INTR                0x20
    167
    168 #define DM9KS_DWORD_MODE        1
    169 #define DM9KS_BYTE_MODE                2
    170 #define DM9KS_WORD_MODE                0
    171
    172 #define TRUE                        1
    173 #define FALSE                        0
    174 /* Number of continuous Rx packets */
    175 #define CONT_RX_PKT_CNT                0xFFFF
    176
    177 #define DMFE_TIMER_WUT jiffies+(HZ*5)        /* timer wakeup time : 5 second */
    178
    179 #ifdef DM9KS_DEBUG
    180 #define DMFE_DBUG(dbug_now, msg, vaule)
    181 if (dmfe_debug||dbug_now) printk(KERN_ERR "dmfe: %s %x ", msg, vaule)
    182 #else
    183 #define DMFE_DBUG(dbug_now, msg, vaule)
    184 if (dbug_now) printk(KERN_ERR "dmfe: %s %x ", msg, vaule)
    185 #endif
    186
    187 #ifndef CONFIG_ARCH_MAINSTONE
    188 #pragma pack(push, 1)
    189 #endif
    190
    191 typedef struct _RX_DESC
    192 {
    193         u8 rxbyte;
    194         u8 status;
    195         u16 length;
    196 }RX_DESC;
    197
    198 typedef union{
    199         u8 buf[4];
    200         RX_DESC desc;
    201 } rx_t;
    202 #ifndef CONFIG_ARCH_MAINSTONE
    203 #pragma pack(pop)
    204 #endif
    205
    206 enum DM9KS_PHY_mode {
    207         DM9KS_10MHD = 0,
    208         DM9KS_100MHD = 1,
    209         DM9KS_10MFD = 4,
    210         DM9KS_100MFD = 5,
    211         DM9KS_AUTO = 8,
    212 };
    213
    214 /* Structure/enum declaration ------------------------------- */
    215 typedef struct board_info {
    216         u32 io_addr;/* Register I/O base address */
    217         u32 io_data;/* Data I/O address */
    218         u8 op_mode;/* PHY operation mode */
    219         u8 io_mode;/* 0:word, 2:byte */
    220         u8 Speed;        /* current speed */
    221         u8 chip_revision;
    222         int rx_csum;/* 0:disable, 1:enable */
    223         
    224         u32 reset_counter;/* counter: RESET */
    225         u32 reset_tx_timeout;/* RESET caused by TX Timeout */
    226         int tx_pkt_cnt;
    227         int cont_rx_pkt_cnt;/* current number of continuos rx packets */
    228         struct net_device_stats stats;
    229         
    230         struct timer_list timer;
    231         unsigned char srom[128];
    232         spinlock_t lock;
    233         struct mii_if_info mii;
    234 } board_info_t;
    235 /* Global variable declaration ----------------------------- */
    236 /*static int dmfe_debug = 0;*/
    237 static struct net_device * dmfe_dev = NULL;
    238 static struct ethtool_ops dmfe_ethtool_ops;
    239 /* For module input parameter */
    240 static int mode = DM9KS_AUTO;
    241 static int media_mode = DM9KS_AUTO;
    242 static int irq = DM9KS_IRQ;
    243 static int iobase = DM9KS_MIN_IO;
    244
    245 #if 0 // use physical address; Not virtual address
    246 #ifdef outb
    247         #undef outb
    248 #endif
    249 #ifdef outw
    250         #undef outw
    251 #endif
    252 #ifdef outl
    253         #undef outl
    254 #endif
    255 #ifdef inb
    256         #undef inb
    257 #endif
    258 #ifdef inw
    259         #undef inw
    260 #endif
    261 #ifdef inl
    262         #undef inl
    263 #endif
    264 void outb(u8 reg, u32 ioaddr)
    265 {
    266         (*(volatile u8 *)(ioaddr)) = reg;
    267 }
    268 void outw(u16 reg, u32 ioaddr)
    269 {
    270         (*(volatile u16 *)(ioaddr)) = reg;
    271 }
    272 void outl(u32 reg, u32 ioaddr)
    273 {
    274         (*(volatile u32 *)(ioaddr)) = reg;
    275 }
    276 u8 inb(u32 ioaddr)
    277 {
    278         return (*(volatile u8 *)(ioaddr));
    279 }
    280 u16 inw(u32 ioaddr)
    281 {
    282         return (*(volatile u16 *)(ioaddr));
    283 }
    284 u32 inl(u32 ioaddr)
    285 {
    286         return (*(volatile u32 *)(ioaddr));
    287 }
    288 #endif
    289
    290 /* function declaration ------------------------------------- */
    291 int dmfe_probe1(struct net_device *);
    292 static int dmfe_open(struct net_device *);
    293 static int dmfe_start_xmit(struct sk_buff *, struct net_device *);
    294 static void dmfe_tx_done(unsigned long);
    295 static void dmfe_packet_receive(struct net_device *);
    296 static int dmfe_stop(struct net_device *);
    297 static struct net_device_stats * dmfe_get_stats(struct net_device *);
    298 static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int);
    299 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    300 static void dmfe_interrupt(int , void *, struct pt_regs *);
    301 #else
    302         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
    303         static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *);
    304         #else
    305         static irqreturn_t dmfe_interrupt(int , void *);/* for kernel 2.6.20 */
    306         
    #endif
    307 #endif
    308 static void dmfe_timer(unsigned long);
    309 static void dmfe_init_dm9000(struct net_device *);
    310 static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
    311 u8 ior(board_info_t *, int);
    312 void iow(board_info_t *, int, u8);
    313 static u16 phy_read(board_info_t *, int);
    314 static void phy_write(board_info_t *, int, u16);
    315 static u16 read_srom_word(board_info_t *, int);
    316 static void dm9000_hash_table(struct net_device *);
    317 static void dmfe_timeout(struct net_device *);
    318 static void dmfe_reset(struct net_device *);
    319 static int mdio_read(struct net_device *, int, int);
    320 static void mdio_write(struct net_device *, int, int, int);
    321 static void dmfe_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
    322 static int dmfe_get_settings(struct net_device *, struct ethtool_cmd *);
    323 static int dmfe_set_settings(struct net_device *, struct ethtool_cmd *);
    324 static u32 dmfe_get_link(struct net_device *);
    325 static int dmfe_nway_reset(struct net_device *);
    326 static uint32_t dmfe_get_rx_csum(struct net_device *);
    327 static uint32_t dmfe_get_tx_csum(struct net_device *);
    328 static int dmfe_set_rx_csum(struct net_device *, uint32_t );
    329 static int dmfe_set_tx_csum(struct net_device *, uint32_t );
    330
    331 #ifdef DM8606
    332 #include "dm8606.h"
    333 #endif
    334
    335 //DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);
    336
    337 /* DM9000 network baord routine ---------------------------- */
    338
    339 /*
    340 Search DM9000 board, allocate space and register it
    341 */
    342
    343 struct net_device * __init dmfe_probe(void)
    344 {
    345         struct net_device *dev;
    346         int err;
    347         
    348         DMFE_DBUG(0, "dmfe_probe()",0);
    349
    350 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    351         dev = init_etherdev(NULL, sizeof(struct board_info));
    352         //ether_setup(dev);                
    353 #else
    354         dev= alloc_etherdev(sizeof(struct board_info));
    355 #endif
    356
    357         if(!dev)
    358                 return ERR_PTR(-ENOMEM);
    359
    360         SET_MODULE_OWNER(dev);
    361         err = dmfe_probe1(dev);
    362         if (err)
    363                 goto out;
    364 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
    365         err = register_netdev(dev);
    366         if (err)
    367                 goto out1;
    368 #endif
    369         return dev;
    370 out1:
    371         release_region(dev->base_addr,2);
    372 out:
    373 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    374         kfree(dev);
    375 #else
    376         free_netdev(dev);
    377 #endif
    378         return ERR_PTR(err);
    379 }
    380
    381 int __init dmfe_probe1(struct net_device *dev)
    382 {
    383         struct board_info *db; /* Point a board information structure */
    384         u32 id_val;
    385         u16 i, dm9000_found = FALSE;
    386         u8 MAC_addr[6]={0x00,0x60,0x6E,0x33,0x44,0x55};
    387         u8 HasEEPROM=0,chip_info;
    388         DMFE_DBUG(0, "dmfe_probe1()",0);
    389
    390         /* Search All DM9000 serial NIC */
    391         do {
    392                 outb(DM9KS_VID_L, iobase);
    393                 id_val = inb(iobase + 4);
    394                 outb(DM9KS_VID_H, iobase);
    395                 id_val |= inb(iobase + 4) << 8;
    396                 outb(DM9KS_PID_L, iobase);
    397                 id_val |= inb(iobase + 4) << 16;
    398                 outb(DM9KS_PID_H, iobase);
    399                 id_val |= inb(iobase + 4) << 24;
    400
    401                 if (id_val == DM9KS_ID || id_val == DM9010_ID) {
    402                         
    403                         /* Request IO from system */
    404                         if(!request_region(iobase, 2, dev->name))
    405                                 return -ENODEV;
    406
    407                         printk(KERN_ERR"<DM9KS> I/O: %x, VID: %x ",iobase, id_val);
    408                         dm9000_found = TRUE;
    409
    410                         /* Allocated board information structure */
    411                         memset(dev->priv, 0, sizeof(struct board_info));
    412                         db = (board_info_t *)dev->priv;
    413                         dmfe_dev = dev;
    414                         db->io_addr = iobase;
    415                         db->io_data = iobase + 4;
    416                         db->chip_revision = ior(db, DM9KS_CHIPR);
    417                         
    418                         chip_info = ior(db,0x43);
    419
    420                         //lhc
    421                         //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) return -ENODEV;
    422                                                 
    423                         /* driver system function */                                
    424                         dev->base_addr                 = iobase;
    425                         dev->irq                 = irq;
    426                         dev->open                 = &dmfe_open;
    427                         dev->hard_start_xmit         = &dmfe_start_xmit;
    428                         dev->watchdog_timeo        = 5*HZ;        
    429                         dev->tx_timeout                = dmfe_timeout;
    430                         dev->stop                 = &dmfe_stop;
    431                         dev->get_stats                 = &dmfe_get_stats;
    432                         dev->set_multicast_list = &dm9000_hash_table;
    433                         dev->do_ioctl                 = &dmfe_do_ioctl;
    434 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28)
    435                         dev->ethtool_ops = &dmfe_ethtool_ops;
    436 #endif
    437 #ifdef CHECKSUM
    438                         //dev->features |= NETIF_F_IP_CSUM;
    439                         dev->features |= NETIF_F_IP_CSUM|NETIF_F_SG;
    440 #endif
    441                         db->mii.dev = dev;
    442                         db->mii.mdio_read = mdio_read;
    443                         db->mii.mdio_write = mdio_write;
    444                         db->mii.phy_id = 1;
    445 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
    446                         db->mii.phy_id_mask = 0x1F;
    447                         db->mii.reg_num_mask = 0x1F;
    448 #endif
    449                         //db->msg_enable =(debug == 0 ? DMFE_DEF_MSG_ENABLE : ((1 << debug) - 1));
    450                         
    451                         /* Read SROM content */
    452                         for (i=0; i<64; i++)
    453                                 ((u16 *)db->srom)[i] = read_srom_word(db, i);
    454
    455                         /* Get the PID and VID from EEPROM to check */
    456                         id_val = (((u16 *)db->srom)[4])|(((u16 *)db->srom)[5]<<16);
    457                         printk("id_val=%x ", id_val);
    458                         if (id_val == DM9KS_ID || id_val == DM9010_ID)
    459                                 HasEEPROM =1;
    460                         
    461                         /* Set Node Address */
    462                         for (i=0; i<6; i++)
    463                         {
    464                                 if (HasEEPROM) /* use EEPROM */
    465                                         dev->dev_addr[i] = db->srom[i];
    466                                 else        /* No EEPROM */
    467                                         dev->dev_addr[i] = MAC_addr[i];
    468                         }
    469                 }//end of if()
    470                 iobase += 0x10;
    471         }while(!dm9000_found && iobase <= DM9KS_MAX_IO);
    472
    473         return dm9000_found ? 0:-ENODEV;
    474 }
    475
    476
    477 /*
    478 Open the interface.
    479 The interface is opened whenever "ifconfig" actives it.
    480 */
    481 static int dmfe_open(struct net_device *dev)
    482 {
    483         board_info_t *db = (board_info_t *)dev->priv;
    484         u8 reg_nsr;
    485         int i;
    486         DMFE_DBUG(0, "dmfe_open", 0);
    487
    488         //lhc
    489         if (request_irq(dev->irq,&dmfe_interrupt, IRQF_TRIGGER_RISING, dev->name, dev))
    490                 return -EAGAIN;
    491
    492         /* Initilize DM910X board */
    493         dmfe_init_dm9000(dev);
    494 #ifdef DM8606
    495         // control DM8606
    496         printk("[8606]reg0=0x%04x ",dm8606_read(db,0));
    497         printk("[8606]reg1=0x%04x ",dm8606_read(db,0x1));
    498 #endif
    499         /* Init driver variable */
    500         db->reset_counter         = 0;
    501         db->reset_tx_timeout         = 0;
    502         db->cont_rx_pkt_cnt        = 0;
    503         
    504         /* check link state and media speed */
    505         db->Speed =10;
    506         i=0;
    507         do {
    508                 reg_nsr = ior(db,DM9KS_NSR);
    509                 if(reg_nsr & 0x40) /* link OK!! */
    510                 {
    511                         /* wait for detected Speed */
    512                         mdelay(200);
    513                         reg_nsr = ior(db,DM9KS_NSR);
    514                         if(reg_nsr & 0x80)
    515                                 db->Speed =10;
    516                         else
    517                                 db->Speed =100;
    518                         break;
    519                 }
    520                 i++;
    521                 mdelay(1);
    522         }while(i<3000);        /* wait 3 second */
    523         //printk("i=%d Speed=%d ",i,db->Speed);        
    524         /* set and active a timer process */
    525         init_timer(&db->timer);
    526         db->timer.expires         = DMFE_TIMER_WUT;
    527         db->timer.data                 = (unsigned long)dev;
    528         db->timer.function         = &dmfe_timer;
    529         add_timer(&db->timer);        //Move to DM9000 initiallization was finished.
    530         
    531         netif_start_queue(dev);
    532
    533         return 0;
    534 }
    535
    536 /* Set PHY operationg mode
    537 */
    538 static void set_PHY_mode(board_info_t *db)
    539 {
    540 #ifndef DM8606
    541         u16 phy_reg0 = 0x1000;/* Auto-negotiation*/
    542         u16 phy_reg4 = 0x01e1;
    543
    544         if ( !(db->op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */
    545         {
    546                 switch(db->op_mode) {
    547                         case DM9KS_10MHD: phy_reg4 = 0x21;
    548          phy_reg0 = 0x1000;
    549                                          break;
    550                         case DM9KS_10MFD: phy_reg4 = 0x41;
    551                                          phy_reg0 = 0x1100;
    552          break;
    553                         case DM9KS_100MHD: phy_reg4 = 0x81;
    554                                          phy_reg0 = 0x3000;
    555                                           break;
    556                         case DM9KS_100MFD: phy_reg4 = 0x101;
    557                                          phy_reg0 = 0x3100;
    558                                           break;
    559                         default:
    560                                          break;
    561                 } // end of switch
    562         } // end of if
    563 #ifdef FLOW_CONTROL
    564         phy_write(db, 4, phy_reg4|(1<<10));
    565 #else
    566         phy_write(db, 4, phy_reg4);
    567 #endif //end of FLOW_CONTROL
    568         phy_write(db, 0, phy_reg0|0x200);
    569 #else
    570         /* Fiber mode */
    571         phy_write(db, 16, 0x4014);
    572         phy_write(db, 0, 0x2100);
    573 #endif //end of DM8606
    574
    575         if (db->chip_revision == 0x1A)
    576         {
    577                 //set 10M TX idle =65mA (TX 100% utility is 160mA)
    578                 phy_write(db,20, phy_read(db,20)|(1<<11)|(1<<10));
    579                 
    580                 //:fix harmonic
    581                 //For short code:
    582                 //PHY_REG 27 (1Bh) <- 0000h
    583                 phy_write(db, 27, 0x0000);
    584                 //PHY_REG 27 (1Bh) <- AA00h
    585                 phy_write(db, 27, 0xaa00);
    586
    587                 //PHY_REG 27 (1Bh) <- 0017h
    588                 phy_write(db, 27, 0x0017);
    589                 //PHY_REG 27 (1Bh) <- AA17h
    590                 phy_write(db, 27, 0xaa17);
    591
    592                 //PHY_REG 27 (1Bh) <- 002Fh
    593                 phy_write(db, 27, 0x002f);
    594                 //PHY_REG 27 (1Bh) <- AA2Fh
    595                 phy_write(db, 27, 0xaa2f);
    596                 
    597                 //PHY_REG 27 (1Bh) <- 0037h
    598                 phy_write(db, 27, 0x0037);
    599                 //PHY_REG 27 (1Bh) <- AA37h
    600                 phy_write(db, 27, 0xaa37);
    601                 
    602                 //PHY_REG 27 (1Bh) <- 0040h
    603                 phy_write(db, 27, 0x0040);
    604                 //PHY_REG 27 (1Bh) <- AA40h
    605                 phy_write(db, 27, 0xaa40);
    606                 
    607                 //For long code:
    608                 //PHY_REG 27 (1Bh) <- 0050h
    609                 phy_write(db, 27, 0x0050);
    610                 //PHY_REG 27 (1Bh) <- AA50h
    611                 phy_write(db, 27, 0xaa50);
    612                 
    613                 //PHY_REG 27 (1Bh) <- 006Bh
    614                 phy_write(db, 27, 0x006b);
    615                 //PHY_REG 27 (1Bh) <- AA6Bh
    616                 phy_write(db, 27, 0xaa6b);
    617                 
    618                 //PHY_REG 27 (1Bh) <- 007Dh
    619                 phy_write(db, 27, 0x007d);
    620                 //PHY_REG 27 (1Bh) <- AA7Dh
    621                 phy_write(db, 27, 0xaa7d);
    622                 
    623                 //PHY_REG 27 (1Bh) <- 008Dh
    624                 phy_write(db, 27, 0x008d);
    625                 //PHY_REG 27 (1Bh) <- AA8Dh
    626                 phy_write(db, 27, 0xaa8d);
    627                 
    628                 //PHY_REG 27 (1Bh) <- 009Ch
    629                 phy_write(db, 27, 0x009c);
    630                 //PHY_REG 27 (1Bh) <- AA9Ch
    631                 phy_write(db, 27, 0xaa9c);
    632                 
    633                 //PHY_REG 27 (1Bh) <- 00A3h
    634                 phy_write(db, 27, 0x00a3);
    635                 //PHY_REG 27 (1Bh) <- AAA3h
    636                 phy_write(db, 27, 0xaaa3);
    637                 
    638                 //PHY_REG 27 (1Bh) <- 00B1h
    639                 phy_write(db, 27, 0x00b1);
    640                 //PHY_REG 27 (1Bh) <- AAB1h
    641                 phy_write(db, 27, 0xaab1);
    642                 
    643                 //PHY_REG 27 (1Bh) <- 00C0h
    644                 phy_write(db, 27, 0x00c0);
    645                 //PHY_REG 27 (1Bh) <- AAC0h
    646                 phy_write(db, 27, 0xaac0);
    647                 
    648                 //PHY_REG 27 (1Bh) <- 00D2h
    649                 phy_write(db, 27, 0x00d2);
    650                 //PHY_REG 27 (1Bh) <- AAD2h
    651                 phy_write(db, 27, 0xaad2);
    652                 
    653                 //PHY_REG 27 (1Bh) <- 00E0h
    654                 phy_write(db, 27, 0x00e0);
    655                 //PHY_REG 27 (1Bh) <- AAE0h
    656                 phy_write(db, 27, 0xaae0);
    657                 //PHY_REG 27 (1Bh) <- 0000h
    658                 phy_write(db, 27, 0x0000);
    659         }
    660 }
    661
    662 /*
    663         Initilize dm9000 board
    664 */
    665 static void dmfe_init_dm9000(struct net_device *dev)
    666 {
    667         board_info_t *db = (board_info_t *)dev->priv;
    668         DMFE_DBUG(0, "dmfe_init_dm9000()", 0);
    669
    670         spin_lock_init(&db->lock);
    671         
    672         iow(db, DM9KS_GPR, 0);        /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
    673         mdelay(20);                /* wait for PHY power-on ready */
    674
    675         /* do a software reset and wait 20us */
    676         iow(db, DM9KS_NCR, 3);
    677         udelay(20);                /* wait 20us at least for software reset ok */
    678         iow(db, DM9KS_NCR, 3);        /* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on */
    679         udelay(20);                /* wait 20us at least for software reset ok */
    680
    681         /* I/O mode */
    682         db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
    683
    684         /* Set PHY */
    685         db->op_mode = media_mode;
    686         set_PHY_mode(db);
    687
    688         /* Program operating register */
    689         iow(db, DM9KS_NCR, 0);
    690         iow(db, DM9KS_TCR, 0);                /* TX Polling clear */
    691         iow(db, DM9KS_BPTR, 0x3f);        /* Less 3kb, 600us */
    692         iow(db, DM9KS_SMCR, 0);                /* Special Mode */
    693         iow(db, DM9KS_NSR, 0x2c);        /* clear TX status */
    694         iow(db, DM9KS_ISR, 0x0f);         /* Clear interrupt status */
    695         iow(db, DM9KS_TCR2, 0x80);        /* Set LED mode 1 */
    696         if (db->chip_revision == 0x1A){
    697                 /* Data bus current driving/sinking capability */
    698                 iow(db, DM9KS_BUSCR, 0x01);        /* default: 2mA */
    699         }
    700 #ifdef FLOW_CONTROL
    701         iow(db, DM9KS_BPTR, 0x37);
    702         iow(db, DM9KS_FCTR, 0x38);
    703         iow(db, DM9KS_FCR, 0x29);
    704 #endif
    705
    706 #ifdef DM8606
    707         iow(db,0x34,1);
    708 #endif
    709
    710         if (dev->features & NETIF_F_HW_CSUM){
    711                 printk(KERN_INFO "DM9KS:enable TX checksum ");
    712                 iow(db, DM9KS_TCCR, 0x07);        /* TX UDP/TCP/IP checksum enable */
    713         }
    714         if (db->rx_csum){
    715                 printk(KERN_INFO "DM9KS:enable RX checksum ");
    716                 iow(db, DM9KS_RCSR, 0x02);        /* RX checksum enable */
    717         }
    718
    719 #ifdef ETRANS
    720         /*If TX loading is heavy, the driver can try to anbel "early transmit".
    721         The programmer can tune the "Early Transmit Threshold" to get
    722         the optimization. (DM9KS_ETXCSR.[1-0])
    723         
    724         Side Effect: It will happen "Transmit under-run". When TX under-run
    725         always happens, the programmer can increase the value of "Early
    726         Transmit Threshold". */
    727         iow(db, DM9KS_ETXCSR, 0x83);
    728 #endif
    729
    730         /* Set address filter table */
    731         dm9000_hash_table(dev);
    732
    733         /* Activate DM9000/DM9010 */
    734         iow(db, DM9KS_IMR, DM9KS_REGFF); /* Enable TX/RX interrupt mask */
    735         iow(db, DM9KS_RXCR, DM9KS_REG05 | 1);        /* RX enable */
    736         
    737         /* Init Driver variable */
    738         db->tx_pkt_cnt                 = 0;
    739                 
    740         netif_carrier_on(dev);
    741
    742 }
    743
    744 /*
    745 Hardware start transmission.
    746 Send a packet to media from the upper layer.
    747 */
    748 static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
    749 {
    750         board_info_t *db = (board_info_t *)dev->priv;
    751         char * data_ptr;
    752         int i, tmplen;
    753         u16 MDWAH, MDWAL;
    754         
    755         #ifdef TDBUG /* check TX FIFO pointer */
    756                         u16 MDWAH1, MDWAL1;
    757                         u16 tx_ptr;
    758         #endif
    759         
    760         DMFE_DBUG(0, "dmfe_start_xmit", 0);
    761         if (db->chip_revision != 0x1A)
    762         {        
    763                 if(db->Speed == 10)
    764                         {if (db->tx_pkt_cnt >= 1) return 1;}
    765                 else
    766                         {if (db->tx_pkt_cnt >= 2) return 1;}
    767         }else
    768                 if (db->tx_pkt_cnt >= 2) return 1;
    769         
    770         /* packet counting */
    771         db->tx_pkt_cnt++;
    772
    773         db->stats.tx_packets++;
    774         db->stats.tx_bytes+=skb->len;
    775         if (db->chip_revision != 0x1A)
    776         {
    777                 if (db->Speed == 10)
    778                         {if (db->tx_pkt_cnt >= 1) netif_stop_queue(dev);}
    779                 else
    780                         {if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);}
    781         }else
    782                 if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);                
    783
    784         /* Disable all interrupt */
    785         iow(db, DM9KS_IMR, DM9KS_DISINTR);
    786
    787         MDWAH = ior(db,DM9KS_MDWAH);
    788         MDWAL = ior(db,DM9KS_MDWAL);
    789
    790         /* Set TX length to reg. 0xfc & 0xfd */
    791         iow(db, DM9KS_TXPLL, (skb->len & 0xff));
    792         iow(db, DM9KS_TXPLH, (skb->len >> 8) & 0xff);
    793
    794         /* Move data to TX SRAM */
    795         data_ptr = (char *)skb->data;
    796         
    797         outb(DM9KS_MWCMD, db->io_addr); // Write data into SRAM trigger
    798         switch(db->io_mode)
    799         {
    800                 case DM9KS_BYTE_MODE:
    801                         for (i = 0; i < skb->len; i++)
    802                                 outb((data_ptr[i] & 0xff), db->io_data);
    803                         break;
    804                 case DM9KS_WORD_MODE:
    805                         tmplen = (skb->len + 1) / 2;
    806                         for (i = 0; i < tmplen; i++)
    807 outw(((u16 *)data_ptr)[i], db->io_data);
    808 break;
    809 case DM9KS_DWORD_MODE:
    810 tmplen = (skb->len + 3) / 4;                        
    811                         for (i = 0; i< tmplen; i++)
    812                                 outl(((u32 *)data_ptr)[i], db->io_data);
    813                         break;
    814         }
    815         
    816 #ifndef ETRANS
    817         /* Issue TX polling command */
    818         iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/
    819 #endif
    820
    821         #ifdef TDBUG /* check TX FIFO pointer */
    822                         MDWAH1 = ior(db,DM9KS_MDWAH);
    823                         MDWAL1 = ior(db,DM9KS_MDWAL);
    824                         tx_ptr = (MDWAH<<8)|MDWAL;
    825                         switch (db->io_mode)
    826                         {
    827                                 case DM9KS_BYTE_MODE:
    828                                         tx_ptr += skb->len;
    829                                         break;
    830                                 case DM9KS_WORD_MODE:
    831                                         tx_ptr += ((skb->len + 1) / 2)*2;
    832                                         break;
    833                                 case DM9KS_DWORD_MODE:
    834                                         tx_ptr += ((skb->len+3)/4)*4;
    835                                         break;
    836                         }
    837                         if (tx_ptr > 0x0bff)
    838                                         tx_ptr -= 0x0c00;
    839                         if (tx_ptr != ((MDWAH1<<8)|MDWAL1))
    840                                         printk("[dm9ks:TX FIFO ERROR ");
    841         #endif
    842         /* Saved the time stamp */
    843         dev->trans_start = jiffies;
    844         db->cont_rx_pkt_cnt =0;
    845
    846         /* Free this SKB */
    847         dev_kfree_skb(skb);
    848
    849         /* Re-enable interrupt */
    850         iow(db, DM9KS_IMR, DM9KS_REGFF);
    851
    852         return 0;
    853 }
    854
    855 /*
    856 Stop the interface.
    857 The interface is stopped when it is brought.
    858 */
    859 static int dmfe_stop(struct net_device *dev)
    860 {
    861         board_info_t *db = (board_info_t *)dev->priv;
    862         DMFE_DBUG(0, "dmfe_stop", 0);
    863
    864         /* deleted timer */
    865         del_timer(&db->timer);
    866
    867         netif_stop_queue(dev);
    868
    869         /* free interrupt */
    870         free_irq(dev->irq, dev);
    871
    872         /* RESET devie */
    873         phy_write(db, 0x00, 0x8000);        /* PHY RESET */
    874         //iow(db, DM9KS_GPR, 0x01);         /* Power-Down PHY */
    875         iow(db, DM9KS_IMR, DM9KS_DISINTR);        /* Disable all interrupt */
    876         iow(db, DM9KS_RXCR, 0x00);        /* Disable RX */
    877
    878         /* Dump Statistic counter */
    879 #if FALSE
    880         printk(" RX FIFO OVERFLOW %lx ", db->stats.rx_fifo_errors);
    881         printk("RX CRC %lx ", db->stats.rx_crc_errors);
    882         printk("RX LEN Err %lx ", db->stats.rx_length_errors);
    883         printk("RESET %x ", db->reset_counter);
    884         printk("RESET: TX Timeout %x ", db->reset_tx_timeout);
    885         printk("g_TX_nsr %x ", g_TX_nsr);
    886 #endif
    887
    888         return 0;
    889 }
    890
    891 static void dmfe_tx_done(unsigned long unused)
    892 {
    893         struct net_device *dev = dmfe_dev;
    894         board_info_t *db = (board_info_t *)dev->priv;
    895         int nsr;
    896
    897         DMFE_DBUG(0, "dmfe_tx_done()", 0);
    898         
    899         nsr = ior(db, DM9KS_NSR);
    900         if (nsr & 0x0c)
    901         {
    902                 if(nsr & 0x04) db->tx_pkt_cnt--;
    903                 if(nsr & 0x08) db->tx_pkt_cnt--;
    904                 if(db->tx_pkt_cnt < 0)
    905                 {
    906                         printk(KERN_DEBUG "DM9KS:tx_pkt_cnt ERROR!! ");
    907                         while(ior(db,DM9KS_TCR) & 0x1){}
    908                         db->tx_pkt_cnt = 0;
    909                 }
    910                         
    911         }else{
    912                 while(ior(db,DM9KS_TCR) & 0x1){}
    913                 db->tx_pkt_cnt = 0;
    914         }
    915                 
    916         netif_wake_queue(dev);
    917         
    918         return;
    919 }
    920
    921 /*
    922 DM9000 insterrupt handler
    923 receive the packet to upper layer, free the transmitted packet
    924 */
    925 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    926 static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    927 #else
    928         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
    929         static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    930         #else
    931         static irqreturn_t dmfe_interrupt(int irq, void *dev_id) /* for kernel 2.6.20*/
    932         #endif

    933 #endif
    934 {
    935         struct net_device *dev = dev_id;
    936         board_info_t *db;
    937         int int_status,i;
    938         u8 reg_save;
    939
    940         DMFE_DBUG(0, "dmfe_interrupt()", 0);
    941
    942         /* A real interrupt coming */
    943         db = (board_info_t *)dev->priv;
    944         spin_lock(&db->lock);
    945
    946         /* Save previous register address */
    947         reg_save = inb(db->io_addr);
    948
    949         /* Disable all interrupt */
    950         iow(db, DM9KS_IMR, DM9KS_DISINTR);
    951
    952         /* Got DM9000/DM9010 interrupt status */
    953         int_status = ior(db, DM9KS_ISR);                /* Got ISR */
    954         iow(db, DM9KS_ISR, int_status);                /* Clear ISR status */
    955
    956         /* Link status change */
    957         if (int_status & DM9KS_LINK_INTR)
    958         {
    959                 netif_stop_queue(dev);
    960                 for(i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
    961                 {
    962                         phy_read(db,0x1);
    963                         if(phy_read(db,0x1) & 0x4) /*Link OK*/
    964                         {
    965                                 /* wait for detected Speed */
    966                                 for(i=0; i<200;i++)
    967                                         udelay(1000);
    968                                 /* set media speed */
    969                                 if(phy_read(db,0)&0x2000) db->Speed =100;
    970                                 else db->Speed =10;
    971                                 break;
    972                         }
    973                         udelay(1000);
    974                 }
    975                 netif_wake_queue(dev);
    976                 //printk("[INTR]i=%d speed=%d ",i, (int)(db->Speed));        
    977         }
    978         /* Received the coming packet */
    979         if (int_status & DM9KS_RX_INTR)
    980                 dmfe_packet_receive(dev);
    981
    982         /* Trnasmit Interrupt check */
    983         if (int_status & DM9KS_TX_INTR)
    984                 dmfe_tx_done(0);
    985         
    986         if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
    987         {
    988                 iow(db, DM9KS_IMR, 0xa2);
    989         }
    990         else
    991         {
    992                 /* Re-enable interrupt mask */
    993                 iow(db, DM9KS_IMR, DM9KS_REGFF);
    994         }
    995         
    996         /* Restore previous register address */
    997         outb(reg_save, db->io_addr);
    998
    999         spin_unlock(&db->lock);
    1000 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
    1001         return IRQ_HANDLED;
    1002 #endif
    1003 }
    1004
    1005 /*
    1006 Get statistics from driver.
    1007 */
    1008 static struct net_device_stats * dmfe_get_stats(struct net_device *dev)
    1009 {
    1010         board_info_t *db = (board_info_t *)dev->priv;
    1011         DMFE_DBUG(0, "dmfe_get_stats", 0);
    1012         return &db->stats;
    1013 }
    1014 /*
    1015 *        Process the ethtool ioctl command
    1016 */
    1017 static int dmfe_ethtool_ioctl(struct net_device *dev, void *useraddr)
    1018 {
    1019         //struct dmfe_board_info *db = dev->priv;
    1020         struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
    1021         u32 ethcmd;
    1022
    1023         if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
    1024                 return -EFAULT;
    1025
    1026         switch (ethcmd)
    1027         {
    1028                 case ETHTOOL_GDRVINFO:
    1029                         strcpy(info.driver, DRV_NAME);
    1030                         strcpy(info.version, DRV_VERSION);
    1031
    1032                         sprintf(info.bus_info, "ISA 0x%lx %d",dev->base_addr, dev->irq);
    1033                         if (copy_to_user(useraddr, &info, sizeof(info)))
    1034                                 return -EFAULT;
    1035                         return 0;
    1036         }
    1037
    1038         return -EOPNOTSUPP;
    1039 }
    1040 /*
    1041 Process the upper socket ioctl command
    1042 */
    1043 static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
    1044 {
    1045         board_info_t *db = (board_info_t *)dev->priv;
    1046         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
    1047 struct mii_ioctl_data *data=(struct mii_ioctl_data *)&ifr->ifr_data;
    1048         #endif
    1049 int rc=0;
    1050         
    1051         DMFE_DBUG(0, "dmfe_do_ioctl()", 0);
    1052         
    1053         if (!netif_running(dev))
    1054                 return -EINVAL;
    1055
    1056         if (cmd == SIOCETHTOOL)
    1057 rc = dmfe_ethtool_ioctl(dev, (void *) ifr->ifr_data);
    1058         else {
    1059                 spin_lock_irq(&db->lock);
    1060                 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
    1061                         rc = generic_mii_ioctl(&db->mii, data, cmd, NULL);
    1062                 #else
    1063                         rc = generic_mii_ioctl(&db->mii, if_mii(ifr), cmd, NULL);
    1064                 #endif
    1065                 spin_unlock_irq(&db->lock);
    1066         }
    1067
    1068         return rc;
    1069 }
    1070
    1071 /* Our watchdog timed out. Called by the networking layer */
    1072 static void dmfe_timeout(struct net_device *dev)
    1073 {
    1074         board_info_t *db = (board_info_t *)dev->priv;
    1075         int i;
    1076         
    1077         DMFE_DBUG(0, "dmfe_TX_timeout()", 0);
    1078         printk("TX time-out -- dmfe_timeout(). ");
    1079         db->reset_tx_timeout++;
    1080         db->stats.tx_errors++;
    1081         
    1082 #if FALSE
    1083         printk("TX packet count = %d ", db->tx_pkt_cnt);        
    1084         printk("TX timeout = %d ", db->reset_tx_timeout);        
    1085         printk("22H=0x%02x 23H=0x%02x ",ior(db,0x22),ior(db,0x23));
    1086         printk("faH=0x%02x fbH=0x%02x ",ior(db,0xfa),ior(db,0xfb));
    1087 #endif
    1088
    1089         i=0;
    1090
    1091         while((i++<100)&&(ior(db,DM9KS_TCR) & 0x01))
    1092         {
    1093                 udelay(30);
    1094         }
    1095                 
    1096         if(i<100)
    1097         {
    1098                         db->tx_pkt_cnt = 0;
    1099                         netif_wake_queue(dev);
    1100         }
    1101         else
    1102         {
    1103                         dmfe_reset(dev);
    1104         }
    1105
    1106 }
    1107
    1108 static void dmfe_reset(struct net_device * dev)
    1109 {
    1110         board_info_t *db = (board_info_t *)dev->priv;
    1111         u8 reg_save;
    1112         int i;
    1113         /* Save previous register address */
    1114         reg_save = inb(db->io_addr);
    1115
    1116         netif_stop_queue(dev);
    1117         db->reset_counter++;
    1118         dmfe_init_dm9000(dev);
    1119         
    1120         db->Speed =10;
    1121         for(i=0; i<1000; i++) /*wait link OK, waiting time=1 second */
    1122         {
    1123                 if(phy_read(db,0x1) & 0x4) /*Link OK*/
    1124                 {
    1125                         if(phy_read(db,0)&0x2000) db->Speed =100;
    1126                         else db->Speed =10;
    1127                         break;
    1128                 }
    1129                 udelay(1000);
    1130         }
    1131         
    1132         netif_wake_queue(dev);
    1133         
    1134         /* Restore previous register address */
    1135         outb(reg_save, db->io_addr);
    1136
    1137 }
    1138 /*
    1139 A periodic timer routine
    1140 */
    1141 static void dmfe_timer(unsigned long data)
    1142 {
    1143         struct net_device * dev = (struct net_device *)data;
    1144         board_info_t *db = (board_info_t *)dev->priv;
    1145         DMFE_DBUG(0, "dmfe_timer()", 0);
    1146         
    1147         if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
    1148         {
    1149                 db->cont_rx_pkt_cnt=0;
    1150                 iow(db, DM9KS_IMR, DM9KS_REGFF);
    1151         }
    1152         /* Set timer again */
    1153         db->timer.expires = DMFE_TIMER_WUT;
    1154         add_timer(&db->timer);
    1155         
    1156         return;
    1157 }
    1158
    1159
    1160 /*
    1161 Received a packet and pass to upper layer
    1162 */
    1163 static void dmfe_packet_receive(struct net_device *dev)
    1164 {
    1165         board_info_t *db = (board_info_t *)dev->priv;
    1166         struct sk_buff *skb;
    1167         u8 rxbyte;
    1168         u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;
    1169         u32 tmpdata;
    1170
    1171         rx_t rx;
    1172
    1173         u16 * ptr = (u16*)&rx;
    1174         u8* rdptr;
    1175
    1176         DMFE_DBUG(0, "dmfe_packet_receive()", 0);
    1177
    1178         db->cont_rx_pkt_cnt=0;
    1179         
    1180         do {
    1181                 /*store the value of Memory Data Read address register*/
    1182                 MDRAH=ior(db, DM9KS_MDRAH);
    1183                 MDRAL=ior(db, DM9KS_MDRAL);
    1184                 
    1185                 ior(db, DM9KS_MRCMDX);                /* Dummy read */
    1186                 rxbyte = inb(db->io_data);        /* Got most updated data */
    1187
    1188 #ifdef CHECKSUM        
    1189                 if (rxbyte&0x2)                        /* check RX byte */
    1190                 {        
    1191 printk("dm9ks: abnormal! ");
    1192                         dmfe_reset(dev);
    1193                         break;        
    1194 }else {
    1195 if (!(rxbyte&0x1))
    1196                                 break;        
    1197 }                
    1198 #else
    1199                 if (rxbyte==0)
    1200                         break;
    1201                 
    1202                 if (rxbyte>1)
    1203                 {        
    1204 printk("dm9ks: Rxbyte error! ");
    1205                  dmfe_reset(dev);
    1206 break;        
    1207 }
    1208 #endif
    1209
    1210                 /* A packet ready now & Get status/length */
    1211                 GoodPacket = TRUE;
    1212                 outb(DM9KS_MRCMD, db->io_addr);
    1213
    1214                 /* Read packet status & length */
    1215                 switch (db->io_mode)
    1216                         {
    1217                          case DM9KS_BYTE_MODE:
    1218                                  *ptr = inb(db->io_data) +
    1219                                  (inb(db->io_data) << 8);
    1220                                  *(ptr+1) = inb(db->io_data) +
    1221                                          (inb(db->io_data) << 8);
    1222                                  break;
    1223                          case DM9KS_WORD_MODE:
    1224                                  *ptr = inw(db->io_data);
    1225                                  *(ptr+1) = inw(db->io_data);
    1226                                  break;
    1227                          case DM9KS_DWORD_MODE:
    1228                                  tmpdata = inl(db->io_data);
    1229                                  *ptr = tmpdata;
    1230                                  *(ptr+1) = tmpdata >> 16;
    1231                                  break;
    1232                          default:
    1233                                  break;
    1234                         }
    1235
    1236                 /* Packet status check */
    1237                 if (rx.desc.status & 0xbf)
    1238                 {
    1239                         GoodPacket = FALSE;
    1240                         if (rx.desc.status & 0x01)
    1241                         {
    1242                                 db->stats.rx_fifo_errors++;
    1243                                 printk(KERN_INFO"<RX FIFO error> ");
    1244                         }
    1245                         if (rx.desc.status & 0x02)
    1246                         {
    1247                                 db->stats.rx_crc_errors++;
    1248                                 printk(KERN_INFO"<RX CRC error> ");
    1249                         }
    1250                         if (rx.desc.status & 0x80)
    1251                         {
    1252                                 db->stats.rx_length_errors++;
    1253                                 printk(KERN_INFO"<RX Length error> ");
    1254                         }
    1255                         if (rx.desc.status & 0x08)
    1256                                 printk(KERN_INFO"<Physical Layer error> ");
    1257                 }
    1258
    1259                 if (!GoodPacket)
    1260                 {
    1261                         // drop this packet!!!
    1262                         switch (db->io_mode)
    1263                         {
    1264                                 case DM9KS_BYTE_MODE:
    1265                                          for (i=0; i<rx.desc.length; i++)
    1266                                                 inb(db->io_data);
    1267                                         break;
    1268                                 case DM9KS_WORD_MODE:
    1269                                         tmplen = (rx.desc.length + 1) / 2;
    1270                                         for (i = 0; i < tmplen; i++)
    1271                                                 inw(db->io_data);
    1272                                         break;
    1273                                 case DM9KS_DWORD_MODE:
    1274                                         tmplen = (rx.desc.length + 3) / 4;
    1275                                         for (i = 0; i < tmplen; i++)
    1276                                                 inl(db->io_data);
    1277                                         break;
    1278                         }
    1279                         continue;/*next the packet*/
    1280                 }
    1281                 
    1282                 skb = dev_alloc_skb(rx.desc.length+4);
    1283                 if (skb == NULL )
    1284                 {        
    1285                         printk(KERN_INFO "%s: Memory squeeze. ", dev->name);
    1286                         /*re-load the value into Memory data read address register*/
    1287                         iow(db,DM9KS_MDRAH,MDRAH);
    1288                         iow(db,DM9KS_MDRAL,MDRAL);
    1289                         return;
    1290                 }
    1291                 else
    1292                 {
    1293                         /* Move data from DM9000 */
    1294                         skb->dev = dev;
    1295                         skb_reserve(skb, 2);
    1296                         rdptr = (u8*)skb_put(skb, rx.desc.length - 4);
    1297                         
    1298                         /* Read received packet from RX SARM */
    1299                         switch (db->io_mode)
    1300                         {
    1301                                 case DM9KS_BYTE_MODE:
    1302                                          for (i=0; i<rx.desc.length; i++)
    1303                                                 rdptr[i]=inb(db->io_data);
    1304                                         break;
    1305                                 case DM9KS_WORD_MODE:
    1306                                         tmplen = (rx.desc.length + 1) / 2;
    1307                                         for (i = 0; i < tmplen; i++)
    1308                                                 ((u16 *)rdptr)[i] = inw(db->io_data);
    1309                                         break;
    1310                                 case DM9KS_DWORD_MODE:
    1311                                         tmplen = (rx.desc.length + 3) / 4;
    1312                                         for (i = 0; i < tmplen; i++)
    1313                                                 ((u32 *)rdptr)[i] = inl(db->io_data);
    1314                                         break;
    1315                         }
    1316                 
    1317                         /* Pass to upper layer */
    1318                         skb->protocol = eth_type_trans(skb,dev);
    1319
    1320 #ifdef CHECKSUM
    1321                 if((rxbyte&0xe0)==0)        /* receive packet no checksum fail */
    1322                                 skb->ip_summed = CHECKSUM_UNNECESSARY;
    1323 #endif
    1324                 
    1325                         netif_rx(skb);
    1326                         dev->last_rx=jiffies;
    1327                         db->stats.rx_packets++;
    1328                         db->stats.rx_bytes += rx.desc.length;
    1329                         db->cont_rx_pkt_cnt++;
    1330 #ifdef RDBG /* check RX FIFO pointer */
    1331                         u16 MDRAH1, MDRAL1;
    1332                         u16 tmp_ptr;
    1333                         MDRAH1 = ior(db,DM9KS_MDRAH);
    1334                         MDRAL1 = ior(db,DM9KS_MDRAL);
    1335                         tmp_ptr = (MDRAH<<8)|MDRAL;
    1336                         switch (db->io_mode)
    1337                         {
    1338                                 case DM9KS_BYTE_MODE:
    1339                                         tmp_ptr += rx.desc.length+4;
    1340                                         break;
    1341                                 case DM9KS_WORD_MODE:
    1342                                         tmp_ptr += ((rx.desc.length+1)/2)*2+4;
    1343                                         break;
    1344                                 case DM9KS_DWORD_MODE:
    1345                                         tmp_ptr += ((rx.desc.length+3)/4)*4+4;
    1346                                         break;
    1347                         }
    1348                         if (tmp_ptr >=0x4000)
    1349                                 tmp_ptr = (tmp_ptr - 0x4000) + 0xc00;
    1350                         if (tmp_ptr != ((MDRAH1<<8)|MDRAL1))
    1351                                 printk("[dm9ks:RX FIFO ERROR ");
    1352 #endif
    1353                                 
    1354                         if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
    1355                         {
    1356                                 dmfe_tx_done(0);
    1357                                 break;
    1358                         }
    1359                 }
    1360                         
    1361         }while((rxbyte & 0x01) == DM9KS_PKT_RDY);
    1362         DMFE_DBUG(0, "[END]dmfe_packet_receive()", 0);
    1363         
    1364 }
    1365
    1366 /*
    1367 Read a word data from SROM
    1368 */
    1369 static u16 read_srom_word(board_info_t *db, int offset)
    1370 {
    1371         iow(db, DM9KS_EPAR, offset);
    1372         iow(db, DM9KS_EPCR, 0x4);
    1373         while(ior(db, DM9KS_EPCR)&0x1);        /* Wait read complete */
    1374         iow(db, DM9KS_EPCR, 0x0);
    1375         return (ior(db, DM9KS_EPDRL) + (ior(db, DM9KS_EPDRH) << 8) );
    1376 }
    1377
    1378 /*
    1379 Set DM9000/DM9010 multicast address
    1380 */
    1381 static void dm9000_hash_table(struct net_device *dev)
    1382 {
    1383         board_info_t *db = (board_info_t *)dev->priv;
    1384         struct dev_mc_list *mcptr = dev->mc_list;
    1385         int mc_cnt = dev->mc_count;
    1386         u32 hash_val;
    1387         u16 i, oft, hash_table[4];
    1388
    1389         DMFE_DBUG(0, "dm9000_hash_table()", 0);
    1390
    1391         /* enable promiscuous mode */
    1392         if (dev->flags & IFF_PROMISC){
    1393                 //printk(KERN_INFO "DM9KS:enable promiscuous mode ");
    1394                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<1));
    1395                 return;
    1396         }else{
    1397                 //printk(KERN_INFO "DM9KS:disable promiscuous mode ");
    1398                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<1)));
    1399         }
    1400                 
    1401         /* Receive all multicast packets */
    1402         if (dev->flags & IFF_ALLMULTI){
    1403                 //printk(KERN_INFO "DM9KS:Pass all multicast ");
    1404                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<3));
    1405         }else{
    1406                 //printk(KERN_INFO "DM9KS:Disable pass all multicast ");
    1407                 iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<3)));
    1408         }
    1409         
    1410         /* Set Node address */
    1411         for (i = 0, oft = 0x10; i < 6; i++, oft++)
    1412                 iow(db, oft, dev->dev_addr[i]);
    1413
    1414         /* Clear Hash Table */
    1415         for (i = 0; i < 4; i++)
    1416                 hash_table[i] = 0x0;
    1417
    1418         /* broadcast address */
    1419         hash_table[3] = 0x8000;
    1420
    1421         /* the multicast address in Hash Table : 64 bits */
    1422         for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
    1423                 hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f;
    1424                 hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
    1425         }
    1426
    1427         /* Write the hash table to MAC MD table */
    1428         for (i = 0, oft = 0x16; i < 4; i++) {
    1429                 iow(db, oft++, hash_table[i] & 0xff);
    1430                 iow(db, oft++, (hash_table[i] >> 8) & 0xff);
    1431         }
    1432 }
    1433
    1434 /*
    1435 Calculate the CRC valude of the Rx packet
    1436 flag = 1 : return the reverse CRC (for the received packet CRC)
    1437 0 : return the normal CRC (for Hash Table index)
    1438 */
    1439 static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
    1440 {        
    1441         u32 crc = ether_crc_le(Len, Data);
    1442
    1443         if (flag)
    1444                 return ~crc;
    1445                 
    1446         return crc;        
    1447 }
    1448
    1449 static int mdio_read(struct net_device *dev, int phy_id, int location)
    1450 {
    1451         board_info_t *db = (board_info_t *)dev->priv;
    1452         return phy_read(db, location);
    1453 }
    1454
    1455 static void mdio_write(struct net_device *dev, int phy_id, int location, int val)
    1456 {
    1457         board_info_t *db = (board_info_t *)dev->priv;
    1458         phy_write(db, location, val);
    1459 }
    1460
    1461 /*
    1462 Read a byte from I/O port
    1463 */
    1464 u8 ior(board_info_t *db, int reg)
    1465 {
    1466         outb(reg, db->io_addr);
    1467         return inb(db->io_data);
    1468 }
    1469
    1470 /*
    1471 Write a byte to I/O port
    1472 */
    1473 void iow(board_info_t *db, int reg, u8 value)
    1474 {
    1475         outb(reg, db->io_addr);
    1476         outb(value, db->io_data);
    1477 }
    1478
    1479 /*
    1480 Read a word from phyxcer
    1481 */
    1482 static u16 phy_read(board_info_t *db, int reg)
    1483 {
    1484         /* Fill the phyxcer register into REG_0C */
    1485         iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
    1486
    1487         iow(db, DM9KS_EPCR, 0xc);         /* Issue phyxcer read command */
    1488         while(ior(db, DM9KS_EPCR)&0x1);        /* Wait read complete */
    1489         iow(db, DM9KS_EPCR, 0x0);         /* Clear phyxcer read command */
    1490
    1491         /* The read data keeps on REG_0D & REG_0E */
    1492         return ( ior(db, DM9KS_EPDRH) << 8 ) | ior(db, DM9KS_EPDRL);
    1493         
    1494 }
    1495
    1496 /*
    1497 Write a word to phyxcer
    1498 */
    1499 static void phy_write(board_info_t *db, int reg, u16 value)
    1500 {
    1501         /* Fill the phyxcer register into REG_0C */
    1502         iow(db, DM9KS_EPAR, DM9KS_PHY | reg);
    1503
    1504         /* Fill the written data into REG_0D & REG_0E */
    1505         iow(db, DM9KS_EPDRL, (value & 0xff));
    1506         iow(db, DM9KS_EPDRH, ( (value >> 8) & 0xff));
    1507
    1508         iow(db, DM9KS_EPCR, 0xa);        /* Issue phyxcer write command */
    1509         while(ior(db, DM9KS_EPCR)&0x1);        /* Wait read complete */
    1510         iow(db, DM9KS_EPCR, 0x0);        /* Clear phyxcer write command */
    1511 }
    1512 //====dmfe_ethtool_ops member functions====
    1513 static void dmfe_get_drvinfo(struct net_device *dev,
    1514                          struct ethtool_drvinfo *info)
    1515 {
    1516         //board_info_t *db = (board_info_t *)dev->priv;
    1517         strcpy(info->driver, DRV_NAME);
    1518         strcpy(info->version, DRV_VERSION);
    1519         sprintf(info->bus_info, "ISA 0x%lx irq=%d",dev->base_addr, dev->irq);
    1520 }
    1521 static int dmfe_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
    1522 {
    1523         board_info_t *db = (board_info_t *)dev->priv;
    1524         spin_lock_irq(&db->lock);
    1525         mii_ethtool_gset(&db->mii, cmd);
    1526         spin_unlock_irq(&db->lock);
    1527         return 0;
    1528 }
    1529 static int dmfe_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
    1530 {
    1531         board_info_t *db = (board_info_t *)dev->priv;
    1532         int rc;
    1533
    1534         spin_lock_irq(&db->lock);
    1535         rc = mii_ethtool_sset(&db->mii, cmd);
    1536         spin_unlock_irq(&db->lock);
    1537         return rc;
    1538 }
    1539 /*
    1540 * Check the link state
    1541 */
    1542 static u32 dmfe_get_link(struct net_device *dev)
    1543 {
    1544         board_info_t *db = (board_info_t *)dev->priv;
    1545         return mii_link_ok(&db->mii);
    1546 }
    1547
    1548 /*
    1549 * Reset Auto-negitiation
    1550 */
    1551 static int dmfe_nway_reset(struct net_device *dev)
    1552 {
    1553         board_info_t *db = (board_info_t *)dev->priv;
    1554         return mii_nway_restart(&db->mii);
    1555 }
    1556 /*
    1557 * Get RX checksum offload state
    1558 */
    1559 static uint32_t dmfe_get_rx_csum(struct net_device *dev)
    1560 {
    1561         board_info_t *db = (board_info_t *)dev->priv;
    1562         return db->rx_csum;
    1563 }
    1564 /*
    1565 * Get TX checksum offload state
    1566 */
    1567 static uint32_t dmfe_get_tx_csum(struct net_device *dev)
    1568 {
    1569         return (dev->features & NETIF_F_HW_CSUM) != 0;
    1570 }
    1571 /*
    1572 * Enable/Disable RX checksum offload
    1573 */
    1574 static int dmfe_set_rx_csum(struct net_device *dev, uint32_t data)
    1575 {
    1576 #ifdef CHECKSUM
    1577         board_info_t *db = (board_info_t *)dev->priv;
    1578         db->rx_csum = data;
    1579
    1580         if(netif_running(dev)) {
    1581                 dmfe_stop(dev);
    1582                 dmfe_open(dev);
    1583         } else
    1584                 dmfe_init_dm9000(dev);
    1585 #else
    1586         printk(KERN_ERR "DM9:Don't support checksum ");
    1587 #endif
    1588         return 0;
    1589 }
    1590 /*
    1591 * Enable/Disable TX checksum offload
    1592 */
    1593 static int dmfe_set_tx_csum(struct net_device *dev, uint32_t data)
    1594 {
    1595 #ifdef CHECKSUM
    1596         if (data)
    1597                 dev->features |= NETIF_F_HW_CSUM;
    1598         else
    1599                 dev->features &= ~NETIF_F_HW_CSUM;
    1600 #else
    1601         printk(KERN_ERR "DM9:Don't support checksum ");
    1602 #endif
    1603
    1604         return 0;
    1605 }
    1606 //=========================================
    1607 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28) /* for kernel 2.4.28 */
    1608 static struct ethtool_ops dmfe_ethtool_ops = {
    1609         .get_drvinfo                = dmfe_get_drvinfo,
    1610         .get_settings                = dmfe_get_settings,
    1611         .set_settings                = dmfe_set_settings,
    1612         .get_link                        = dmfe_get_link,
    1613         .nway_reset                = dmfe_nway_reset,
    1614         .get_rx_csum                = dmfe_get_rx_csum,
    1615         .set_rx_csum                = dmfe_set_rx_csum,
    1616         .get_tx_csum                = dmfe_get_tx_csum,
    1617         .set_tx_csum                = dmfe_set_tx_csum,
    1618 };
    1619 #endif
    1620
    1621 #define MODULE
    1622 #ifdef MODULE
    1623
    1624 MODULE_LICENSE("GPL");
    1625 MODULE_DESCRIPTION("Davicom DM9000/DM9010 ISA/uP Fast Ethernet Driver");
    1626 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    1627 MODULE_PARM(mode, "i");
    1628 MODULE_PARM(irq, "i");
    1629 MODULE_PARM(iobase, "i");
    1630 #else
    1631 module_param(mode, int, 0);
    1632 module_param(irq, int, 0);
    1633 module_param(iobase, int, 0);
    1634 #endif
    1635 MODULE_PARM_DESC(mode,"Media Speed, 0:10MHD, 1:10MFD, 4:100MHD, 5:100MFD");
    1636 MODULE_PARM_DESC(irq,"EtherLink IRQ number");
    1637 MODULE_PARM_DESC(iobase, "EtherLink I/O base address");
    1638
    1639 /* Description:
    1640 when user used insmod to add module, system invoked init_module()
    1641 to initilize and register.
    1642 */
    1643 //lhc
    1644 static volatile unsigned long bwscon;
    1645 static volatile unsigned long bankcon4;
    1646
    1647 static int __init dm9000c_init(void)
    1648 {
    1649         //lhc
    1650         unsigned long val;
    1651         
    1652         irq = IRQ_EINT7;
    1653         io_base = ioremap(0x20000000, 1024);
    1654
    1655         bwscon = ioremap(0x48000000, 4);
    1656         bankcon4 = ioremap(0x48000014, 4);
    1657
    1658         val = *bwscon;
    1659         val &= ~(0xf<<16);
    1660         val |= (1<<16);
    1661         *bwscon = val;
    1662
    1663         *bankcon4 = (1<<6);
    1664         //lhc¡ª¡ªend
    1665
    1666         switch(mode) {
    1667                 case DM9KS_10MHD:
    1668                 case DM9KS_100MHD:
    1669                 case DM9KS_10MFD:
    1670                 case DM9KS_100MFD:
    1671                         media_mode = mode;
    1672                         break;
    1673                 default:
    1674                         media_mode = DM9KS_AUTO;
    1675         }
    1676         dmfe_dev = dmfe_probe();
    1677         if(IS_ERR(dmfe_dev))
    1678                 return PTR_ERR(dmfe_dev);
    1679         return 0;
    1680 }
    1681 /* Description:
    1682 when user used rmmod to delete module, system invoked clean_module()
    1683 to un-register DEVICE.
    1684 */
    1685 static void __exit dm9000c_exit(void)
    1686 {
    1687         struct net_device *dev = dmfe_dev;
    1688         DMFE_DBUG(0, "clean_module()", 0);
    1689
    1690         iounmap(io_base);//lhc
    1691         ioremap(bwscon);
    1692         ioremap(bankcon4);
    1693
    1694         unregister_netdev(dmfe_dev);
    1695         release_region(dev->base_addr, 2);
    1696 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    1697         kfree(dev);
    1698 #else
    1699         free_netdev(dev);
    1700 #endif
    1701         
    1702         DMFE_DBUG(0, "clean_module() exit", 0);
    1703 }
    1704
    1705 module_init(dm9000c_init);
    1706 module_exit(dm9000c_exit);
    1707 #endif

       

    虚拟网卡

     

    老师的笔记

    网卡驱动程序框架:

       

    app: socket

    --------------------------------------------------

    ---------------

    --------------- 若干层网络协议--纯软件

    ---------------

    ---------------

                 /

    hard_start_xmit ||

    || netif_rx sk_buff

    /

    ---------------

    硬件相关的驱动程序(要提供hard_start_xmit, 有数据时要用netif_rx上报)

    --------------------------------------------------

    硬件

     

    怎么写网卡驱动程序?

    1. 分配一个net_device结构体

    2. 设置:

    2.1 发包函数: hard_start_xmit

    2.2 收到数据时(在中断处理函数里)用netif_rx上报数据

    2.3 其他设置

    3. 注册: register_netdevice

       

       

    测试1th/2th:

    1. insmod virt_net.ko

    2. ifconfig vnet0 3.3.3.3

    ifconfig // 查看

    3. ping 3.3.3.3 // 成功

    ping 3.3.3.4 // 死机

       

       

    测试DM9000C驱动程序:

    1. 把dm9dev9000c.c放到内核的drivers/net目录下

    2. 修改drivers/net/Makefile

    obj-$(CONFIG_DM9000) += dm9000.o

    改为

    obj-$(CONFIG_DM9000) += dm9dev9000c.o

    3. make uImage

    使用新内核启动

    4.

    使用NFS启动

    ifconfig eth0 192.168.1.17

    ping 192.168.1.1

     

       

    虚拟网卡——源码

    1 /*
    2 * 参考.linux-2.6.22.6drivers etcs89x0.c
    3 */
    4 #include <linux/module.h>
    5 #include <linux/errno.h>
    6 #include <linux/netdevice.h>
    7 #include <linux/etherdevice.h>
    8 #include <linux/kernel.h>
    9 #include <linux/types.h>
    10 #include <linux/fcntl.h>
    11 #include <linux/interrupt.h>
    12 #include <linux/ioport.h>
    13 #include <linux/in.h>
    14 #include <linux/skbuff.h>
    15 #include <linux/slab.h>
    16 #include <linux/spinlock.h>
    17 #include <linux/string.h>
    18 #include <linux/init.h>
    19 #include <linux/bitops.h>
    20 #include <linux/delay.h>
    21 #include <linux/ip.h>
    22         
    23 #include <asm/system.h>
    24 #include <asm/io.h>
    25 #include <asm/irq.h>
    26
    27
    28 static struct net_device *vnet_dev;
    29
    30 //造假
    31 static void emulator_rx_packet(skb, dev)
    32 {
    33         /* 参考LDD3 */
    34         unsigned char *type;
    35         struct iphdr *ih;
    36         __be32 *saddr, *daddr, tmp;
    37         unsigned char        tmp_dev_addr[ETH_ALEN];
    38         struct ethhdr *ethhdr;
    39         
    40         struct sk_buff *rx_skb;
    41                 
    42         // 从硬件读出/保存数据
    43         /* 对调"源/目的"的mac地址 */
    44         ethhdr = (struct ethhdr *)skb->data;
    45         memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);
    46         memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);
    47         memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);
    48
    49         /* 对调"源/目的"的ip地址 */
    50         ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
    51         saddr = &ih->saddr;
    52         daddr = &ih->daddr;
    53
    54         tmp = *saddr;
    55         *saddr = *daddr;
    56         *daddr = tmp;
    57         
    58         //((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
    59         //((u8 *)daddr)[2] ^= 1;
    60         type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);
    61         //printk("tx package type = %02x ", *type);
    62         // 修改类型, 原来0x8表示ping
    63         *type = 0; /* 0表示reply */
    64         
    65         ih->check = 0;                 /* and rebuild the checksum (ip needs it) */
    66         ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
    67         
    68         // 构造一个sk_buff
    69         rx_skb = dev_alloc_skb(skb->len + 2);
    70         skb_reserve(rx_skb, 2); /* align IP on 16B boundary */        
    71         memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);
    72
    73         /* Write metadata, and then pass to the receive level */
    74         rx_skb->dev = dev;
    75         rx_skb->protocol = eth_type_trans(rx_skb, dev);
    76         rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
    77         dev->stats.rx_packets++;
    78         dev->stats.rx_bytes += skb->len;
    79
    80         // 提交sk_buff
    81         netif_rx(rx_skb);
    82 }
    83
    84
    85 static int virt_net_send_packet(struct sk_buff* skb, struct net_device *dev)
    86 {
    87         static int cnt = 0;
    88
    89         printk("virt_net_send_packet: %d", cnt++);
    90
    91         /* 对于真是的网卡,把skb里的数据通过网卡发送出去 */
    92         netif_stop_queue(dev);        //停止该网卡的队列
    93
    94         //......                                //把skb数据写入网卡
    95
    96         emulator_rx_packet(skb, dev);        //构造一个假包上报
    97
    98         dev_kfree_skb(skb);                //释放skb
    99         netif_wake_queue(dev);        //(真实是放在中断里)数据全部发送出去后,唤醒网卡的队列
    100
    101         /* 更新统计信息 */
    102         dev->stats.tx_packets ++;
    103         dev->stats.tx_bytes += skb->len;
    104
    105
    106         return 0;
    107 }
    108
    109
    110 /* 1 出、入口函数 */
    111 static int virt_net_init(void)
    112 {
    113         /* 2 分配 */
    114         vnet_dev = alloc_netdev(0, "vnet%d", vnet_dev);
    115         /******** 2 end ********/
    116
    117         /* 3 设置 */
    118         vnet_dev->hard_start_xmit = virt_net_send_packet;
    119
    120         //设置MAC地址
    121         vnet_dev->dev_addr[0] = 0x08;
    122         vnet_dev->dev_addr[1] = 0x89;
    123         vnet_dev->dev_addr[2] = 0x89;
    124         vnet_dev->dev_addr[3] = 0x89;
    125         vnet_dev->dev_addr[4] = 0x89;
    126         vnet_dev->dev_addr[5] = 0x11;
    127
    128         
    129         //设置下面两项才能ping通
    130         vnet_dev->flags                  |= IFF_NOARP;
    131         vnet_dev->features                 |= NETIF_F_NO_CSUM;        
    132         /******** 3 end ********/
    133
    134         /* 4 注册 */
    135         register_netdev(vnet_dev);
    136         /******** 4 end ********/
    137
    138         return 0;
    139 }
    140
    141
    142 static void virt_net_exit(void)
    143 {
    144         unregister_netdev(vnet_dev);
    145         kfree(vnet_dev);
    146         return;
    147 }
    148
    149 module_init(virt_net_init);
    150 module_exit(virt_net_exit);
    151
    152 MODULE_AUTHOR("XXX@163.com, XXX");
    153 MODULE_LICENSE("GPL");
    154 /******** 1 end ********/

  • 相关阅读:
    shell 指令
    在Linux下搭建nRF51822的开发烧写环境(makefile版)
    宏定义。字符串拼接和字符串整形转字符串
    django-debug-toolbar安装过程中的error
    pipenv
    Docker 命令大全
    MySQL性能优化
    docker操作
    使用网易源解决docker下载镜像文件慢的问题
    w3school/jQuery 教程
  • 原文地址:https://www.cnblogs.com/lilto/p/11878536.html
Copyright © 2020-2023  润新知