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; }
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; }