Understanding the Physical Layer (PHY)

If you’ve ever chased down a “the network is slow but only sometimes and only in one direction” ticket, there’s a good chance the real culprit was sitting quietly at Layer 1, way below anything a ping or traceroute will show you. That’s the world of the PHY chip, the piece of silicon on every Ethernet interface that actually puts bits onto the wire and pulls them back off again.

It’s easy to think of Ethernet as just “the cable,” but there’s a surprising amount of active electrical negotiation happening before a single frame ever gets switched. The PHY is the layer that does that work, and it’s responsible for a handful of jobs that never show up in a packet capture:

  • Turning digital bits into electrical (or optical) signals for transmission, and doing the reverse on receive
  • Detecting that a cable is actually plugged into something alive on the other end, and figuring out wiring polarity so a crossed pair doesn’t kill the link
  • Negotiating operating parameters, like speed and duplex, with whatever’s on the other end of the cable
  • Reporting the resulting link state up to the MAC (Media Access Control) layer, which is what your OS and switching logic actually see

On copper Ethernet standards like 100BASE-TX and 1000BASE-T, the PHY also handles MDI/MDI-X crossover detection (so you don’t need to care whether you grabbed a straight-through or crossover cable anymore) and it drives the auto-negotiation handshake through a series of link pulses. All of that happens in the analog and electrical domain, purely between the two PHY chips, before the MAC layer even knows a device is present. That’s exactly why duplex mismatch is such a sneaky problem: it lives entirely below the layer most of our usual diagnostic tools are looking at.

How Auto-Negotiation Works

Auto-negotiation (AN) was standardized in IEEE 802.3u, back when 100 Mbps Fast Ethernet was new and vendors needed a reliable way for two devices to figure out, automatically, what speed and duplex mode they could both support without a human setting DIP switches. The mechanism it uses is a burst of Fast Link Pulses (FLPs), which are really just a specially timed sequence of the same link pulses that plain 10BASE-T already used to say “I’m alive.” By encoding a bit pattern into the timing of those pulses, two PHYs can exchange a small capability word without needing any higher-layer protocol running yet. There’s no IP, no frame, not even a MAC address involved. It’s pure electrical signaling.

Conceptually, the process is straightforward, but it’s worth walking through why each step exists:

  1. Both link partners start transmitting FLP bursts as soon as the cable is connected. Neither side waits for permission, because neither side knows yet whether the other end even supports auto-negotiation.
  2. Each side listens to the other’s pulses and decodes the capability bits. This tells each PHY exactly which speeds and duplex modes the far end claims to support.
  3. The two devices independently compute the highest common denominator of what’s advertised. If both can do 1000 Mbps full duplex, that wins, since AN is designed to always pick the fastest, most capable mode both ends agree on.
  4. Once that agreement is reached, both PHYs lock into that configuration and the link comes up. From that point on, the MAC layer sees a link that’s already running at the negotiated speed and duplex.

The “highest common denominator” logic is really just a priority-ordered list baked into the standard. Here’s the rough ordering, from most to least preferred, which is what lets two devices resolve capability mismatches deterministically rather than needing to argue about it:

AdvertisementMeaning
10BASE-T HalfLegacy 10 Mbps half duplex
10BASE-T Full10 Mbps full duplex
100BASE-TX Half100 Mbps half duplex
100BASE-TX Full100 Mbps full duplex
1000BASE-T Full1000 Mbps full duplex (half duplex was never actually defined for gigabit)

That last row matters more than it looks. Gigabit and faster copper standards (1000BASE-T and beyond) don’t just prefer auto-negotiation, they actually require it, because the electrical handshake is doing more than picking a speed. It’s also used to establish master/slave timing roles between the two PHYs (one has to act as the timing source for the other) and to agree on other signal parameters needed for the more complex encoding gigabit uses. There’s no equivalent “just force it and hope” mode the way there is at 10 or 100 Mbps, which is part of why forcing gigabit links tends to fail outright rather than quietly degrading.

What Duplex Actually Means

Before getting into how things go wrong, it’s worth being precise about what “duplex” even controls, because it’s easy to gloss over as just another link setting when it actually changes how the medium itself is treated.

ModeWhat’s happeningWhere you’ll see it
Half DuplexBoth devices share one transmission medium, so only one side can be transmitting at any given instant. If both try at once, that’s a collision, and CSMA/CD (Carrier Sense Multiple Access with Collision Detection) is the mechanism that detects it and backs both sides off before retrying.Legacy hubs, or a link that’s fallen into a mismatched state
Full DuplexEach device gets its own dedicated transmit and receive path, so both sides can send and receive at exactly the same time. Because there’s no shared medium to contend for, there’s no such thing as a collision, and CSMA/CD logic simply isn’t running.Essentially every modern switch and NIC

That last point about collisions is the crux of the whole duplex mismatch problem. Collision detection isn’t just “on” or “off” as a policy choice, it’s a behavior that only makes sense in a shared-medium world. A full-duplex device has no concept of a collision because its transmit and receive circuits are electrically separate. So when two sides of a link disagree about which mode they’re in, they don’t just have a “setting mismatch,” they have a fundamentally different model of what the wire is for. One side is quietly assuming it owns the medium whenever it wants to talk. The other side is watching for contention that, from its perspective, is real. That asymmetry is what turns a simple configuration slip into packet loss, retransmissions, and throughput that can fall off a cliff under load.

How Duplex Mismatch Happens

In practice, duplex mismatch almost always traces back to one specific decision: someone manually forced speed and duplex on one end of a link while leaving the other end on auto-negotiation. It sounds like a minor inconsistency, but the mechanics of why it breaks things are worth understanding, because they explain why the failure mode is so asymmetric and so hard to spot.

Take this common setup:

DeviceSetting
Switch PortAuto-negotiation enabled
Server NICForced 100 Mbps full duplex

When you force a NIC’s speed and duplex, you’re not just setting a preference, you’re telling the PHY to skip the FLP negotiation process entirely and just start transmitting at those fixed parameters. The problem is that FLP bursts are also the only signal the switch’s auto-negotiating port uses to learn the other side’s capabilities. If the server never sends them, the switch has nothing to negotiate with.

Here’s the part that trips people up: the switch port doesn’t just fail and go link-down. IEEE 802.3 includes a fallback behavior called parallel detection, specifically for this situation. If a port configured for auto-negotiation sees link pulses but no FLP bursts, it can still tell that something is electrically alive on the other end (via plain link pulses, the same signaling 10BASE-T always used), so it assumes the other side is an older, non-negotiating device and falls back to a safe default: half duplex, at whatever speed it can infer from the signal characteristics. This fallback exists specifically for backward compatibility with equipment older than 802.3u. But it becomes a trap the moment the “old” device on the other end is actually a modern NIC that was simply forced into full duplex.

So you end up with one side hard-set to full duplex and the other side landing on half duplex, not because anyone configured it that way, but as an emergent consequence of the fallback logic. The behavior that follows is entirely predictable once you see the mismatch:

  • The full-duplex side transmits whenever it has data, with no concept of collisions and therefore no reason to ever back off.
  • The half-duplex side is running CSMA/CD, so it’s actively listening for the medium to be clear and interpreting any overlapping activity from the other side as a collision, triggering a backoff and retransmit.
  • The result is a stream of dropped or delayed frames that gets worse the more traffic you push through the link, since more traffic means more opportunities for the half-duplex side to perceive collisions.

Tip The fix is really about consistency, not about which mode is “better.” Either let both ends auto-negotiate, or manually fix both ends to the same speed and duplex. Mixing a forced side with an auto side is what creates the mismatch in the first place, regardless of which specific values you pick.

Detecting Duplex Mismatch Symptoms

What makes duplex mismatch particularly nasty to troubleshoot is that it doesn’t announce itself. The link light is on. show interfaces or your equivalent tool reports a link that’s up. There’s no syslog message screaming “duplex mismatch detected,” because from the perspective of each individual PHY, everything is working exactly as configured. The clues only show up once you start looking at traffic behavior and interface error counters rather than link state.

A few patterns tend to show up together and are worth treating as a set, since any one of them alone could have other causes:

  • Throughput that’s badly asymmetric, fast in one direction and crawling in the other. This tracks directly with which side is half duplex versus full duplex under load.
  • TCP retransmission rates that climb noticeably as soon as you push real traffic through the link, even though the link “looks” fine at idle.
  • Late collisions accumulating on the switch’s interface counters. This one is a strong signal specifically for duplex mismatch, because late collisions shouldn’t really happen at all on a correctly functioning full-duplex link, and even on a properly functioning half-duplex link they should be rare once cable lengths are within spec.
  • Ping loss that’s asymmetric by direction, for example, host-to-switch pings succeed reliably while switch-to-host pings drop intermittently under load, because the two directions are being handled by circuitry running two different sets of rules.

The interface counters are usually the fastest way to confirm what’s going on, because they’re reporting what’s physically happening rather than what was configured. Here’s a representative example from a Cisco device:

PLAINTEXT
Switch# show interfaces gigabitEthernet0/1
  Full-duplex, 100Mb/s
  500 late collisions, 1200 input errors
Click to expand and view more

This output is contradictory on its face, and that contradiction is the tell. The switch believes it’s running full duplex, yet it’s counting late collisions, which are a phenomenon that only makes sense if collision detection logic is active somewhere on the link. That’s the signature of a mismatch: the reported configuration and the observed electrical behavior don’t agree, because one PHY thinks it owns the wire and the other is still watching for contention that’s actually happening.

Inside the Signaling: FLP Bursts

It’s worth zooming into the FLP mechanism itself for a moment, because understanding what’s actually being transmitted makes the failure modes above much more intuitive rather than just being a rule you memorize.

An FLP burst isn’t a special new kind of signal invented from scratch, it’s built from ordinary Normal Link Pulses (NLPs), the same simple heartbeat pulses that classic 10BASE-T used just to indicate “link present.” Auto-negotiation reuses that mechanism cleverly: instead of one pulse, it sends a tightly timed burst of pulses, and the presence or absence of a pulse at each defined timing slot encodes one bit. String enough of those slots together and you get a 16-bit word, the Link Codeword, that describes what the sending device supports.

That 16-bit budget is small, so the standard packs it efficiently. Each field carries a specific piece of the negotiation:

ParameterHow it’s signaled
Supported speedsA set of bit positions within the FLP burst’s capability field
Duplex capabilityA dedicated bit per speed, marking full versus half support
Flow control supportSignaled optionally through a “next page” exchange, an extension mechanism for encoding more capability data than fits in the base word
Remote fault detectionAdditional flag bits used to report link problems back to the far end

The entire exchange happens in the space of microseconds, well before any software on either device is even aware a cable was plugged in. That speed is a feature: it means link establishment can happen fast enough to feel instantaneous to a user. But it’s also exactly why duplex mismatch is invisible to normal debugging. By the time your OS reports “link up,” this whole negotiation (or lack of it, if one side skipped negotiation entirely) has already finished and the resulting duplex state is locked in. There’s no log of what was offered versus what was chosen unless you go digging at the driver or hardware counter level.

Practical Example

Let’s walk through a concrete scenario, since the abstract description of parallel detection is easier to follow with real numbers attached.

Say you’re connecting a new access switch with a modern gigabit-capable PHY to an older firewall appliance that only ever shipped with Fast Ethernet hardware:

DeviceAdvertised capabilities
Switch (modern PHY)10/100/1000, full duplex
Firewall (legacy PHY)10/100, full duplex only
Negotiated result100 Mbps, full duplex

Both sides are auto-negotiating here, so this works exactly as intended. The switch advertises everything it can do, the firewall advertises its more limited set, and both sides independently compute the same answer: 100 Mbps full duplex is the fastest mode they have in common. No human had to know in advance what the firewall supported.

Now change one variable: someone forces the firewall to 100 Mbps full duplex instead of leaving it on auto, maybe because an older troubleshooting guide told them to, while the switch stays on auto-negotiation. The firewall stops sending FLP bursts entirely. The switch still sees electrical activity on the line (plain link pulses are still present), so parallel detection kicks in, and the switch falls back to 100 Mbps half duplex. The firewall is now transmitting as if it has the wire to itself; the switch is running CSMA/CD and treating overlapping traffic as collisions. Same physical link, same negotiated speed, but now a duplex mismatch that will quietly degrade throughput the moment real traffic starts flowing in both directions.

To actually confirm something like this in the field, you want to compare what each side thinks it’s running, not just whether the link is up:

  • Check both ends explicitly: ethtool eth0 on Linux, or show interfaces (or the equivalent) on Cisco and similar platforms.
  • Line up the duplex and speed values reported by each side. If auto-negotiation succeeded properly, both sides should report the exact same values, since they arrived at that result through the same handshake.
  • Push sustained traffic across the link and watch RTT and loss during that load, not just at idle. Duplex mismatch symptoms often only show up once there’s enough traffic to generate genuine contention on the half-duplex side.

Correcting and Preventing Mismatches

Once you understand that the root cause is almost always an inconsistency between forced and auto-negotiated settings, the fix list is less about clever workarounds and more about discipline:

  1. Leave auto-negotiation enabled on both ends whenever possible. Modern PHY implementations have gotten quite good at this, and the vast majority of negotiation failures you’ll encounter today trace back to old firmware bugs or someone forcing settings manually, not to the protocol itself misbehaving.

  2. Check driver and firmware versions, especially on older gigabit NICs. There were real, well-documented interoperability bugs in early 1000BASE-T implementations where negotiation would fail or pick the wrong parameters. A firmware update is sometimes the actual fix, not a configuration change.

  3. If you do need to force settings, force them symmetrically on both ends. There are legitimate reasons to want fixed parameters, tightly latency-sensitive links or environments where you want to eliminate any negotiation variability. That’s fine, as long as both sides agree explicitly rather than one side being forced and the other left to guess via fallback logic.

  4. Keep an eye on interface statistics as an ongoing habit, not just when something’s already broken. Late collisions, rising input errors, or CRC mismatches showing up on an interface are early warning signs of a Layer 1 negotiation problem, often well before users start filing tickets about slowness.

Info One of the more frustrating things about duplex mismatch is that it never produces a “link down” event, because the electrical layer genuinely stays up and active the whole time. That’s precisely why it can sit undetected in a production network for months, quietly capping throughput on one link while everything upstream looks fine.

Relationship Between Duplex, Flow Control and Performance

Duplex mode and flow control are technically independent mechanisms defined in different parts of the 802.3 standard, but they interact in ways that make a mismatch even more disruptive than it would otherwise be. It’s worth understanding both, since they represent two completely different philosophies for managing how fast a sender is allowed to push data.

In half-duplex mode, there’s no explicit flow control protocol at all, because collisions themselves are the pacing mechanism. If a sender is going too fast for the shared medium to handle cleanly, collisions increase, backoff timers grow, and throughput self-limits as a side effect of CSMA/CD. It’s crude, but it works, because it’s built into the same mechanism that arbitrates access to the medium in the first place.

In full-duplex mode, there’s no shared medium to contend for, so that implicit pacing mechanism doesn’t exist. Instead, 802.3x defines an explicit signal, the PAUSE frame, that a receiver can send to ask the transmitter to briefly hold off, typically because a buffer is filling up faster than it can be drained. This is a genuinely different model: instead of collisions imposing a passive rate limit, PAUSE frames are an active request-based mechanism.

When a link is duplex-mismatched, this distinction becomes a real problem, not just a theoretical inconsistency. The half-duplex side has no concept of PAUSE frames, since it’s not expecting to receive them and its backpressure model is entirely collision-based. The full-duplex side, meanwhile, isn’t seeing the collisions the other side is generating and has no reason to slow down on its own. So you end up with backpressure signals from one side that the other side can’t interpret at all, on top of the base collision problem already described.

ModeHow pacing worksFlow control
Half DuplexCSMA/CD collisions self-limit throughputNot used, not expected
Full DuplexNo collisions possiblePAUSE frames, if supported by both sides

The practical upshot is that even a link running at low overall utilization can show inconsistent latency and reduced effective throughput, because the two sides are operating under entirely different assumptions about how backpressure is communicated, on top of one side actively dropping and retransmitting frames the other side never expected to collide with in the first place.

Visual Summary

Here’s the whole failure chain laid out as a single picture, tracing one frame’s journey through a mismatched link from the forced full-duplex host down to the auto-negotiated switch port that fell back to half duplex:

PLAINTEXT
              Host NIC (Forced 100 Full Duplex)
                +---------------------------+
                |  Transmits continuously   |
                |  No collision detection   |
                +------------+--------------+
                             |
                  Electrical link (100 Mbps)
                             v
        Switch PHY (Auto, Defaults to 100 Half Duplex)
                +---------------------------+
                |      CSMA/CD enabled      |
                |     Detects collisions    |
                +------------+--------------+
                             |
                             v
                  Collision Domain Exists
                             |
                             v
             Half-duplex side detects collisions
             Full-duplex side ignores collisions
Click to expand and view more

The mismatch isn’t a failure of either device individually, both are behaving exactly as their configuration tells them to. It’s the disagreement between the two configurations, one forced and one that fell back via parallel detection, that creates a link where each end has a fundamentally different understanding of how the medium works. That’s the core lesson worth taking away: at the PHY layer, “link up” only tells you that electrons are flowing, not that both ends agree on the rules for using the wire.

Copyright Notice

Author: Kernelstub

Link: https://blog.kernelstub.dev/posts/decoding-auto-negotiation-and-duplex-mismatch-at-the-phy-layer/

License: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

© 2026 Prepakis Georgios | Kernelstub | Security Researcher. All rights reserved.

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut