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

📄 de4x5.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
static void    enable_ast(struct net_device *dev, u32 time_out);static long    de4x5_switch_mac_port(struct net_device *dev);static int     gep_rd(struct net_device *dev);static void    gep_wr(s32 data, struct net_device *dev);static void    timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec);static void    yawn(struct net_device *dev, int state);static void    de4x5_parse_params(struct net_device *dev);static void    de4x5_dbg_open(struct net_device *dev);static void    de4x5_dbg_mii(struct net_device *dev, int k);static void    de4x5_dbg_media(struct net_device *dev);static void    de4x5_dbg_srom(struct de4x5_srom *p);static void    de4x5_dbg_rx(struct sk_buff *skb, int len);static int     de4x5_strncmp(char *a, char *b, int n);static int     dc21041_infoleaf(struct net_device *dev);static int     dc21140_infoleaf(struct net_device *dev);static int     dc21142_infoleaf(struct net_device *dev);static int     dc21143_infoleaf(struct net_device *dev);static int     type0_infoblock(struct net_device *dev, u_char count, u_char *p);static int     type1_infoblock(struct net_device *dev, u_char count, u_char *p);static int     type2_infoblock(struct net_device *dev, u_char count, u_char *p);static int     type3_infoblock(struct net_device *dev, u_char count, u_char *p);static int     type4_infoblock(struct net_device *dev, u_char count, u_char *p);static int     type5_infoblock(struct net_device *dev, u_char count, u_char *p);static int     compact_infoblock(struct net_device *dev, u_char count, u_char *p);/*** Note now that module autoprobing is allowed under EISA and PCI. The** IRQ lines will not be auto-detected; instead I'll rely on the BIOSes** to "do the right thing".*/static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED        */module_param(io, int, 0);module_param(de4x5_debug, int, 0);module_param(dec_only, int, 0);module_param(args, charp, 0);MODULE_PARM_DESC(io, "de4x5 I/O base address");MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask");MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)");MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details");MODULE_LICENSE("GPL");/*** List the SROM infoleaf functions and chipsets*/struct InfoLeaf {    int chipset;    int (*fn)(struct net_device *);};static struct InfoLeaf infoleaf_array[] = {    {DC21041, dc21041_infoleaf},    {DC21140, dc21140_infoleaf},    {DC21142, dc21142_infoleaf},    {DC21143, dc21143_infoleaf}};#define INFOLEAF_SIZE (sizeof(infoleaf_array)/(sizeof(int)+sizeof(int *)))/*** List the SROM info block functions*/static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = {    type0_infoblock,    type1_infoblock,    type2_infoblock,    type3_infoblock,    type4_infoblock,    type5_infoblock,    compact_infoblock};#define COMPACT (sizeof(dc_infoblock)/sizeof(int *) - 1)/*** Miscellaneous defines...*/#define RESET_DE4X5 {\    int i;\    i=inl(DE4X5_BMR);\    mdelay(1);\    outl(i | BMR_SWR, DE4X5_BMR);\    mdelay(1);\    outl(i, DE4X5_BMR);\    mdelay(1);\    for (i=0;i<5;i++) {inl(DE4X5_BMR); mdelay(1);}\    mdelay(1);\}#define PHY_HARD_RESET {\    outl(GEP_HRST, DE4X5_GEP);           /* Hard RESET the PHY dev. */\    mdelay(1);                           /* Assert for 1ms */\    outl(0x00, DE4X5_GEP);\    mdelay(2);                           /* Wait for 2ms */\}static int __devinit de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev){    char name[DE4X5_NAME_LENGTH + 1];    struct de4x5_private *lp = netdev_priv(dev);    struct pci_dev *pdev = NULL;    int i, status=0;    gendev->driver_data = dev;    /* Ensure we're not sleeping */    if (lp->bus == EISA) {	outb(WAKEUP, PCI_CFPM);    } else {	pdev = to_pci_dev (gendev);	pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP);    }    mdelay(10);    RESET_DE4X5;        if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) {	return -ENXIO;                       /* Hardware could not reset */    }        /*     ** Now find out what kind of DC21040/DC21041/DC21140 board we have.    */    lp->useSROM = FALSE;    if (lp->bus == PCI) {	PCI_signature(name, lp);    } else {	EISA_signature(name, gendev);    }        if (*name == '\0') {                     /* Not found a board signature */	return -ENXIO;    }        dev->base_addr = iobase;    printk ("%s: %s at 0x%04lx", gendev->bus_id, name, iobase);        printk(", h/w address ");    status = get_hw_addr(dev);    for (i = 0; i < ETH_ALEN - 1; i++) {     /* get the ethernet addr. */	printk("%2.2x:", dev->dev_addr[i]);    }    printk("%2.2x,\n", dev->dev_addr[i]);        if (status != 0) {	printk("      which has an Ethernet PROM CRC error.\n");	return -ENXIO;    } else {	lp->cache.gepc = GEP_INIT;	lp->asBit = GEP_SLNK;	lp->asPolarity = GEP_SLNK;	lp->asBitValid = TRUE;	lp->timeout = -1;	lp->gendev = gendev;	spin_lock_init(&lp->lock);	init_timer(&lp->timer);	de4x5_parse_params(dev);	/*	** Choose correct autosensing in case someone messed up	*/        lp->autosense = lp->params.autosense;        if (lp->chipset != DC21140) {            if ((lp->chipset==DC21040) && (lp->params.autosense&TP_NW)) {                lp->params.autosense = TP;            }            if ((lp->chipset==DC21041) && (lp->params.autosense&BNC_AUI)) {                lp->params.autosense = BNC;            }        }	lp->fdx = lp->params.fdx;	sprintf(lp->adapter_name,"%s (%s)", name, gendev->bus_id);	lp->dma_size = (NUM_RX_DESC + NUM_TX_DESC) * sizeof(struct de4x5_desc);#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc_v9__) || defined(DE4X5_DO_MEMCPY)	lp->dma_size += RX_BUFF_SZ * NUM_RX_DESC + DE4X5_ALIGN;#endif	lp->rx_ring = dma_alloc_coherent(gendev, lp->dma_size,					 &lp->dma_rings, GFP_ATOMIC);	if (lp->rx_ring == NULL) {	    return -ENOMEM;	}	lp->tx_ring = lp->rx_ring + NUM_RX_DESC;	    	/*	** Set up the RX descriptor ring (Intels)	** Allocate contiguous receive buffers, long word aligned (Alphas) 	*/#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc_v9__) && !defined(DE4X5_DO_MEMCPY)	for (i=0; i<NUM_RX_DESC; i++) {	    lp->rx_ring[i].status = 0;	    lp->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);	    lp->rx_ring[i].buf = 0;	    lp->rx_ring[i].next = 0;	    lp->rx_skb[i] = (struct sk_buff *) 1;     /* Dummy entry */	}#else	{		dma_addr_t dma_rx_bufs;		dma_rx_bufs = lp->dma_rings + (NUM_RX_DESC + NUM_TX_DESC)		      	* sizeof(struct de4x5_desc);		dma_rx_bufs = (dma_rx_bufs + DE4X5_ALIGN) & ~DE4X5_ALIGN;		lp->rx_bufs = (char *)(((long)(lp->rx_ring + NUM_RX_DESC		      	+ NUM_TX_DESC) + DE4X5_ALIGN) & ~DE4X5_ALIGN);		for (i=0; i<NUM_RX_DESC; i++) {	    		lp->rx_ring[i].status = 0;	    		lp->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);	    		lp->rx_ring[i].buf =				cpu_to_le32(dma_rx_bufs+i*RX_BUFF_SZ);	    		lp->rx_ring[i].next = 0;	    		lp->rx_skb[i] = (struct sk_buff *) 1; /* Dummy entry */		}	}#endif	barrier();	lp->rxRingSize = NUM_RX_DESC;	lp->txRingSize = NUM_TX_DESC;	    	/* Write the end of list marker to the descriptor lists */	lp->rx_ring[lp->rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);	lp->tx_ring[lp->txRingSize - 1].des1 |= cpu_to_le32(TD_TER);	/* Tell the adapter where the TX/RX rings are located. */	outl(lp->dma_rings, DE4X5_RRBA);	outl(lp->dma_rings + NUM_RX_DESC * sizeof(struct de4x5_desc),	     DE4X5_TRBA);	    	/* Initialise the IRQ mask and Enable/Disable */	lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM | IMR_UNM;	lp->irq_en   = IMR_NIM | IMR_AIM;	/* Create a loopback packet frame for later media probing */	create_packet(dev, lp->frame, sizeof(lp->frame));	/* Check if the RX overflow bug needs testing for */	i = lp->cfrv & 0x000000fe;	if ((lp->chipset == DC21140) && (i == 0x20)) {	    lp->rx_ovf = 1;	}	/* Initialise the SROM pointers if possible */	if (lp->useSROM) {	    lp->state = INITIALISED;	    if (srom_infoleaf_info(dev)) {	        dma_free_coherent (gendev, lp->dma_size,			       lp->rx_ring, lp->dma_rings);		return -ENXIO;	    }	    srom_init(dev);	}	lp->state = CLOSED;	/*	** Check for an MII interface	*/	if ((lp->chipset != DC21040) && (lp->chipset != DC21041)) {	    mii_get_phy(dev);	}	#ifndef __sparc_v9__	printk("      and requires IRQ%d (provided by %s).\n", dev->irq,#else	printk("      and requires IRQ%x (provided by %s).\n", dev->irq,#endif	       ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG"));    }        if (de4x5_debug & DEBUG_VERSION) {	printk(version);    }        /* The DE4X5-specific entries in the device structure. */    SET_MODULE_OWNER(dev);    SET_NETDEV_DEV(dev, gendev);    dev->open = &de4x5_open;    dev->hard_start_xmit = &de4x5_queue_pkt;    dev->stop = &de4x5_close;    dev->get_stats = &de4x5_get_stats;    dev->set_multicast_list = &set_multicast_list;    dev->do_ioctl = &de4x5_ioctl;        dev->mem_start = 0;        /* Fill in the generic fields of the device structure. */    if ((status = register_netdev (dev))) {	    dma_free_coherent (gendev, lp->dma_size,			       lp->rx_ring, lp->dma_rings);	    return status;    }        /* Let the adapter sleep to save power */    yawn(dev, SLEEP);        return status;}static intde4x5_open(struct net_device *dev){    struct de4x5_private *lp = netdev_priv(dev);    u_long iobase = dev->base_addr;    int i, status = 0;    s32 omr;    /* Allocate the RX buffers */    for (i=0; i<lp->rxRingSize; i++) {	if (de4x5_alloc_rx_buff(dev, i, 0) == NULL) {	    de4x5_free_rx_buffs(dev);	    return -EAGAIN;	}    }    /*    ** Wake up the adapter    */    yawn(dev, WAKEUP);    /*     ** Re-initialize the DE4X5... 

⌨️ 快捷键说明

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