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

📄 via-rhine.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 C
📖 第 1 页 / 共 3 页
字号:
    byMIIAdrbak = inb (byMIIAD);    byMIICRbak = inb (byMIICR);    outb (byMIICRbak & 0x7f, byMIICR);    MIIDelay ();    outb (byMIISetByte, byMIIAD);    MIIDelay ();    outb (inb (byMIICR) | 0x40, byMIICR);    byMIItemp = inb (byMIICR);    byMIItemp = byMIItemp & 0x40;    while (byMIItemp != 0)    {	byMIItemp = inb (byMIICR);	byMIItemp = byMIItemp & 0x40;    }    MIIDelay ();    ReadMIItmp = inw (wMIIDATA);    MIIMask = 0x0001;    MIIMask = MIIMask << byMIISetBit;    if (byMIIOP == 0)    {	MIIMask = ~MIIMask;	ReadMIItmp = ReadMIItmp & MIIMask;    }    else    {	ReadMIItmp = ReadMIItmp | MIIMask;    }    outw (ReadMIItmp, wMIIDATA);    MIIDelay ();    outb (inb (byMIICR) | 0x20, byMIICR);    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);    }}struct nic *rhine_probe (struct nic *nic, unsigned short *probeaddrs,	       struct pci_device *pci){    if (!pci->ioaddr)	return NULL;    nic = rhine_probe1 (nic, pci->ioaddr, 0, -1);    if (nic)	adjust_pci_device(pci);    nic->poll = rhine_poll;    nic->transmit = rhine_transmit;    nic->reset = rhine_reset;    nic->disable = rhine_disable;    rhine_reset (nic);    return nic;}static struct nic *rhine_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);    /* 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 nic;}static voidrhine_disable (struct nic *nic){    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;    int ioaddr = tp->ioaddr;    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;#ifdef	USE_LOWMEM_BUFFER#define buf1 (0x10000 - (RX_RING_SIZE * PKT_BUF_SZ + 32))#define buf2 (buf1 - (RX_RING_SIZE * PKT_BUF_SZ + 32))#define desc1 (buf2 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))#define desc2 (desc1 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))#else    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];#endif    /* 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);    /* 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);    tp->cur_tx++;    /*outw(IMRShadow,byIMR0); */    /*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */    /*tp->tx_skbuff[entry] = 0; */}/* EOF via-rhine.c */

⌨️ 快捷键说明

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