Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Feb 2007 00:20:34 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 114022 for review
Message-ID:  <200702050020.l150KYKX047005@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=114022

Change 114022 by sam@sam_ebb on 2007/02/05 00:19:59

	rx works; tx still not right

Affected files ...

.. //depot/projects/wifi/sys/dev/usb/if_axe.c#13 edit
.. //depot/projects/wifi/sys/dev/usb/if_axereg.h#8 edit

Differences ...

==== //depot/projects/wifi/sys/dev/usb/if_axe.c#13 (text+ko) ====

@@ -69,6 +69,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/endian.h>
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/malloc.h>
@@ -290,7 +291,7 @@
 	else
 		val = 0;
 
-	if ((sc->axe_flags & AX178) || (sc->axe_flags & AX772)) {
+	if (sc->axe_flags & (AX178|AX772)) {
 		val |= (AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC);
 
 		switch (IFM_SUBTYPE(mii->mii_media_active)) {
@@ -306,6 +307,7 @@
 		}
 	}
 
+printf("axe%d: write media 0x%x\n", sc->axe_unit, val);/*XXX*/
 	err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
 	if (err) {
 		printf("axe%d: media change failed\n", sc->axe_unit);
@@ -713,7 +715,8 @@
 	struct ue_chain	*c;
         struct mbuf		*m;
         struct ifnet		*ifp;
-	int			total_len = 0;
+	int total_len, pktlen;
+	struct axe_sframe_hdr hdr;
 
 	c = priv;
 	sc = c->ue_sc;
@@ -741,15 +744,39 @@
 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
 
 	m = c->ue_mbuf;
+	/* XXX don't handle multiple packets in one transfer */
+	if (sc->axe_flags & (AX178|AX772)) {
+		if (total_len < sizeof(hdr)) {
+printf("axe%d: total_len %d\n", sc->axe_unit, total_len);/*XXX*/
+			ifp->if_ierrors++;
+			goto done;
+		}
+		m_copydata(m, 0, sizeof(hdr), (caddr_t) &hdr);
+		total_len -= sizeof(hdr);
 
-	if (total_len < sizeof(struct ether_header)) {
-		ifp->if_ierrors++;
-		goto done;
+		if ((hdr.len ^ hdr.ilen) != 0xffff) {
+printf("axe%d: len %d ilen %d\n", sc->axe_unit, hdr.len, hdr.ilen);/*XXX*/
+			ifp->if_ierrors++;
+			goto done;
+		}
+		pktlen = le16toh(hdr.len);
+		if (pktlen > total_len) {
+printf("axe%d: pktlen %d total_len %d\n", sc->axe_unit, pktlen, total_len);/*XXX*/
+			ifp->if_ierrors++;
+			goto done;
+		}
+		m_adj(m, sizeof(hdr));
+	} else {
+		if (total_len < sizeof(struct ether_header)) {
+			ifp->if_ierrors++;
+			goto done;
+		}
+		pktlen = total_len;
 	}
 
 	ifp->if_ipackets++;
 	m->m_pkthdr.rcvif = (void *)&sc->axe_qdat;
-	m->m_pkthdr.len = m->m_len = total_len;
+	m->m_pkthdr.len = m->m_len = pktlen;
 
 	/* Put the packet on the special USB input queue. */
 	usb_ether_input(m);
@@ -875,20 +902,38 @@
 axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
 {
 	struct ue_chain	*c;
-	usbd_status		err;
+	struct axe_sframe_hdr hdr;
+	usbd_status err;
+	int length, boundary;
 
 	c = &sc->axe_cdata.ue_tx_chain[idx];
 
-	/*
-	 * Copy the mbuf data into a contiguous buffer, leaving two
-	 * bytes at the beginning to hold the frame length.
-	 */
-	m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
+	if (sc->axe_flags & (AX178|AX772)) {
+		hdr.len = htole16(m->m_pkthdr.len);
+		hdr.ilen = -hdr.len;
+printf("axe%d: %s len %d\n", sc->axe_unit, __func__, m->m_pkthdr.len);
+		memcpy(c->ue_buf, &hdr, sizeof(hdr));
+
+		m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + sizeof(hdr));
+		length = sizeof(hdr) + m->m_pkthdr.len;
+
+		boundary = 64;
+		if ((length % boundary) == 0) {
+			hdr.len = 0;
+			hdr.ilen = 0xffff;
+printf("axe%d: %s add null segment\n", sc->axe_unit, __func__);
+			memcpy(c->ue_buf + length, &hdr, sizeof(hdr));
+			length += sizeof(hdr);
+		}
+	} else {
+		m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
+		length = m->m_pkthdr.len;
+	}
 	c->ue_mbuf = m;
 
+printf("axe%d: %s length %d\n", sc->axe_unit, __func__, length);
 	usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_TX],
-	    c, c->ue_buf, m->m_pkthdr.len, USBD_FORCE_SHORT_XFER,
-	    10000, axe_txeof);
+	    c, c->ue_buf, length, USBD_FORCE_SHORT_XFER, 10000, axe_txeof);
 
 	/* Transmit */
 	err = usbd_transfer(c->ue_xfer);
@@ -915,6 +960,7 @@
 	AXE_LOCK(sc);
 
 	if (!sc->axe_link) {
+if_printf(ifp, "%s: no link\n", __func__);/*XXX*/
 		AXE_UNLOCK(sc);
 		return;
 	}
@@ -950,8 +996,6 @@
 	 */
 	ifp->if_timer = 5;
 	AXE_UNLOCK(sc);
-
-	return;
 }
 
 static void
@@ -1070,8 +1114,6 @@
 	AXE_SLEEPUNLOCK(sc);
 
 	sc->axe_stat_ch = timeout(axe_tick, sc, hz);
-
-	return;
 }
 
 static int
@@ -1158,7 +1200,7 @@
 	AXE_LOCK(sc);
 
 	ifp->if_oerrors++;
-	printf("axe%d: watchdog timeout\n", sc->axe_unit);
+	if_printf(ifp, "watchdog timeout\n");
 
 	c = &sc->axe_cdata.ue_tx_chain[0];
 	usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
@@ -1168,8 +1210,6 @@
 
 	if (ifp->if_snd.ifq_head != NULL)
 		axe_start(ifp);
-
-	return;
 }
 
 /*
@@ -1243,8 +1283,6 @@
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
         sc->axe_link = 0;
 	AXE_UNLOCK(sc);
-
-	return;
 }
 
 /*
@@ -1261,6 +1299,4 @@
 	AXE_SLEEPLOCK(sc);
 	axe_stop(sc);
 	AXE_SLEEPUNLOCK(sc);
-
-	return;
 }

==== //depot/projects/wifi/sys/dev/usb/if_axereg.h#8 (text+ko) ====

@@ -153,6 +153,11 @@
 #define AXE_ENDPT_INTR		0x2
 #define AXE_ENDPT_MAX		0x3
 
+struct axe_sframe_hdr {
+	uint16_t	len;
+	uint16_t	ilen;
+} __packed;
+
 struct axe_type {
 	int			axe_flags;
 #define	AX172	0x0001		/* AX88172 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200702050020.l150KYKX047005>