Date: Fri, 01 Mar 2019 02:59:30 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 236119] Intel Ethernet 82547 device cannot transfer data Message-ID: <bug-236119-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D236119 Bug ID: 236119 Summary: Intel Ethernet 82547 device cannot transfer data Product: Base System Version: 12.0-STABLE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: jgibbons@protogate.com When upgrading some of my machines from FreeBSD 11 to FreeBSD 12, I found t= hat some of them could not transfer data via Ethernet after the upgrade. ifcon= fig seemed to work normally, including showing "status: active", but that inter= face could neither send nor receive data packets, no matter what I tried. And a= few minutes after booting my systems, they would silently hang, with no response whatsoever, even on a serial console. I eventually narrowed down the problem to my machines with Intel 82547GI ch= ips, which look like this in "pciconf -lv": em0@pci0:1:1:0: class=3D0x020000 card=3D0x10758086 chip=3D0x10758086 rev=3D= 0x00 hdr=3D0x00 vendor =3D 'Intel Corporation' device =3D '82547GI Gigabit Ethernet Controller' class =3D network subclass =3D ethernet By comparing the FreeBSD 11 code (which I knew worked) with the FreeBSD 12 = code which had the problem, I found the solution: the 82547 is an "edge" case wh= ich slipped through the cracks when the Intel em driver was modified for FreeBSD 12. Here is what I had to change in if_em.c to make the Intel 82547 Ethern= et chips work: root@prod:~ # svn diff /usr/src/sys/dev/e1000/if_em.c Index: /usr/src/sys/dev/e1000/if_em.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /usr/src/sys/dev/e1000/if_em.c (revision 344229) +++ /usr/src/sys/dev/e1000/if_em.c (working copy) @@ -31,13 +31,16 @@ #include <sys/sbuf.h> #include <machine/_inttypes.h> -#define em_mac_min e1000_82547 +// jagwas: #define em_mac_min e1000_82547 +#define em_mac_min e1000_82571 // jag; 25feb2019; + // so (adapter->hw.mac.type < em_mac_mi= n) + // is true for 82547GI and below #define igb_mac_min e1000_82575 /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] =3D "7.6.1-k"; +char em_driver_version[] =3D "7.6.1-k+jag3"; /********************************************************************* * PCI Device ID Table @@ -2476,6 +2479,24 @@ case e1000_i211: pba =3D E1000_PBA_34K; break; + // jag; 26feb2019 added this case section; adapted from + // FreeBSD 11 /usr/src/sys/dev/e1000/if_lem.c + case e1000_82547: + case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */ + if (adapter->hw.mac.max_frame_size > 8192) + pba =3D E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ + else + pba =3D E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ + + // jag; the following would be needed for plain 82547 (befo= re GI) + // and would also require adding the elements set here to + // struct adapter in if_em.h: + // adapter->tx_fifo_head =3D 0; + // adapter->tx_head_addr =3D pba << EM_TX_HEAD_ADDR_SHIFT; + // adapter->tx_fifo_size =3D + // (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT; + + break; default: if (adapter->hw.mac.max_frame_size > 8192) pba =3D E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ root@prod:~ # With that change, my interfaces all now work fine, and my systems don't han= g (I think the hanging problem was because the pre-change if_em.c was assigning = more packet buffer space than the 82547GI actually has). I believe this change will also help some of the other 82547 models to work, but I don't have any of those chips and so cannot test them. Those chips a= lso seem to need some workarounds for special cases (like jumbo frames which cr= oss buffer boundaries); those workarounds are implemented in FreeBSD 11 but not= in FreeBSD 12, and I didn't implement them as part of this change because my 82547GI chip doesn't need them. (For example, see the lem_82547_fifo_workaround() function; search for "82547" in the /usr/src/sys/dev/e1000/if_lem.c file in FreeBSD 11 to see other workarounds= ). This problem seems to exist on CURRENT, too (from looking at the code; I ha= ve not tested that). --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-236119-227>