⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9000x.c

📁 这个源码相信对很多用arm开发板开发的人会有用的
💻 C
📖 第 1 页 / 共 3 页
字号:
	    for (i = 0; i < 6; i++)		dev->dev_addr[i] = db->srom[i];#else	    //random_ether_addr(dev->dev_addr);	// mhfan	{	    ////unsigned char enet_addr[]={0x26, 0xdc, 0x6c, 0x11, 0x7b, 0xbb}; //origion	    unsigned char  enet_addr[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x89}; //from 2.4	    for (i=0; i < 6; i++) dev->dev_addr[i] = enet_addr[i];	}#endif	/* comment by mhfan */	    /* Request IO from system */	    request_region(iobase, 2, dev->name);	}    } while (!dm9000_found && (iobase+=0x10) <= DM9000_MAX_IO);	   printk("\n\nsun----dmfe_probe_exit\n\n");    return (dm9000_found ? 0 : -ENODEV);}/* Open the interface. * The interface is opened whenever "ifconfig" actives it. */static int dmfe_open(struct net_device *dev){    board_info_t *db = (board_info_t *) dev->priv;	  printk("\n\nsun----dmfe_open\n\n");      DMFE_DBUG(0, "dmfe_open", 0);    //MOD_INC_USE_COUNT;	//printk("net irq num is %d\n",dev->irq);         //dev->irq=0;  //--        // dev->irq=IRQ_EINT0 ;  //--         printk("net irq num is %d\n",dev->irq);	 printk("dev->name  is %s\n",dev->name);	// set_irq_type(dev->irq, IRQT_RISING);	 										//net irq num is 0										//dev->name  is eth0    //if (request_irq(dev->irq, &dmfe_interrupt, SA_INTERRUPT/*SA_SHIRQ*/, dev->name, dev))    if (request_irq(dev->irq, &dmfe_interrupt, /*SA_INTERRUPT*/SA_SHIRQ, dev->name/*"DM9000 device"*/, dev))    	{    	  printk("\n\nsun----request_irq failure\n\n");  //   if (request_irq(dev->irq, &dmfe_interrupt, SA_INTERRUPT, dev->name, dev))	return -EAGAIN;    	}     	 //printk("sun-----requets irq exit\n");		 /*		//writel(0x04|0x4,extint0);  //OLD   	writel(readl(extint0)|0x4444,extint0); //rising edge	//writel(readl(intmsk)&0xfff7,intmsk);   //OLD    	  writel(readl(intmsk)&0xfffffff0,intmsk); //mask open		 printk("sun-----set irq register exit\n");	 */    /* Initilize DM910X board */    dmfe_init_dm9000(dev);    /* Init driver variable */    db->dbug_cnt	    = 0;    db->runt_length_counter = 0;    db->long_length_counter = 0;    db->reset_counter	    = 0;    /* set and active a timer process */    init_timer(&db->timer);    db->timer.expires	    = DMFE_TIMER_WUT * 2;    db->timer.data	    = (unsigned long) dev;    db->timer.function	    = &dmfe_timer;    add_timer(&db->timer);	// Move to DM9000 initiallization was finished.#if defined(AUTOMDIX)    /* set and active a timer process for Auto-MDIX */    init_timer(&db->mdix_timer);    db->mdix_timer.expires  = DMFE_TIMER_MDIX;    db->mdix_timer.data	    = (unsigned long) dev;    db->mdix_timer.function = &dmfe_mdix_timer;    add_timer(&db->mdix_timer);#endif    netif_start_queue(dev);    enable_irq(dev->irq);    return 0;}/* Set PHY operationg mode */static void set_PHY_mode(board_info_t * db){    u16 phy_reg0 = 0x1000;	/* Auto-negotiation & non-duplux mode */    u16 phy_reg4 = 0x01e1;	/* Default non flow control */    if (!(db->op_mode & DM9000_AUTO)) {	// op_mode didn't auto sense */	switch (db->op_mode) {	case DM9000_10MHD:	    phy_reg4 = 0x21;	    phy_reg0 = 0x0000;	    break;	case DM9000_10MFD:	    phy_reg4 = 0x41;	    phy_reg0 = 0x1100;	    break;	case DM9000_100MHD:	    phy_reg4 = 0x81;	    phy_reg0 = 0x2000;	    break;	case DM9000_100MFD:	    phy_reg4 = 0x101;	    phy_reg0 = 0x3100;	    break;	}			// end of switch    }				// end of if    phy_write(db, 0, phy_reg0);    phy_write(db, 4, 0x0400 | phy_reg4);    db->Preg0 = phy_reg0;    db->Preg4 = phy_reg4 + 0x0400;}/* Init HomeRun DM9801 */static void program_dm9801(board_info_t * db, u16 HPNA_rev){    __u16 reg16, reg17, reg24, reg25;    if (!nfloor) nfloor = DM9801_NOISE_FLOOR;    reg16 = phy_read(db, 16);    reg17 = phy_read(db, 17);    reg24 = phy_read(db, 24);    reg25 = phy_read(db, 25);    switch (HPNA_rev) {    case 0xb900:		/* DM9801 E3 */	reg16 |= 0x1000;	reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000;	break;    case 0xb901:		/* DM9801 E4 */	reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200;	reg17 = (reg17 & 0xfff0) + nfloor + 3;	break;    case 0xb902:		/* DM9801 E5 */    case 0xb903:		/* DM9801 E6 */    default:	reg16 |= 0x1000;	reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200;	reg17 = (reg17 & 0xfff0) + nfloor;    }    phy_write(db, 16, reg16);    phy_write(db, 17, reg17);    phy_write(db, 25, reg25);}/* Init LongRun DM9802 */static void program_dm9802(board_info_t * db){    __u16 reg25;    if (!nfloor) nfloor = DM9802_NOISE_FLOOR;    reg25 = phy_read(db, 25);    reg25 = (reg25 & 0xff00) + nfloor;    phy_write(db, 25, reg25);}/* Identify NIC type */static void identify_nic(board_info_t * db){    u16 phy_reg3;    iow(db, 0, DM9000_EXT_MII);    phy_reg3 = phy_read(db, 3);    switch (phy_reg3 & 0xfff0) {    case 0xb900:	if (phy_read(db, 31) == 0x4404) {	    db->nic_type = HOMERUN_NIC;	    program_dm9801(db, phy_reg3);	} else {	    db->nic_type = LONGRUN_NIC;	    program_dm9802(db);	}	break;    default:	db->nic_type = FASTETHER_NIC;	break;    }    iow(db, 0, DM9000_INT_MII);}/* Initilize dm9000 board */static void dmfe_init_dm9000(struct net_device *dev){    board_info_t *db = (board_info_t *) dev->priv;    //printk("\n\nsun----dmfe_init_dm9000\n\n");    DMFE_DBUG(0, "dmfe_init_dm9000()", 0);    /* set the internal PHY power-on, GPIOs normal, and wait 2ms */    iow(db, 0x1F, 0);		/* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */    udelay(20);			/* wait 2ms for PHY power-on ready */    /* do a software reset and wait 20us */    iow(db, DM9000_NCR, 3);    udelay(20);			/* wait 20us at least for software reset ok */    iow(db, 0, 3);		/* NCR (reg_00h) bit[0] RST=1 & Loopback=1,				 * reset on. Added by SPenser */    udelay(20);			/* wait 20us at least for software reset ok */// Marked by Spenser    /* set GPIO0=1 then GPIO0=0 to turn off and on the internal PHY */    iow(db, 0x1F, 1);		/* GPR (reg_1Fh) bit[0] GPIO0=1 turn-off PHY  */    iow(db, 0x1F, 0);		/* GPR (reg_1Fh) bit[0] GPIO0=0 activate PHY  *///modify by he    udelay(1000);		/* wait 4ms linking PHY (AUTO sense) if RX/TX */    udelay(1000);    udelay(1000);    udelay(1000);    /* I/O mode */    db->io_mode = ior(db, 0xfe) >> 6;	/* ISR bit7:6 keeps I/O mode */    /* NIC Type: FASTETHER, HOMERUN, LONGRUN */    identify_nic(db);    /* Set PHY */    db->op_mode = media_mode;    set_PHY_mode(db);    /* Init needed register value */    db->reg0 = DM9000_NCR;    if ((db->nic_type != FASTETHER_NIC) && (db->op_mode & DM9000_1M_HPNA))	db->reg0 |= DM9000_EXT_MII;    /* User passed argument */    db->reg5 = reg5;    db->reg8 = reg8;    db->reg9 = reg9;    db->rega = rega;    /* Program operating register */    iow(db, 0x00, 0x08);    iow(db, 0x02, 0);		/* TX Polling clear */    iow(db, 0x2f, 0);		/* Special Mode */    iow(db, 0x01, 0x2c);	/* clear TX status */    iow(db, 0xfe, 0x0f);	/* Clear interrupt status */    iow(db, 0x08, 0x37);    iow(db, 0x09, 0x38);	/* Flow control: High/Low water */    iow(db, 0x0a, 0x29);	/* flow control */    /* Set address filter table */    dm9000_hash_table(dev);    /* Activate DM9000 */    iow(db, 0x05, db->reg5 | 1);	/* RX enable */    iow(db, 0xff, DM9000_REGFF);	/* Enable TX/RX interrupt mask */    /* Init Driver variable */    db->link_failed	= 1;    db->tx_pkt_cnt	= 0;    db->queue_pkt_len	= 0;    dev->trans_start	= 0;    netif_carrier_on(dev);    spin_lock_init(&db->lock);}#if 0	/* comment by mhfan *//* Reset dm9000 board due to 32bits mode while excess collision * or late collision. */static void dmfe_reset_dm9000(struct net_device *dev){    board_info_t *db = (board_info_t *) dev->priv;    DMFE_DBUG(0, "dmfe_reset_dm9000()", 0);    iow(db, 0, 1);		/* NCR (reg_00h) bit[0] RST=1, reset on.				 * Added by SPenser */    udelay(1);			/* wait 20us at least for software reset ok */    iow(db, 0, 0);    /* software reset 2 times */    iow(db, DM9000_NCR, 3);    udelay(20);    iow(db, DM9000_NCR, 3);    udelay(20);    /* Program operating register */    iow(db, 0x00, db->reg0);    iow(db, 0x02, 0);		/* TX Polling clear */    iow(db, 0x08, 0x3f);	/* Less 3Kb, 200us */    iow(db, 0x09, 0x38);	/* Flow Control : High/Low Water */    iow(db, 0x0a, 0x29);	/* TX Pause packet */    iow(db, 0x2f, 0);		/* Special Mode */    iow(db, 0x01, 0x2c);	/* clear TX status */    iow(db, 0xfe, 0x0f);	/* Clear interrupt status */    /* Activate DM9000 */    iow(db, 0x05, db->reg5 | 1);	/* RX enable */    iow(db, 0xff, DM9000_REGFF);	/* Enable TX/RX interrupt mask */    /* Init Driver variable */    db->link_failed = 1;    db->tx_pkt_cnt = 0;    db->queue_pkt_len = 0;    dev->trans_start = 0;    netif_carrier_on(dev);}#endif	/* comment by mhfan *//* Hardware start transmission. * Send a packet to media from the upper layer. */static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev){    board_info_t *db = (board_info_t *) dev->priv;    char *data_ptr;    int i, tmplen;  //printk("\n\nsun----dmfe_start_xmit\n\n");    DMFE_DBUG(0, "dmfe_start_xmit", 0);    if (db->tx_pkt_cnt > 1) return 1;    netif_stop_queue(dev);    /* Disable all interrupt */    iow(db, 0xff, 0x80);    /* Move data to DM9000 TX RAM */    data_ptr = (char *) skb->data;    outb(0xf8, db->ioaddr);    db->sent_pkt_len = skb->len;    if (db->io_mode == DM9000_BYTE_MODE) {	    /* Byte mode */	for (i = 0; i < skb->len; i++)	    outb((data_ptr[i] & 0xff), db->io_data);    } else if (db->io_mode == DM9000_WORD_MODE) {   /* Word mode */	tmplen = (skb->len + 1) / 2;#if 0 	/* comment by mhfan */{    int j = 0;    for (i = 0; i < tmplen; i++) {	printk("%04x ", ((u16 *) data_ptr)[i]);	if (++j == 16) { printk("\n"); j = 0; }    }    printk("\n\033[0m");}#endif	/* comment by mhfan */	for (i = 0; i < tmplen; i++)	    outw(((u16 *) data_ptr)[i], db->io_data);    } else {					    /* DWord mode */	tmplen = (skb->len + 3) / 4;	for (i = 0; i < tmplen; i++)	    outl(((u32 *) data_ptr)[i], db->io_data);    }    /* TX control: First packet immediately send, second packet queue */    if (db->tx_pkt_cnt == 0) {			/* First Packet */	db->tx_pkt_cnt++;	/* Set TX length to DM9000 */	iow(db, 0xfc, skb->len & 0xff);	iow(db, 0xfd, (skb->len >> 8) & 0xff);	/* Issue TX polling command */	iow(db, 0x2, 0x1);			/* Cleared after TX complete */	/* saved the time stamp */	dev->trans_start = jiffies;    } else {					/* Second packet */	db->tx_pkt_cnt++;	db->queue_pkt_len = skb->len;    }    /* free this SKB */    dev_kfree_skb(skb);    /* Re-enable resource check */    if (db->tx_pkt_cnt == 1) netif_wake_queue(dev);    /* Re-enable interrupt */iow(db, 0xff, 0x83);    return 0;}/* Stop the interface. * The interface is stopped when it is brought. */static int dmfe_stop(struct net_device *dev){    board_info_t *db = (board_info_t *) dev->priv;    //printk("\n\nsun----dmfe_stop\n\n");    DMFE_DBUG(0, "dmfe_stop", 0);    /* deleted timer */    del_timer(&db->timer);    del_timer(&db->mdix_timer);    netif_stop_queue(dev);    /* free interrupt */    free_irq(dev->irq, dev);    /* RESET devie */    phy_write(db, 0x00, 0x8000);	/* PHY RESET */    iow(db, 0x1f, 0x01);	/* Power-Down PHY */    iow(db, 0xff, 0x80);	/* Disable all interrupt */    iow(db, 0x05, 0x00);	/* Disable RX */    //MOD_DEC_USE_COUNT;#if FALSE /* Dump Statistic counter */    printk("\nRX FIFO OVERFLOW %lx\n", db->stats.rx_fifo_errors);    printk("RX CRC %lx\n", db->stats.rx_crc_errors);    printk("RX LEN Err %lx\n", db->stats.rx_length_errors);    printk("RX LEN < 64byte %x\n", db->runt_length_counter);    printk("RX LEN > 1514byte %x\n", db->long_length_counter);    printk("RESET %x\n", db->reset_counter);    printk("RESET: TX Timeout %x\n", db->reset_tx_timeout);    printk("RESET: RX Status Wrong %x\n", db->reset_rx_status);#endif    return 0;}static void dmfe_tx_done(unsigned long unused){    struct net_device *dev = dmfe_dev;    board_info_t *db = (board_info_t *) dev->priv;    int tx_status = ior(db, 0x01);	/* Got TX status */    DMFE_DBUG(0, "dmfe_tx_done()", 0);    if (tx_status & 0xc) {		/* One packet sent complete */	db->tx_pkt_cnt--;	dev->trans_start = 0;	db->stats.tx_packets++;	if (db->tx_pkt_cnt > 0) {	/* Queue packet check & send */	    /* Set TX length to DM9000 */	    iow(db, 0xfc, db->queue_pkt_len & 0xff);	    iow(db, 0xfd, (db->queue_pkt_len >> 8) & 0xff);	    /* Issue TX polling command */	    iow(db, 0x2, 0x1);		/* Cleared after TX complete */	    dev->trans_start = jiffies;	/* saved the time stamp */	}	netif_wake_queue(dev);    }}/* DM9102 insterrupt handler. * receive the packet to upper layer, free the transmitted packet */static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs){    struct net_device *dev = dev_id;    board_info_t *db;    int int_status;    u8 reg_save;   //printk("\n\nsun----dmfe_interrupt\n\n");#if 0	/* comment by mhfan */    DMFE_DBUG(0, "dmfe_interrupt()", 0);    if (!(*pFIO_FLAG_C & LAN_FIO_PATTERN)) return IRQ_NONE;    *pFIO_FLAG_C = LAN_FIO_PATTERN;    asm __volatile__ ("ssync;");#endif	/* comment by mhfan *///	printk("net isr --->\n");/* //---	if((GEDR2 & 0x40000000) == 0)		return;   GEDR2 |= 0x40000000;   */    if (!dev) {	DMFE_DBUG(1, "dmfe_interrupt() without DEVICE arg", 0);	return IRQ_NONE;    }    tintrflag++;    /* A real interrupt coming */    db = (board_info_t *) dev->priv;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -