On Thu, Jan 22, 2015 at 08:52:25PM +0000, Stuart Henderson wrote:
> some minor things I spotted:
> 
> slight KNF issues, some of the new lines are > 80 columns.
> 
> +     case RL_HWREV_8168E:
> +             CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) | 0x01);
> +             break;
> +     default:
> +             CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) | 
> RL_CFG4_JUMBO_EN1);
> +             break;
> 
> there's a new #define for one of these but not the other; probably
> would be preferable to a "magic" 0x01

ok, fixed.

> 
> +     if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0) {
> +             ifp->if_capabilities &= ~(IFCAP_CSUM_IPv4);
> +             re_set_jumbo(sc);
> +     }
> 
> wondering...would it be possible to only disable checksum offload iff
> the user has configured a large mtu?

something along the lines of dlg's solution seems reasonable, but should
probably come in a separate diff. for now i've added the 8168/8111D/E
chips to the "broken tx checksum" list rather than having it sitting
in that chunk as a special snowflake.

thanks for the feedback, diff below.


Index: re.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/re.c,v
retrieving revision 1.173
diff -u -r1.173 re.c
--- re.c        21 Jan 2015 10:00:42 -0000      1.173
+++ re.c        28 Jan 2015 12:04:49 -0000
@@ -171,6 +171,8 @@
 int    re_ifmedia_upd(struct ifnet *);
 void   re_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
+void   re_set_jumbo(struct rl_softc *);
+
 void   re_eeprom_putbyte(struct rl_softc *, int);
 void   re_eeprom_getword(struct rl_softc *, int, u_int16_t *);
 void   re_read_eeprom(struct rl_softc *, caddr_t, int, int);
@@ -206,6 +208,10 @@
        CSR_WRITE_1(sc, RL_EECMD,                       \
                CSR_READ_1(sc, RL_EECMD) & ~x)
 
+#define RL_FRAMELEN(mtu)                               \
+       (mtu + ETHER_HDR_LEN + ETHER_CRC_LEN +          \
+               ETHER_VLAN_ENCAP_LEN)
+
 static const struct re_revision {
        u_int32_t               re_chipid;
        const char              *re_name;
@@ -1022,8 +1028,10 @@
 
        /* Create DMA maps for RX buffers */
        for (i = 0; i < RL_RX_DESC_CNT; i++) {
-               error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
-                   0, 0, &sc->rl_ldata.rl_rxsoft[i].rxs_dmamap);
+               error = bus_dmamap_create(sc->sc_dmat,
+                   RL_FRAMELEN(sc->rl_max_mtu), 1,
+                   RL_FRAMELEN(sc->rl_max_mtu), 0, 0,
+                   &sc->rl_ldata.rl_rxsoft[i].rxs_dmamap);
                if (error) {
                        printf("%s: can't create DMA map for RX\n",
                            sc->sc_dev.dv_xname);
@@ -1038,8 +1046,7 @@
        ifp->if_ioctl = re_ioctl;
        ifp->if_start = re_start;
        ifp->if_watchdog = re_watchdog;
-       if ((sc->rl_flags & RL_FLAG_JUMBOV2) == 0)
-               ifp->if_hardmtu = sc->rl_max_mtu;
+       ifp->if_hardmtu = sc->rl_max_mtu;
        IFQ_SET_MAXLEN(&ifp->if_snd, RL_TX_QLEN);
        IFQ_SET_READY(&ifp->if_snd);
 
@@ -1054,6 +1061,9 @@
        case RL_HWREV_8168C:
        case RL_HWREV_8168C_SPIN2:
        case RL_HWREV_8168CP:
+       /* 8186/8111D/E seem to have a similar problem. */
+       case RL_HWREV_8168D:
+       case RL_HWREV_8168E:
                break;
        default:
                ifp->if_capabilities |= IFCAP_CSUM_IPv4;
@@ -1159,7 +1169,7 @@
        u_int32_t       cmdstat;
        int             error, idx;
 
-       m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
+       m = MCLGETI(NULL, M_DONTWAIT, NULL, RL_FRAMELEN(sc->rl_max_mtu));
        if (!m)
                return (ENOBUFS);
 
@@ -1168,7 +1178,7 @@
         * alignment so that the frame payload is
         * longword aligned on strict alignment archs.
         */
-       m->m_len = m->m_pkthdr.len = RE_RX_DESC_BUFLEN;
+       m->m_len = m->m_pkthdr.len = RL_FRAMELEN(sc->rl_max_mtu);
        m->m_data += RE_ETHER_ALIGN;
 
        idx = sc->rl_ldata.rl_rx_prodidx;
@@ -1306,8 +1316,12 @@
                    BUS_DMASYNC_POSTREAD);
                bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
 
-               if (!(rxstat & RL_RDESC_STAT_EOF)) {
-                       m->m_len = RE_RX_DESC_BUFLEN;
+               if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0 &&
+                   (rxstat & (RL_RDESC_STAT_SOF | RL_RDESC_STAT_EOF)) !=
+                   (RL_RDESC_STAT_SOF | RL_RDESC_STAT_EOF)) {
+                       continue;
+               } else if (!(rxstat & RL_RDESC_STAT_EOF)) {
+                       m->m_len = RL_FRAMELEN(sc->rl_max_mtu);
                        if (sc->rl_head == NULL)
                                sc->rl_head = sc->rl_tail = m;
                        else {
@@ -1341,8 +1355,9 @@
                 * if total_len > 2^13-1, both _RXERRSUM and _GIANT will be
                 * set, but if CRC is clear, it will still be a valid frame.
                 */
-               if (rxstat & RL_RDESC_STAT_RXERRSUM && !(total_len > 8191 &&
-                   (rxstat & RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT)) {
+               if ((rxstat & RL_RDESC_STAT_RXERRSUM) != 0 &&
+                   !(rxstat & RL_RDESC_STAT_RXERRSUM && !(total_len > 8191 &&
+                   (rxstat & RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT))) {
                        ifp->if_ierrors++;
                        /*
                         * If this is part of a multi-fragment packet,
@@ -1356,9 +1371,9 @@
                }
 
                if (sc->rl_head != NULL) {
-                       m->m_len = total_len % RE_RX_DESC_BUFLEN;
+                       m->m_len = total_len % RL_FRAMELEN(sc->rl_max_mtu);
                        if (m->m_len == 0)
-                               m->m_len = RE_RX_DESC_BUFLEN;
+                               m->m_len = RL_FRAMELEN(sc->rl_max_mtu);
                        /* 
                         * Special case: if there's 4 bytes or less
                         * in this buffer, the mbuf can be discarded:
@@ -1916,6 +1931,9 @@
            htole32(*(u_int32_t *)(&eaddr.eaddr[0])));
        CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
 
+       if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0)
+               re_set_jumbo(sc);
+
        /*
         * For C+ mode, initialize the RX descriptors and mbufs.
         */
@@ -1979,7 +1997,8 @@
         * size so we can receive jumbo frames.
         */
        if (sc->sc_hwrev != RL_HWREV_8139CPLUS) {
-               if (sc->rl_flags & RL_FLAG_PCIE)
+               if (sc->rl_flags & RL_FLAG_PCIE &&
+                   (sc->rl_flags & RL_FLAG_JUMBOV2) == 0)
                        CSR_WRITE_2(sc, RL_MAXRXPKTLEN, RE_RX_DESC_BUFLEN);
                else
                        CSR_WRITE_2(sc, RL_MAXRXPKTLEN, 16383);
@@ -2064,7 +2083,7 @@
                break;
        case SIOCGIFRXR:
                error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
-                   NULL, MCLBYTES, &sc->rl_ldata.rl_rx_ring);
+                   NULL, RL_FRAMELEN(sc->rl_max_mtu), 
&sc->rl_ldata.rl_rx_ring);
                break;
        default:
                error = ether_ioctl(ifp, &sc->sc_arpcom, command, data);
@@ -2282,6 +2301,29 @@
                panic("%s: unknown imtype %d",
                      sc->sc_dev.dv_xname, imtype);
        }
+}
+
+void
+re_set_jumbo(struct rl_softc *sc)
+{
+       CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG);
+       CSR_WRITE_1(sc, RL_CFG3, CSR_READ_1(sc, RL_CFG3) |
+           RL_CFG3_JUMBO_EN0);
+
+       switch (sc->sc_hwrev) {
+       case RL_HWREV_8168DP:
+               break;
+       case RL_HWREV_8168E:
+               CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) |
+                   RL_CFG4_8168E_JUMBO_EN1);
+               break;
+       default:
+               CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) |
+                   RL_CFG4_JUMBO_EN1);
+               break;
+       }
+
+       CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
 }
 
 void
Index: rtl81x9reg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/rtl81x9reg.h,v
retrieving revision 1.90
diff -u -r1.90 rtl81x9reg.h
--- rtl81x9reg.h        20 Jan 2015 04:33:06 -0000      1.90
+++ rtl81x9reg.h        28 Jan 2015 12:04:49 -0000
@@ -442,6 +442,7 @@
 #define RL_CFG3_GRANTSEL       0x80
 #define RL_CFG3_WOL_MAGIC      0x20
 #define RL_CFG3_WOL_LINK       0x10
+#define RL_CFG3_JUMBO_EN0      0x04
 #define RL_CFG3_FAST_B2B       0x01
 
 /*
@@ -449,6 +450,8 @@
  */
 #define RL_CFG4_LWPTN          0x04
 #define RL_CFG4_LWPME          0x10
+#define RL_CFG4_JUMBO_EN1      0x02
+#define RL_CFG4_8168E_JUMBO_EN1 0x01
 
 /*
  * Config 5 register
@@ -742,8 +745,7 @@
 #define RL_ADDR_LO(y)  ((u_int64_t) (y) & 0xFFFFFFFF)
 #define RL_ADDR_HI(y)  ((u_int64_t) (y) >> 32)
 
-/* see comment in dev/ic/re.c */
-#define RL_JUMBO_FRAMELEN      7440
+#define RL_JUMBO_FRAMELEN      (9 * 1024)
 #define RL_JUMBO_MTU_4K                \
        ((4 * 1024) - ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN)
 #define RL_JUMBO_MTU_6K                \

Reply via email to