/* Check the MII negotiated duplex, and change the CSR6 setting if required. Return 0 if everything is OK. Return < 0 if the transceiver is missing or has no link beat. */ int tulip_check_duplex(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int mii_reg1, mii_reg5, negotiated, duplex; if (tp->full_duplex_lock) return 0; mii_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); mii_reg5 = tulip_mdio_read(dev, tp->phys[0], 5); if (tulip_debug > 1) printk(KERN_INFO "%s: MII status %4.4x, Link partner report " "%4.4x.\n", dev->name, mii_reg1, mii_reg5); if (mii_reg1 == 0xffff) return -2; if ((mii_reg1 & 0x0004) == 0) { int new_reg1 = tulip_mdio_read(dev, tp->phys[0], 1); if ((new_reg1 & 0x0004) == 0) { if (tulip_debug > 1) printk(KERN_INFO "%s: No link beat on the MII interface," " status %4.4x.\n", dev->name, new_reg1); return -1; } } negotiated = mii_reg5 & tp->advertising[0]; duplex = ((negotiated & 0x0300) == 0x0100 || (negotiated & 0x00C0) == 0x0040); /* 100baseTx-FD or 10T-FD, but not 100-HD */ if (tp->full_duplex != duplex) { tp->full_duplex = duplex; if (negotiated & 0x038) /* 100mbps. */ tp->csr6 &= ~0x00400000; if (tp->full_duplex) tp->csr6 |= 0x0200; else tp->csr6 &= ~0x0200; tulip_restart_rxtx(tp, tp->csr6); if (tulip_debug > 0) printk(KERN_INFO "%s: Setting %s-duplex based on MII" "#%d link partner capability of %4.4x.\n", dev->name, tp->full_duplex ? "full" : "half", tp->phys[0], mii_reg5); return 1; } return 0; }
static void tulip_up(/*RTnet*/struct rtnet_device *rtdev) { struct tulip_private *tp = (struct tulip_private *)rtdev->priv; long ioaddr = rtdev->base_addr; int i; /* Wake the chip from sleep/snooze mode. */ tulip_set_power_state (tp, 0, 0); /* On some chip revs we must set the MII/SYM port before the reset!? */ if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) outl(0x00040000, ioaddr + CSR6); /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ outl(0x00000001, ioaddr + CSR0); udelay(100); /* Deassert reset. Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ outl(tp->csr0, ioaddr + CSR0); udelay(100); if (tulip_debug > 1) printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", rtdev->name, rtdev->irq); outl(tp->rx_ring_dma, ioaddr + CSR3); outl(tp->tx_ring_dma, ioaddr + CSR4); tp->cur_rx = tp->cur_tx = 0; tp->dirty_rx = tp->dirty_tx = 0; if (tp->flags & MC_HASH_ONLY) { u32 addr_low = cpu_to_le32(get_unaligned((u32 *)rtdev->dev_addr)); u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(rtdev->dev_addr+4))); if (tp->chip_id == AX88140) { outl(0, ioaddr + CSR13); outl(addr_low, ioaddr + CSR14); outl(1, ioaddr + CSR13); outl(addr_high, ioaddr + CSR14); } else if (tp->flags & COMET_MAC_ADDR) { outl(addr_low, ioaddr + 0xA4); outl(addr_high, ioaddr + 0xA8); outl(0, ioaddr + 0xAC); outl(0, ioaddr + 0xB0); } } else { /* This is set_rx_mode(), but without starting the transmitter. */ u16 *eaddrs = (u16 *)rtdev->dev_addr; u16 *setup_frm = &tp->setup_frame[15*6]; dma_addr_t mapping; /* 21140 bug: you must add the broadcast address. */ memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame)); /* Fill the final entry of the table with our physical address. */ *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; mapping = pci_map_single(tp->pdev, tp->setup_frame, sizeof(tp->setup_frame), PCI_DMA_TODEVICE); tp->tx_buffers[tp->cur_tx].skb = NULL; tp->tx_buffers[tp->cur_tx].mapping = mapping; /* Put the setup frame on the Tx list. */ tp->tx_ring[tp->cur_tx].length = cpu_to_le32(0x08000000 | 192); tp->tx_ring[tp->cur_tx].buffer1 = cpu_to_le32(mapping); tp->tx_ring[tp->cur_tx].status = cpu_to_le32(DescOwned); tp->cur_tx++; } tp->saved_if_port = rtdev->if_port; if (rtdev->if_port == 0) rtdev->if_port = tp->default_port; /* Allow selecting a default media. */ i = 0; if (tp->mtable == NULL) goto media_picked; if (rtdev->if_port) { int looking_for = tulip_media_cap[rtdev->if_port] & MediaIsMII ? 11 : (rtdev->if_port == 12 ? 0 : rtdev->if_port); for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printk(KERN_INFO "%s: Using user-specified media %s.\n", rtdev->name, medianame[rtdev->if_port]); goto media_picked; } } if ((tp->mtable->defaultmedia & 0x0800) == 0) { int looking_for = tp->mtable->defaultmedia & MEDIA_MASK; for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printk(KERN_INFO "%s: Using EEPROM-set media %s.\n", rtdev->name, medianame[looking_for]); goto media_picked; } } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) ; media_picked: tp->csr6 = 0; tp->cur_index = i; tp->nwayset = 0; if (rtdev->if_port) { if (tp->chip_id == DC21143 && (tulip_media_cap[rtdev->if_port] & MediaIsMII)) { /* We must reset the media CSRs when we force-select MII mode. */ outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); outl(0x0008, ioaddr + CSR15); } tulip_select_media(rtdev, 1); } else if (tp->chip_id == DC21041) { rtdev->if_port = 0; tp->nway = tp->mediasense = 1; tp->nwayset = tp->lpar = 0; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ tp->csr6 = 0x80020000; if (tp->sym_advertise & 0x0040) tp->csr6 |= FullDuplex; outl(tp->csr6, ioaddr + CSR6); outl(0x0000EF01, ioaddr + CSR13); } else if (tp->chip_id == DC21142) { if (tp->mii_cnt) { tulip_select_media(rtdev, 1); if (tulip_debug > 1) printk(KERN_INFO "%s: Using MII transceiver %d, status %4.4x.\n", rtdev->name, tp->phys[0], tulip_mdio_read(rtdev, tp->phys[0], 1)); outl(csr6_mask_defstate, ioaddr + CSR6); tp->csr6 = csr6_mask_hdcap; rtdev->if_port = 11; outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); } else t21142_start_nway(rtdev); } else if (tp->chip_id == PNIC2) { /* for initial startup advertise 10/100 Full and Half */ tp->sym_advertise = 0x01E0; /* enable autonegotiate end interrupt */ outl(inl(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5); outl(inl(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7); pnic2_start_nway(rtdev); } else if (tp->chip_id == LC82C168 && ! tp->medialock) { if (tp->mii_cnt) { rtdev->if_port = 11; tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0001, ioaddr + CSR15); } else if (inl(ioaddr + CSR5) & TPLnkPass) pnic_do_nway(rtdev); else { /* Start with 10mbps to do autonegotiation. */ outl(0x32, ioaddr + CSR12); tp->csr6 = 0x00420000; outl(0x0001B078, ioaddr + 0xB8); outl(0x0201B078, ioaddr + 0xB8); } } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) && ! tp->medialock) { rtdev->if_port = 0; tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); } else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) { /* Provided by BOLO, Macronix - 12/10/1998. */ rtdev->if_port = 0; tp->csr6 = 0x01a80200; outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); } else if (tp->chip_id == COMET) { /* Enable automatic Tx underrun recovery. */ outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); rtdev->if_port = tp->mii_cnt ? 11 : 0; tp->csr6 = 0x00040000; } else if (tp->chip_id == AX88140) { tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; } else tulip_select_media(rtdev, 1); /* Start the chip's Tx to process setup frame. */ tulip_stop_rxtx(tp); barrier(); udelay(5); outl(tp->csr6 | TxOn, ioaddr + CSR6); /* Enable interrupts by setting the interrupt mask. */ outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5); outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); tulip_start_rxtx(tp); outl(0, ioaddr + CSR2); /* Rx poll demand */ if (tulip_debug > 2) { printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n", rtdev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5), inl(ioaddr + CSR6)); } }