Exemple #1
0
static int rtl_init(unsigned long dev_ioaddr, const char *name,
		    unsigned char *enetaddr)
{
	static int board_idx = -1;
	int i, rc;
	int option = -1, Cap10_100 = 0, Cap1000 = 0;

#ifdef DEBUG_RTL8169
	printf ("%s\n", __FUNCTION__);
#endif
	ioaddr = dev_ioaddr;

	board_idx++;

	/* point to private storage */
	tpc = &tpx;

	rc = rtl8169_init_board(ioaddr, name);
	if (rc)
		return rc;

	/* Get MAC address.  FIXME: read EEPROM */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		enetaddr[i] = RTL_R8(MAC0 + i);

#ifdef DEBUG_RTL8169
	printf("chipset = %d\n", tpc->chipset);
	printf("MAC Address");
	for (i = 0; i < MAC_ADDR_LEN; i++)
		printf(":%02x", enetaddr[i]);
	putc('\n');
#endif

#ifdef DEBUG_RTL8169
	/* Print out some hardware info */
	printf("%s: at ioaddr 0x%lx\n", name, ioaddr);
#endif

	/* if TBI is not endbled */
	if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
		int val = mdio_read(PHY_AUTO_NEGO_REG);

		option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
		/* Force RTL8169 in 10/100/1000 Full/Half mode. */
		if (option > 0) {
#ifdef DEBUG_RTL8169
			printf("%s: Force-mode Enabled.\n", name);
#endif
			Cap10_100 = 0, Cap1000 = 0;
			switch (option) {
			case _10_Half:
				Cap10_100 = PHY_Cap_10_Half;
				Cap1000 = PHY_Cap_Null;
				break;
			case _10_Full:
				Cap10_100 = PHY_Cap_10_Full;
				Cap1000 = PHY_Cap_Null;
				break;
			case _100_Half:
				Cap10_100 = PHY_Cap_100_Half;
				Cap1000 = PHY_Cap_Null;
				break;
			case _100_Full:
				Cap10_100 = PHY_Cap_100_Full;
				Cap1000 = PHY_Cap_Null;
				break;
			case _1000_Full:
				Cap10_100 = PHY_Cap_Null;
				Cap1000 = PHY_Cap_1000_Full;
				break;
			default:
				break;
			}
			mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));	/* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
			mdio_write(PHY_1000_CTRL_REG, Cap1000);
		} else {
#ifdef DEBUG_RTL8169
			printf("%s: Auto-negotiation Enabled.\n",
			       name);
#endif
			/* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
			mdio_write(PHY_AUTO_NEGO_REG,
				   PHY_Cap_10_Half | PHY_Cap_10_Full |
				   PHY_Cap_100_Half | PHY_Cap_100_Full |
				   (val & 0x1F));

			/* enable 1000 Full Mode */
			mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);

		}

		/* Enable auto-negotiation and restart auto-nigotiation */
		mdio_write(PHY_CTRL_REG,
			   PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
		udelay(100);

		/* wait for auto-negotiation process */
		for (i = 10000; i > 0; i--) {
			/* check if auto-negotiation complete */
			if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) {
				udelay(100);
				option = RTL_R8(PHYstatus);
				if (option & _1000bpsF) {
#ifdef DEBUG_RTL8169
					printf("%s: 1000Mbps Full-duplex operation.\n",
					       name);
#endif
				} else {
#ifdef DEBUG_RTL8169
					printf("%s: %sMbps %s-duplex operation.\n",
					       name,
					       (option & _100bps) ? "100" :
					       "10",
					       (option & FullDup) ? "Full" :
					       "Half");
#endif
				}
				break;
			} else {
				udelay(100);
			}
		}		/* end for-loop to wait for auto-negotiation process */

	} else {
		udelay(100);
#ifdef DEBUG_RTL8169
		printf
		    ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
		     name,
		     (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
#endif
	}


	tpc->RxDescArray = rtl_alloc_descs(NUM_RX_DESC);
	if (!tpc->RxDescArray)
		return -ENOMEM;

	tpc->TxDescArray = rtl_alloc_descs(NUM_TX_DESC);
	if (!tpc->TxDescArray)
		return -ENOMEM;

	return 0;
}
Exemple #2
0
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
    struct net_device *dev = NULL;
    struct rtl8169_private *tp = NULL;
    void *ioaddr = NULL;
    static int board_idx = -1;
    static int printed_version = 0;
    int i, rc;
    int option = -1, Cap10_100 = 0, Cap1000 = 0;

    assert(pdev != NULL);
    assert(ent != NULL);

    board_idx++;

    if (!printed_version) {
        printk(KERN_INFO RTL8169_DRIVER_NAME " loaded\n");
        printed_version = 1;
    }

    rc = rtl8169_init_board(pdev, &dev, &ioaddr);
    if (rc)
        return rc;

    tp = dev->priv;
    assert(ioaddr != NULL);
    assert(dev != NULL);
    assert(tp != NULL);

    // Get MAC address.  FIXME: read EEPROM
    for (i = 0; i < MAC_ADDR_LEN; i++)
        dev->dev_addr[i] = RTL_R8(MAC0 + i);

    dev->open = rtl8169_open;
    dev->hard_start_xmit = rtl8169_start_xmit;
    dev->get_stats = rtl8169_get_stats;
    dev->ethtool_ops = &rtl8169_ethtool_ops;
    dev->stop = rtl8169_close;
    dev->tx_timeout = rtl8169_tx_timeout;
    dev->set_multicast_list = rtl8169_set_rx_mode;
    dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
    dev->irq = pdev->irq;
    dev->base_addr = (unsigned long) ioaddr;
//      dev->do_ioctl           = mii_ioctl;

    tp = dev->priv;		// private data //
    tp->pci_dev = pdev;
    tp->mmio_addr = ioaddr;

    spin_lock_init(&tp->lock);

    rc = register_netdev(dev);
    if (rc) {
        iounmap(ioaddr);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        free_netdev(dev);
        return rc;
    }

    printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
           rtl_chip_info[tp->chipset].name);

    pci_set_drvdata(pdev, dev);

    printk(KERN_INFO "%s: %s at 0x%lx, "
           "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
           "IRQ %d\n",
           dev->name,
           rtl_chip_info[ent->driver_data].name,
           dev->base_addr,
           dev->dev_addr[0], dev->dev_addr[1],
           dev->dev_addr[2], dev->dev_addr[3],
           dev->dev_addr[4], dev->dev_addr[5], dev->irq);

    rtl8169_hw_phy_config(dev);

    dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
    RTL_W8(0x82, 0x01);

    if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
        dprintk("Set PCI Latency=0x40\n");
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
    }

    if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
        dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
        RTL_W8(0x82, 0x01);
        dprintk("Set PHY Reg 0x0bh = 0x00h\n");
        mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
    }

    // if TBI is not endbled
    if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
        int val = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);

        option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
        // Force RTL8169 in 10/100/1000 Full/Half mode.
        if (option > 0) {
            printk(KERN_INFO "%s: Force-mode Enabled.\n",
                   dev->name);
            Cap10_100 = 0, Cap1000 = 0;
            switch (option) {
            case _10_Half:
                Cap10_100 = PHY_Cap_10_Half_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _10_Full:
                Cap10_100 = PHY_Cap_10_Full_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _100_Half:
                Cap10_100 = PHY_Cap_100_Half_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _100_Full:
                Cap10_100 = PHY_Cap_100_Full_Or_Less;
                Cap1000 = PHY_Cap_Null;
                break;
            case _1000_Full:
                Cap10_100 = PHY_Cap_100_Full_Or_Less;
                Cap1000 = PHY_Cap_1000_Full;
                break;
            default:
                break;
            }
            mdio_write(ioaddr, PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));	//leave PHY_AUTO_NEGO_REG bit4:0 unchanged
            mdio_write(ioaddr, PHY_1000_CTRL_REG, Cap1000);
        } else {
            printk(KERN_INFO "%s: Auto-negotiation Enabled.\n",
                   dev->name);

            // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
            mdio_write(ioaddr, PHY_AUTO_NEGO_REG,
                       PHY_Cap_100_Full_Or_Less | (val & 0x1f));

            // enable 1000 Full Mode
            mdio_write(ioaddr, PHY_1000_CTRL_REG,
                       PHY_Cap_1000_Full);

        }

        // Enable auto-negotiation and restart auto-nigotiation
        mdio_write(ioaddr, PHY_CTRL_REG,
                   PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
        udelay(100);

        // wait for auto-negotiation process
        for (i = 10000; i > 0; i--) {
            //check if auto-negotiation complete
            if (mdio_read(ioaddr, PHY_STAT_REG) &
                    PHY_Auto_Neco_Comp) {
                udelay(100);
                option = RTL_R8(PHYstatus);
                if (option & _1000bpsF) {
                    printk(KERN_INFO
                           "%s: 1000Mbps Full-duplex operation.\n",
                           dev->name);
                } else {
                    printk(KERN_INFO
                           "%s: %sMbps %s-duplex operation.\n",
                           dev->name,
                           (option & _100bps) ? "100" :
                           "10",
                           (option & FullDup) ? "Full" :
                           "Half");
                }
                break;
            } else {
                udelay(100);
            }
        }		// end for-loop to wait for auto-negotiation process

    } else {
        udelay(100);
        printk(KERN_INFO
               "%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
               dev->name,
               (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");

    }

    return 0;
}