• dm9000c 移值新内核 linux-4.1.24


    错误 1

    /home/dm9000/dm9dev9000c.c:309: error: conflicting types for 'phy_read'
    include/linux/phy.h:637: error: previous definition of 'phy_read' was here
    /home/dm9000/dm9dev9000c.c:310: error: conflicting types for 'phy_write'
    include/linux/phy.h:652: error: previous definition of 'phy_write' was here

    linux/phy.h 也定义了这个函数,所以这里要改名.
    phy_read 改名为 dm9000_phy_read

    错误 2
    dm9dev9000c.c:356: error: implicit declaration of function 'SET_MODULE_OWNER'
    查看 linux2.6.22 源码查看发现只是一个宏定义 #define SET_MODULE_OWNER(dev) do { } while (0)

    错误 3
    /home/dm9000/dm9dev9000c.c:407: error: 'struct net_device' has no member named 'priv'
    /home/dm9000/dm9dev9000c.c:408: error: 'struct net_device' has no member named 'priv'
    /home/dm9000/dm9dev9000c.c:422: error: 'struct net_device' has no member named 'open'
    /home/dm9000/dm9dev9000c.c:423: error: 'struct net_device' has no member named 'hard_start_xmit'

    /* Allocated board information structure */
    memset(dev->priv, 0, sizeof(struct board_info));
    db = (board_info_t *)dev->priv;
    改为
    db = netdev_priv(dev);
    /* Allocated board information structure */
    memset(db, 0, sizeof(struct board_info));

    这里改的比较多,最后见补丁吧
    static const struct net_device_ops dm9000_netdev_ops = {
    .ndo_open = dm9000_open,
    .ndo_stop = dm9000_stop,
    .ndo_start_xmit = dm9000_start_xmit,
    .ndo_tx_timeout = dm9000_timeout,
    .ndo_set_rx_mode = dm9000_hash_table,
    .ndo_do_ioctl = dm9000_ioctl,
    .ndo_change_mtu = eth_change_mtu,
    .ndo_set_features = dm9000_set_features,
    .ndo_validate_addr = eth_validate_addr,
    .ndo_set_mac_address = eth_mac_addr,
    #ifdef CONFIG_NET_POLL_CONTROLLER
    .ndo_poll_controller = dm9000_poll_controller,
    #endif
    };

    需要复制 内核自带的 dm9000.h 

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