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

📄 sis900.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 3 页
字号:
        rx_flags |= RxATX;    }    outl (tx_flags, ioaddr + txcfg);    outl (rx_flags, ioaddr + rxcfg);}/* Function: sis900_read_mode * * Description: retrieves and displays speed and duplex *    parameters from the NIC *     * Arguments: struct nic *nic:          NIC data structure * * Returns:   void. */static voidsis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex){    int i = 0;    u32 status;    u16 phy_id0, phy_id1;            /* STSOUT register is Latched on Transition, read operation updates it */    while (i++ < 2)        status = sis900_mdio_read(phy_addr, MII_STSOUT);    *speed = HW_SPEED_10_MBPS;    *duplex = FDX_CAPABLE_HALF_SELECTED;        if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))	*speed = HW_SPEED_100_MBPS;    if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))	*duplex = FDX_CAPABLE_FULL_SELECTED;	    /* Workaround for Realtek RTL8201 PHY issue */    phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);    phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);    if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){	if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX)	    *duplex = FDX_CAPABLE_FULL_SELECTED;	if(sis900_mdio_read(phy_addr, 0x0019) & 0x01)	    *speed = HW_SPEED_100_MBPS;    }    if (status & MII_STSOUT_LINK_FAIL)        printf("sis900_read_mode: Media Link Off\n");    else        printf("sis900_read_mode: Media Link On %s %s-duplex \n",                *speed == HW_SPEED_100_MBPS ?                "100mbps" : "10mbps",               *duplex == FDX_CAPABLE_FULL_SELECTED ?               "full" : "half");}/* Function: amd79c901_read_mode * * Description: retrieves and displays speed and duplex *    parameters from the NIC *     * Arguments: struct nic *nic:          NIC data structure * * Returns:   void. */static voidamd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex){    int i;    u16 status;            for (i = 0; i < 2; i++)        status = sis900_mdio_read(phy_addr, MII_STATUS);    if (status & MII_STAT_CAN_AUTO) {        /* 10BASE-T PHY */        for (i = 0; i < 2; i++)            status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY);        if (status & MII_STSSUM_SPD)            *speed = HW_SPEED_100_MBPS;        else            *speed = HW_SPEED_10_MBPS;        if (status & MII_STSSUM_DPLX)            *duplex = FDX_CAPABLE_FULL_SELECTED;        else            *duplex = FDX_CAPABLE_HALF_SELECTED;        if (status & MII_STSSUM_LINK)            printf("amd79c901_read_mode: Media Link On %s %s-duplex \n",                    *speed == HW_SPEED_100_MBPS ?                    "100mbps" : "10mbps",                   *duplex == FDX_CAPABLE_FULL_SELECTED ?                   "full" : "half");        else            printf("amd79c901_read_mode: Media Link Off\n");    }    else {        /* HomePNA */        *speed = HW_SPEED_HOME;        *duplex = FDX_CAPABLE_HALF_SELECTED;        if (status & MII_STAT_LINK)            printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");        else            printf("amd79c901_read_mode: Media Link Off\n");    }}/** *	ics1893_read_mode: - read media mode for ICS1893 PHY *	@net_dev: the net device to read mode for *	@phy_addr: mii phy address *	@speed: the transmit speed to be determined *	@duplex: the duplex mode to be determined * *	ICS1893 PHY use Quick Poll Detailed Status register *	to determine the speed and duplex mode for sis900 */static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex){	int i = 0;	u32 status;	/* MII_QPDSTS is Latched, read twice in succession will reflect the current state */	for (i = 0; i < 2; i++)		status = sis900_mdio_read(phy_addr, MII_QPDSTS);	if (status & MII_STSICS_SPD)		*speed = HW_SPEED_100_MBPS;	else		*speed = HW_SPEED_10_MBPS;	if (status & MII_STSICS_DPLX)		*duplex = FDX_CAPABLE_FULL_SELECTED;	else		*duplex = FDX_CAPABLE_HALF_SELECTED;	if (status & MII_STSICS_LINKSTS)		printf("ics1893_read_mode: Media Link On %s %s-duplex \n",		       *speed == HW_SPEED_100_MBPS ?		       "100mbps" : "10mbps",		       *duplex == FDX_CAPABLE_FULL_SELECTED ?		       "full" : "half");	else		printf("ics1893_read_mode: Media Link Off\n");}/** *	rtl8201_read_mode: - read media mode for rtl8201 phy *	@nic: the net device to read mode for *	@phy_addr: mii phy address *	@speed: the transmit speed to be determined *	@duplex: the duplex mode to be determined * *	read MII_STATUS register from rtl8201 phy *	to determine the speed and duplex mode for sis900 */static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex){	u32 status;	status = sis900_mdio_read(phy_addr, MII_STATUS);	if (status & MII_STAT_CAN_TX_FDX) {		*speed = HW_SPEED_100_MBPS;		*duplex = FDX_CAPABLE_FULL_SELECTED;	}	else if (status & MII_STAT_CAN_TX) {		*speed = HW_SPEED_100_MBPS;		*duplex = FDX_CAPABLE_HALF_SELECTED;	}	else if (status & MII_STAT_CAN_T_FDX) {		*speed = HW_SPEED_10_MBPS;		*duplex = FDX_CAPABLE_FULL_SELECTED;	}	else if (status & MII_STAT_CAN_T) {		*speed = HW_SPEED_10_MBPS;		*duplex = FDX_CAPABLE_HALF_SELECTED;	}	if (status & MII_STAT_LINK)		printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",		       *speed == HW_SPEED_100_MBPS ?		       "100mbps" : "10mbps",		       *duplex == FDX_CAPABLE_FULL_SELECTED ?		       "full" : "half");	else		printf("rtl8201_read_config_mode: Media Link Off\n");}/** *	vt6103_read_mode: - read media mode for vt6103 phy *	@nic: the net device to read mode for *	@phy_addr: mii phy address *	@speed: the transmit speed to be determined *	@duplex: the duplex mode to be determined * *	read MII_STATUS register from rtl8201 phy *	to determine the speed and duplex mode for sis900 */static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex){	u32 status;	status = sis900_mdio_read(phy_addr, MII_STATUS);	if (status & MII_STAT_CAN_TX_FDX) {		*speed = HW_SPEED_100_MBPS;		*duplex = FDX_CAPABLE_FULL_SELECTED;	}	else if (status & MII_STAT_CAN_TX) {		*speed = HW_SPEED_100_MBPS;		*duplex = FDX_CAPABLE_HALF_SELECTED;	}	else if (status & MII_STAT_CAN_T_FDX) {		*speed = HW_SPEED_10_MBPS;		*duplex = FDX_CAPABLE_FULL_SELECTED;	}	else if (status & MII_STAT_CAN_T) {		*speed = HW_SPEED_10_MBPS;		*duplex = FDX_CAPABLE_HALF_SELECTED;	}	if (status & MII_STAT_LINK)		printf("vt6103_read_mode: Media Link On %s %s-duplex \n",		       *speed == HW_SPEED_100_MBPS ?		       "100mbps" : "10mbps",		       *duplex == FDX_CAPABLE_FULL_SELECTED ?		       "full" : "half");	else		printf("vt6103_read_config_mode: Media Link Off\n");}/* Function: sis900_transmit * * Description: transmits a packet and waits for completion or timeout. * * Arguments: char d[6]:          destination ethernet address. *            unsigned short t:   ethernet protocol type. *            unsigned short s:   size of the data-part of the packet. *            char *p:            the data for the packet. *     * Returns:   void. */static voidsis900_transmit(struct nic  *nic,                const char  *d,     /* Destination */                unsigned int t,     /* Type */                unsigned int s,     /* size */                const char  *p)     /* Packet */{    u32 to, nstype;    u32 tx_status;        /* Stop the transmitter */    outl(TxDIS | inl(ioaddr + cr), ioaddr + cr);    /* load Transmit Descriptor Register */    outl(virt_to_bus(&txd), ioaddr + txdp);     if (sis900_debug > 1)        printf("sis900_transmit: TX descriptor register loaded with: %X\n",                inl(ioaddr + txdp));    memcpy(txb, d, ETH_ALEN);    memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);    nstype = htons(t);    memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);    memcpy(txb + ETH_HLEN, p, s);    s += ETH_HLEN;    s &= DSIZE;    if (sis900_debug > 1)        printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);    /* pad to minimum packet size */    while (s < ETH_ZLEN)          txb[s++] = '\0';    /* set the transmit buffer descriptor and enable Transmit State Machine */    txd.bufptr = virt_to_bus(&txb[0]);    txd.cmdsts = (u32) OWN | s;    /* restart the transmitter */    outl(TxENA | inl(ioaddr + cr), ioaddr + cr);    if (sis900_debug > 1)        printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);    to = currticks() + TX_TIMEOUT;    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))        /* wait */ ;    if (currticks() >= to) {        printf("sis900_transmit: TX Timeout! Tx status %X.\n", tx_status);    }        if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {        /* packet unsuccessfully transmited */        printf("sis900_transmit: Transmit error, Tx status %X.\n", tx_status);    }    /* Disable interrupts by clearing the interrupt mask. */    outl(0, ioaddr + imr);}/* Function: sis900_poll * * Description: checks for a received packet and returns it if found. * * Arguments: struct nic *nic:          NIC data structure * * Returns:   1 if a packet was recieved. *            0 if no pacet was recieved. * * Side effects: *            Returns (copies) the packet to the array nic->packet. *            Returns the length of the packet in nic->packetlen. */static intsis900_poll(struct nic *nic){    u32 rx_status = rxd[cur_rx].cmdsts;    int retstat = 0;    if (sis900_debug > 2)        printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);    if (!(rx_status & OWN))        return retstat;    if (sis900_debug > 1)        printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",               cur_rx, rx_status);    nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;    if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {        /* corrupted packet received */        printf("sis900_poll: Corrupted packet received, buffer status = %X\n",               rx_status);        retstat = 0;    } else {        /* give packet to higher level routine */        memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);        retstat = 1;    }    /* return the descriptor and buffer to receive ring */    rxd[cur_rx].cmdsts = RX_BUF_SIZE;    rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);            if (++cur_rx == NUM_RX_DESC)        cur_rx = 0;    /* re-enable the potentially idle receive state machine */    outl(RxENA | inl(ioaddr + cr), ioaddr + cr);    return retstat;}/* Function: sis900_disable * * Description: Turns off interrupts and stops Tx and Rx engines *     * Arguments: struct nic *nic:          NIC data structure * * Returns:   void. */static voidsis900_disable(struct dev *dev){    struct nic *nic = (struct nic *)dev;    /* merge reset and disable */    sis900_init(nic);    /* Disable interrupts by clearing the interrupt mask. */    outl(0, ioaddr + imr);    outl(0, ioaddr + ier);        /* Stop the chip's Tx and Rx Status Machine */    outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);}static struct pci_id sis900_nics[] = {PCI_ROM(0x1039, 0x0900, "sis900",  "SIS900"),PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016"),};static struct pci_driver sis900_driver __pci_driver = {	.type     = NIC_DRIVER,	.name     = "SIS900",	.probe    = sis900_probe,	.ids      = sis900_nics,	.id_count = sizeof(sis900_nics)/sizeof(sis900_nics[0]),	.class    = 0,};

⌨️ 快捷键说明

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