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