drivers/net/ethernet/dec/tulip/pnic.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dec/tulip/pnic.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/dec/tulip/pnic.c- Extension
.c- Size
- 5100 bytes
- Lines
- 171
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/kernel.hlinux/jiffies.htulip.h
Detected Declarations
function pnic_do_nwayfunction pnic_lnk_changefunction pnic_timer
Annotated Snippet
if (phy_reg & 0x30000000) {
tp->full_duplex = 1;
new_csr6 |= 0x00000200;
}
if (tulip_debug > 1)
netdev_dbg(dev, "PNIC autonegotiated status %08x, %s\n",
phy_reg, medianame[dev->if_port]);
if (tp->csr6 != new_csr6) {
tp->csr6 = new_csr6;
/* Restart Tx */
tulip_restart_rxtx(tp);
netif_trans_update(dev);
}
}
}
void pnic_lnk_change(struct net_device *dev, int csr5)
{
struct tulip_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->base_addr;
int phy_reg = ioread32(ioaddr + 0xB8);
if (tulip_debug > 1)
netdev_dbg(dev, "PNIC link changed state %08x, CSR5 %08x\n",
phy_reg, csr5);
if (ioread32(ioaddr + CSR5) & TPLnkFail) {
iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
/* If we use an external MII, then we mustn't use the
* internal negotiation.
*/
if (tulip_media_cap[dev->if_port] & MediaIsMII)
return;
if (! tp->nwayset || time_after(jiffies, dev_trans_start(dev) + 1*HZ)) {
tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
iowrite32(tp->csr6, ioaddr + CSR6);
iowrite32(0x30, ioaddr + CSR12);
iowrite32(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
netif_trans_update(dev);
}
} else if (ioread32(ioaddr + CSR5) & TPLnkPass) {
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
spin_lock(&tp->lock);
tulip_check_duplex(dev);
spin_unlock(&tp->lock);
} else {
pnic_do_nway(dev);
}
iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
}
}
void pnic_timer(struct timer_list *t)
{
struct tulip_private *tp = timer_container_of(tp, t, timer);
struct net_device *dev = tp->dev;
void __iomem *ioaddr = tp->base_addr;
int next_tick = 60*HZ;
if(!ioread32(ioaddr + CSR7)) {
/* the timer was called due to a work overflow
* in the interrupt handler. Skip the connection
* checks, the nic is definitively speaking with
* his link partner.
*/
goto too_good_connection;
}
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
spin_lock_irq(&tp->lock);
if (tulip_check_duplex(dev) > 0)
next_tick = 3*HZ;
spin_unlock_irq(&tp->lock);
} else {
int csr12 = ioread32(ioaddr + CSR12);
int new_csr6 = tp->csr6 & ~0x40C40200;
int phy_reg = ioread32(ioaddr + 0xB8);
int csr5 = ioread32(ioaddr + CSR5);
if (tulip_debug > 1)
netdev_dbg(dev, "PNIC timer PHY status %08x, %s CSR5 %08x\n",
phy_reg, medianame[dev->if_port], csr5);
if (phy_reg & 0x04000000) { /* Remote link fault */
iowrite32(0x0201F078, ioaddr + 0xB8);
next_tick = 1*HZ;
tp->nwayset = 0;
} else if (phy_reg & 0x78000000) { /* Ignore baseT4 */
pnic_do_nway(dev);
next_tick = 60*HZ;
} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
if (tulip_debug > 1)
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/kernel.h`, `linux/jiffies.h`, `tulip.h`.
- Detected declarations: `function pnic_do_nway`, `function pnic_lnk_change`, `function pnic_timer`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.