Module Name:    src
Committed By:   msaitoh
Date:           Wed Oct 14 07:16:04 UTC 2015

Modified Files:
        src/sys/dev/pci: if_wm.c

Log Message:
- Update TODO:
  - "Multiqueue" -> "TX Multiqueue" because RX Multiqueue was added.
  - Sort entries.
- Grouping functions.


To generate a diff of this commit:
cvs rdiff -u -r1.370 -r1.371 src/sys/dev/pci/if_wm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.370 src/sys/dev/pci/if_wm.c:1.371
--- src/sys/dev/pci/if_wm.c:1.370	Tue Oct 13 21:28:41 2015
+++ src/sys/dev/pci/if_wm.c	Wed Oct 14 07:16:04 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.370 2015/10/13 21:28:41 christos Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.371 2015/10/14 07:16:04 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -73,17 +73,17 @@
  * TODO (in order of importance):
  *
  *	- Check XXX'ed comments
- *	- EEE (Energy Efficiency Ethernet)
- *	- Multi queue
- *	- Image Unique ID
  *	- LPLU other than PCH*
+ *	- TX Multi queue
+ *	- EEE (Energy Efficiency Ethernet)
  *	- Virtual Function
  *	- Set LED correctly (based on contents in EEPROM)
  *	- Rework how parameters are loaded from the EEPROM.
+ *	- Image Unique ID
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.370 2015/10/13 21:28:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.371 2015/10/14 07:16:04 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -566,12 +566,15 @@ static void	wm_reset(struct wm_softc *);
 static int	wm_add_rxbuf(struct wm_rxqueue *, int);
 static void	wm_rxdrain(struct wm_rxqueue *);
 static void	wm_init_rss(struct wm_softc *);
+#ifdef WM_MSI_MSIX
+static void	wm_adjust_qnum(struct wm_softc *, int);
+static int	wm_setup_legacy(struct wm_softc *);
+static int	wm_setup_msix(struct wm_softc *);
+#endif
 static int	wm_init(struct ifnet *);
 static int	wm_init_locked(struct ifnet *);
 static void	wm_stop(struct ifnet *, int);
 static void	wm_stop_locked(struct ifnet *, int);
-static int	wm_tx_offload(struct wm_softc *, struct wm_txsoft *,
-    uint32_t *, uint8_t *);
 static void	wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *);
 static void	wm_82547_txfifo_stall(void *);
 static int	wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *);
@@ -595,6 +598,8 @@ static int	wm_alloc_txrx_queues(struct w
 static void	wm_free_txrx_queues(struct wm_softc *);
 static int	wm_init_txrx_queues(struct wm_softc *);
 /* Start */
+static int	wm_tx_offload(struct wm_softc *, struct wm_txsoft *,
+    uint32_t *, uint8_t *);
 static void	wm_start(struct ifnet *);
 static void	wm_start_locked(struct ifnet *);
 static int	wm_nq_tx_offload(struct wm_softc *, struct wm_txsoft *,
@@ -610,9 +615,6 @@ static void	wm_linkintr_serdes(struct wm
 static void	wm_linkintr(struct wm_softc *, uint32_t);
 static int	wm_intr_legacy(void *);
 #ifdef WM_MSI_MSIX
-static void	wm_adjust_qnum(struct wm_softc *, int);
-static int	wm_setup_legacy(struct wm_softc *);
-static int	wm_setup_msix(struct wm_softc *);
 static int	wm_txintr_msix(void *);
 static int	wm_rxintr_msix(void *);
 static int	wm_linkintr_msix(void *);
@@ -5052,202 +5054,6 @@ wm_stop_locked(struct ifnet *ifp, int di
 #endif
 }
 
-/*
- * wm_tx_offload:
- *
- *	Set up TCP/IP checksumming parameters for the
- *	specified packet.
- */
-static int
-wm_tx_offload(struct wm_softc *sc, struct wm_txsoft *txs, uint32_t *cmdp,
-    uint8_t *fieldsp)
-{
-	struct wm_txqueue *txq = &sc->sc_txq[0];
-	struct mbuf *m0 = txs->txs_mbuf;
-	struct livengood_tcpip_ctxdesc *t;
-	uint32_t ipcs, tucs, cmd, cmdlen, seg;
-	uint32_t ipcse;
-	struct ether_header *eh;
-	int offset, iphl;
-	uint8_t fields;
-
-	/*
-	 * XXX It would be nice if the mbuf pkthdr had offset
-	 * fields for the protocol headers.
-	 */
-
-	eh = mtod(m0, struct ether_header *);
-	switch (htons(eh->ether_type)) {
-	case ETHERTYPE_IP:
-	case ETHERTYPE_IPV6:
-		offset = ETHER_HDR_LEN;
-		break;
-
-	case ETHERTYPE_VLAN:
-		offset = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
-		break;
-
-	default:
-		/*
-		 * Don't support this protocol or encapsulation.
-		 */
-		*fieldsp = 0;
-		*cmdp = 0;
-		return 0;
-	}
-
-	if ((m0->m_pkthdr.csum_flags &
-	    (M_CSUM_TSOv4|M_CSUM_UDPv4|M_CSUM_TCPv4)) != 0) {
-		iphl = M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
-	} else {
-		iphl = M_CSUM_DATA_IPv6_HL(m0->m_pkthdr.csum_data);
-	}
-	ipcse = offset + iphl - 1;
-
-	cmd = WTX_CMD_DEXT | WTX_DTYP_D;
-	cmdlen = WTX_CMD_DEXT | WTX_DTYP_C | WTX_CMD_IDE;
-	seg = 0;
-	fields = 0;
-
-	if ((m0->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6)) != 0) {
-		int hlen = offset + iphl;
-		bool v4 = (m0->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0;
-
-		if (__predict_false(m0->m_len <
-				    (hlen + sizeof(struct tcphdr)))) {
-			/*
-			 * TCP/IP headers are not in the first mbuf; we need
-			 * to do this the slow and painful way.  Let's just
-			 * hope this doesn't happen very often.
-			 */
-			struct tcphdr th;
-
-			WM_EVCNT_INCR(&sc->sc_ev_txtsopain);
-
-			m_copydata(m0, hlen, sizeof(th), &th);
-			if (v4) {
-				struct ip ip;
-
-				m_copydata(m0, offset, sizeof(ip), &ip);
-				ip.ip_len = 0;
-				m_copyback(m0,
-				    offset + offsetof(struct ip, ip_len),
-				    sizeof(ip.ip_len), &ip.ip_len);
-				th.th_sum = in_cksum_phdr(ip.ip_src.s_addr,
-				    ip.ip_dst.s_addr, htons(IPPROTO_TCP));
-			} else {
-				struct ip6_hdr ip6;
-
-				m_copydata(m0, offset, sizeof(ip6), &ip6);
-				ip6.ip6_plen = 0;
-				m_copyback(m0,
-				    offset + offsetof(struct ip6_hdr, ip6_plen),
-				    sizeof(ip6.ip6_plen), &ip6.ip6_plen);
-				th.th_sum = in6_cksum_phdr(&ip6.ip6_src,
-				    &ip6.ip6_dst, 0, htonl(IPPROTO_TCP));
-			}
-			m_copyback(m0, hlen + offsetof(struct tcphdr, th_sum),
-			    sizeof(th.th_sum), &th.th_sum);
-
-			hlen += th.th_off << 2;
-		} else {
-			/*
-			 * TCP/IP headers are in the first mbuf; we can do
-			 * this the easy way.
-			 */
-			struct tcphdr *th;
-
-			if (v4) {
-				struct ip *ip =
-				    (void *)(mtod(m0, char *) + offset);
-				th = (void *)(mtod(m0, char *) + hlen);
-
-				ip->ip_len = 0;
-				th->th_sum = in_cksum_phdr(ip->ip_src.s_addr,
-				    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
-			} else {
-				struct ip6_hdr *ip6 =
-				    (void *)(mtod(m0, char *) + offset);
-				th = (void *)(mtod(m0, char *) + hlen);
-
-				ip6->ip6_plen = 0;
-				th->th_sum = in6_cksum_phdr(&ip6->ip6_src,
-				    &ip6->ip6_dst, 0, htonl(IPPROTO_TCP));
-			}
-			hlen += th->th_off << 2;
-		}
-
-		if (v4) {
-			WM_EVCNT_INCR(&sc->sc_ev_txtso);
-			cmdlen |= WTX_TCPIP_CMD_IP;
-		} else {
-			WM_EVCNT_INCR(&sc->sc_ev_txtso6);
-			ipcse = 0;
-		}
-		cmd |= WTX_TCPIP_CMD_TSE;
-		cmdlen |= WTX_TCPIP_CMD_TSE |
-		    WTX_TCPIP_CMD_TCP | (m0->m_pkthdr.len - hlen);
-		seg = WTX_TCPIP_SEG_HDRLEN(hlen) |
-		    WTX_TCPIP_SEG_MSS(m0->m_pkthdr.segsz);
-	}
-
-	/*
-	 * NOTE: Even if we're not using the IP or TCP/UDP checksum
-	 * offload feature, if we load the context descriptor, we
-	 * MUST provide valid values for IPCSS and TUCSS fields.
-	 */
-
-	ipcs = WTX_TCPIP_IPCSS(offset) |
-	    WTX_TCPIP_IPCSO(offset + offsetof(struct ip, ip_sum)) |
-	    WTX_TCPIP_IPCSE(ipcse);
-	if (m0->m_pkthdr.csum_flags & (M_CSUM_IPv4|M_CSUM_TSOv4)) {
-		WM_EVCNT_INCR(&sc->sc_ev_txipsum);
-		fields |= WTX_IXSM;
-	}
-
-	offset += iphl;
-
-	if (m0->m_pkthdr.csum_flags &
-	    (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) {
-		WM_EVCNT_INCR(&sc->sc_ev_txtusum);
-		fields |= WTX_TXSM;
-		tucs = WTX_TCPIP_TUCSS(offset) |
-		    WTX_TCPIP_TUCSO(offset +
-		    M_CSUM_DATA_IPv4_OFFSET(m0->m_pkthdr.csum_data)) |
-		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
-	} else if ((m0->m_pkthdr.csum_flags &
-	    (M_CSUM_TCPv6|M_CSUM_UDPv6|M_CSUM_TSOv6)) != 0) {
-		WM_EVCNT_INCR(&sc->sc_ev_txtusum6);
-		fields |= WTX_TXSM;
-		tucs = WTX_TCPIP_TUCSS(offset) |
-		    WTX_TCPIP_TUCSO(offset +
-		    M_CSUM_DATA_IPv6_OFFSET(m0->m_pkthdr.csum_data)) |
-		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
-	} else {
-		/* Just initialize it to a valid TCP context. */
-		tucs = WTX_TCPIP_TUCSS(offset) |
-		    WTX_TCPIP_TUCSO(offset + offsetof(struct tcphdr, th_sum)) |
-		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
-	}
-
-	/* Fill in the context descriptor. */
-	t = (struct livengood_tcpip_ctxdesc *)
-	    &txq->txq_descs[txq->txq_next];
-	t->tcpip_ipcs = htole32(ipcs);
-	t->tcpip_tucs = htole32(tucs);
-	t->tcpip_cmdlen = htole32(cmdlen);
-	t->tcpip_seg = htole32(seg);
-	wm_cdtxsync(txq, txq->txq_next, 1, BUS_DMASYNC_PREWRITE);
-
-	txq->txq_next = WM_NEXTTX(txq, txq->txq_next);
-	txs->txs_ndesc++;
-
-	*cmdp = cmd;
-	*fieldsp = fields;
-
-	return 0;
-}
-
 static void
 wm_dump_mbuf_chain(struct wm_softc *sc, struct mbuf *m0)
 {
@@ -5971,6 +5777,202 @@ wm_init_txrx_queues(struct wm_softc *sc)
 }
 
 /*
+ * wm_tx_offload:
+ *
+ *	Set up TCP/IP checksumming parameters for the
+ *	specified packet.
+ */
+static int
+wm_tx_offload(struct wm_softc *sc, struct wm_txsoft *txs, uint32_t *cmdp,
+    uint8_t *fieldsp)
+{
+	struct wm_txqueue *txq = &sc->sc_txq[0];
+	struct mbuf *m0 = txs->txs_mbuf;
+	struct livengood_tcpip_ctxdesc *t;
+	uint32_t ipcs, tucs, cmd, cmdlen, seg;
+	uint32_t ipcse;
+	struct ether_header *eh;
+	int offset, iphl;
+	uint8_t fields;
+
+	/*
+	 * XXX It would be nice if the mbuf pkthdr had offset
+	 * fields for the protocol headers.
+	 */
+
+	eh = mtod(m0, struct ether_header *);
+	switch (htons(eh->ether_type)) {
+	case ETHERTYPE_IP:
+	case ETHERTYPE_IPV6:
+		offset = ETHER_HDR_LEN;
+		break;
+
+	case ETHERTYPE_VLAN:
+		offset = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+		break;
+
+	default:
+		/*
+		 * Don't support this protocol or encapsulation.
+		 */
+		*fieldsp = 0;
+		*cmdp = 0;
+		return 0;
+	}
+
+	if ((m0->m_pkthdr.csum_flags &
+	    (M_CSUM_TSOv4|M_CSUM_UDPv4|M_CSUM_TCPv4)) != 0) {
+		iphl = M_CSUM_DATA_IPv4_IPHL(m0->m_pkthdr.csum_data);
+	} else {
+		iphl = M_CSUM_DATA_IPv6_HL(m0->m_pkthdr.csum_data);
+	}
+	ipcse = offset + iphl - 1;
+
+	cmd = WTX_CMD_DEXT | WTX_DTYP_D;
+	cmdlen = WTX_CMD_DEXT | WTX_DTYP_C | WTX_CMD_IDE;
+	seg = 0;
+	fields = 0;
+
+	if ((m0->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6)) != 0) {
+		int hlen = offset + iphl;
+		bool v4 = (m0->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0;
+
+		if (__predict_false(m0->m_len <
+				    (hlen + sizeof(struct tcphdr)))) {
+			/*
+			 * TCP/IP headers are not in the first mbuf; we need
+			 * to do this the slow and painful way.  Let's just
+			 * hope this doesn't happen very often.
+			 */
+			struct tcphdr th;
+
+			WM_EVCNT_INCR(&sc->sc_ev_txtsopain);
+
+			m_copydata(m0, hlen, sizeof(th), &th);
+			if (v4) {
+				struct ip ip;
+
+				m_copydata(m0, offset, sizeof(ip), &ip);
+				ip.ip_len = 0;
+				m_copyback(m0,
+				    offset + offsetof(struct ip, ip_len),
+				    sizeof(ip.ip_len), &ip.ip_len);
+				th.th_sum = in_cksum_phdr(ip.ip_src.s_addr,
+				    ip.ip_dst.s_addr, htons(IPPROTO_TCP));
+			} else {
+				struct ip6_hdr ip6;
+
+				m_copydata(m0, offset, sizeof(ip6), &ip6);
+				ip6.ip6_plen = 0;
+				m_copyback(m0,
+				    offset + offsetof(struct ip6_hdr, ip6_plen),
+				    sizeof(ip6.ip6_plen), &ip6.ip6_plen);
+				th.th_sum = in6_cksum_phdr(&ip6.ip6_src,
+				    &ip6.ip6_dst, 0, htonl(IPPROTO_TCP));
+			}
+			m_copyback(m0, hlen + offsetof(struct tcphdr, th_sum),
+			    sizeof(th.th_sum), &th.th_sum);
+
+			hlen += th.th_off << 2;
+		} else {
+			/*
+			 * TCP/IP headers are in the first mbuf; we can do
+			 * this the easy way.
+			 */
+			struct tcphdr *th;
+
+			if (v4) {
+				struct ip *ip =
+				    (void *)(mtod(m0, char *) + offset);
+				th = (void *)(mtod(m0, char *) + hlen);
+
+				ip->ip_len = 0;
+				th->th_sum = in_cksum_phdr(ip->ip_src.s_addr,
+				    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
+			} else {
+				struct ip6_hdr *ip6 =
+				    (void *)(mtod(m0, char *) + offset);
+				th = (void *)(mtod(m0, char *) + hlen);
+
+				ip6->ip6_plen = 0;
+				th->th_sum = in6_cksum_phdr(&ip6->ip6_src,
+				    &ip6->ip6_dst, 0, htonl(IPPROTO_TCP));
+			}
+			hlen += th->th_off << 2;
+		}
+
+		if (v4) {
+			WM_EVCNT_INCR(&sc->sc_ev_txtso);
+			cmdlen |= WTX_TCPIP_CMD_IP;
+		} else {
+			WM_EVCNT_INCR(&sc->sc_ev_txtso6);
+			ipcse = 0;
+		}
+		cmd |= WTX_TCPIP_CMD_TSE;
+		cmdlen |= WTX_TCPIP_CMD_TSE |
+		    WTX_TCPIP_CMD_TCP | (m0->m_pkthdr.len - hlen);
+		seg = WTX_TCPIP_SEG_HDRLEN(hlen) |
+		    WTX_TCPIP_SEG_MSS(m0->m_pkthdr.segsz);
+	}
+
+	/*
+	 * NOTE: Even if we're not using the IP or TCP/UDP checksum
+	 * offload feature, if we load the context descriptor, we
+	 * MUST provide valid values for IPCSS and TUCSS fields.
+	 */
+
+	ipcs = WTX_TCPIP_IPCSS(offset) |
+	    WTX_TCPIP_IPCSO(offset + offsetof(struct ip, ip_sum)) |
+	    WTX_TCPIP_IPCSE(ipcse);
+	if (m0->m_pkthdr.csum_flags & (M_CSUM_IPv4|M_CSUM_TSOv4)) {
+		WM_EVCNT_INCR(&sc->sc_ev_txipsum);
+		fields |= WTX_IXSM;
+	}
+
+	offset += iphl;
+
+	if (m0->m_pkthdr.csum_flags &
+	    (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) {
+		WM_EVCNT_INCR(&sc->sc_ev_txtusum);
+		fields |= WTX_TXSM;
+		tucs = WTX_TCPIP_TUCSS(offset) |
+		    WTX_TCPIP_TUCSO(offset +
+		    M_CSUM_DATA_IPv4_OFFSET(m0->m_pkthdr.csum_data)) |
+		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
+	} else if ((m0->m_pkthdr.csum_flags &
+	    (M_CSUM_TCPv6|M_CSUM_UDPv6|M_CSUM_TSOv6)) != 0) {
+		WM_EVCNT_INCR(&sc->sc_ev_txtusum6);
+		fields |= WTX_TXSM;
+		tucs = WTX_TCPIP_TUCSS(offset) |
+		    WTX_TCPIP_TUCSO(offset +
+		    M_CSUM_DATA_IPv6_OFFSET(m0->m_pkthdr.csum_data)) |
+		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
+	} else {
+		/* Just initialize it to a valid TCP context. */
+		tucs = WTX_TCPIP_TUCSS(offset) |
+		    WTX_TCPIP_TUCSO(offset + offsetof(struct tcphdr, th_sum)) |
+		    WTX_TCPIP_TUCSE(0) /* rest of packet */;
+	}
+
+	/* Fill in the context descriptor. */
+	t = (struct livengood_tcpip_ctxdesc *)
+	    &txq->txq_descs[txq->txq_next];
+	t->tcpip_ipcs = htole32(ipcs);
+	t->tcpip_tucs = htole32(tucs);
+	t->tcpip_cmdlen = htole32(cmdlen);
+	t->tcpip_seg = htole32(seg);
+	wm_cdtxsync(txq, txq->txq_next, 1, BUS_DMASYNC_PREWRITE);
+
+	txq->txq_next = WM_NEXTTX(txq, txq->txq_next);
+	txs->txs_ndesc++;
+
+	*cmdp = cmd;
+	*fieldsp = fields;
+
+	return 0;
+}
+
+/*
  * wm_start:		[ifnet interface function]
  *
  *	Start packet transmission on the interface.

Reply via email to