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

📄 xirc2ps_cs.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
do_get_stats(struct net_device *dev){    local_info_t *lp = netdev_priv(dev);    /*	lp->stats.rx_missed_errors = GetByte(?) */    return &lp->stats;}/**************** * Set all addresses: This first one is the individual address, * the next 9 addresses are taken from the multicast list and * the rest is filled with the individual address. */static voidset_addresses(struct net_device *dev){    kio_addr_t ioaddr = dev->base_addr;    local_info_t *lp = netdev_priv(dev);    struct dev_mc_list *dmi = dev->mc_list;    char *addr;    int i,j,k,n;    SelectPage(k=0x50);    for (i=0,j=8,n=0; ; i++, j++) {	if (i > 5) {	    if (++n > 9)		break;	    i = 0;	}	if (j > 15) {	    j = 8;	    k++;	    SelectPage(k);	}	if (n && n <= dev->mc_count && dmi) {	    addr = dmi->dmi_addr;	    dmi = dmi->next;	} else	    addr = dev->dev_addr;	if (lp->mohawk)	    PutByte(j, addr[5-i]);	else	    PutByte(j, addr[i]);    }    SelectPage(0);}/**************** * Set or clear the multicast filter for this adaptor. * We can filter up to 9 addresses, if more are requested we set * multicast promiscuous mode. */static voidset_multicast_list(struct net_device *dev){    kio_addr_t ioaddr = dev->base_addr;    SelectPage(0x42);    if (dev->flags & IFF_PROMISC) { /* snoop */	PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */    } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {	PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */    } else if (dev->mc_count) {	/* the chip can filter 9 addresses perfectly */	PutByte(XIRCREG42_SWC1, 0x00);	SelectPage(0x40);	PutByte(XIRCREG40_CMD0, Offline);	set_addresses(dev);	SelectPage(0x40);	PutByte(XIRCREG40_CMD0, EnableRecv | Online);    } else { /* standard usage */	PutByte(XIRCREG42_SWC1, 0x00);    }    SelectPage(0);}static intdo_config(struct net_device *dev, struct ifmap *map){    local_info_t *local = netdev_priv(dev);    DEBUG(0, "do_config(%p)\n", dev);    if (map->port != 255 && map->port != dev->if_port) {	if (map->port > 4)	    return -EINVAL;	if (!map->port) {	    local->probe_port = 1;	    dev->if_port = 1;	} else {	    local->probe_port = 0;	    dev->if_port = map->port;	}	printk(KERN_INFO "%s: switching to %s port\n",	       dev->name, if_names[dev->if_port]);	do_reset(dev,1);  /* not the fine way :-) */    }    return 0;}/**************** * Open the driver */static intdo_open(struct net_device *dev){    local_info_t *lp = netdev_priv(dev);    dev_link_t *link = &lp->link;    DEBUG(0, "do_open(%p)\n", dev);    /* Check that the PCMCIA card is still here. */    /* Physical device present signature. */    if (!DEV_OK(link))	return -ENODEV;    /* okay */    link->open++;    netif_start_queue(dev);    do_reset(dev,1);    return 0;}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 */    Wait(HZ/25);		     /* 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 */    Wait(HZ/50);		     /* 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 */    Wait(HZ/50);		     /* wait 20 msec */    PutByte(XIRCREG_CR, 0);	     /* clear */    Wait(HZ/25);		     /* 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 */    Wait(HZ/2);		/* 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);    }    Wait(HZ/25);		     /* 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);	    Wait(HZ/50);	} 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);	    Wait(HZ/25);	/* 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++) {	    Wait(HZ/10);	 /* 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_driver xirc2ps_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "xirc2ps_cs",	},	.attach		= xirc2ps_attach,	.detach		= xirc2ps_detach,};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 + -