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

📄 via-rhine.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 3 页
字号:
    byMIItemp = inb (byMIICR);    byMIItemp = byMIItemp & 0x20;    while (byMIItemp != 0)    {	byMIItemp = inb (byMIICR);	byMIItemp = byMIItemp & 0x20;    }    MIIDelay ();    outb (byMIIAdrbak & 0x7f, byMIIAD);    outb (byMIICRbak, byMIICR);    MIIDelay ();}voidMIIDelay (void){    int i;    for (i = 0; i < 0x7fff; i++)    {	inb (0x61);	inb (0x61);	inb (0x61);	inb (0x61);    }}static intrhine_probe (struct dev *dev, struct pci_device *pci){    struct nic *nic = (struct nic *)dev;    if (!pci->ioaddr)	return 0;    rhine_probe1 (nic, pci->ioaddr, pci->dev_id, -1);    adjust_pci_device(pci);    rhine_reset (nic);    dev->disable  = rhine_disable;    nic->poll     = rhine_poll;    nic->transmit = rhine_transmit;    return 1;}static void set_rx_mode(struct nic *nic __unused) {    	struct rhine_private *tp = (struct rhine_private *) nic->priv_data;	unsigned char rx_mode;    	int ioaddr = tp->ioaddr;	/* ! IFF_PROMISC */	outl(0xffffffff, byMAR0);	outl(0xffffffff, byMAR4);	rx_mode = 0x0C;	outb(0x60 /* thresh */ | rx_mode, byRCR );}static voidrhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options){    struct rhine_private *tp;    static int did_version = 0;	/* Already printed version info. */    int i;    unsigned int timeout;    int FDXFlag;    int byMIIvalue, LineSpeed, MIICRbak;    if (rhine_debug > 0 && did_version++ == 0)	printf (version);    /* D-Link provided reset code (with comment additions) */    if((chip_id != 0x3043) && (chip_id != 0x6100)) {	unsigned char byOrgValue;		if(rhine_debug > 0)		printf("Enabling Sticky Bit Workaround for Chip_id: 0x%hX\n"				, chip_id);	/* clear sticky bit before reset & read ethernet address */	byOrgValue = inb(bySTICKHW);	byOrgValue = byOrgValue & 0xFC;	outb(byOrgValue, bySTICKHW);	/* (bits written are cleared?) */	/* disable force PME-enable */	outb(0x80, byWOLcgClr);	/* disable power-event config bit */	outb(0xFF, byWOLcrClr);	/* clear power status (undocumented in vt6102 docs?) */	outb(0xFF, byPwrcsrClr);	    }    /* Perhaps this should be read from the EEPROM? */    for (i = 0; i < ETH_ALEN; i++)	nic->node_addr[i] = inb (byPAR0 + i);    printf ("IO address %hX Ethernet Address: %!\n", ioaddr, nic->node_addr);    /* restart MII auto-negotiation */    WriteMII (0, 9, 1, ioaddr);    printf ("Analyzing Media type,this will take several seconds........");    for (i = 0; i < 5; i++)    {	/* need to wait 1 millisecond - we will round it up to 50-100ms */	timeout = currticks() + 2;	for (timeout = currticks() + 2; currticks() < timeout;)	    /* nothing */;	if (ReadMII (1, ioaddr) & 0x0020)	    break;    }    printf ("OK\n");#if	0	/* JJM : for Debug */	printf("MII : Address %hhX ",inb(ioaddr+0x6c));	{	 unsigned char st1,st2,adv1,adv2,l1,l2;		 st1=ReadMII(1,ioaddr)>>8;	 st2=ReadMII(1,ioaddr)&0xFF;	 adv1=ReadMII(4,ioaddr)>>8;	 adv2=ReadMII(4,ioaddr)&0xFF;	 l1=ReadMII(5,ioaddr)>>8;	 l2=ReadMII(5,ioaddr)&0xFF;	 printf(" status 0x%hhX%hhX, advertising 0x%hhX%hhX, link 0x%hhX%hhX\n", st1,st2,adv1,adv2,l1,l2);	}#endif        /* query MII to know LineSpeed,duplex mode */    byMIIvalue = inb (ioaddr + 0x6d);    LineSpeed = byMIIvalue & MIISR_SPEED;    if (LineSpeed != 0)						//JJM    {	printf ("Linespeed=10Mbs");    }    else    {	printf ("Linespeed=100Mbs");    }	    FDXFlag = QueryAuto (ioaddr);    if (FDXFlag == 1)    {	printf (" Fullduplex\n");	outw (CR_FDX, byCR0);    }    else    {	printf (" Halfduplex\n");    }    /* set MII 10 FULL ON */    WriteMII (17, 1, 1, ioaddr);    /* turn on MII link change */    MIICRbak = inb (byMIICR);    outb (MIICRbak & 0x7F, byMIICR);    MIIDelay ();    outb (0x41, byMIIAD);    MIIDelay ();    /* while((inb(byMIIAD)&0x20)==0) ; */    outb (MIICRbak | 0x80, byMIICR);    nic->priv_data = &rhine;    tp = &rhine;    tp->chip_id = chip_id;    tp->ioaddr = ioaddr;    tp->phys[0] = -1;    /* The lower four bits are the media type. */    if (options > 0)    {	tp->full_duplex = (options & 16) ? 1 : 0;	tp->default_port = options & 15;	if (tp->default_port)	    tp->medialock = 1;    }    return;}static void rhine_disable (struct dev *dev){    struct nic *nic = (struct nic *)dev;    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;    int ioaddr = tp->ioaddr;    /* merge reset and disable */    rhine_reset(nic);    printf ("rhine disable\n");    /* Switch to loopback mode to avoid hardware races. */    writeb(0x60 | 0x01, byTCR);    /* Stop the chip's Tx and Rx processes. */    writew(CR_STOP, byCR0);}/**************************************************************************ETH_RESET - Reset adapter***************************************************************************/static voidrhine_reset (struct nic *nic){    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;    int ioaddr = tp->ioaddr;    int i, j;    int FDXFlag, CRbak;    int rx_ring_tmp, rx_ring_tmp1;    int tx_ring_tmp, tx_ring_tmp1;    int rx_bufs_tmp, rx_bufs_tmp1;    int tx_bufs_tmp, tx_bufs_tmp1;    static char buf1[RX_RING_SIZE * PKT_BUF_SZ + 32];    static char buf2[RX_RING_SIZE * PKT_BUF_SZ + 32];    static char desc1[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];    static char desc2[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];    /* printf ("rhine_reset\n"); */    /* Soft reset the chip. */    /*outb(CmdReset, ioaddr + ChipCmd); */    tx_bufs_tmp = (int) buf1;    tx_ring_tmp = (int) desc1;    rx_bufs_tmp = (int) buf2;    rx_ring_tmp = (int) desc2;    /* tune RD TD 32 byte alignment */    rx_ring_tmp1 = (int) virt_to_bus ((char *) rx_ring_tmp);    j = (rx_ring_tmp1 + 32) & (~0x1f);    /* printf ("txring[%d]", j); */    tp->rx_ring = (struct rhine_rx_desc *) bus_to_virt (j);    tx_ring_tmp1 = (int) virt_to_bus ((char *) tx_ring_tmp);    j = (tx_ring_tmp1 + 32) & (~0x1f);    tp->tx_ring = (struct rhine_tx_desc *) bus_to_virt (j);    /* printf ("rxring[%X]", j); */    tx_bufs_tmp1 = (int) virt_to_bus ((char *) tx_bufs_tmp);    j = (int) (tx_bufs_tmp1 + 32) & (~0x1f);    tx_bufs_tmp = (int) bus_to_virt (j);    /* printf ("txb[%X]", j); */    rx_bufs_tmp1 = (int) virt_to_bus ((char *) rx_bufs_tmp);    j = (int) (rx_bufs_tmp1 + 32) & (~0x1f);    rx_bufs_tmp = (int) bus_to_virt (j);    /* printf ("rxb[%X][%X]", rx_bufs_tmp1, j); */    for (i = 0; i < RX_RING_SIZE; i++)    {	tp->rx_buffs[i] = (char *) rx_bufs_tmp;	/* printf("r[%X]",tp->rx_buffs[i]); */	rx_bufs_tmp += 1536;    }    for (i = 0; i < TX_RING_SIZE; i++)    {	tp->tx_buffs[i] = (char *) tx_bufs_tmp;	/* printf("t[%X]",tp->tx_buffs[i]);  */	tx_bufs_tmp += 1536;    }    /* software reset */    outb (CR1_SFRST, byCR1);    MIIDelay ();    /* printf ("init ring"); */    rhine_init_ring (nic);    /*write TD RD Descriptor to MAC */    outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);    outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);    /* Setup Multicast */	    set_rx_mode(nic);    /* close IMR */    outw (0x0000, byIMR0);    /* set TCR RCR threshold */    outb (0x06, byBCR0);    outb (0x00, byBCR1);    outb (0x2c, byRCR);    outb (0x60, byTCR);    /* Set Fulldupex */    FDXFlag = QueryAuto (ioaddr);    if (FDXFlag == 1)    {	outb (CFGD_CFDX, byCFGD);	outw (CR_FDX, byCR0);    }    /* KICK NIC to WORK */    CRbak = inw (byCR0);    CRbak = CRbak & 0xFFFB;	/* not CR_STOP */    outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);    /*set IMR to work */    outw (IMRShadow, byIMR0);}static intrhine_poll (struct nic *nic){    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;    int rxstatus, good = 0;;    if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)    {	rxstatus = tp->rx_ring[tp->cur_rx].rx_status.lw;	if ((rxstatus & 0x0300) != 0x0300)	{	    printf("rhine_poll: bad status\n");	}	else if (rxstatus & (RSR_ABNORMAL))	{	    printf ("rxerr[%X]\n", rxstatus);	}	else	    good = 1;	if (good)	{	    nic->packetlen = tp->rx_ring[tp->cur_rx].rx_status.bits.frame_length;	    memcpy (nic->packet, tp->rx_buffs[tp->cur_rx], nic->packetlen);	    /* printf ("Packet RXed\n"); */	}	tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit = 1;	tp->cur_rx++;	tp->cur_rx = tp->cur_rx % RX_RING_SIZE;    }    return good;}static voidrhine_transmit (struct nic *nic,		const char *d, unsigned int t, unsigned int s, const char *p){    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;    int ioaddr = tp->ioaddr;    int entry;    unsigned char CR1bak;    /*printf ("rhine_transmit\n"); */    /* setup ethernet header */    /* Calculate the next Tx descriptor entry. */    entry = tp->cur_tx % TX_RING_SIZE;    memcpy (tp->tx_buffs[entry], d, ETH_ALEN);	/* dst */    memcpy (tp->tx_buffs[entry] + ETH_ALEN, nic->node_addr, ETH_ALEN);	/* src */    *((char *) tp->tx_buffs[entry] + 12) = t >> 8;	/* type */    *((char *) tp->tx_buffs[entry] + 13) = t;    memcpy (tp->tx_buffs[entry] + ETH_HLEN, p, s);    s += ETH_HLEN;    while (s < ETH_ZLEN)	*((char *) tp->tx_buffs[entry] + ETH_HLEN + (s++)) = 0;    tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = ETH_HLEN + s;    tp->tx_ring[entry].tx_status.bits.own_bit = 1;    CR1bak = inb (byCR1);    CR1bak = CR1bak | CR1_TDMD1;    /*printf("tdsw=[%X]",tp->tx_ring[entry].tx_status.lw); */    /*printf("tdcw=[%X]",tp->tx_ring[entry].tx_ctrl.lw); */    /*printf("tdbuf1=[%X]",tp->tx_ring[entry].buf_addr_1); */    /*printf("tdbuf2=[%X]",tp->tx_ring[entry].buf_addr_2); */    /*printf("td1=[%X]",inl(dwCurrentTDSE0)); */    /*printf("td2=[%X]",inl(dwCurrentTDSE1)); */    /*printf("td3=[%X]",inl(dwCurrentTDSE2)); */    /*printf("td4=[%X]",inl(dwCurrentTDSE3)); */    outb (CR1bak, byCR1);    /* Wait until transmit is finished */    while (tp->tx_ring[entry].tx_status.bits.own_bit != 0)	;    tp->cur_tx++;    /*outw(IMRShadow,byIMR0); */    /*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */    /*tp->tx_skbuff[entry] = 0; */}static struct pci_id rhine_nics[] = {PCI_ROM(0x1106, 0x3065, "dlink-530tx",     "VIA 6102"),PCI_ROM(0x1106, 0x3106, "via-rhine-6105",  "VIA 6105"),PCI_ROM(0x1106, 0x3043, "dlink-530tx-old", "VIA 3043"),		/* Rhine-I 86c100a */PCI_ROM(0x1106, 0x3053, "via6105m",        "VIA 6105M"),	PCI_ROM(0x1106, 0x6100, "via-rhine-old",   "VIA 86C100A"),	/* Rhine-II */};static struct pci_driver rhine_driver __pci_driver = {	.type     = NIC_DRIVER,	.name     = "VIA 86C100",	.probe    = rhine_probe,	.ids      = rhine_nics,	.id_count = sizeof(rhine_nics)/sizeof(rhine_nics[0]),	.class    = 0,};/* EOF via-rhine.c */

⌨️ 快捷键说明

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