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