/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
of available transceivers. */ void t21142_media_task(struct work_struct *work)
{ struct tulip_private *tp =
container_of(work, struct tulip_private, media_work); struct net_device *dev = tp->dev; void __iomem *ioaddr = tp->base_addr; int csr12 = ioread32(ioaddr + CSR12); int next_tick = 60*HZ; int new_csr6 = 0; int csr14 = ioread32(ioaddr + CSR14);
/* CSR12[LS10,LS100] are not reliable during autonegotiation */ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
csr12 |= 6; if (tulip_debug > 2)
dev_info(&dev->dev, "21143 negotiation status %08x, %s\n",
csr12, medianame[dev->if_port]); if (tulip_media_cap[dev->if_port] & MediaIsMII) { if (tulip_check_duplex(dev) < 0) {
netif_carrier_off(dev);
next_tick = 3*HZ;
} else {
netif_carrier_on(dev);
next_tick = 60*HZ;
}
} elseif (tp->nwayset) { /* Don't screw up a negotiated session! */ if (tulip_debug > 1)
dev_info(&dev->dev, "Using NWay-set %s media, csr12 %08x\n",
medianame[dev->if_port], csr12);
} elseif (tp->medialock) {
;
} elseif (dev->if_port == 3) { if (csr12 & 2) { /* No 100mbps link beat, revert to 10mbps. */ if (tulip_debug > 1)
dev_info(&dev->dev, "No 21143 100baseTx link beat, %08x, trying NWay\n",
csr12);
t21142_start_nway(dev);
next_tick = 3*HZ;
}
} elseif ((csr12 & 0x7000) != 0x5000) { /* Negotiation failed. Search media types. */ if (tulip_debug > 1)
dev_info(&dev->dev, "21143 negotiation failed, status %08x\n",
csr12); if (!(csr12 & 4)) { /* 10mbps link beat good. */
new_csr6 = 0x82420000;
dev->if_port = 0;
iowrite32(0, ioaddr + CSR13);
iowrite32(0x0003FFFF, ioaddr + CSR14);
iowrite16(t21142_csr15[dev->if_port], ioaddr + CSR15);
iowrite32(t21142_csr13[dev->if_port], ioaddr + CSR13);
} else { /* Select 100mbps port to check for link beat. */
new_csr6 = 0x83860000;
dev->if_port = 3;
iowrite32(0, ioaddr + CSR13);
iowrite32(0x0003FFFF, ioaddr + CSR14);
iowrite16(8, ioaddr + CSR15);
iowrite32(1, ioaddr + CSR13);
} if (tulip_debug > 1)
dev_info(&dev->dev, "Testing new 21143 media %s\n",
medianame[dev->if_port]); if (new_csr6 != (tp->csr6 & ~0x00D5)) {
tp->csr6 &= 0x00D5;
tp->csr6 |= new_csr6;
iowrite32(0x0301, ioaddr + CSR12);
tulip_restart_rxtx(tp);
}
next_tick = 3*HZ;
}
/* mod_timer synchronizes us with potential add_timer calls *frominterrupts.
*/
mod_timer(&tp->timer, RUN_AT(next_tick));
}
void t21142_lnk_change(struct net_device *dev, int csr5)
{ struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; int csr12 = ioread32(ioaddr + CSR12); int csr14 = ioread32(ioaddr + CSR14);
/* CSR12[LS10,LS100] are not reliable during autonegotiation */ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
csr12 |= 6; if (tulip_debug > 1)
dev_info(&dev->dev, "21143 link status interrupt %08x, CSR5 %x, %08x\n",
csr12, csr5, csr14);
/* If NWay finished and we have a negotiated partner capability. */ if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { int setup_done = 0; int negotiated = tp->sym_advertise & (csr12 >> 16);
tp->lpar = csr12 >> 16;
tp->nwayset = 1; /* If partner cannot negotiate, it is 10Mbps Half Duplex */ if (!(csr12 & 0x8000)) dev->if_port = 0; elseif (negotiated & 0x0100) dev->if_port = 5; elseif (negotiated & 0x0080) dev->if_port = 3; elseif (negotiated & 0x0040) dev->if_port = 4; elseif (negotiated & 0x0020) dev->if_port = 0; else {
tp->nwayset = 0; if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180))
dev->if_port = 3;
}
tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
if (tulip_debug > 1) { if (tp->nwayset)
dev_info(&dev->dev, "Switching to %s based on link negotiation %04x & %04x = %04x\n",
medianame[dev->if_port],
tp->sym_advertise, tp->lpar,
negotiated); else
dev_info(&dev->dev, "Autonegotiation failed, using %s, link beat status %04x\n",
medianame[dev->if_port], csr12);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.