S3C2440实现dm9000网卡驱动程序移植
发布日期:2021-06-29 14:51:45 浏览次数:2 分类:技术文章

本文共 96181 字,大约阅读时间需要 320 分钟。

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

2015-04-19 Lover雪儿

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

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

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

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

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

 

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

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

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

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

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

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

4.配置网卡中断

在入口函数中设置中断线

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

5.增加头文件包含

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

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

 

7.测试驱动程序

/*1把文件放入内核的drivers/net目录下2修改drivers/net/Makefile3把 obj-$(CONFIG_DM9000) += dm9000.o    改为obj-$(CONFIG_DM9000) += dm9dev9000c.o4使用网络文件系统启动的话,说明已经能用了不用网络文件系统的话,就 ifconfig eth0 xxx.xxx.xxx.xxx        ping xxx.xxx.xxx.xxn*/

 

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

1 /*   2    3   dm9ks.c: Version 2.08 2007/02/12    4      5         A Davicom DM9000/DM9010 ISA NIC fast Ethernet driver for Linux.   6    7     This program is free software; you can redistribute it and/or   8     modify it under the terms of the GNU General Public License   9     as published by the Free Software Foundation; either version 2  10     of the License, or (at your option) any later version.  11   12     This program is distributed in the hope that it will be useful,  13     but WITHOUT ANY WARRANTY; without even the implied warranty of  14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  15     GNU General Public License for more details.  16   17   18   (C)Copyright 1997-2007 DAVICOM Semiconductor,Inc. All Rights Reserved.  19   20 V2.00 Spenser - 01/10/2005  21             - Modification for PXA270 MAINSTONE.  22             - Modified dmfe_tx_done().  23             - Add dmfe_timeout().  24 V2.01    10/07/2005    -Modified dmfe_timer()  25             -Dected network speed 10/100M  26 V2.02    10/12/2005    -Use link change to chage db->Speed  27             -dmfe_open() wait for Link OK    28 V2.03    11/22/2005    -Power-off and Power-on PHY in dmfe_init_dm9000()  29             -support IOL  30 V2.04    12/13/2005    -delay 1.6s between power-on and power-off in   31              dmfe_init_dm9000()  32             -set LED mode 1 in dmfe_init_dm9000()  33             -add data bus driving capability in dmfe_init_dm9000()  34              (optional)  35 10/3/2006    -Add DM8606 read/write function by MDC and MDIO  36 V2.06    01/03/2007    -CONT_RX_PKT_CNT=0xFFFF  37             -modify dmfe_tx_done function  38             -check RX FIFO pointer  39             -if using physical address, re-define I/O function  40             -add db->cont_rx_pkt_cnt=0 at the front of dmfe_packet_receive()  41 V2.08    02/12/2007    -module parameter macro  42             2.4  MODULE_PARM  43             2.6  module_param  44             -remove #include 
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
51 -Modyfy dmfe_do_ioctl for kernel 2.6.7 52 11/23/2007 -Add TDBUG to check TX FIFO pointer shift 53 - Remove check_rx_ready() 54 - Add #define CHECKSUM to modify CHECKSUM function 55 12/20/2007 -Modify TX timeout routine(+)check TCR&0x01 56 57 */ 58 59 /* 主要就是修改基地址,位宽,中断引脚等 */ 60 61 //#define CHECKSUM 62 //#define TDBUG /* check TX FIFO pointer */ 63 //#define RDBUG /* check RX FIFO pointer */ 64 //#define DM8606 65 66 #define DRV_NAME "dm9KS" 67 #define DRV_VERSION "2.09" 68 #define DRV_RELDATE "2007-11-22" 69 70 #ifdef MODVERSIONS 71 #include
72 #endif 73 74 //#include
75 #include
76 #include
77 #include
78 #include
79 #include
80 #include
81 #include
82 #include
83 #include
84 #include
85 #include
86 #include
87 #include
88 #include
89 90 #ifdef CONFIG_ARCH_MAINSTONE 91 #include
92 #include
93 #include
94 #endif 95 96 #include
97 #include
98 #include
99 #include
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
147 #define DM9KS_MIN_IO (MST_ETH_PHYS + 0x300) 148 #define DM9KS_MAX_IO (MST_ETH_PHYS + 0x370) 149 #define DM9K_IRQ MAINSTONE_IRQ(3) 150 #else 151 #define DM9KS_MIN_IO 0x300 152 #define DM9KS_MAX_IO 0x370 153 #define DM9KS_IRQ 3 154 #endif 155 156 #define DM9KS_VID_L 0x28 157 #define DM9KS_VID_H 0x29 158 #define DM9KS_PID_L 0x2A 159 #define DM9KS_PID_H 0x2B 160 161 #define DM9KS_RX_INTR 0x01 162 #define DM9KS_TX_INTR 0x02 163 #define DM9KS_LINK_INTR 0x20 164 165 #define DM9KS_DWORD_MODE 1 166 #define DM9KS_BYTE_MODE 2 167 #define DM9KS_WORD_MODE 0 168 169 #define TRUE 1 170 #define FALSE 0 171 /* Number of continuous Rx packets */ 172 #define CONT_RX_PKT_CNT 0xFFFF 173 174 #define DMFE_TIMER_WUT jiffies+(HZ*5) /* timer wakeup time : 5 second */ 175 176 #ifdef DM9KS_DEBUG 177 #define DMFE_DBUG(dbug_now, msg, vaule)\ 178 if (dmfe_debug||dbug_now) printk(KERN_ERR "dmfe: %s %x\n", msg, vaule) 179 #else 180 #define DMFE_DBUG(dbug_now, msg, vaule)\ 181 if (dbug_now) printk(KERN_ERR "dmfe: %s %x\n", msg, vaule) 182 #endif 183 184 #ifndef CONFIG_ARCH_MAINSTONE 185 #pragma pack(push, 1) 186 #endif 187 188 typedef struct _RX_DESC 189 { 190 u8 rxbyte; 191 u8 status; 192 u16 length; 193 }RX_DESC; 194 195 typedef union{ 196 u8 buf[4]; 197 RX_DESC desc; 198 } rx_t; 199 #ifndef CONFIG_ARCH_MAINSTONE 200 #pragma pack(pop) 201 #endif 202 203 enum DM9KS_PHY_mode { 204 DM9KS_10MHD = 0, 205 DM9KS_100MHD = 1, 206 DM9KS_10MFD = 4, 207 DM9KS_100MFD = 5, 208 DM9KS_AUTO = 8, 209 }; 210 211 /* Structure/enum declaration ------------------------------- */ 212 typedef struct board_info { 213 u32 io_addr;/* Register I/O base address */ 214 u32 io_data;/* Data I/O address */ 215 u8 op_mode;/* PHY operation mode */ 216 u8 io_mode;/* 0:word, 2:byte */ 217 u8 Speed; /* current speed */ 218 u8 chip_revision; 219 int rx_csum;/* 0:disable, 1:enable */ 220 221 u32 reset_counter;/* counter: RESET */ 222 u32 reset_tx_timeout;/* RESET caused by TX Timeout */ 223 int tx_pkt_cnt; 224 int cont_rx_pkt_cnt;/* current number of continuos rx packets */ 225 struct net_device_stats stats; 226 227 struct timer_list timer; 228 unsigned char srom[128]; 229 spinlock_t lock; 230 struct mii_if_info mii; 231 } board_info_t; 232 /* Global variable declaration ----------------------------- */ 233 /*static int dmfe_debug = 0;*/ 234 static struct net_device * dmfe_dev = NULL; 235 static struct ethtool_ops dmfe_ethtool_ops; 236 /* For module input parameter */ 237 static int mode = DM9KS_AUTO; 238 static int media_mode = DM9KS_AUTO; 239 static int irq = DM9KS_IRQ; 240 static int iobase = DM9KS_MIN_IO; 241 242 #if 0 // use physical address; Not virtual address 243 #ifdef outb 244 #undef outb 245 #endif 246 #ifdef outw 247 #undef outw 248 #endif 249 #ifdef outl 250 #undef outl 251 #endif 252 #ifdef inb 253 #undef inb 254 #endif 255 #ifdef inw 256 #undef inw 257 #endif 258 #ifdef inl 259 #undef inl 260 #endif 261 void outb(u8 reg, u32 ioaddr) 262 { 263 (*(volatile u8 *)(ioaddr)) = reg; 264 } 265 void outw(u16 reg, u32 ioaddr) 266 { 267 (*(volatile u16 *)(ioaddr)) = reg; 268 } 269 void outl(u32 reg, u32 ioaddr) 270 { 271 (*(volatile u32 *)(ioaddr)) = reg; 272 } 273 u8 inb(u32 ioaddr) 274 { 275 return (*(volatile u8 *)(ioaddr)); 276 } 277 u16 inw(u32 ioaddr) 278 { 279 return (*(volatile u16 *)(ioaddr)); 280 } 281 u32 inl(u32 ioaddr) 282 { 283 return (*(volatile u32 *)(ioaddr)); 284 } 285 #endif 286 287 /* function declaration ------------------------------------- */ 288 int dmfe_probe1(struct net_device *); 289 static int dmfe_open(struct net_device *); 290 static int dmfe_start_xmit(struct sk_buff *, struct net_device *); 291 static void dmfe_tx_done(unsigned long); 292 static void dmfe_packet_receive(struct net_device *); 293 static int dmfe_stop(struct net_device *); 294 static struct net_device_stats * dmfe_get_stats(struct net_device *); 295 static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int); 296 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 297 static void dmfe_interrupt(int , void *, struct pt_regs *); 298 #else 299 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 300 static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *); 301 #else 302 static irqreturn_t dmfe_interrupt(int , void *);/* for kernel 2.6.20 */ 303 #endif 304 #endif 305 static void dmfe_timer(unsigned long); 306 static void dmfe_init_dm9000(struct net_device *); 307 static unsigned long cal_CRC(unsigned char *, unsigned int, u8); 308 u8 ior(board_info_t *, int); 309 void iow(board_info_t *, int, u8); 310 static u16 phy_read(board_info_t *, int); 311 static void phy_write(board_info_t *, int, u16); 312 static u16 read_srom_word(board_info_t *, int); 313 static void dm9000_hash_table(struct net_device *); 314 static void dmfe_timeout(struct net_device *); 315 static void dmfe_reset(struct net_device *); 316 static int mdio_read(struct net_device *, int, int); 317 static void mdio_write(struct net_device *, int, int, int); 318 static void dmfe_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 319 static int dmfe_get_settings(struct net_device *, struct ethtool_cmd *); 320 static int dmfe_set_settings(struct net_device *, struct ethtool_cmd *); 321 static u32 dmfe_get_link(struct net_device *); 322 static int dmfe_nway_reset(struct net_device *); 323 static uint32_t dmfe_get_rx_csum(struct net_device *); 324 static uint32_t dmfe_get_tx_csum(struct net_device *); 325 static int dmfe_set_rx_csum(struct net_device *, uint32_t ); 326 static int dmfe_set_tx_csum(struct net_device *, uint32_t ); 327 328 #ifdef DM8606 329 #include "dm8606.h" 330 #endif 331 332 //DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0); 333 334 /* DM9000 network baord routine ---------------------------- */ 335 336 /* 337 Search DM9000 board, allocate space and register it 338 */ 339 340 struct net_device * __init dmfe_probe(void) 341 { 342 struct net_device *dev; 343 int err; 344 345 DMFE_DBUG(0, "dmfe_probe()",0); 346 347 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 348 dev = init_etherdev(NULL, sizeof(struct board_info)); 349 //ether_setup(dev); 350 #else 351 dev= alloc_etherdev(sizeof(struct board_info)); //分配一个net_device结构体 352 #endif 353 354 if(!dev) 355 return ERR_PTR(-ENOMEM); 356 357 SET_MODULE_OWNER(dev); 358 err = dmfe_probe1(dev); 359 if (err) 360 goto out; 361 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) 362 err = register_netdev(dev); 363 if (err) 364 goto out1; 365 #endif 366 return dev; 367 out1: 368 release_region(dev->base_addr,2); 369 out: 370 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 371 kfree(dev); 372 #else 373 free_netdev(dev); 374 #endif 375 return ERR_PTR(err); 376 } 377 378 int __init dmfe_probe1(struct net_device *dev) 379 { 380 struct board_info *db; /* Point a board information structure */ 381 u32 id_val; 382 u16 i, dm9000_found = FALSE; 383 u8 MAC_addr[6]={ 0x00,0x60,0x6E,0x33,0x44,0x55}; 384 u8 HasEEPROM=0,chip_info; 385 DMFE_DBUG(0, "dmfe_probe1()",0); 386 387 /* Search All DM9000 serial NIC 对网卡芯片,与读内存差不多,读某个地址就可以了*/ 388 do { 389 outb(DM9KS_VID_L, iobase); /* DM9000C的索引寄存器 cmd = 0*/ 390 id_val = inb(iobase + 4); /* 读DM9000C的数据寄存器 cmd = 1*/ 391 outb(DM9KS_VID_H, iobase); 392 id_val |= inb(iobase + 4) << 8; 393 outb(DM9KS_PID_L, iobase); 394 id_val |= inb(iobase + 4) << 16; 395 outb(DM9KS_PID_H, iobase); 396 id_val |= inb(iobase + 4) << 24; 397 398 if (id_val == DM9KS_ID || id_val == DM9010_ID) { 399 400 /* Request IO from system */ 401 if(!request_region(iobase, 2, dev->name)) 402 return -ENODEV; 403 404 printk(KERN_ERR"
I/O: %x, VID: %x \n",iobase, id_val); 405 dm9000_found = TRUE; 406 407 /* Allocated board information structure */ 408 memset(dev->priv, 0, sizeof(struct board_info)); 409 db = (board_info_t *)dev->priv; 410 dmfe_dev = dev; 411 db->io_addr = iobase; 412 db->io_data = iobase + 4; 413 db->chip_revision = ior(db, DM9KS_CHIPR); 414 415 chip_info = ior(db,0x43); 416 //防止应为版本不匹配而导致的出错,版本不同,也可以用 417 //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) 418 // return -ENODEV; 419 420 /* driver system function 硬件相关的设置*/ 421 dev->base_addr = iobase; 422 dev->irq = irq; 423 dev->open = &dmfe_open; 424 dev->hard_start_xmit = &dmfe_start_xmit; //硬件启动传输 425 dev->watchdog_timeo = 5*HZ; 426 dev->tx_timeout = dmfe_timeout; 427 dev->stop = &dmfe_stop; 428 dev->get_stats = &dmfe_get_stats; 429 dev->set_multicast_list = &dm9000_hash_table; 430 dev->do_ioctl = &dmfe_do_ioctl; 431 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28) 432 dev->ethtool_ops = &dmfe_ethtool_ops; 433 #endif 434 #ifdef CHECKSUM 435 //dev->features |= NETIF_F_IP_CSUM; 436 dev->features |= NETIF_F_IP_CSUM|NETIF_F_SG; 437 #endif 438 db->mii.dev = dev; 439 db->mii.mdio_read = mdio_read; 440 db->mii.mdio_write = mdio_write; 441 db->mii.phy_id = 1; 442 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) 443 db->mii.phy_id_mask = 0x1F; 444 db->mii.reg_num_mask = 0x1F; 445 #endif 446 //db->msg_enable =(debug == 0 ? DMFE_DEF_MSG_ENABLE : ((1 << debug) - 1)); 447 448 /* Read SROM content */ 449 for (i=0; i<64; i++) 450 ((u16 *)db->srom)[i] = read_srom_word(db, i); 451 452 /* Get the PID and VID from EEPROM to check */ 453 id_val = (((u16 *)db->srom)[4])|(((u16 *)db->srom)[5]<<16); 454 printk("id_val=%x\n", id_val); 455 if (id_val == DM9KS_ID || id_val == DM9010_ID) 456 HasEEPROM =1; 457 458 /* Set Node Address */ 459 for (i=0; i<6; i++) 460 { 461 if (HasEEPROM) /* use EEPROM */ 462 dev->dev_addr[i] = db->srom[i]; 463 else /* No EEPROM */ 464 dev->dev_addr[i] = MAC_addr[i]; 465 } 466 }//end of if() 467 iobase += 0x10; 468 }while(!dm9000_found && iobase <= DM9KS_MAX_IO); 469 470 return dm9000_found ? 0:-ENODEV; 471 } 472 473 474 /* 475 Open the interface. 476 The interface is opened whenever "ifconfig" actives it. 477 */ 478 static int dmfe_open(struct net_device *dev) 479 { 480 board_info_t *db = (board_info_t *)dev->priv; 481 u8 reg_nsr; 482 int i; 483 DMFE_DBUG(0, "dmfe_open", 0); 484 //对于2440来说,可以设置它为上升沿触发 485 if (request_irq(dev->irq,&dmfe_interrupt,IRQF_TRIGGER_RISING,dev->name,dev)) //申请注册中断 486 return -EAGAIN; 487 488 /* Initilize DM910X board */ 489 dmfe_init_dm9000(dev); 490 #ifdef DM8606 491 // control DM8606 492 printk("[8606]reg0=0x%04x\n",dm8606_read(db,0)); 493 printk("[8606]reg1=0x%04x\n",dm8606_read(db,0x1)); 494 #endif 495 /* Init driver variable */ 496 db->reset_counter = 0; 497 db->reset_tx_timeout = 0; 498 db->cont_rx_pkt_cnt = 0; 499 500 /* check link state and media speed */ 501 db->Speed =10; 502 i=0; 503 do { 504 reg_nsr = ior(db,DM9KS_NSR); 505 if(reg_nsr & 0x40) /* link OK!! */ 506 { 507 /* wait for detected Speed */ 508 mdelay(200); 509 reg_nsr = ior(db,DM9KS_NSR); 510 if(reg_nsr & 0x80) 511 db->Speed =10; 512 else 513 db->Speed =100; 514 break; 515 } 516 i++; 517 mdelay(1); 518 }while(i<3000); /* wait 3 second */ 519 //printk("i=%d Speed=%d\n",i,db->Speed); 520 /* set and active a timer process */ 521 init_timer(&db->timer); 522 db->timer.expires = DMFE_TIMER_WUT; 523 db->timer.data = (unsigned long)dev; 524 db->timer.function = &dmfe_timer; 525 add_timer(&db->timer); //Move to DM9000 initiallization was finished. 526 527 netif_start_queue(dev); 528 529 return 0; 530 } 531 532 /* Set PHY operationg mode 533 */ 534 static void set_PHY_mode(board_info_t *db) 535 { 536 #ifndef DM8606 537 u16 phy_reg0 = 0x1000;/* Auto-negotiation*/ 538 u16 phy_reg4 = 0x01e1; 539 540 if ( !(db->op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */ 541 { 542 switch(db->op_mode) { 543 case DM9KS_10MHD: phy_reg4 = 0x21; 544 phy_reg0 = 0x1000; 545 break; 546 case DM9KS_10MFD: phy_reg4 = 0x41; 547 phy_reg0 = 0x1100; 548 break; 549 case DM9KS_100MHD: phy_reg4 = 0x81; 550 phy_reg0 = 0x3000; 551 break; 552 case DM9KS_100MFD: phy_reg4 = 0x101; 553 phy_reg0 = 0x3100; 554 break; 555 default: 556 break; 557 } // end of switch 558 } // end of if 559 #ifdef FLOW_CONTROL 560 phy_write(db, 4, phy_reg4|(1<<10)); 561 #else 562 phy_write(db, 4, phy_reg4); 563 #endif //end of FLOW_CONTROL 564 phy_write(db, 0, phy_reg0|0x200); 565 #else 566 /* Fiber mode */ 567 phy_write(db, 16, 0x4014); 568 phy_write(db, 0, 0x2100); 569 #endif //end of DM8606 570 571 if (db->chip_revision == 0x1A) 572 { 573 //set 10M TX idle =65mA (TX 100% utility is 160mA) 574 phy_write(db,20, phy_read(db,20)|(1<<11)|(1<<10)); 575 576 //:fix harmonic 577 //For short code: 578 //PHY_REG 27 (1Bh) <- 0000h 579 phy_write(db, 27, 0x0000); 580 //PHY_REG 27 (1Bh) <- AA00h 581 phy_write(db, 27, 0xaa00); 582 583 //PHY_REG 27 (1Bh) <- 0017h 584 phy_write(db, 27, 0x0017); 585 //PHY_REG 27 (1Bh) <- AA17h 586 phy_write(db, 27, 0xaa17); 587 588 //PHY_REG 27 (1Bh) <- 002Fh 589 phy_write(db, 27, 0x002f); 590 //PHY_REG 27 (1Bh) <- AA2Fh 591 phy_write(db, 27, 0xaa2f); 592 593 //PHY_REG 27 (1Bh) <- 0037h 594 phy_write(db, 27, 0x0037); 595 //PHY_REG 27 (1Bh) <- AA37h 596 phy_write(db, 27, 0xaa37); 597 598 //PHY_REG 27 (1Bh) <- 0040h 599 phy_write(db, 27, 0x0040); 600 //PHY_REG 27 (1Bh) <- AA40h 601 phy_write(db, 27, 0xaa40); 602 603 //For long code: 604 //PHY_REG 27 (1Bh) <- 0050h 605 phy_write(db, 27, 0x0050); 606 //PHY_REG 27 (1Bh) <- AA50h 607 phy_write(db, 27, 0xaa50); 608 609 //PHY_REG 27 (1Bh) <- 006Bh 610 phy_write(db, 27, 0x006b); 611 //PHY_REG 27 (1Bh) <- AA6Bh 612 phy_write(db, 27, 0xaa6b); 613 614 //PHY_REG 27 (1Bh) <- 007Dh 615 phy_write(db, 27, 0x007d); 616 //PHY_REG 27 (1Bh) <- AA7Dh 617 phy_write(db, 27, 0xaa7d); 618 619 //PHY_REG 27 (1Bh) <- 008Dh 620 phy_write(db, 27, 0x008d); 621 //PHY_REG 27 (1Bh) <- AA8Dh 622 phy_write(db, 27, 0xaa8d); 623 624 //PHY_REG 27 (1Bh) <- 009Ch 625 phy_write(db, 27, 0x009c); 626 //PHY_REG 27 (1Bh) <- AA9Ch 627 phy_write(db, 27, 0xaa9c); 628 629 //PHY_REG 27 (1Bh) <- 00A3h 630 phy_write(db, 27, 0x00a3); 631 //PHY_REG 27 (1Bh) <- AAA3h 632 phy_write(db, 27, 0xaaa3); 633 634 //PHY_REG 27 (1Bh) <- 00B1h 635 phy_write(db, 27, 0x00b1); 636 //PHY_REG 27 (1Bh) <- AAB1h 637 phy_write(db, 27, 0xaab1); 638 639 //PHY_REG 27 (1Bh) <- 00C0h 640 phy_write(db, 27, 0x00c0); 641 //PHY_REG 27 (1Bh) <- AAC0h 642 phy_write(db, 27, 0xaac0); 643 644 //PHY_REG 27 (1Bh) <- 00D2h 645 phy_write(db, 27, 0x00d2); 646 //PHY_REG 27 (1Bh) <- AAD2h 647 phy_write(db, 27, 0xaad2); 648 649 //PHY_REG 27 (1Bh) <- 00E0h 650 phy_write(db, 27, 0x00e0); 651 //PHY_REG 27 (1Bh) <- AAE0h 652 phy_write(db, 27, 0xaae0); 653 //PHY_REG 27 (1Bh) <- 0000h 654 phy_write(db, 27, 0x0000); 655 } 656 } 657 658 /* 659 Initilize dm9000 board 660 */ 661 static void dmfe_init_dm9000(struct net_device *dev) 662 { 663 board_info_t *db = (board_info_t *)dev->priv; 664 DMFE_DBUG(0, "dmfe_init_dm9000()", 0); 665 666 spin_lock_init(&db->lock); 667 668 iow(db, DM9KS_GPR, 0); /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */ 669 mdelay(20); /* wait for PHY power-on ready */ 670 671 /* do a software reset and wait 20us */ 672 iow(db, DM9KS_NCR, 3); 673 udelay(20); /* wait 20us at least for software reset ok */ 674 iow(db, DM9KS_NCR, 3); /* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on */ 675 udelay(20); /* wait 20us at least for software reset ok */ 676 677 /* I/O mode */ 678 db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ 679 680 /* Set PHY */ 681 db->op_mode = media_mode; 682 set_PHY_mode(db); 683 684 /* Program operating register */ 685 iow(db, DM9KS_NCR, 0); 686 iow(db, DM9KS_TCR, 0); /* TX Polling clear */ 687 iow(db, DM9KS_BPTR, 0x3f); /* Less 3kb, 600us */ 688 iow(db, DM9KS_SMCR, 0); /* Special Mode */ 689 iow(db, DM9KS_NSR, 0x2c); /* clear TX status */ 690 iow(db, DM9KS_ISR, 0x0f); /* Clear interrupt status */ 691 iow(db, DM9KS_TCR2, 0x80); /* Set LED mode 1 */ 692 if (db->chip_revision == 0x1A){ 693 /* Data bus current driving/sinking capability */ 694 iow(db, DM9KS_BUSCR, 0x01); /* default: 2mA */ 695 } 696 #ifdef FLOW_CONTROL 697 iow(db, DM9KS_BPTR, 0x37); 698 iow(db, DM9KS_FCTR, 0x38); 699 iow(db, DM9KS_FCR, 0x29); 700 #endif 701 702 #ifdef DM8606 703 iow(db,0x34,1); 704 #endif 705 706 if (dev->features & NETIF_F_HW_CSUM){ 707 printk(KERN_INFO "DM9KS:enable TX checksum\n"); 708 iow(db, DM9KS_TCCR, 0x07); /* TX UDP/TCP/IP checksum enable */ 709 } 710 if (db->rx_csum){ 711 printk(KERN_INFO "DM9KS:enable RX checksum\n"); 712 iow(db, DM9KS_RCSR, 0x02); /* RX checksum enable */ 713 } 714 715 #ifdef ETRANS 716 /*If TX loading is heavy, the driver can try to anbel "early transmit". 717 The programmer can tune the "Early Transmit Threshold" to get 718 the optimization. (DM9KS_ETXCSR.[1-0]) 719 720 Side Effect: It will happen "Transmit under-run". When TX under-run 721 always happens, the programmer can increase the value of "Early 722 Transmit Threshold". */ 723 iow(db, DM9KS_ETXCSR, 0x83); 724 #endif 725 726 /* Set address filter table */ 727 dm9000_hash_table(dev); 728 729 /* Activate DM9000/DM9010 */ 730 iow(db, DM9KS_IMR, DM9KS_REGFF); /* Enable TX/RX interrupt mask */ 731 iow(db, DM9KS_RXCR, DM9KS_REG05 | 1); /* RX enable */ 732 733 /* Init Driver variable */ 734 db->tx_pkt_cnt = 0; 735 736 netif_carrier_on(dev); 737 738 } 739 740 /* 741 Hardware start transmission. 742 Send a packet to media from the upper layer. 743 */ 744 static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev) 745 { 746 board_info_t *db = (board_info_t *)dev->priv; 747 char * data_ptr; 748 int i, tmplen; 749 u16 MDWAH, MDWAL; 750 751 #ifdef TDBUG /* check TX FIFO pointer */ 752 u16 MDWAH1, MDWAL1; 753 u16 tx_ptr; 754 #endif 755 756 DMFE_DBUG(0, "dmfe_start_xmit", 0); 757 if (db->chip_revision != 0x1A) 758 { 759 if(db->Speed == 10) 760 { if (db->tx_pkt_cnt >= 1) return 1;} 761 else 762 { if (db->tx_pkt_cnt >= 2) return 1;} 763 }else 764 if (db->tx_pkt_cnt >= 2) return 1; 765 766 /* packet counting */ 767 db->tx_pkt_cnt++; 768 769 db->stats.tx_packets++; 770 db->stats.tx_bytes+=skb->len; 771 if (db->chip_revision != 0x1A) 772 { 773 if (db->Speed == 10) 774 { if (db->tx_pkt_cnt >= 1) netif_stop_queue(dev);} 775 else 776 { if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);} 777 }else 778 if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev); 779 780 /* Disable all interrupt */ 781 iow(db, DM9KS_IMR, DM9KS_DISINTR); 782 783 MDWAH = ior(db,DM9KS_MDWAH); 784 MDWAL = ior(db,DM9KS_MDWAL); 785 786 /* Set TX length to reg. 0xfc & 0xfd */ 787 iow(db, DM9KS_TXPLL, (skb->len & 0xff)); 788 iow(db, DM9KS_TXPLH, (skb->len >> 8) & 0xff); 789 790 /* Move data to TX SRAM */ 791 data_ptr = (char *)skb->data; 792 793 outb(DM9KS_MWCMD, db->io_addr); // Write data into SRAM trigger 794 switch(db->io_mode) 795 { 796 case DM9KS_BYTE_MODE: 797 for (i = 0; i < skb->len; i++) 798 outb((data_ptr[i] & 0xff), db->io_data); 799 break; 800 case DM9KS_WORD_MODE: 801 tmplen = (skb->len + 1) / 2; 802 for (i = 0; i < tmplen; i++) 803 outw(((u16 *)data_ptr)[i], db->io_data); 804 break; 805 case DM9KS_DWORD_MODE: 806 tmplen = (skb->len + 3) / 4; 807 for (i = 0; i< tmplen; i++) 808 outl(((u32 *)data_ptr)[i], db->io_data); 809 break; 810 } 811 812 #ifndef ETRANS 813 /* Issue TX polling command */ 814 iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/ 815 #endif 816 817 #ifdef TDBUG /* check TX FIFO pointer */ 818 MDWAH1 = ior(db,DM9KS_MDWAH); 819 MDWAL1 = ior(db,DM9KS_MDWAL); 820 tx_ptr = (MDWAH<<8)|MDWAL; 821 switch (db->io_mode) 822 { 823 case DM9KS_BYTE_MODE: 824 tx_ptr += skb->len; 825 break; 826 case DM9KS_WORD_MODE: 827 tx_ptr += ((skb->len + 1) / 2)*2; 828 break; 829 case DM9KS_DWORD_MODE: 830 tx_ptr += ((skb->len+3)/4)*4; 831 break; 832 } 833 if (tx_ptr > 0x0bff) 834 tx_ptr -= 0x0c00; 835 if (tx_ptr != ((MDWAH1<<8)|MDWAL1)) 836 printk("[dm9ks:TX FIFO ERROR\n"); 837 #endif 838 /* Saved the time stamp */ 839 dev->trans_start = jiffies; 840 db->cont_rx_pkt_cnt =0; 841 842 /* Free this SKB */ 843 dev_kfree_skb(skb); 844 845 /* Re-enable interrupt */ 846 iow(db, DM9KS_IMR, DM9KS_REGFF); 847 848 return 0; 849 } 850 851 /* 852 Stop the interface. 853 The interface is stopped when it is brought. 854 */ 855 static int dmfe_stop(struct net_device *dev) 856 { 857 board_info_t *db = (board_info_t *)dev->priv; 858 DMFE_DBUG(0, "dmfe_stop", 0); 859 860 /* deleted timer */ 861 del_timer(&db->timer); 862 863 netif_stop_queue(dev); 864 865 /* free interrupt */ 866 free_irq(dev->irq, dev); 867 868 /* RESET devie */ 869 phy_write(db, 0x00, 0x8000); /* PHY RESET */ 870 //iow(db, DM9KS_GPR, 0x01); /* Power-Down PHY */ 871 iow(db, DM9KS_IMR, DM9KS_DISINTR); /* Disable all interrupt */ 872 iow(db, DM9KS_RXCR, 0x00); /* Disable RX */ 873 874 /* Dump Statistic counter */ 875 #if FALSE 876 printk("\nRX FIFO OVERFLOW %lx\n", db->stats.rx_fifo_errors); 877 printk("RX CRC %lx\n", db->stats.rx_crc_errors); 878 printk("RX LEN Err %lx\n", db->stats.rx_length_errors); 879 printk("RESET %x\n", db->reset_counter); 880 printk("RESET: TX Timeout %x\n", db->reset_tx_timeout); 881 printk("g_TX_nsr %x\n", g_TX_nsr); 882 #endif 883 884 return 0; 885 } 886 887 static void dmfe_tx_done(unsigned long unused) 888 { 889 struct net_device *dev = dmfe_dev; 890 board_info_t *db = (board_info_t *)dev->priv; 891 int nsr; 892 893 DMFE_DBUG(0, "dmfe_tx_done()", 0); 894 895 nsr = ior(db, DM9KS_NSR); 896 if (nsr & 0x0c) 897 { 898 if(nsr & 0x04) db->tx_pkt_cnt--; 899 if(nsr & 0x08) db->tx_pkt_cnt--; 900 if(db->tx_pkt_cnt < 0) 901 { 902 printk(KERN_DEBUG "DM9KS:tx_pkt_cnt ERROR!!\n"); 903 while(ior(db,DM9KS_TCR) & 0x1){} 904 db->tx_pkt_cnt = 0; 905 } 906 907 }else{ 908 while(ior(db,DM9KS_TCR) & 0x1){} 909 db->tx_pkt_cnt = 0; 910 } 911 912 netif_wake_queue(dev); 913 914 return; 915 } 916 917 /* 918 DM9000 insterrupt handler 919 receive the packet to upper layer, free the transmitted packet 920 */ 921 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 922 static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) 923 #else 924 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 925 static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs) 926 #else 927 static irqreturn_t dmfe_interrupt(int irq, void *dev_id) /* for kernel 2.6.20*/ 928 #endif 929 #endif 930 { 931 struct net_device *dev = dev_id; 932 board_info_t *db; 933 int int_status,i; 934 u8 reg_save; 935 936 DMFE_DBUG(0, "dmfe_interrupt()", 0); 937 938 /* A real interrupt coming */ 939 db = (board_info_t *)dev->priv; 940 spin_lock(&db->lock); 941 942 /* Save previous register address */ 943 reg_save = inb(db->io_addr); 944 945 /* Disable all interrupt */ 946 iow(db, DM9KS_IMR, DM9KS_DISINTR); 947 948 /* Got DM9000/DM9010 interrupt status */ 949 int_status = ior(db, DM9KS_ISR); /* Got ISR */ 950 iow(db, DM9KS_ISR, int_status); /* Clear ISR status */ 951 952 /* Link status change */ 953 if (int_status & DM9KS_LINK_INTR) 954 { 955 netif_stop_queue(dev); 956 for(i=0; i<500; i++) /*wait link OK, waiting time =0.5s */ 957 { 958 phy_read(db,0x1); 959 if(phy_read(db,0x1) & 0x4) /*Link OK*/ 960 { 961 /* wait for detected Speed */ 962 for(i=0; i<200;i++) 963 udelay(1000); 964 /* set media speed */ 965 if(phy_read(db,0)&0x2000) db->Speed =100; 966 else db->Speed =10; 967 break; 968 } 969 udelay(1000); 970 } 971 netif_wake_queue(dev); 972 //printk("[INTR]i=%d speed=%d\n",i, (int)(db->Speed)); 973 } 974 /* Received the coming packet */ 975 if (int_status & DM9KS_RX_INTR) 976 dmfe_packet_receive(dev); 977 978 /* Trnasmit Interrupt check */ 979 if (int_status & DM9KS_TX_INTR) 980 dmfe_tx_done(0); 981 982 if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT) 983 { 984 iow(db, DM9KS_IMR, 0xa2); 985 } 986 else 987 { 988 /* Re-enable interrupt mask */ 989 iow(db, DM9KS_IMR, DM9KS_REGFF); 990 } 991 992 /* Restore previous register address */ 993 outb(reg_save, db->io_addr); 994 995 spin_unlock(&db->lock); 996 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) 997 return IRQ_HANDLED; 998 #endif 999 }1000 1001 /*1002 Get statistics from driver.1003 */1004 static struct net_device_stats * dmfe_get_stats(struct net_device *dev)1005 {1006 board_info_t *db = (board_info_t *)dev->priv;1007 DMFE_DBUG(0, "dmfe_get_stats", 0);1008 return &db->stats;1009 }1010 /*1011 * Process the ethtool ioctl command1012 */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 command1038 */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 #endif1045 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 #else1059 rc = generic_mii_ioctl(&db->mii, if_mii(ifr), cmd, NULL);1060 #endif1061 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 FALSE1079 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 #endif1084 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 else1098 {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 routine1136 */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 layer1158 */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*)℞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 #else1195 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 #endif1205 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"
\n");1240 }1241 if (rx.desc.status & 0x02) 1242 {1243 db->stats.rx_crc_errors++;1244 printk(KERN_INFO"
\n");1245 }1246 if (rx.desc.status & 0x80) 1247 {1248 db->stats.rx_length_errors++;1249 printk(KERN_INFO"
\n");1250 }1251 if (rx.desc.status & 0x08)1252 printk(KERN_INFO"
\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
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 else1288 {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
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 CHECKSUM1317 if((rxbyte&0xe0)==0) /* receive packet no checksum fail */1318 skb->ip_summed = CHECKSUM_UNNECESSARY;1319 #endif1320 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 #endif1349 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 SROM1364 */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 address1376 */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 packet1432 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 port1459 */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 port1468 */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 phyxcer1477 */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 phyxcer1494 */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 state1537 */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-negitiation1546 */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 state1554 */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 state1562 */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 offload1569 */1570 static int dmfe_set_rx_csum(struct net_device *dev, uint32_t data)1571 {1572 #ifdef CHECKSUM1573 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 } else1580 dmfe_init_dm9000(dev);1581 #else1582 printk(KERN_ERR "DM9:Don't support checksum\n");1583 #endif1584 return 0;1585 }1586 /* 1587 * Enable/Disable TX checksum offload1588 */1589 static int dmfe_set_tx_csum(struct net_device *dev, uint32_t data)1590 {1591 #ifdef CHECKSUM1592 if (data)1593 dev->features |= NETIF_F_HW_CSUM;1594 else1595 dev->features &= ~NETIF_F_HW_CSUM;1596 #else1597 printk(KERN_ERR "DM9:Don't support checksum\n");1598 #endif1599 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 #endif1616 1617 //#ifdef MODULE1618 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 #else1626 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; // 0x480000001641 volatile unsigned long *bankcon4; // 0x480000141642 unsigned long val;1643 1644 iobase = (int)ioremap(0x20000000,1024); /* 添加内存映射 */1645 1646 //2440使用的中断引脚为外部中断7,此处我们设置中断号1647 irq = IRQ_EINT7;1648 1649 /* 设置S3C2440的memory controller */1650 bwscon = ioremap(0x48000000, 4);1651 bankcon4 = ioremap(0x48000014, 4);1652 1653 /* DW4[17:16]: 01-16bit1654 * WS4[18] : 0-WAIT disable1655 * ST4[19] : 0 = Not using UB/LB (The pins are dedicated nWBE[3:0])1656 */1657 val = *bwscon;1658 val &= ~(0xf<<16);1659 val |= (1<<16);1660 *bwscon = val;1661 1662 /*1663 * Tacs[14:13]: 发出片选信号之前,多长时间内要先发出地址信号1664 * DM9000C的片选信号和CMD信号可以同时发出,1665 * 所以它设为01666 * Tcos[12:11]: 发出片选信号之后,多长时间才能发出读信号nOE1667 * DM9000C的T1>=0ns, 1668 * 所以它设为01669 * Tacc[10:8] : 读写信号的脉冲长度, 1670 * DM9000C的T2>=10ns, 1671 * 所以它设为1, 表示2个hclk周期,hclk=100MHz,就是20ns1672 * Tcoh[7:6] : 当读信号nOE变为高电平后,片选信号还要维持多长时间1673 * DM9000C进行写操作时, nWE变为高电平之后, 数据线上的数据还要维持最少3ns1674 * DM9000C进行读操作时, nOE变为高电平之后, 数据线上的数据在6ns之内会消失1675 * 我们取一个宽松值: 让片选信号在nOE放为高电平后,再维持10ns, 1676 * 所以设为011677 * Tcah[5:4] : 当片选信号变为高电平后, 地址信号还要维持多长时间1678 * DM9000C的片选信号和CMD信号可以同时出现,同时消失1679 * 所以设为01680 * PMC[1:0] : 00-正常模式1681 *1682 */1683 //*bankcon4 = (1<<8)|(1<<6); /* 对于DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7 */1684 *bankcon4 = (7<<8)|(1<<6); /* TQ2440和MINI2440使用DM9000E,Tacc要设大一点 正常来说1也可以 */1685 1686 iounmap(bwscon);1687 iounmap(bankcon4);1688 1689 1690 switch(mode) {1691 case DM9KS_10MHD:1692 case DM9KS_100MHD:1693 case DM9KS_10MFD:1694 case DM9KS_100MFD:1695 media_mode = mode;1696 break;1697 default:1698 media_mode = DM9KS_AUTO;1699 }1700 dmfe_dev = dmfe_probe();1701 if(IS_ERR(dmfe_dev))1702 return PTR_ERR(dmfe_dev);1703 return 0;1704 }1705 /* Description: 1706 when user used rmmod to delete module, system invoked clean_module()1707 to un-register DEVICE.1708 */1709 void __exit dm9000c_exit(void)1710 {1711 struct net_device *dev = dmfe_dev;1712 DMFE_DBUG(0, "clean_module()", 0);1713 1714 unregister_netdev(dmfe_dev);1715 release_region(dev->base_addr, 2);1716 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)1717 kfree(dev);1718 #else1719 free_netdev(dev);1720 #endif1721 iounmap((void *)iobase);1722 DMFE_DBUG(0, "clean_module() exit", 0);1723 }1724 1725 module_init(dm9000c_init);1726 module_exit(dm9000c_exit);1727 1728 //#endif1729 1730 1731 /*1732 1733 1把文件放入内核的drivers/net目录下1734 2修改drivers/net/Makefile1735 3把 obj-$(CONFIG_DM9000) += dm9000.o1736 改为obj-$(CONFIG_DM9000) += dm9dev9000c.o1737 4使用网络文件系统启动的话,说明已经能用了1738 1739 不用网络文件系统的话,1740 就 ifconfig eth0 xxx.xxx.xxx.xxx 1741 ping xxx.xxx.xxx.xxn1742 1743 */
dm9000c.c

 

转载地址:https://ciellee.blog.csdn.net/article/details/105961421 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【倒车影像分流需求 一】- 需求分解 及 进程间通信共享内存原理
下一篇:【高通SDM660平台】(8) --- Camera MetaData介绍

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月29日 21时30分17秒