Using the e1000 driver, when a igb interface is configured with: `media 100BaseTX mediaopt full-duplex` and connected to a switchport which is configured accordingly with autonegotiation disabled speed = 100Mbps duplex = full and connected with a straight cable (as it should), the resulting interface status is `no carrier`, while it should not. I am able to reproduce this behavior with both Cisco and Netgear switches. Switching back the igb to `media auto` entails the status to become active, but with a duplex resolved to `half`, as it is expected in this case. Switching the igb to `media 100BaseTX mediaopt full-duplex`, and the switchport to autoneg, entails both side to be up (ie igb status: active), but the duplex to be resolved as `full` on the switch side, while it should be resolved to 'half' instead in this case. To be clean the configuration should be either set to autoneg on both sides, either forced to 100-full on both sides. In this second case, when an igb interface is forced to media `100BaseTX mediaopt full-duplex` and connected to a switchport also set to `100-full`, the igb status remains at `no-carrier` while the expected one is `active`. The same configuration with other NIC drivers, e.g. bge or bce, entails a correct behavior.
Here is an exemple of hardware on which this uncorrect behavior can be observed: # pciconf -l -v | grep -i igb -A 4 igb0@pci0:26:0:0: class=0x020000 rev=0x01 hdr=0x00 vendor=0x8086 device=0x1521 subvendor=0x1028 subdevice=0x1faa vendor = 'Intel Corporation' device = 'I350 Gigabit Network Connection' class = network subclass = ethernet igb1@pci0:26:0:1: class=0x020000 rev=0x01 hdr=0x00 vendor=0x8086 device=0x1521 subvendor=0x1028 subdevice=0x1faa vendor = 'Intel Corporation' device = 'I350 Gigabit Network Connection' class = network subclass = ethernet
We've taken a look at the PHY interactions with this dtrace snippet: dtrace -n 'fbt::e1000_read_phy_reg_82580:entry { printf("read(%#x)", arg1); self->data = arg2; }' -n 'fbt::e1000_read_phy_reg_82580:return { printf("=> %#x", *(uint16_t *)self->data); }' -n 'fbt::e1000_write_phy_reg_82580:entry { printf("write(%#x, %#x)", arg1, arg2); }' -c "ifconfig igb0 media 100BaseTX mediaopt full-duplex" It's a bit strange that running the command to force 100-full with dtrace does not entail the problem. but running again ifconfig igb1 media auto; ifconfig igb1 media 100BaseTX mediaopt full-duplex; entails the problem again. See the bellow output: [root@r640fw7m ~]# ifconfig igb1 media auto [root@r640fw7m ~]# ifconfig igb1 igb1: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=4e100bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP> ether e4:43:4b:de:53:03 inet 10.2.7.141 netmask 0xffff0000 broadcast 10.2.255.255 media: Ethernet autoselect (100baseTX ) status: active nd6 options=1 [root@r640fw7m ~]# dtrace -n 'fbt::e1000_read_phy_reg_82580:entry { printf("read(%#x)", arg1); self->data = arg2; }' -n 'fbt::e1000_read_phy_reg_82580:return { printf("=> %#x", *(uint16_t *)self->data); }' -n 'fbt::e1000_write_phy_reg_82580:entry { printf("write(%#x, %#x)", arg1, arg2); }' -c "ifconfig igb1 media 100BaseTX mediaopt full-duplex" dtrace: description 'fbt::e1000_read_phy_reg_82580:entry ' matched 1 probe dtrace: description 'fbt::e1000_read_phy_reg_82580:return ' matched 1 probe dtrace: description 'fbt::e1000_write_phy_reg_82580:entry ' matched 1 probe dtrace: pid 31422 has exited CPU ID FUNCTION:NAME 26 4923 e1000_read_phy_reg_82580:entry read(0x16) 26 4924 e1000_read_phy_reg_82580:return => 0x7f08 26 4925 e1000_write_phy_reg_82580:entry write(0x16, 0xff08) 26 4923 e1000_read_phy_reg_82580:entry read(0x12) 26 4924 e1000_read_phy_reg_82580:return => 0x840a 26 4925 e1000_write_phy_reg_82580:entry write(0x12, 0x840a) 26 4923 e1000_read_phy_reg_82580:entry read(0x9) 26 4924 e1000_read_phy_reg_82580:return => 0x600 26 4925 e1000_write_phy_reg_82580:entry write(0x9, 0x600) 26 4923 e1000_read_phy_reg_82580:entry read(0) 26 4924 e1000_read_phy_reg_82580:return => 0x1040 26 4925 e1000_write_phy_reg_82580:entry write(0, 0x2100) 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x16) 26 4924 e1000_read_phy_reg_82580:return => 0x7f08 26 4925 e1000_write_phy_reg_82580:entry write(0x16, 0xff08) 26 4923 e1000_read_phy_reg_82580:entry read(0x12) 26 4924 e1000_read_phy_reg_82580:return => 0x840a 26 4925 e1000_write_phy_reg_82580:entry write(0x12, 0x840a) 26 4923 e1000_read_phy_reg_82580:entry read(0x9) 26 4924 e1000_read_phy_reg_82580:return => 0x600 26 4925 e1000_write_phy_reg_82580:entry write(0x9, 0x600) 26 4923 e1000_read_phy_reg_82580:entry read(0) 26 4924 e1000_read_phy_reg_82580:return => 0x1040 26 4925 e1000_write_phy_reg_82580:entry write(0, 0x2100) 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 2 4923 e1000_read_phy_reg_82580:entry read(0x1) [root@r640fw7m ~]# ifconfig igb1 igb1: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=4e100bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP> ether e4:43:4b:de:53:03 inet 10.2.7.141 netmask 0xffff0000 broadcast 10.2.255.255 media: Ethernet 100baseTX status: active nd6 options=1 [root@r640fw7m ~]# ifconfig igb1 media 100BaseTX mediaopt full-duplex [root@r640fw7m ~]# ifconfig igb1 igb1: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=4e100bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP> ether e4:43:4b:de:53:03 inet 10.2.7.141 netmask 0xffff0000 broadcast 10.2.255.255 media: Ethernet 100baseTX status: active nd6 options=1 [root@r640fw7m ~]# ifconfig igb1 media auto [root@r640fw7m ~]# ifconfig igb1 media 100BaseTX mediaopt full-duplex [root@r640fw7m ~]# ifconfig igb1 igb1: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=4e100bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP> ether e4:43:4b:de:53:03 inet 10.2.7.141 netmask 0xffff0000 broadcast 10.2.255.255 media: Ethernet 100baseTX (autoselect) status: no carrier nd6 options=1
I'm struggling to make sense of this. I can't quite follow how the code produces this PHY access pattern, and can also not work out why we end up getting link when dtrace instrumented, and not when it's not. Unless we're not waiting long enough for the PHY to do its thing, but I also can't see evidence of that in the dtrace output. There are two series of what looks like a wait for link pattern in the dtrace output> That is, this: 26 4923 e1000_read_phy_reg_82580:entry read(0x1) 26 4924 e1000_read_phy_reg_82580:return => 0x7949 I'd assume that's produced by e1000_phy_has_link_generic() where we do 2x iterations of read_reg(PHY_STATUS), and check for the MII_SR_LINK_STATUS flag. That flag (0x0004) is not set in any of these reads, and yet ifconfig does later report "status: active".
Possibly https://reviews.freebsd.org/D34449 which was already reverted after multiple reports of a regression.