Date: Tue, 1 Aug 2006 17:34:17 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102957 for review Message-ID: <200608011734.k71HYHWr019911@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102957 Change 102957 by jhb@jhb_mutex on 2006/08/01 17:33:57 IFC @102955. Affected files ... .. //depot/projects/smpng/sys/dev/re/if_re.c#43 integrate .. //depot/projects/smpng/sys/net/if_vlan.c#51 integrate .. //depot/projects/smpng/sys/pci/if_rlreg.h#33 integrate Differences ... ==== //depot/projects/smpng/sys/dev/re/if_re.c#43 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.70 2006/07/30 23:25:21 wpaul Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.71 2006/08/01 17:18:25 wpaul Exp $"); /* * RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver @@ -190,6 +190,8 @@ "Corega CG-LAPCIGT (RTL8169S) Gigabit Ethernet" }, { LINKSYS_VENDORID, LINKSYS_DEVICEID_EG1032, RL_HWREV_8169S, "Linksys EG1032 (RTL8169S) Gigabit Ethernet" }, + { USR_VENDORID, USR_DEVICEID_997902, RL_HWREV_8169S, + "US Robotics 997902 (RTL8169S) Gigabit Ethernet" }, { 0, 0, 0, NULL } }; @@ -984,26 +986,6 @@ RL_DESC_INC(idx); } - /* - * With some of the RealTek chips, using the checksum offload - * support in conjunction with the autopadding feature results - * in the transmission of corrupt frames. For example, if we - * need to send a really small IP fragment that's less than 60 - * bytes in size, and IP header checksumming is enabled, the - * resulting ethernet frame that appears on the wire will - * have garbled payload. To work around this, if TX checksum - * offload is enabled, we always manually pad short frames out - * to the minimum ethernet frame size. We do this by lying - * about the size of the final fragment in the DMA map. - */ - - if (ctx->rl_flags && totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { - i = cmdstat & 0xFFFF; - i += ETHER_MIN_LEN - ETHER_CRC_LEN - totlen; - cmdstat = (cmdstat & 0xFFFF) | i; - d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags); - } - d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF); ctx->rl_maxsegs = nseg; ctx->rl_idx = idx; @@ -1386,6 +1368,9 @@ if (sc->rl_res) bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); + /* Yield the CPU long enough for any tasks to drain */ + + tsleep(sc, PPAUSE, "rewait", hz); /* Unload and free the RX DMA ring memory and map */ @@ -1812,6 +1797,17 @@ ifp->if_timer = 0; } + /* + * Some chips will ignore a second TX request issued while an + * existing transmission is in progress. If the transmitter goes + * idle but there are still packets waiting to be sent, we need + * to restart the channel here to flush them out. This only seems + * to be required with the PCIe devices. + */ + + if (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT) + CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); + #ifdef RE_TX_MODERATION /* * If not all descriptors have been released reaped yet, @@ -1822,6 +1818,7 @@ if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT) CSR_WRITE_4(sc, RL_TIMERCNT, 1); #endif + } static void @@ -2031,8 +2028,27 @@ arg.rl_ring = sc->rl_ldata.rl_tx_list; map = sc->rl_ldata.rl_tx_dmamap[*idx]; - error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map, - *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT); + + /* + * With some of the RealTek chips, using the checksum offload + * support in conjunction with the autopadding feature results + * in the transmission of corrupt frames. For example, if we + * need to send a really small IP fragment that's less than 60 + * bytes in size, and IP header checksumming is enabled, the + * resulting ethernet frame that appears on the wire will + * have garbled payload. To work around this, if TX checksum + * offload is enabled, we always manually pad short frames out + * to the minimum ethernet frame size. We do this by pretending + * the mbuf chain has too many fragments so the coalescing code + * below can assemble the packet into a single buffer that's + * padded out to the mininum frame size. + */ + + if (arg.rl_flags && (*m_head)->m_pkthdr.len < RL_MIN_FRAMELEN) + error = EFBIG; + else + error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map, + *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT); if (error && error != EFBIG) { if_printf(sc->rl_ifp, "can't map mbuf (error %d)\n", error); @@ -2048,6 +2064,19 @@ else *m_head = m_new; + /* + * Manually pad short frames, and zero the pad space + * to avoid leaking data. + */ + + if (m_new->m_pkthdr.len < RL_MIN_FRAMELEN) { + bzero(mtod(m_new, char *) + m_new->m_pkthdr.len, + RL_MIN_FRAMELEN - m_new->m_pkthdr.len); + m_new->m_pkthdr.len += RL_MIN_FRAMELEN - + m_new->m_pkthdr.len; + m_new->m_len = m_new->m_pkthdr.len; + } + arg.sc = sc; arg.rl_idx = *idx; arg.rl_maxsegs = sc->rl_ldata.rl_tx_free; @@ -2176,7 +2205,7 @@ * location on the 8169 gigE chip. I don't know why. */ - CSR_WRITE_2(sc, sc->rl_txstart, RL_TXSTART_START); + CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); #ifdef RE_TX_MODERATION /* ==== //depot/projects/smpng/sys/net/if_vlan.c#51 (text+ko) ==== @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/net/if_vlan.c,v 1.106 2006/07/09 06:04:00 sam Exp $ + * $FreeBSD: src/sys/net/if_vlan.c,v 1.107 2006/08/01 17:28:10 qingli Exp $ */ /* @@ -917,21 +917,15 @@ __func__, ntohs(evl->evl_encap_proto))); tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); - - /* - * Restore the original ethertype. We'll remove - * the encapsulation after we've found the vlan - * interface corresponding to the tag. - */ - evl->evl_encap_proto = evl->evl_proto; break; default: - tag = (uint16_t) -1; -#ifdef INVARIANTS - panic("%s: unsupported if_type (%u)", - __func__, ifp->if_type); +#ifdef DEBUG + /* XXX rate limit? */ + if_printf(ifp, "unsupported if_type %u", ifp->if_type); #endif - break; + m_freem(m); + ifp->if_noproto++; /* XXX? */ + return; } } @@ -952,12 +946,12 @@ if (mtag == NULL) { /* * Packet had an in-line encapsulation header; - * remove it. The original header has already - * been fixed up above. + * remove it. Note that we leave the type field + * unchanged; we only copy up the mac addresses. */ bcopy(mtod(m, caddr_t), mtod(m, caddr_t) + ETHER_VLAN_ENCAP_LEN, - ETHER_HDR_LEN); + ETHER_HDR_LEN - ETHER_TYPE_LEN); m_adj(m, ETHER_VLAN_ENCAP_LEN); } ==== //depot/projects/smpng/sys/pci/if_rlreg.h#33 (text+ko) ==== @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/pci/if_rlreg.h,v 1.59 2006/07/30 23:25:20 wpaul Exp $ + * $FreeBSD: src/sys/pci/if_rlreg.h,v 1.60 2006/08/01 17:18:25 wpaul Exp $ */ /* @@ -938,6 +938,14 @@ */ #define EDIMAX_DEVICEID_EP4103DL 0xAB06 +/* US Robotics vendor ID */ + +#define USR_VENDORID 0x16EC + +/* US Robotics 997902 device ID */ + +#define USR_DEVICEID_997902 0x0116 + /* * PCI low memory base and low I/O base register, and * other PCI registers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608011734.k71HYHWr019911>