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

📄 xirc2ps_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
}static void netdev_get_drvinfo(struct net_device *dev,			       struct ethtool_drvinfo *info){	strcpy(info->driver, "xirc2ps_cs");	sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);}static struct ethtool_ops netdev_ethtool_ops = {	.get_drvinfo		= netdev_get_drvinfo,};static intdo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){    local_info_t *local = netdev_priv(dev);    kio_addr_t ioaddr = dev->base_addr;    u16 *data = (u16 *)&rq->ifr_ifru;    DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",	  dev->name, rq->ifr_ifrn.ifrn_name, cmd,	  data[0], data[1], data[2], data[3]);    if (!local->mohawk)	return -EOPNOTSUPP;    switch(cmd) {      case SIOCGMIIPHY:		/* Get the address of the PHY in use. */	data[0] = 0;		/* we have only this address */	/* fall trough */      case SIOCGMIIREG:		/* Read the specified MII register. */	data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f);	break;      case SIOCSMIIREG:		/* Write the specified MII register */	if (!capable(CAP_NET_ADMIN))	    return -EPERM;	mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16);	break;      default:	return -EOPNOTSUPP;    }    return 0;}static voidhardreset(struct net_device *dev){    local_info_t *local = netdev_priv(dev);    kio_addr_t ioaddr = dev->base_addr;    SelectPage(4);    udelay(1);    PutByte(XIRCREG4_GPR1, 0);	     /* clear bit 0: power down */    msleep(40);				     /* wait 40 msec */    if (local->mohawk)	PutByte(XIRCREG4_GPR1, 1);	 /* set bit 0: power up */    else	PutByte(XIRCREG4_GPR1, 1 | 4);	 /* set bit 0: power up, bit 2: AIC */    msleep(20);			     /* wait 20 msec */}static voiddo_reset(struct net_device *dev, int full){    local_info_t *local = netdev_priv(dev);    kio_addr_t ioaddr = dev->base_addr;    unsigned value;    DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);    hardreset(dev);    PutByte(XIRCREG_CR, SoftReset); /* set */    msleep(20);			     /* wait 20 msec */    PutByte(XIRCREG_CR, 0);	     /* clear */    msleep(40);			     /* wait 40 msec */    if (local->mohawk) {	SelectPage(4);	/* set pin GP1 and GP2 to output  (0x0c)	 * set GP1 to low to power up the ML6692 (0x00)	 * set GP2 to high to power up the 10Mhz chip  (0x02)	 */	PutByte(XIRCREG4_GPR0, 0x0e);    }    /* give the circuits some time to power up */    msleep(500);			/* about 500ms */    local->last_ptr_value = 0;    local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4				   : (GetByte(XIRCREG4_BOV) & 0x30) >> 4;    if (local->probe_port) {	if (!local->mohawk) {	    SelectPage(4);	    PutByte(XIRCREG4_GPR0, 4);	    local->probe_port = 0;	}    } else if (dev->if_port == 2) { /* enable 10Base2 */	SelectPage(0x42);	PutByte(XIRCREG42_SWC1, 0xC0);    } else { /* enable 10BaseT */	SelectPage(0x42);	PutByte(XIRCREG42_SWC1, 0x80);    }    msleep(40);			     /* wait 40 msec to let it complete */  #ifdef PCMCIA_DEBUG    if (pc_debug) {	SelectPage(0);	value = GetByte(XIRCREG_ESR);	 /* read the ESR */	printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);    }  #endif    /* setup the ECR */    SelectPage(1);    PutByte(XIRCREG1_IMR0, 0xff); /* allow all ints */    PutByte(XIRCREG1_IMR1, 1	); /* and Set TxUnderrunDetect */    value = GetByte(XIRCREG1_ECR);  #if 0    if (local->mohawk)	value |= DisableLinkPulse;    PutByte(XIRCREG1_ECR, value);  #endif    DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);    SelectPage(0x42);    PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */    if (local->silicon != 1) {	/* set the local memory dividing line.	 * The comments in the sample code say that this is only	 * settable with the scipper version 2 which is revision 0.	 * Always for CE3 cards	 */	SelectPage(2);	PutWord(XIRCREG2_RBS, 0x2000);    }    if (full)	set_addresses(dev);    /* Hardware workaround:     * The receive byte pointer after reset is off by 1 so we need     * to move the offset pointer back to 0.     */    SelectPage(0);    PutWord(XIRCREG0_DO, 0x2000); /* change offset command, off=0 */    /* setup MAC IMRs and clear status registers */    SelectPage(0x40);		     /* Bit 7 ... bit 0 */    PutByte(XIRCREG40_RMASK0, 0xff); /* ROK, RAB, rsv, RO, CRC, AE, PTL, MP */    PutByte(XIRCREG40_TMASK0, 0xff); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */    PutByte(XIRCREG40_TMASK1, 0xb0); /* rsv, rsv, PTD, EXT, rsv,rsv,rsv, rsv*/    PutByte(XIRCREG40_RXST0,  0x00); /* ROK, RAB, REN, RO, CRC, AE, PTL, MP */    PutByte(XIRCREG40_TXST0,  0x00); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */    PutByte(XIRCREG40_TXST1,  0x00); /* TEN, rsv, PTD, EXT, retry_counter:4  */    if (full && local->mohawk && init_mii(dev)) {	if (dev->if_port == 4 || local->dingo || local->new_mii) {	    printk(KERN_INFO "%s: MII selected\n", dev->name);	    SelectPage(2);	    PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);	    msleep(20);	} else {	    printk(KERN_INFO "%s: MII detected; using 10mbs\n",		   dev->name);	    SelectPage(0x42);	    if (dev->if_port == 2) /* enable 10Base2 */		PutByte(XIRCREG42_SWC1, 0xC0);	    else  /* enable 10BaseT */		PutByte(XIRCREG42_SWC1, 0x80);	    msleep(40);			/* wait 40 msec to let it complete */	}	if (full_duplex)	    PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex));    } else {  /* No MII */	SelectPage(0);	value = GetByte(XIRCREG_ESR);	 /* read the ESR */	dev->if_port = (value & MediaSelect) ? 1 : 2;    }    /* configure the LEDs */    SelectPage(2);    if (dev->if_port == 1 || dev->if_port == 4) /* TP: Link and Activity */	PutByte(XIRCREG2_LED, 0x3b);    else			      /* Coax: Not-Collision and Activity */	PutByte(XIRCREG2_LED, 0x3a);    if (local->dingo)	PutByte(0x0b, 0x04); /* 100 Mbit LED */    /* enable receiver and put the mac online */    if (full) {	SelectPage(0x40);	PutByte(XIRCREG40_CMD0, EnableRecv | Online);    }    /* setup Ethernet IMR and enable interrupts */    SelectPage(1);    PutByte(XIRCREG1_IMR0, 0xff);    udelay(1);    SelectPage(0);    PutByte(XIRCREG_CR, EnableIntr);    if (local->modem && !local->dingo) { /* do some magic */	if (!(GetByte(0x10) & 0x01))	    PutByte(0x10, 0x11); /* unmask master-int bit */    }    if (full)	printk(KERN_INFO "%s: media %s, silicon revision %d\n",	       dev->name, if_names[dev->if_port], local->silicon);    /* We should switch back to page 0 to avoid a bug in revision 0     * where regs with offset below 8 can't be read after an access     * to the MAC registers */    SelectPage(0);}/**************** * Initialize the Media-Independent-Interface * Returns: True if we have a good MII */static intinit_mii(struct net_device *dev){    local_info_t *local = netdev_priv(dev);    kio_addr_t ioaddr = dev->base_addr;    unsigned control, status, linkpartner;    int i;    if (if_port == 4 || if_port == 1) { /* force 100BaseT or 10BaseT */	dev->if_port = if_port;	local->probe_port = 0;	return 1;    }    status = mii_rd(ioaddr,  0, 1);    if ((status & 0xff00) != 0x7800)	return 0; /* No MII */    local->new_mii = (mii_rd(ioaddr, 0, 2) != 0xffff);        if (local->probe_port)	control = 0x1000; /* auto neg */    else if (dev->if_port == 4)	control = 0x2000; /* no auto neg, 100mbs mode */    else	control = 0x0000; /* no auto neg, 10mbs mode */    mii_wr(ioaddr,  0, 0, control, 16);    udelay(100);    control = mii_rd(ioaddr, 0, 0);    if (control & 0x0400) {	printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n",	       dev->name);	local->probe_port = 0;	return 0;    }    if (local->probe_port) {	/* according to the DP83840A specs the auto negotiation process	 * may take up to 3.5 sec, so we use this also for our ML6692	 * Fixme: Better to use a timer here!	 */	for (i=0; i < 35; i++) {	    msleep(100);	 /* wait 100 msec */	    status = mii_rd(ioaddr,  0, 1);	    if ((status & 0x0020) && (status & 0x0004))		break;	}	if (!(status & 0x0020)) {	    printk(KERN_INFO "%s: autonegotiation failed;"		   " using 10mbs\n", dev->name);	    if (!local->new_mii) {		control = 0x0000;		mii_wr(ioaddr,  0, 0, control, 16);		udelay(100);		SelectPage(0);		dev->if_port = (GetByte(XIRCREG_ESR) & MediaSelect) ? 1 : 2;	    }	} else {	    linkpartner = mii_rd(ioaddr, 0, 5);	    printk(KERN_INFO "%s: MII link partner: %04x\n",		   dev->name, linkpartner);	    if (linkpartner & 0x0080) {		dev->if_port = 4;	    } else		dev->if_port = 1;	}    }    return 1;}static voiddo_powerdown(struct net_device *dev){    kio_addr_t ioaddr = dev->base_addr;    DEBUG(0, "do_powerdown(%p)\n", dev);    SelectPage(4);    PutByte(XIRCREG4_GPR1, 0);	     /* clear bit 0: power down */    SelectPage(0);}static intdo_stop(struct net_device *dev){    kio_addr_t ioaddr = dev->base_addr;    local_info_t *lp = netdev_priv(dev);    dev_link_t *link = &lp->link;    DEBUG(0, "do_stop(%p)\n", dev);    if (!link)	return -ENODEV;    netif_stop_queue(dev);    SelectPage(0);    PutByte(XIRCREG_CR, 0);  /* disable interrupts */    SelectPage(0x01);    PutByte(XIRCREG1_IMR0, 0x00); /* forbid all ints */    SelectPage(4);    PutByte(XIRCREG4_GPR1, 0);	/* clear bit 0: power down */    SelectPage(0);    link->open--;    return 0;}static struct pcmcia_device_id xirc2ps_ids[] = {	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0089, 0x110a),	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0138, 0x110a),	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a),	PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2),	PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37),	PCMCIA_DEVICE_PROD_ID13("Xircom", "PS-CE2-10", 0x2e3ee845, 0x947d9073),	PCMCIA_DEVICE_PROD_ID13("Xircom", "R2E-100BTX", 0x2e3ee845, 0x2464a6e3),	PCMCIA_DEVICE_PROD_ID13("Xircom", "RE-10", 0x2e3ee845, 0x3e08d609),	PCMCIA_DEVICE_PROD_ID13("Xircom", "XE2000", 0x2e3ee845, 0xf7188e46),	PCMCIA_DEVICE_PROD_ID12("Compaq", "Ethernet LAN Card", 0x54f7c49c, 0x9fd2f0a2),	PCMCIA_DEVICE_PROD_ID12("Compaq", "Netelligent 10/100 PC Card", 0x54f7c49c, 0xefe96769),	PCMCIA_DEVICE_PROD_ID12("Intel", "EtherExpress(TM) PRO/100 PC Card Mobile Adapter16", 0x816cc815, 0x174397db),	PCMCIA_DEVICE_PROD_ID12("Toshiba", "10/100 Ethernet PC Card", 0x44a09d9c, 0xb44deecf),	/* also matches CFE-10 cards! */	/* PCMCIA_DEVICE_MANF_CARD(0x0105, 0x010a), */	PCMCIA_DEVICE_NULL,};MODULE_DEVICE_TABLE(pcmcia, xirc2ps_ids);static struct pcmcia_driver xirc2ps_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "xirc2ps_cs",	},	.attach		= xirc2ps_attach,	.event		= xirc2ps_event,	.detach		= xirc2ps_detach,	.id_table       = xirc2ps_ids,};static int __initinit_xirc2ps_cs(void){	return pcmcia_register_driver(&xirc2ps_cs_driver);}static void __exitexit_xirc2ps_cs(void){	pcmcia_unregister_driver(&xirc2ps_cs_driver);	BUG_ON(dev_list != NULL);}module_init(init_xirc2ps_cs);module_exit(exit_xirc2ps_cs);#ifndef MODULEstatic int __init setup_xirc2ps_cs(char *str){	/* if_port, full_duplex, do_sound, lockup_hack	 */	int ints[10] = { -1 };	str = get_options(str, 9, ints);#define MAYBE_SET(X,Y) if (ints[0] >= Y && ints[Y] != -1) { X = ints[Y]; }	MAYBE_SET(if_port, 3);	MAYBE_SET(full_duplex, 4);	MAYBE_SET(do_sound, 5);	MAYBE_SET(lockup_hack, 6);#undef  MAYBE_SET	return 0;}__setup("xirc2ps_cs=", setup_xirc2ps_cs);#endif

⌨️ 快捷键说明

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