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>