PERFORCE change 114022 for review
Sam Leffler
sam at FreeBSD.org
Mon Feb 5 00:20:37 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=114022
Change 114022 by sam at 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 */
More information about the p4-projects
mailing list