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

1、DM9000C的硬件连接

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

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

2、DM9000C的驱动代码编写

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

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

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

  • 1、将入口函数与出口函数改为模块,增加1721行与1722行,增加协议。去掉模块的宏定义1617、1724行
  • 2、看到dm9000c_init->dmfe_probe->dmfe_probe1中的416行,由于所有使用的dm9000c芯片版本号不满足此条件,所以直接去掉这一行注释掉。
  • 3、看到dmfe_open函数,这个函数在ifconfig后会被调用。里面的485行,更改中断方式为上升沿触发;看到dm9000c_init的1645行,更改中断引脚IRQ_EINT7
  • 4、更改网卡芯片数据地址,看到dm9000c_init的1644行,将实际地址0x20000000转换为虚拟地址后赋给iobase ,存储控制器的BANK4所控制的存储地址为0x20000000
  • 5、最后设置bwscon、bankcon4两个寄存器的值,他们可以控制BANK4的位宽、时序等信息。它的设置全部在dm9000c_init中。这里以读数据的Tacc时间参数做一下介绍,时序的参数是怎么设置的。直接贴图,其中左边为S3C2440的可以设置时间,右边是DM9000C需要设置的时间,可以看到Tacc时间对应的是DM9000C的T2参数,它主要至少10ns,那么我们设它为20ns,HCLK为100Mhz,那么设置20ns需要2个时钟周期,所以Tacc[10:8]=001b。

 3、DM9000C的驱动测试

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

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

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

转载于:https://www.cnblogs.com/andyfly/p/11259515.html

DM9000C网卡驱动程序编写与测试相关推荐

  1. Linux网卡驱动程序编写

    Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...

  2. 嵌入式Linux驱动学习之路(二十六)DM9000C网卡驱动程序

    基于DM9000C的原厂代码修改dm9000c的驱动程序. 首先确认内存的基地址 iobase. 确定中断号码. 打开模块的初始化函数定义. 配置内存控制器的相应时序(结合DM9000C.C的手册). ...

  3. S3C2440 DMA驱动程序编写及测试(三十二)

    https://www.cnblogs.com/lifexy/p/7880737.html DMA(Direct Memory Access) 即直接存储访问,DMA传输方式无需CPU直接控制传输,通 ...

  4. 11-S3C2440驱动学习(五)嵌入式linux-网络设备驱动(一)虚拟网卡驱动程序

    本节是网卡驱动的入门基础部分,移植移植DM9000C网卡驱动程序 请看下节:移植DM9000C网卡驱动程序http://blog.csdn.net/fengyuwuzu0519/article/det ...

  5. linux 网卡的驱动程序,Linux网卡驱动程序代码

    广告 100%的CPU性能,计算能力不会降低!选择最主流的云服务器来满足各种业务需求,有数百种流行的云产品和8888元起价套餐,可帮助行业恢复工作! 获取网卡信息的代码示例. 通过命令获取arp(地址 ...

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

    20150419 S3C2440实现dm9000网卡驱动程序移植 2015-04-19 Lover雪儿 首先附上厂家提供的完整的dm9000程序: 1 /* 2 3 dm9ks.c: Version ...

  7. 网卡驱动程序框架和编写

    参考韦东山二期视频资料 网卡驱动程序框架 1.网卡驱动程序"收发功能" 2.编程步骤: 2.1设置net_device结构 2.2硬件相关设置 2.3接收到数据要做的事情 2.4发 ...

  8. linux 3.10 网卡驱动程序示例,网卡驱动程序框架以及虚拟网卡驱动程序的实现

    LINUX驱动程序分三大块:字符驱动程序.块设备驱动程序.网络驱动程序.其中网络驱动程序分为好多层协议层+与硬件相关的层.这篇主要介绍网络驱动中与硬件相关的层的框架:网卡驱动程序. 1.网卡驱动程序框 ...

  9. 二十一、Linux驱动之移植DM9000C网卡驱动(下)

    通过二十.Linux驱动之移植DM9000C网卡驱动(上)对厂家提供的网卡驱动程序dm9dev9000c.c的分析,下面将该网卡驱动移植到JZ2440开发板上(内核版本为linux-2.6.22.6) ...

最新文章

  1. 中国农业科技领域最大一笔融资来了:极飞科技拿下12亿投资,百度&软银领投...
  2. 深大教授开源的人脸检测库,速度号称史上最快
  3. java企业号回调模式,微信公众平台企业号开发—开启回调模式
  4. Python实训day12pm【答辩要求、定时器】
  5. expdp impdp中 exclude/include 的使用
  6. js监听只读文本框_js 动态控制 input 框 的只读属性
  7. 用hundred造句子_八个有趣的开学破冰游戏,线上线下都能用
  8. Scrapy框架高级操作
  9. idea 部署 web tomcat
  10. IE浏览器不能自动显示PDF文件的解决办法
  11. apk反编译 Android apktool下载 dex2jar下载 jd-gui下载
  12. vue使用tinymce富文本编辑器
  13. 中国近代史-蒋廷黻-笔记-第一章-剿夷与抚夷-第一节-英国请中国订立邦交
  14. Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning
  15. 深度学习中的Lipschitz约束:泛化与生成模型
  16. C语言decompose函数,R语言时间序列应用(decompose、Holt-Winters初步)
  17. oracle 支持ltfs的厂商_甲骨文革新磁带存储StorageTek产品线
  18. [Acwing] 健康的荷斯坦奶牛 -二进制枚举
  19. java面试亮点技术
  20. 关于移动互联网时代营销的成长启示

热门文章

  1. Varnish反向代理服务器和 HTTP 加速器
  2. 全国计算机竞赛保送清华,连夺奥赛金牌 高二男生保送清华、北大
  3. Using getResponseBodyAsStream instead is recommended
  4. cesium借助 turf 工具库绘制矩形 --任意倾斜角度 --vue2.0
  5. Naver 三方登录
  6. 查理·芒格的人类误判心理学
  7. 关于 SCI、SSCI、CSSCI 北大核心,南大核心 等期刊介绍
  8. 团购网站8月份用户普及率淘宝聚划算最高
  9. FLASH按钮链接网页
  10. iOS图片加载渲染的优化