Move Rx/Tx lists management routines into central location.

This commit is contained in:
Maxim Sobolev 2005-03-25 12:42:30 +00:00
parent 7d2832e654
commit d521dc21e7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=144104
16 changed files with 462 additions and 1040 deletions

View file

@ -181,8 +181,6 @@ Static int aue_attach(device_ptr_t);
Static int aue_detach(device_ptr_t);
Static void aue_reset_pegasus_II(struct aue_softc *sc);
Static int aue_tx_list_init(struct aue_softc *);
Static int aue_rx_list_init(struct aue_softc *);
Static int aue_encap(struct aue_softc *, struct mbuf *, int);
#ifdef AUE_INTR_PIPE
Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -803,57 +801,6 @@ aue_detach(device_ptr_t dev)
return (0);
}
Static int
aue_rx_list_init(struct aue_softc *sc)
{
struct aue_cdata *cd;
struct aue_chain *c;
int i;
cd = &sc->aue_cdata;
for (i = 0; i < AUE_RX_LIST_CNT; i++) {
c = &cd->aue_rx_chain[i];
c->aue_sc = sc;
c->aue_idx = i;
c->aue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->aue_dev));
if (c->aue_mbuf == NULL)
return (ENOBUFS);
if (c->aue_xfer == NULL) {
c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
if (c->aue_xfer == NULL)
return (ENOBUFS);
}
}
return (0);
}
Static int
aue_tx_list_init(struct aue_softc *sc)
{
struct aue_cdata *cd;
struct aue_chain *c;
int i;
cd = &sc->aue_cdata;
for (i = 0; i < AUE_TX_LIST_CNT; i++) {
c = &cd->aue_tx_chain[i];
c->aue_sc = sc;
c->aue_idx = i;
c->aue_mbuf = NULL;
if (c->aue_xfer == NULL) {
c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
if (c->aue_xfer == NULL)
return (ENOBUFS);
}
c->aue_buf = malloc(AUE_BUFSZ, M_USBDEV, M_NOWAIT);
if (c->aue_buf == NULL)
return (ENOBUFS);
}
return (0);
}
#ifdef AUE_INTR_PIPE
Static void
aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
@ -900,24 +847,26 @@ Static void
aue_rxstart(struct ifnet *ifp)
{
struct aue_softc *sc;
struct aue_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
AUE_LOCK(sc);
c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod];
c = &sc->aue_cdata.ue_rx_chain[sc->aue_cdata.ue_rx_prod];
c->aue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->aue_dev));
if (c->aue_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
ifp->if_ierrors++;
AUE_UNLOCK(sc);
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->aue_mbuf, char *), AUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, aue_rxeof);
usbd_transfer(c->aue_xfer);
usbd_transfer(c->ue_xfer);
AUE_UNLOCK(sc);
return;
@ -930,8 +879,8 @@ aue_rxstart(struct ifnet *ifp)
Static void
aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct aue_chain *c = priv;
struct aue_softc *sc = c->aue_sc;
struct ue_chain *c = priv;
struct aue_softc *sc = c->ue_sc;
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
@ -967,7 +916,7 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
goto done;
}
m = c->aue_mbuf;
m = c->ue_mbuf;
bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof(r));
/* Turn off all the non-error bits in the rx status word. */
@ -993,7 +942,7 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
/* Setup new transfer. */
usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->aue_mbuf, char *), AUE_BUFSZ, USBD_SHORT_XFER_OK,
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, aue_rxeof);
usbd_transfer(xfer);
@ -1009,8 +958,8 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
Static void
aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct aue_chain *c = priv;
struct aue_softc *sc = c->aue_sc;
struct ue_chain *c = priv;
struct aue_softc *sc = c->ue_sc;
struct ifnet *ifp;
usbd_status err;
@ -1032,12 +981,12 @@ aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->aue_mbuf != NULL) {
c->aue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->aue_mbuf);
c->aue_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -1088,17 +1037,17 @@ Static int
aue_encap(struct aue_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct aue_chain *c;
struct ue_chain *c;
usbd_status err;
c = &sc->aue_cdata.aue_tx_chain[idx];
c = &sc->aue_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->aue_buf + 2);
c->aue_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
c->ue_mbuf = m;
total_len = m->m_pkthdr.len + 2;
@ -1108,21 +1057,21 @@ aue_encap(struct aue_softc *sc, struct mbuf *m, int idx)
* transfer, however it actually seems to ignore this info
* and base the frame size on the bulk transfer length.
*/
c->aue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->aue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_TX],
c, c->aue_buf, total_len, USBD_FORCE_SHORT_XFER,
usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_TX],
c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER,
10000, aue_txeof);
/* Transmit */
err = usbd_transfer(c->aue_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
aue_stop(sc);
return (EIO);
}
sc->aue_cdata.aue_tx_cnt++;
sc->aue_cdata.ue_tx_cnt++;
return (0);
}
@ -1181,7 +1130,7 @@ aue_init(void *xsc)
struct aue_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mii_data *mii = GET_MII(sc);
struct aue_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
@ -1208,21 +1157,23 @@ aue_init(void *xsc)
AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
/* Init TX ring. */
if (aue_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->aue_cdata,
USBDEVNAME(sc->aue_dev), sc->aue_udev) == ENOBUFS) {
printf("aue%d: tx list init failed\n", sc->aue_unit);
AUE_UNLOCK(sc);
return;
}
/* Init RX ring. */
if (aue_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->aue_cdata,
USBDEVNAME(sc->aue_dev), sc->aue_udev) == ENOBUFS) {
printf("aue%d: rx list init failed\n", sc->aue_unit);
AUE_UNLOCK(sc);
return;
}
#ifdef AUE_INTR_PIPE
sc->aue_cdata.aue_ibuf = malloc(AUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
sc->aue_cdata.ue_ibuf = malloc(AUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
#endif
/* Load the multicast filter. */
@ -1256,7 +1207,7 @@ aue_init(void *xsc)
#ifdef AUE_INTR_PIPE
err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR],
USBD_SHORT_XFER_OK, &sc->aue_ep[AUE_ENDPT_INTR], sc,
sc->aue_cdata.aue_ibuf, AUE_INTR_PKTLEN, aue_intr,
sc->aue_cdata.ue_ibuf, AUE_INTR_PKTLEN, aue_intr,
AUE_INTR_INTERVAL);
if (err) {
printf("aue%d: open intr pipe failed: %s\n",
@ -1267,12 +1218,12 @@ aue_init(void *xsc)
#endif
/* Start up the receive pipe. */
for (i = 0; i < AUE_RX_LIST_CNT; i++) {
c = &sc->aue_cdata.aue_rx_chain[i];
usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->aue_mbuf, char *), AUE_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->aue_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, aue_rxeof);
usbd_transfer(c->aue_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -1375,7 +1326,7 @@ Static void
aue_watchdog(struct ifnet *ifp)
{
struct aue_softc *sc = ifp->if_softc;
struct aue_chain *c;
struct ue_chain *c;
usbd_status stat;
AUE_LOCK(sc);
@ -1383,9 +1334,9 @@ aue_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("aue%d: watchdog timeout\n", sc->aue_unit);
c = &sc->aue_cdata.aue_tx_chain[0];
usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &stat);
aue_txeof(c->aue_xfer, c, stat);
c = &sc->aue_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
aue_txeof(c->ue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
aue_start(ifp);
@ -1459,40 +1410,13 @@ aue_stop(struct aue_softc *sc)
#endif
/* Free RX resources. */
for (i = 0; i < AUE_RX_LIST_CNT; i++) {
if (sc->aue_cdata.aue_rx_chain[i].aue_buf != NULL) {
free(sc->aue_cdata.aue_rx_chain[i].aue_buf, M_USBDEV);
sc->aue_cdata.aue_rx_chain[i].aue_buf = NULL;
}
if (sc->aue_cdata.aue_rx_chain[i].aue_mbuf != NULL) {
m_freem(sc->aue_cdata.aue_rx_chain[i].aue_mbuf);
sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL;
}
if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) {
usbd_free_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer);
sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->aue_cdata);
/* Free TX resources. */
for (i = 0; i < AUE_TX_LIST_CNT; i++) {
if (sc->aue_cdata.aue_tx_chain[i].aue_buf != NULL) {
free(sc->aue_cdata.aue_tx_chain[i].aue_buf, M_USBDEV);
sc->aue_cdata.aue_tx_chain[i].aue_buf = NULL;
}
if (sc->aue_cdata.aue_tx_chain[i].aue_mbuf != NULL) {
m_freem(sc->aue_cdata.aue_tx_chain[i].aue_mbuf);
sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL;
}
if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) {
usbd_free_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer);
sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->aue_cdata);
#ifdef AUE_INTR_PIPE
free(sc->aue_cdata.aue_ibuf, M_USBDEV);
sc->aue_cdata.aue_ibuf = NULL;
free(sc->aue_cdata.ue_ibuf, M_USBDEV);
sc->aue_cdata.ue_ibuf = NULL;
#endif
sc->aue_link = 0;

View file

@ -196,29 +196,6 @@ struct aue_rxpkt {
#define AUE_RXSTAT_DRIBBLE 0x10
#define AUE_RXSTAT_MASK 0x1E
#define AUE_TX_LIST_CNT 1
#define AUE_RX_LIST_CNT 1
struct aue_softc;
struct aue_chain {
struct aue_softc *aue_sc;
usbd_xfer_handle aue_xfer;
char *aue_buf;
struct mbuf *aue_mbuf;
int aue_idx;
};
struct aue_cdata {
struct aue_chain aue_tx_chain[AUE_TX_LIST_CNT];
struct aue_chain aue_rx_chain[AUE_RX_LIST_CNT];
struct aue_intrpkt *aue_ibuf;
int aue_tx_prod;
int aue_tx_cons;
int aue_tx_cnt;
int aue_rx_prod;
};
#define AUE_INC(x, y) (x) = (x + 1) % y
struct aue_softc {
@ -241,7 +218,7 @@ struct aue_softc {
int aue_unit;
u_int8_t aue_link;
int aue_if_flags;
struct aue_cdata aue_cdata;
struct ue_cdata aue_cdata;
struct callout_handle aue_stat_ch;
#if __FreeBSD_version >= 500000
struct mtx aue_mtx;
@ -261,6 +238,5 @@ struct aue_softc {
#endif
#define AUE_TIMEOUT 1000
#define AUE_BUFSZ 1536
#define AUE_MIN_FRAMELEN 60
#define AUE_INTR_INTERVAL 100 /* ms */

View file

@ -124,8 +124,6 @@ Static int axe_match(device_ptr_t);
Static int axe_attach(device_ptr_t);
Static int axe_detach(device_ptr_t);
Static int axe_tx_list_init(struct axe_softc *);
Static int axe_rx_list_init(struct axe_softc *);
Static int axe_encap(struct axe_softc *, struct mbuf *, int);
Static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -561,79 +559,30 @@ axe_detach(device_ptr_t dev)
return(0);
}
Static int
axe_rx_list_init(struct axe_softc *sc)
{
struct axe_cdata *cd;
struct axe_chain *c;
int i;
cd = &sc->axe_cdata;
for (i = 0; i < AXE_RX_LIST_CNT; i++) {
c = &cd->axe_rx_chain[i];
c->axe_sc = sc;
c->axe_idx = i;
c->axe_mbuf = usb_ether_newbuf(USBDEVNAME(sc->axe_dev));
if (c->axe_mbuf == NULL)
return(ENOBUFS);
if (c->axe_xfer == NULL) {
c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
if (c->axe_xfer == NULL)
return(ENOBUFS);
}
}
return(0);
}
Static int
axe_tx_list_init(struct axe_softc *sc)
{
struct axe_cdata *cd;
struct axe_chain *c;
int i;
cd = &sc->axe_cdata;
for (i = 0; i < AXE_TX_LIST_CNT; i++) {
c = &cd->axe_tx_chain[i];
c->axe_sc = sc;
c->axe_idx = i;
c->axe_mbuf = NULL;
if (c->axe_xfer == NULL) {
c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
if (c->axe_xfer == NULL)
return(ENOBUFS);
}
c->axe_buf = malloc(AXE_BUFSZ, M_USBDEV, M_NOWAIT);
if (c->axe_buf == NULL)
return(ENOBUFS);
}
return(0);
}
Static void
axe_rxstart(struct ifnet *ifp)
{
struct axe_softc *sc;
struct axe_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
AXE_LOCK(sc);
c = &sc->axe_cdata.axe_rx_chain[sc->axe_cdata.axe_rx_prod];
c = &sc->axe_cdata.ue_rx_chain[sc->axe_cdata.ue_rx_prod];
c->axe_mbuf = usb_ether_newbuf(USBDEVNAME(sc->axe_dev));
if (c->axe_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->axe_dev));
ifp->if_ierrors++;
AXE_UNLOCK(sc);
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->axe_mbuf, char *), AXE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, axe_rxeof);
usbd_transfer(c->axe_xfer);
usbd_transfer(c->ue_xfer);
AXE_UNLOCK(sc);
return;
@ -647,13 +596,13 @@ Static void
axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct axe_softc *sc;
struct axe_chain *c;
struct ue_chain *c;
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
c = priv;
sc = c->axe_sc;
sc = c->ue_sc;
AXE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -677,7 +626,7 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
m = c->axe_mbuf;
m = c->ue_mbuf;
if (total_len < sizeof(struct ether_header)) {
ifp->if_ierrors++;
@ -695,10 +644,10 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
return;
done:
/* Setup new transfer. */
usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->axe_mbuf, char *), AXE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, axe_rxeof);
usbd_transfer(c->axe_xfer);
usbd_transfer(c->ue_xfer);
AXE_UNLOCK(sc);
return;
@ -713,12 +662,12 @@ Static void
axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct axe_softc *sc;
struct axe_chain *c;
struct ue_chain *c;
struct ifnet *ifp;
usbd_status err;
c = priv;
sc = c->axe_sc;
sc = c->ue_sc;
AXE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -737,12 +686,12 @@ axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->axe_mbuf != NULL) {
c->axe_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->axe_mbuf);
c->axe_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -794,30 +743,30 @@ axe_tick(void *xsc)
Static int
axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
{
struct axe_chain *c;
struct ue_chain *c;
usbd_status err;
c = &sc->axe_cdata.axe_tx_chain[idx];
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->axe_buf);
c->axe_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
c->ue_mbuf = m;
usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX],
c, c->axe_buf, m->m_pkthdr.len, USBD_FORCE_SHORT_XFER,
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);
/* Transmit */
err = usbd_transfer(c->axe_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
axe_stop(sc);
return(EIO);
}
sc->axe_cdata.axe_tx_cnt++;
sc->axe_cdata.ue_tx_cnt++;
return(0);
}
@ -876,7 +825,7 @@ axe_init(void *xsc)
{
struct axe_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct axe_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
int rxmode;
@ -900,14 +849,16 @@ axe_init(void *xsc)
/* Enable RX logic. */
/* Init TX ring. */
if (axe_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->axe_cdata,
USBDEVNAME(sc->axe_dev), sc->axe_udev) == ENOBUFS) {
printf("axe%d: tx list init failed\n", sc->axe_unit);
AXE_UNLOCK(sc);
return;
}
/* Init RX ring. */
if (axe_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->axe_cdata,
USBDEVNAME(sc->axe_dev), sc->axe_udev) == ENOBUFS) {
printf("axe%d: rx list init failed\n", sc->axe_unit);
AXE_UNLOCK(sc);
return;
@ -953,12 +904,12 @@ axe_init(void *xsc)
}
/* Start up the receive pipe. */
for (i = 0; i < AXE_RX_LIST_CNT; i++) {
c = &sc->axe_cdata.axe_rx_chain[i];
usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->axe_mbuf, char *), AXE_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->axe_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->axe_ep[AXE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof);
usbd_transfer(c->axe_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -1039,7 +990,7 @@ Static void
axe_watchdog(struct ifnet *ifp)
{
struct axe_softc *sc;
struct axe_chain *c;
struct ue_chain *c;
usbd_status stat;
sc = ifp->if_softc;
@ -1048,9 +999,9 @@ axe_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("axe%d: watchdog timeout\n", sc->axe_unit);
c = &sc->axe_cdata.axe_tx_chain[0];
usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
axe_txeof(c->axe_xfer, c, stat);
c = &sc->axe_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
axe_txeof(c->ue_xfer, c, stat);
AXE_UNLOCK(sc);
@ -1124,36 +1075,9 @@ axe_stop(struct axe_softc *sc)
axe_reset(sc);
/* Free RX resources. */
for (i = 0; i < AXE_RX_LIST_CNT; i++) {
if (sc->axe_cdata.axe_rx_chain[i].axe_buf != NULL) {
free(sc->axe_cdata.axe_rx_chain[i].axe_buf, M_USBDEV);
sc->axe_cdata.axe_rx_chain[i].axe_buf = NULL;
}
if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) {
m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf);
sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL;
}
if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->axe_cdata);
/* Free TX resources. */
for (i = 0; i < AXE_TX_LIST_CNT; i++) {
if (sc->axe_cdata.axe_tx_chain[i].axe_buf != NULL) {
free(sc->axe_cdata.axe_tx_chain[i].axe_buf, M_USBDEV);
sc->axe_cdata.axe_tx_chain[i].axe_buf = NULL;
}
if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) {
m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf);
sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL;
}
if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->axe_cdata);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
sc->axe_link = 0;

View file

@ -93,14 +93,10 @@
#define AXE_NOPHY 0xE0
#define AXE_TIMEOUT 1000
#define AXE_BUFSZ 1536
#define AXE_MIN_FRAMELEN 60
#define AXE_RX_FRAMES 1
#define AXE_TX_FRAMES 1
#define AXE_RX_LIST_CNT 1
#define AXE_TX_LIST_CNT 1
#define AXE_CTL_READ 0x01
#define AXE_CTL_WRITE 0x02
@ -121,25 +117,6 @@ struct axe_type {
u_int16_t axe_did;
};
struct axe_softc;
struct axe_chain {
struct axe_softc *axe_sc;
usbd_xfer_handle axe_xfer;
char *axe_buf;
struct mbuf *axe_mbuf;
int axe_idx;
};
struct axe_cdata {
struct axe_chain axe_tx_chain[AXE_TX_LIST_CNT];
struct axe_chain axe_rx_chain[AXE_RX_LIST_CNT];
int axe_tx_prod;
int axe_tx_cons;
int axe_tx_cnt;
int axe_rx_prod;
};
#define AXE_INC(x, y) (x) = (x + 1) % y
struct axe_softc {
@ -159,7 +136,7 @@ struct axe_softc {
usbd_pipe_handle axe_ep[AXE_ENDPT_MAX];
int axe_unit;
int axe_if_flags;
struct axe_cdata axe_cdata;
struct ue_cdata axe_cdata;
struct callout_handle axe_stat_ch;
#if __FreeBSD_version >= 500000
struct mtx axe_mtx;

View file

@ -81,8 +81,6 @@ USB_DECLARE_DRIVER_INIT(cdce,
DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, usbd_driver_load, 0);
MODULE_VERSION(cdce, 0);
Static int cdce_tx_list_init(struct cdce_softc *);
Static int cdce_rx_list_init(struct cdce_softc *);
Static int cdce_encap(struct cdce_softc *, struct mbuf *, int);
Static void cdce_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -373,32 +371,32 @@ cdce_start(struct ifnet *ifp)
Static int
cdce_encap(struct cdce_softc *sc, struct mbuf *m, int idx)
{
struct cdce_chain *c;
struct ue_chain *c;
usbd_status err;
int extra = 0;
c = &sc->cdce_cdata.cdce_tx_chain[idx];
c = &sc->cdce_cdata.ue_tx_chain[idx];
m_copydata(m, 0, m->m_pkthdr.len, c->cdce_buf);
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
if (sc->cdce_flags & CDCE_ZAURUS) {
/* Zaurus wants a 32-bit CRC appended to every frame */
u_int32_t crc;
crc = htole32(crc32(c->cdce_buf, m->m_pkthdr.len));
bcopy(&crc, c->cdce_buf + m->m_pkthdr.len, 4);
crc = htole32(crc32(c->ue_buf, m->m_pkthdr.len));
bcopy(&crc, c->ue_buf + m->m_pkthdr.len, 4);
extra = 4;
}
c->cdce_mbuf = m;
c->ue_mbuf = m;
usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkout_pipe, c, c->cdce_buf,
usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkout_pipe, c, c->ue_buf,
m->m_pkthdr.len + extra, 0, 10000, cdce_txeof);
err = usbd_transfer(c->cdce_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
cdce_stop(sc);
return (EIO);
}
sc->cdce_cdata.cdce_tx_cnt++;
sc->cdce_cdata.ue_tx_cnt++;
return (0);
}
@ -441,27 +439,8 @@ cdce_stop(struct cdce_softc *sc)
sc->cdce_bulkout_pipe = NULL;
}
for (i = 0; i < CDCE_RX_LIST_CNT; i++) {
if (sc->cdce_cdata.cdce_rx_chain[i].cdce_mbuf != NULL) {
m_freem(sc->cdce_cdata.cdce_rx_chain[i].cdce_mbuf);
sc->cdce_cdata.cdce_rx_chain[i].cdce_mbuf = NULL;
}
if (sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer != NULL) {
usbd_free_xfer(sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer);
sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer = NULL;
}
}
for (i = 0; i < CDCE_TX_LIST_CNT; i++) {
if (sc->cdce_cdata.cdce_tx_chain[i].cdce_mbuf != NULL) {
m_freem(sc->cdce_cdata.cdce_tx_chain[i].cdce_mbuf);
sc->cdce_cdata.cdce_tx_chain[i].cdce_mbuf = NULL;
}
if (sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer != NULL) {
usbd_free_xfer(sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer);
sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->cdce_cdata);
usb_ether_tx_list_free(&sc->cdce_cdata);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
CDCE_UNLOCK(sc);
@ -521,7 +500,7 @@ cdce_init(void *xsc)
{
struct cdce_softc *sc = xsc;
struct ifnet *ifp = GET_IFP(sc);
struct cdce_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
@ -531,13 +510,15 @@ cdce_init(void *xsc)
CDCE_LOCK(sc);
cdce_reset(sc);
if (cdce_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->cdce_cdata,
USBDEVNAME(sc->cdce_dev), sc->cdce_udev) == ENOBUFS) {
printf("%s: tx list init failed\n", USBDEVNAME(sc->cdce_dev));
CDCE_UNLOCK(sc);
return;
}
if (cdce_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->cdce_cdata,
USBDEVNAME(sc->cdce_dev), sc->cdce_udev) == ENOBUFS) {
printf("%s: rx list init failed\n", USBDEVNAME(sc->cdce_dev));
CDCE_UNLOCK(sc);
return;
@ -563,12 +544,12 @@ cdce_init(void *xsc)
return;
}
for (i = 0; i < CDCE_RX_LIST_CNT; i++) {
c = &sc->cdce_cdata.cdce_rx_chain[i];
usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->cdce_mbuf, char *), CDCE_BUFSZ, USBD_SHORT_XFER_OK,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->cdce_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, cdce_rxeof);
usbd_transfer(c->cdce_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -579,65 +560,11 @@ cdce_init(void *xsc)
return;
}
Static int
cdce_rx_list_init(struct cdce_softc *sc)
{
struct cdce_cdata *cd;
struct cdce_chain *c;
int i;
cd = &sc->cdce_cdata;
for (i = 0; i < CDCE_RX_LIST_CNT; i++) {
c = &cd->cdce_rx_chain[i];
c->cdce_sc = sc;
c->cdce_idx = i;
c->cdce_mbuf = usb_ether_newbuf(USBDEVNAME(sc->cdce_dev));
if (c->cdce_mbuf == NULL)
return (ENOBUFS);
if (c->cdce_xfer == NULL) {
c->cdce_xfer = usbd_alloc_xfer(sc->cdce_udev);
if (c->cdce_xfer == NULL)
return (ENOBUFS);
c->cdce_buf = usbd_alloc_buffer(c->cdce_xfer, CDCE_BUFSZ);
if (c->cdce_buf == NULL)
return (ENOBUFS);
}
}
return (0);
}
Static int
cdce_tx_list_init(struct cdce_softc *sc)
{
struct cdce_cdata *cd;
struct cdce_chain *c;
int i;
cd = &sc->cdce_cdata;
for (i = 0; i < CDCE_TX_LIST_CNT; i++) {
c = &cd->cdce_tx_chain[i];
c->cdce_sc = sc;
c->cdce_idx = i;
c->cdce_mbuf = NULL;
if (c->cdce_xfer == NULL) {
c->cdce_xfer = usbd_alloc_xfer(sc->cdce_udev);
if (c->cdce_xfer == NULL)
return (ENOBUFS);
c->cdce_buf = usbd_alloc_buffer(c->cdce_xfer, CDCE_BUFSZ);
if (c->cdce_buf == NULL)
return (ENOBUFS);
}
}
return (0);
}
Static void
cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct cdce_chain *c = priv;
struct cdce_softc *sc = c->cdce_sc;
struct ue_chain *c = priv;
struct cdce_softc *sc = c->ue_sc;
struct ifnet *ifp;
struct mbuf *m;
int total_len = 0;
@ -672,7 +599,7 @@ cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
if (sc->cdce_flags & CDCE_ZAURUS)
total_len -= 4; /* Strip off CRC added by Zaurus */
m = c->cdce_mbuf;
m = c->ue_mbuf;
if (total_len < sizeof(struct ether_header)) {
ifp->if_ierrors++;
@ -691,11 +618,11 @@ cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
done:
/* Setup new transfer. */
usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->cdce_mbuf, char *),
CDCE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->ue_mbuf, char *),
UE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
cdce_rxeof);
usbd_transfer(c->cdce_xfer);
usbd_transfer(c->ue_xfer);
CDCE_UNLOCK(sc);
return;
@ -704,8 +631,8 @@ cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
Static void
cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct cdce_chain *c = priv;
struct cdce_softc *sc = c->cdce_sc;
struct ue_chain *c = priv;
struct cdce_softc *sc = c->ue_sc;
struct ifnet *ifp;
usbd_status err;
@ -733,12 +660,12 @@ cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
}
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->cdce_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->cdce_mbuf != NULL) {
c->cdce_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->cdce_mbuf);
c->cdce_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -755,7 +682,7 @@ Static void
cdce_rxstart(struct ifnet *ifp)
{
struct cdce_softc *sc;
struct cdce_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
CDCE_LOCK(sc);
@ -765,19 +692,21 @@ cdce_rxstart(struct ifnet *ifp)
return;
}
c = &sc->cdce_cdata.cdce_rx_chain[sc->cdce_cdata.cdce_rx_prod];
c = &sc->cdce_cdata.ue_rx_chain[sc->cdce_cdata.ue_rx_prod];
c->cdce_mbuf = usb_ether_newbuf(USBDEVNAME(sc->cdce_dev));
if (c->cdce_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->cdce_dev));
ifp->if_ierrors++;
CDCE_UNLOCK(sc);
return;
}
usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->cdce_mbuf, char *), CDCE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, cdce_rxeof);
usbd_transfer(c->cdce_xfer);
usbd_transfer(c->ue_xfer);
CDCE_UNLOCK(sc);
return;

View file

@ -35,10 +35,6 @@
#ifndef _USB_IF_CDCEREG_H_
#define _USB_IF_CDCEREG_H_
#define CDCE_RX_LIST_CNT 1
#define CDCE_TX_LIST_CNT 1
#define CDCE_BUFSZ 1542
struct cdce_type {
struct usb_devno cdce_dev;
u_int16_t cdce_flags;
@ -46,25 +42,6 @@ struct cdce_type {
#define CDCE_NO_UNION 2
};
struct cdce_softc;
struct cdce_chain {
struct cdce_softc *cdce_sc;
usbd_xfer_handle cdce_xfer;
char *cdce_buf;
struct mbuf *cdce_mbuf;
int cdce_idx;
};
struct cdce_cdata {
struct cdce_chain cdce_tx_chain[CDCE_TX_LIST_CNT];
struct cdce_chain cdce_rx_chain[CDCE_TX_LIST_CNT];
int cdce_tx_prod;
int cdce_tx_cons;
int cdce_tx_cnt;
int cdce_rx_prod;
};
struct cdce_softc {
struct arpcom arpcom;
#define GET_IFP(sc) (&(sc)->arpcom.ac_if)
@ -79,7 +56,7 @@ struct cdce_softc {
device_t cdce_dev;
int cdce_unit;
struct cdce_cdata cdce_cdata;
struct ue_cdata cdce_cdata;
struct timeval cdce_rx_notice;
int cdce_rxeof_errors;

View file

@ -96,8 +96,6 @@ Static int cue_match(device_ptr_t);
Static int cue_attach(device_ptr_t);
Static int cue_detach(device_ptr_t);
Static int cue_tx_list_init(struct cue_softc *);
Static int cue_rx_list_init(struct cue_softc *);
Static int cue_encap(struct cue_softc *, struct mbuf *, int);
Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -568,79 +566,30 @@ cue_detach(device_ptr_t dev)
return(0);
}
Static int
cue_rx_list_init(struct cue_softc *sc)
{
struct cue_cdata *cd;
struct cue_chain *c;
int i;
cd = &sc->cue_cdata;
for (i = 0; i < CUE_RX_LIST_CNT; i++) {
c = &cd->cue_rx_chain[i];
c->cue_sc = sc;
c->cue_idx = i;
c->cue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->cue_dev));
if (c->cue_mbuf == NULL)
return(ENOBUFS);
if (c->cue_xfer == NULL) {
c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
if (c->cue_xfer == NULL)
return(ENOBUFS);
}
}
return(0);
}
Static int
cue_tx_list_init(struct cue_softc *sc)
{
struct cue_cdata *cd;
struct cue_chain *c;
int i;
cd = &sc->cue_cdata;
for (i = 0; i < CUE_TX_LIST_CNT; i++) {
c = &cd->cue_tx_chain[i];
c->cue_sc = sc;
c->cue_idx = i;
c->cue_mbuf = NULL;
if (c->cue_xfer == NULL) {
c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
if (c->cue_xfer == NULL)
return(ENOBUFS);
}
c->cue_buf = malloc(CUE_BUFSZ, M_USBDEV, M_NOWAIT);
if (c->cue_buf == NULL)
return(ENOBUFS);
}
return(0);
}
Static void
cue_rxstart(struct ifnet *ifp)
{
struct cue_softc *sc;
struct cue_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
CUE_LOCK(sc);
c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
c = &sc->cue_cdata.ue_rx_chain[sc->cue_cdata.ue_rx_prod];
c->cue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->cue_dev));
if (c->cue_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->cue_dev));
ifp->if_ierrors++;
CUE_UNLOCK(sc);
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, cue_rxeof);
usbd_transfer(c->cue_xfer);
usbd_transfer(c->ue_xfer);
CUE_UNLOCK(sc);
return;
@ -654,14 +603,14 @@ Static void
cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct cue_softc *sc;
struct cue_chain *c;
struct ue_chain *c;
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
u_int16_t len;
c = priv;
sc = c->cue_sc;
sc = c->ue_sc;
CUE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -685,7 +634,7 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
m = c->cue_mbuf;
m = c->ue_mbuf;
len = *mtod(m, u_int16_t *);
/* No errors; receive the packet. */
@ -708,10 +657,10 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
return;
done:
/* Setup new transfer. */
usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, cue_rxeof);
usbd_transfer(c->cue_xfer);
usbd_transfer(c->ue_xfer);
CUE_UNLOCK(sc);
return;
@ -726,12 +675,12 @@ Static void
cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct cue_softc *sc;
struct cue_chain *c;
struct ue_chain *c;
struct ifnet *ifp;
usbd_status err;
c = priv;
sc = c->cue_sc;
sc = c->ue_sc;
CUE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -750,12 +699,12 @@ cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->cue_mbuf != NULL) {
c->cue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->cue_mbuf);
c->cue_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -801,35 +750,35 @@ Static int
cue_encap(struct cue_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct cue_chain *c;
struct ue_chain *c;
usbd_status err;
c = &sc->cue_cdata.cue_tx_chain[idx];
c = &sc->cue_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->cue_buf + 2);
c->cue_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
c->ue_mbuf = m;
total_len = m->m_pkthdr.len + 2;
/* The first two bytes are the frame length */
c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX],
c, c->cue_buf, total_len, 0, 10000, cue_txeof);
usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_TX],
c, c->ue_buf, total_len, 0, 10000, cue_txeof);
/* Transmit */
err = usbd_transfer(c->cue_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
cue_stop(sc);
return(EIO);
}
sc->cue_cdata.cue_tx_cnt++;
sc->cue_cdata.ue_tx_cnt++;
return(0);
}
@ -883,7 +832,7 @@ cue_init(void *xsc)
{
struct cue_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct cue_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
@ -914,14 +863,16 @@ cue_init(void *xsc)
}
/* Init TX ring. */
if (cue_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->cue_cdata,
USBDEVNAME(sc->cue_dev), sc->cue_udev) == ENOBUFS) {
printf("cue%d: tx list init failed\n", sc->cue_unit);
CUE_UNLOCK(sc);
return;
}
/* Init RX ring. */
if (cue_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->cue_cdata,
USBDEVNAME(sc->cue_dev), sc->cue_udev) == ENOBUFS) {
printf("cue%d: rx list init failed\n", sc->cue_unit);
CUE_UNLOCK(sc);
return;
@ -963,12 +914,12 @@ cue_init(void *xsc)
}
/* Start up the receive pipe. */
for (i = 0; i < CUE_RX_LIST_CNT; i++) {
c = &sc->cue_cdata.cue_rx_chain[i];
usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->cue_mbuf, char *), CUE_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->cue_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof);
usbd_transfer(c->cue_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -1030,7 +981,7 @@ Static void
cue_watchdog(struct ifnet *ifp)
{
struct cue_softc *sc;
struct cue_chain *c;
struct ue_chain *c;
usbd_status stat;
sc = ifp->if_softc;
@ -1039,9 +990,9 @@ cue_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("cue%d: watchdog timeout\n", sc->cue_unit);
c = &sc->cue_cdata.cue_tx_chain[0];
usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat);
cue_txeof(c->cue_xfer, c, stat);
c = &sc->cue_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
cue_txeof(c->ue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
cue_start(ifp);
@ -1114,36 +1065,9 @@ cue_stop(struct cue_softc *sc)
}
/* Free RX resources. */
for (i = 0; i < CUE_RX_LIST_CNT; i++) {
if (sc->cue_cdata.cue_rx_chain[i].cue_buf != NULL) {
free(sc->cue_cdata.cue_rx_chain[i].cue_buf, M_USBDEV);
sc->cue_cdata.cue_rx_chain[i].cue_buf = NULL;
}
if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) {
m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf);
sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL;
}
if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) {
usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer);
sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->cue_cdata);
/* Free TX resources. */
for (i = 0; i < CUE_TX_LIST_CNT; i++) {
if (sc->cue_cdata.cue_tx_chain[i].cue_buf != NULL) {
free(sc->cue_cdata.cue_tx_chain[i].cue_buf, M_USBDEV);
sc->cue_cdata.cue_tx_chain[i].cue_buf = NULL;
}
if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) {
m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf);
sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL;
}
if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) {
usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer);
sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->cue_cdata);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
CUE_UNLOCK(sc);

View file

@ -116,14 +116,10 @@
#define CUE_MCAST_TABLE_LEN 64
#define CUE_TIMEOUT 1000
#define CUE_BUFSZ 1536
#define CUE_MIN_FRAMELEN 60
#define CUE_RX_FRAMES 1
#define CUE_TX_FRAMES 1
#define CUE_RX_LIST_CNT 1
#define CUE_TX_LIST_CNT 1
#define CUE_CTL_READ 0x01
#define CUE_CTL_WRITE 0x02
@ -143,25 +139,6 @@ struct cue_type {
u_int16_t cue_did;
};
struct cue_softc;
struct cue_chain {
struct cue_softc *cue_sc;
usbd_xfer_handle cue_xfer;
char *cue_buf;
struct mbuf *cue_mbuf;
int cue_idx;
};
struct cue_cdata {
struct cue_chain cue_tx_chain[CUE_TX_LIST_CNT];
struct cue_chain cue_rx_chain[CUE_RX_LIST_CNT];
int cue_tx_prod;
int cue_tx_cons;
int cue_tx_cnt;
int cue_rx_prod;
};
#define CUE_INC(x, y) (x) = (x + 1) % y
struct cue_softc {
@ -175,7 +152,7 @@ struct cue_softc {
u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN];
int cue_if_flags;
u_int16_t cue_rxfilt;
struct cue_cdata cue_cdata;
struct ue_cdata cue_cdata;
struct callout_handle cue_stat_ch;
#if __FreeBSD_version >= 500000
struct mtx cue_mtx;

View file

@ -130,8 +130,6 @@ Static int kue_match(device_ptr_t);
Static int kue_attach(device_ptr_t);
Static int kue_detach(device_ptr_t);
Static void kue_shutdown(device_ptr_t);
Static int kue_tx_list_init(struct kue_softc *);
Static int kue_rx_list_init(struct kue_softc *);
Static int kue_encap(struct kue_softc *, struct mbuf *, int);
Static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -546,78 +544,29 @@ kue_detach(device_ptr_t dev)
return(0);
}
Static int
kue_rx_list_init(struct kue_softc *sc)
{
struct kue_cdata *cd;
struct kue_chain *c;
int i;
cd = &sc->kue_cdata;
for (i = 0; i < KUE_RX_LIST_CNT; i++) {
c = &cd->kue_rx_chain[i];
c->kue_sc = sc;
c->kue_idx = i;
c->kue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->kue_dev));
if (c->kue_mbuf == NULL)
return(ENOBUFS);
if (c->kue_xfer == NULL) {
c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
if (c->kue_xfer == NULL)
return(ENOBUFS);
}
}
return(0);
}
Static int
kue_tx_list_init(struct kue_softc *sc)
{
struct kue_cdata *cd;
struct kue_chain *c;
int i;
cd = &sc->kue_cdata;
for (i = 0; i < KUE_TX_LIST_CNT; i++) {
c = &cd->kue_tx_chain[i];
c->kue_sc = sc;
c->kue_idx = i;
c->kue_mbuf = NULL;
if (c->kue_xfer == NULL) {
c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
if (c->kue_xfer == NULL)
return(ENOBUFS);
}
c->kue_buf = malloc(KUE_BUFSZ, M_USBDEV, M_NOWAIT);
if (c->kue_buf == NULL)
return(ENOBUFS);
}
return(0);
}
Static void
kue_rxstart(struct ifnet *ifp)
{
struct kue_softc *sc;
struct kue_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
KUE_LOCK(sc);
c = &sc->kue_cdata.kue_rx_chain[sc->kue_cdata.kue_rx_prod];
c = &sc->kue_cdata.ue_rx_chain[sc->kue_cdata.ue_rx_prod];
c->kue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->kue_dev));
if (c->kue_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
ifp->if_ierrors++;
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, kue_rxeof);
usbd_transfer(c->kue_xfer);
usbd_transfer(c->ue_xfer);
KUE_UNLOCK(sc);
@ -632,14 +581,14 @@ Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status status)
{
struct kue_softc *sc;
struct kue_chain *c;
struct ue_chain *c;
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
u_int16_t len;
c = priv;
sc = c->kue_sc;
sc = c->ue_sc;
KUE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -662,7 +611,7 @@ Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
}
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
m = c->kue_mbuf;
m = c->ue_mbuf;
if (total_len <= 1)
goto done;
@ -689,10 +638,10 @@ Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
done:
/* Setup new transfer. */
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, kue_rxeof);
usbd_transfer(c->kue_xfer);
usbd_transfer(c->ue_xfer);
KUE_UNLOCK(sc);
return;
@ -707,12 +656,12 @@ Static void
kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct kue_softc *sc;
struct kue_chain *c;
struct ue_chain *c;
struct ifnet *ifp;
usbd_status err;
c = priv;
sc = c->kue_sc;
sc = c->ue_sc;
KUE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
@ -732,12 +681,12 @@ kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
return;
}
usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->kue_mbuf != NULL) {
c->kue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->kue_mbuf);
c->kue_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -754,36 +703,36 @@ Static int
kue_encap(struct kue_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct kue_chain *c;
struct ue_chain *c;
usbd_status err;
c = &sc->kue_cdata.kue_tx_chain[idx];
c = &sc->kue_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->kue_buf + 2);
c->kue_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
c->ue_mbuf = m;
total_len = m->m_pkthdr.len + 2;
total_len += 64 - (total_len % 64);
/* Frame length is specified in the first 2 bytes of the buffer. */
c->kue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->kue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_TX],
c, c->kue_buf, total_len, 0, 10000, kue_txeof);
usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_TX],
c, c->ue_buf, total_len, 0, 10000, kue_txeof);
/* Transmit */
err = usbd_transfer(c->kue_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
kue_stop(sc);
return(EIO);
}
sc->kue_cdata.kue_tx_cnt++;
sc->kue_cdata.ue_tx_cnt++;
return(0);
}
@ -837,7 +786,7 @@ kue_init(void *xsc)
{
struct kue_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct kue_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
@ -871,14 +820,16 @@ kue_init(void *xsc)
kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
/* Init TX ring. */
if (kue_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->kue_cdata,
USBDEVNAME(sc->kue_dev), sc->kue_udev) == ENOBUFS) {
printf("kue%d: tx list init failed\n", sc->kue_unit);
KUE_UNLOCK(sc);
return;
}
/* Init RX ring. */
if (kue_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->kue_cdata,
USBDEVNAME(sc->kue_dev), sc->kue_udev) == ENOBUFS) {
printf("kue%d: rx list init failed\n", sc->kue_unit);
KUE_UNLOCK(sc);
return;
@ -907,12 +858,12 @@ kue_init(void *xsc)
}
/* Start up the receive pipe. */
for (i = 0; i < KUE_RX_LIST_CNT; i++) {
c = &sc->kue_cdata.kue_rx_chain[i];
usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->kue_mbuf, char *), KUE_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->kue_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof);
usbd_transfer(c->kue_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -974,7 +925,7 @@ Static void
kue_watchdog(struct ifnet *ifp)
{
struct kue_softc *sc;
struct kue_chain *c;
struct ue_chain *c;
usbd_status stat;
sc = ifp->if_softc;
@ -982,9 +933,9 @@ kue_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("kue%d: watchdog timeout\n", sc->kue_unit);
c = &sc->kue_cdata.kue_tx_chain[0];
usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
kue_txeof(c->kue_xfer, c, stat);
c = &sc->kue_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
kue_txeof(c->ue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
kue_start(ifp);
@ -1052,36 +1003,9 @@ kue_stop(struct kue_softc *sc)
}
/* Free RX resources. */
for (i = 0; i < KUE_RX_LIST_CNT; i++) {
if (sc->kue_cdata.kue_rx_chain[i].kue_buf != NULL) {
free(sc->kue_cdata.kue_rx_chain[i].kue_buf, M_USBDEV);
sc->kue_cdata.kue_rx_chain[i].kue_buf = NULL;
}
if (sc->kue_cdata.kue_rx_chain[i].kue_mbuf != NULL) {
m_freem(sc->kue_cdata.kue_rx_chain[i].kue_mbuf);
sc->kue_cdata.kue_rx_chain[i].kue_mbuf = NULL;
}
if (sc->kue_cdata.kue_rx_chain[i].kue_xfer != NULL) {
usbd_free_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer);
sc->kue_cdata.kue_rx_chain[i].kue_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->kue_cdata);
/* Free TX resources. */
for (i = 0; i < KUE_TX_LIST_CNT; i++) {
if (sc->kue_cdata.kue_tx_chain[i].kue_buf != NULL) {
free(sc->kue_cdata.kue_tx_chain[i].kue_buf, M_USBDEV);
sc->kue_cdata.kue_tx_chain[i].kue_buf = NULL;
}
if (sc->kue_cdata.kue_tx_chain[i].kue_mbuf != NULL) {
m_freem(sc->kue_cdata.kue_tx_chain[i].kue_mbuf);
sc->kue_cdata.kue_tx_chain[i].kue_mbuf = NULL;
}
if (sc->kue_cdata.kue_tx_chain[i].kue_xfer != NULL) {
usbd_free_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer);
sc->kue_cdata.kue_tx_chain[i].kue_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->kue_cdata);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
KUE_UNLOCK(sc);

View file

@ -110,12 +110,8 @@ struct kue_ether_desc {
#define KUE_RXFILT_MULTICAST 0x0010
#define KUE_TIMEOUT 1000
#define KUE_BUFSZ 1536
#define KUE_MIN_FRAMELEN 60
#define KUE_RX_LIST_CNT 1
#define KUE_TX_LIST_CNT 1
#define KUE_CTL_READ 0x01
#define KUE_CTL_WRITE 0x02
@ -136,25 +132,6 @@ struct kue_type {
u_int16_t kue_did;
};
struct kue_softc;
struct kue_chain {
struct kue_softc *kue_sc;
usbd_xfer_handle kue_xfer;
char *kue_buf;
struct mbuf *kue_mbuf;
int kue_idx;
};
struct kue_cdata {
struct kue_chain kue_tx_chain[KUE_TX_LIST_CNT];
struct kue_chain kue_rx_chain[KUE_RX_LIST_CNT];
int kue_tx_prod;
int kue_tx_cons;
int kue_tx_cnt;
int kue_rx_prod;
};
#define KUE_INC(x, y) (x) = (x + 1) % y
struct kue_softc {
@ -169,7 +146,7 @@ struct kue_softc {
int kue_if_flags;
u_int16_t kue_rxfilt;
u_int8_t *kue_mcfilters;
struct kue_cdata kue_cdata;
struct ue_cdata kue_cdata;
#if __FreeBSD_version >= 500000
struct mtx kue_mtx;
#endif

View file

@ -132,8 +132,6 @@ Static int rue_match(device_ptr_t);
Static int rue_attach(device_ptr_t);
Static int rue_detach(device_ptr_t);
Static int rue_tx_list_init(struct rue_softc *);
Static int rue_rx_list_init(struct rue_softc *);
Static int rue_encap(struct rue_softc *, struct mbuf *, int);
#ifdef RUE_INTR_PIPE
Static void rue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -738,57 +736,6 @@ rue_detach(device_ptr_t dev)
return (0);
}
Static int
rue_rx_list_init(struct rue_softc *sc)
{
struct rue_cdata *cd;
struct rue_chain *c;
int i;
cd = &sc->rue_cdata;
for (i = 0; i < RUE_RX_LIST_CNT; i++) {
c = &cd->rue_rx_chain[i];
c->rue_sc = sc;
c->rue_idx = i;
c->rue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->rue_dev));
if (c->rue_mbuf == NULL)
return (ENOBUFS);
if (c->rue_xfer == NULL) {
c->rue_xfer = usbd_alloc_xfer(sc->rue_udev);
if (c->rue_xfer == NULL)
return (ENOBUFS);
}
}
return (0);
}
Static int
rue_tx_list_init(struct rue_softc *sc)
{
struct rue_cdata *cd;
struct rue_chain *c;
int i;
cd = &sc->rue_cdata;
for (i = 0; i < RUE_TX_LIST_CNT; i++) {
c = &cd->rue_tx_chain[i];
c->rue_sc = sc;
c->rue_idx = i;
c->rue_mbuf = NULL;
if (c->rue_xfer == NULL) {
c->rue_xfer = usbd_alloc_xfer(sc->rue_udev);
if (c->rue_xfer == NULL)
return (ENOBUFS);
}
c->rue_buf = malloc(RUE_BUFSZ, M_USBDEV, M_NOWAIT);
if (c->rue_buf == NULL)
return (ENOBUFS);
}
return (0);
}
#ifdef RUE_INTR_PIPE
Static void
rue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
@ -832,24 +779,26 @@ Static void
rue_rxstart(struct ifnet *ifp)
{
struct rue_softc *sc;
struct rue_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
RUE_LOCK(sc);
c = &sc->rue_cdata.rue_rx_chain[sc->rue_cdata.rue_rx_prod];
c = &sc->rue_cdata.ue_rx_chain[sc->rue_cdata.ue_rx_prod];
c->rue_mbuf = usb_ether_newbuf(USBDEVNAME(sc->rue_dev));
if (c->rue_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->rue_dev));
ifp->if_ierrors++;
RUE_UNLOCK(sc);
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->rue_xfer, sc->rue_ep[RUE_ENDPT_RX],
c, mtod(c->rue_mbuf, char *), RUE_BUFSZ, USBD_SHORT_XFER_OK,
usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
USBD_NO_TIMEOUT, rue_rxeof);
usbd_transfer(c->rue_xfer);
usbd_transfer(c->ue_xfer);
RUE_UNLOCK(sc);
}
@ -862,8 +811,8 @@ rue_rxstart(struct ifnet *ifp)
Static void
rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct rue_chain *c = priv;
struct rue_softc *sc = c->rue_sc;
struct ue_chain *c = priv;
struct rue_softc *sc = c->ue_sc;
struct mbuf *m;
struct ifnet *ifp;
int total_len = 0;
@ -899,7 +848,7 @@ rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
goto done;
}
m = c->rue_mbuf;
m = c->ue_mbuf;
bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof (r));
/* Check recieve packet was valid or not */
@ -924,7 +873,7 @@ rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
done:
/* Setup new transfer. */
usbd_setup_xfer(xfer, sc->rue_ep[RUE_ENDPT_RX],
c, mtod(c->rue_mbuf, char *), RUE_BUFSZ,
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
usbd_transfer(xfer);
RUE_UNLOCK(sc);
@ -938,8 +887,8 @@ rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
Static void
rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct rue_chain *c = priv;
struct rue_softc *sc = c->rue_sc;
struct ue_chain *c = priv;
struct rue_softc *sc = c->ue_sc;
struct ifnet *ifp;
usbd_status err;
@ -962,12 +911,12 @@ rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->rue_xfer, NULL, NULL, NULL, &err);
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
if (c->rue_mbuf != NULL) {
c->rue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->rue_mbuf);
c->rue_mbuf = NULL;
if (c->ue_mbuf != NULL) {
c->ue_mbuf->m_pkthdr.rcvif = ifp;
usb_tx_done(c->ue_mbuf);
c->ue_mbuf = NULL;
}
if (err)
@ -1014,16 +963,16 @@ Static int
rue_encap(struct rue_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct rue_chain *c;
struct ue_chain *c;
usbd_status err;
c = &sc->rue_cdata.rue_tx_chain[idx];
c = &sc->rue_cdata.ue_tx_chain[idx];
/*
* Copy the mbuf data into a contiguous buffer
*/
m_copydata(m, 0, m->m_pkthdr.len, c->rue_buf);
c->rue_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
c->ue_mbuf = m;
total_len = m->m_pkthdr.len;
@ -1035,18 +984,18 @@ rue_encap(struct rue_softc *sc, struct mbuf *m, int idx)
if (total_len < RUE_MIN_FRAMELEN)
total_len = RUE_MIN_FRAMELEN;
usbd_setup_xfer(c->rue_xfer, sc->rue_ep[RUE_ENDPT_TX],
c, c->rue_buf, total_len, USBD_FORCE_SHORT_XFER,
usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_TX],
c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER,
10000, rue_txeof);
/* Transmit */
err = usbd_transfer(c->rue_xfer);
err = usbd_transfer(c->ue_xfer);
if (err != USBD_IN_PROGRESS) {
rue_stop(sc);
return (EIO);
}
sc->rue_cdata.rue_tx_cnt++;
sc->rue_cdata.ue_tx_cnt++;
return (0);
}
@ -1104,7 +1053,7 @@ rue_init(void *xsc)
struct rue_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mii_data *mii = GET_MII(sc);
struct rue_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
int rxcfg;
@ -1125,21 +1074,23 @@ rue_init(void *xsc)
rue_write_mem(sc, RUE_IDR0, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
/* Init TX ring. */
if (rue_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->rue_cdata,
USBDEVNAME(sc->rue_dev), sc->rue_udev) == ENOBUFS) {
printf("rue%d: tx list init failed\n", sc->rue_unit);
RUE_UNLOCK(sc);
return;
}
/* Init RX ring. */
if (rue_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->rue_cdata,
USBDEVNAME(sc->rue_dev), sc->rue_udev) == ENOBUFS) {
printf("rue%d: rx list init failed\n", sc->rue_unit);
RUE_UNLOCK(sc);
return;
}
#ifdef RUE_INTR_PIPE
sc->rue_cdata.rue_ibuf = malloc(RUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
sc->rue_cdata.ue_ibuf = malloc(RUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
#endif
/*
@ -1193,7 +1144,7 @@ rue_init(void *xsc)
err = usbd_open_pipe_intr(sc->rue_iface, sc->rue_ed[RUE_ENDPT_INTR],
USBD_SHORT_XFER_OK,
&sc->rue_ep[RUE_ENDPT_INTR], sc,
sc->rue_cdata.rue_ibuf, RUE_INTR_PKTLEN,
sc->rue_cdata.ue_ibuf, RUE_INTR_PKTLEN,
rue_intr, RUE_INTR_INTERVAL);
if (err) {
printf("rue%d: open intr pipe failed: %s\n",
@ -1204,12 +1155,12 @@ rue_init(void *xsc)
#endif
/* Start up the receive pipe. */
for (i = 0; i < RUE_RX_LIST_CNT; i++) {
c = &sc->rue_cdata.rue_rx_chain[i];
usbd_setup_xfer(c->rue_xfer, sc->rue_ep[RUE_ENDPT_RX],
c, mtod(c->rue_mbuf, char *), RUE_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->rue_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
usbd_transfer(c->rue_xfer);
usbd_transfer(c->ue_xfer);
}
ifp->if_flags |= IFF_RUNNING;
@ -1314,7 +1265,7 @@ Static void
rue_watchdog(struct ifnet *ifp)
{
struct rue_softc *sc = ifp->if_softc;
struct rue_chain *c;
struct ue_chain *c;
usbd_status stat;
RUE_LOCK(sc);
@ -1322,9 +1273,9 @@ rue_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("rue%d: watchdog timeout\n", sc->rue_unit);
c = &sc->rue_cdata.rue_tx_chain[0];
usbd_get_xfer_status(c->rue_xfer, NULL, NULL, NULL, &stat);
rue_txeof(c->rue_xfer, c, stat);
c = &sc->rue_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
rue_txeof(c->ue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
rue_start(ifp);
@ -1400,40 +1351,13 @@ rue_stop(struct rue_softc *sc)
#endif
/* Free RX resources. */
for (i = 0; i < RUE_RX_LIST_CNT; i++) {
if (sc->rue_cdata.rue_rx_chain[i].rue_buf != NULL) {
free(sc->rue_cdata.rue_rx_chain[i].rue_buf, M_USBDEV);
sc->rue_cdata.rue_rx_chain[i].rue_buf = NULL;
}
if (sc->rue_cdata.rue_rx_chain[i].rue_mbuf != NULL) {
m_freem(sc->rue_cdata.rue_rx_chain[i].rue_mbuf);
sc->rue_cdata.rue_rx_chain[i].rue_mbuf = NULL;
}
if (sc->rue_cdata.rue_rx_chain[i].rue_xfer != NULL) {
usbd_free_xfer(sc->rue_cdata.rue_rx_chain[i].rue_xfer);
sc->rue_cdata.rue_rx_chain[i].rue_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->rue_cdata);
/* Free TX resources. */
for (i = 0; i < RUE_TX_LIST_CNT; i++) {
if (sc->rue_cdata.rue_tx_chain[i].rue_buf != NULL) {
free(sc->rue_cdata.rue_tx_chain[i].rue_buf, M_USBDEV);
sc->rue_cdata.rue_tx_chain[i].rue_buf = NULL;
}
if (sc->rue_cdata.rue_tx_chain[i].rue_mbuf != NULL) {
m_freem(sc->rue_cdata.rue_tx_chain[i].rue_mbuf);
sc->rue_cdata.rue_tx_chain[i].rue_mbuf = NULL;
}
if (sc->rue_cdata.rue_tx_chain[i].rue_xfer != NULL) {
usbd_free_xfer(sc->rue_cdata.rue_tx_chain[i].rue_xfer);
sc->rue_cdata.rue_tx_chain[i].rue_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->rue_cdata);
#ifdef RUE_INTR_PIPE
free(sc->rue_cdata.rue_ibuf, M_USBDEV);
sc->rue_cdata.rue_ibuf = NULL;
free(sc->rue_cdata.ue_ibuf, M_USBDEV);
sc->rue_cdata.ue_ibuf = NULL;
#endif
sc->rue_link = 0;

View file

@ -43,7 +43,6 @@
#define RUE_TIMEOUT 1000
#define ETHER_ALIGN 2
#define RUE_BUFSZ 1536
#define RUE_MIN_FRAMELEN 60
#define RUE_INTR_INTERVAL 100 /* ms */
@ -187,29 +186,6 @@ struct rue_type {
u_int16_t rue_did;
};
#define RUE_TX_LIST_CNT 1
#define RUE_RX_LIST_CNT 1
struct rue_softc;
struct rue_chain {
struct rue_softc *rue_sc;
usbd_xfer_handle rue_xfer;
char *rue_buf;
struct mbuf *rue_mbuf;
int rue_idx;
};
struct rue_cdata {
struct rue_chain rue_tx_chain[RUE_TX_LIST_CNT];
struct rue_chain rue_rx_chain[RUE_RX_LIST_CNT];
struct rue_intrpkt *rue_ibuf;
int rue_tx_prod;
int rue_tx_cons;
int rue_tx_cnt;
int rue_rx_prod;
};
struct rue_softc {
struct arpcom arpcom;
device_t rue_dev;
@ -222,7 +198,7 @@ struct rue_softc {
int rue_unit;
u_int8_t rue_link;
int rue_if_flags;
struct rue_cdata rue_cdata;
struct ue_cdata rue_cdata;
struct callout_handle rue_stat_ch;
#if __FreeBSD_version >= 500000
struct mtx rue_mtx;

View file

@ -159,8 +159,6 @@ Static void udav_shutdown(device_ptr_t);
#endif
Static int udav_openpipes(struct udav_softc *);
Static int udav_rx_list_init(struct udav_softc *);
Static int udav_tx_list_init(struct udav_softc *);
Static void udav_start(struct ifnet *);
Static int udav_send(struct udav_softc *, struct mbuf *, int);
Static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
@ -856,7 +854,8 @@ udav_init(void *xsc)
UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
/* Initialize transmit ring */
if (udav_tx_list_init(sc) == ENOBUFS) {
if (usb_ether_tx_list_init(sc, &sc->sc_cdata,
USBDEVNAME(sc->sc_dev), sc->sc_udev) == ENOBUFS) {
printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
#if defined(__NetBSD__)
splx(s);
@ -869,7 +868,8 @@ udav_init(void *xsc)
}
/* Initialize receive ring */
if (udav_rx_list_init(sc) == ENOBUFS) {
if (usb_ether_rx_list_init(sc, &sc->sc_cdata,
USBDEVNAME(sc->sc_dev), sc->sc_udev) == ENOBUFS) {
printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
#if defined(__NetBSD__)
splx(s);
@ -1060,7 +1060,7 @@ udav_setmulti(struct udav_softc *sc)
Static int
udav_openpipes(struct udav_softc *sc)
{
struct udav_chain *c;
struct ue_chain *c;
usbd_status err;
int i;
int error = 0;
@ -1095,7 +1095,7 @@ udav_openpipes(struct udav_softc *sc)
/* Open Interrupt pipe */
err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
&sc->sc_cdata.udav_ibuf, UDAV_INTR_PKGLEN,
&sc->sc_cdata.ue_ibuf, UDAV_INTR_PKGLEN,
udav_intr, UDAV_INTR_INTERVAL);
if (err) {
printf("%s: open intr pipe failed: %s\n",
@ -1107,13 +1107,13 @@ udav_openpipes(struct udav_softc *sc)
/* Start up the receive pipe. */
for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
c = &sc->sc_cdata.udav_rx_chain[i];
usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
c, c->udav_buf, UDAV_BUFSZ,
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &sc->sc_cdata.ue_rx_chain[i];
usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
c, c->ue_buf, UE_BUFSZ,
USBD_SHORT_XFER_OK | USBD_NO_COPY,
USBD_NO_TIMEOUT, udav_rxeof);
(void)usbd_transfer(c->udav_xfer);
(void)usbd_transfer(c->ue_xfer);
DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
__func__));
}
@ -1125,68 +1125,6 @@ udav_openpipes(struct udav_softc *sc)
return (error);
}
Static int
udav_rx_list_init(struct udav_softc *sc)
{
struct udav_cdata *cd;
struct udav_chain *c;
int i;
DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
cd = &sc->sc_cdata;
for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
c = &cd->udav_rx_chain[i];
c->udav_sc = sc;
c->udav_idx = i;
c->udav_mbuf = usb_ether_newbuf(USBDEVNAME(sc->sc_dev));
if (c->udav_mbuf == NULL)
return (ENOBUFS);
if (c->udav_xfer == NULL) {
c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
if (c->udav_xfer == NULL)
return (ENOBUFS);
c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
if (c->udav_buf == NULL) {
usbd_free_xfer(c->udav_xfer);
return (ENOBUFS);
}
}
}
return (0);
}
Static int
udav_tx_list_init(struct udav_softc *sc)
{
struct udav_cdata *cd;
struct udav_chain *c;
int i;
DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
cd = &sc->sc_cdata;
for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
c = &cd->udav_tx_chain[i];
c->udav_sc = sc;
c->udav_idx = i;
c->udav_mbuf = NULL;
if (c->udav_xfer == NULL) {
c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
if (c->udav_xfer == NULL)
return (ENOBUFS);
c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
if (c->udav_buf == NULL) {
usbd_free_xfer(c->udav_xfer);
return (ENOBUFS);
}
}
}
return (0);
}
Static void
udav_start(struct ifnet *ifp)
{
@ -1238,36 +1176,36 @@ Static int
udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
{
int total_len;
struct udav_chain *c;
struct ue_chain *c;
usbd_status err;
DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
c = &sc->sc_cdata.udav_tx_chain[idx];
c = &sc->sc_cdata.ue_tx_chain[idx];
/* Copy the mbuf data into a contiguous buffer */
/* first 2 bytes are packet length */
m_copydata(m, 0, m->m_pkthdr.len, c->udav_buf + 2);
c->udav_mbuf = m;
m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
c->ue_mbuf = m;
total_len = m->m_pkthdr.len;
if (total_len < UDAV_MIN_FRAME_LEN) {
memset(c->udav_buf + 2 + total_len, 0,
memset(c->ue_buf + 2 + total_len, 0,
UDAV_MIN_FRAME_LEN - total_len);
total_len = UDAV_MIN_FRAME_LEN;
}
/* Frame length is specified in the first 2bytes of the buffer */
c->udav_buf[0] = (u_int8_t)total_len;
c->udav_buf[1] = (u_int8_t)(total_len >> 8);
c->ue_buf[0] = (u_int8_t)total_len;
c->ue_buf[1] = (u_int8_t)(total_len >> 8);
total_len += 2;
usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len,
usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_tx, c, c->ue_buf, total_len,
USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
UDAV_TX_TIMEOUT, udav_txeof);
/* Transmit */
sc->sc_refcnt++;
err = usbd_transfer(c->udav_xfer);
err = usbd_transfer(c->ue_xfer);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
if (err != USBD_IN_PROGRESS) {
@ -1281,7 +1219,7 @@ udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
__func__, total_len));
sc->sc_cdata.udav_tx_cnt++;
sc->sc_cdata.ue_tx_cnt++;
return (0);
}
@ -1289,8 +1227,8 @@ udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
Static void
udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct udav_chain *c = priv;
struct udav_softc *sc = c->udav_sc;
struct ue_chain *c = priv;
struct udav_softc *sc = c->ue_sc;
struct ifnet *ifp = GET_IFP(sc);
#if defined(__NetBSD__)
int s;
@ -1338,8 +1276,8 @@ udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
ifp->if_opackets++;
m_freem(c->udav_mbuf);
c->udav_mbuf = NULL;
m_freem(c->ue_mbuf);
c->ue_mbuf = NULL;
#if defined(__NetBSD__)
if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
@ -1358,8 +1296,8 @@ udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
Static void
udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct udav_chain *c = priv;
struct udav_softc *sc = c->udav_sc;
struct ue_chain *c = priv;
struct udav_softc *sc = c->ue_sc;
struct ifnet *ifp = GET_IFP(sc);
struct mbuf *m;
u_int32_t total_len;
@ -1395,8 +1333,8 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
/* copy data to mbuf */
m = c->udav_mbuf;
memcpy(mtod(m, char *), c->udav_buf, total_len);
m = c->ue_mbuf;
memcpy(mtod(m, char *), c->ue_buf, total_len);
/* first byte in received data */
pktstat = mtod(m, u_int8_t *);
@ -1434,8 +1372,10 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
#endif
#if defined(__NetBSD__)
c->udav_mbuf = usb_ether_newbuf(USBDEVNAME(sc->sc_dev));
if (c->udav_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
ifp->if_ierrors++;
goto done1;
}
@ -1464,7 +1404,7 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
#endif
done:
/* Setup new transfer */
usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ,
usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->ue_buf, UE_BUFSZ,
USBD_SHORT_XFER_OK | USBD_NO_COPY,
USBD_NO_TIMEOUT, udav_rxeof);
sc->sc_refcnt++;
@ -1563,7 +1503,7 @@ Static void
udav_watchdog(struct ifnet *ifp)
{
struct udav_softc *sc = ifp->if_softc;
struct udav_chain *c;
struct ue_chain *c;
usbd_status stat;
#if defined(__NetBSD__)
int s;
@ -1579,9 +1519,9 @@ udav_watchdog(struct ifnet *ifp)
#elif defined(__FreeBSD__)
UDAV_LOCK(sc)
#endif
c = &sc->sc_cdata.udav_tx_chain[0];
usbd_get_xfer_status(c->udav_xfer, NULL, NULL, NULL, &stat);
udav_txeof(c->udav_xfer, c, stat);
c = &sc->sc_cdata.ue_tx_chain[0];
usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
udav_txeof(c->ue_xfer, c, stat);
#if defined(__NetBSD__)
if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
@ -1662,28 +1602,9 @@ udav_stop(struct ifnet *ifp, int disable)
#endif
/* Free RX resources. */
for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
if (sc->sc_cdata.udav_rx_chain[i].udav_mbuf != NULL) {
m_freem(sc->sc_cdata.udav_rx_chain[i].udav_mbuf);
sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL;
}
if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) {
usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer);
sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL;
}
}
usb_ether_rx_list_free(&sc->sc_cdata);
/* Free TX resources. */
for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
if (sc->sc_cdata.udav_tx_chain[i].udav_mbuf != NULL) {
m_freem(sc->sc_cdata.udav_tx_chain[i].udav_mbuf);
sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL;
}
if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) {
usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer);
sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL;
}
}
usb_ether_tx_list_free(&sc->sc_cdata);
sc->sc_link = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
@ -1986,25 +1907,27 @@ Static void
udav_rxstart(struct ifnet *ifp)
{
struct udav_softc *sc;
struct udav_chain *c;
struct ue_chain *c;
sc = ifp->if_softc;
UDAV_LOCK(sc);
c = &sc->sc_cdata.udav_rx_chain[sc->sc_cdata.udav_rx_prod];
c = &sc->sc_cdata.ue_rx_chain[sc->sc_cdata.ue_rx_prod];
c->udav_mbuf = usb_ether_newbuf(USBDEVNAME(sc->sc_dev));
if (c->udav_mbuf == NULL) {
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
ifp->if_ierrors++;
UDAV_UNLOCK(sc);
return;
}
/* Setup new transfer. */
usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
c, c->udav_buf, UDAV_BUFSZ,
usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
c, c->ue_buf, UE_BUFSZ,
USBD_SHORT_XFER_OK | USBD_NO_COPY,
USBD_NO_TIMEOUT, udav_rxeof);
usbd_transfer(c->udav_xfer);
usbd_transfer(c->ue_xfer);
UDAV_UNLOCK(sc);
return;

View file

@ -34,9 +34,6 @@
#define UDAV_IFACE_INDEX 0
#define UDAV_CONFIG_NO 1
#define UDAV_TX_LIST_CNT 1
#define UDAV_RX_LIST_CNT 1
#define UDAV_TX_TIMEOUT 1000
#define UDAV_TIMEOUT 10000
@ -44,9 +41,7 @@
/* Packet length */
#define UDAV_MAX_MTU 1536 /* XXX: max frame size is unknown */
#define UDAV_MIN_FRAME_LEN 60
#define UDAV_BUFSZ UDAV_MAX_MTU
/* Request */
#define UDAV_REQ_REG_READ 0x00 /* Read from register(s) */
@ -163,27 +158,6 @@
#endif
#endif
struct udav_chain {
struct udav_softc *udav_sc;
usbd_xfer_handle udav_xfer;
char *udav_buf;
struct mbuf *udav_mbuf;
int udav_idx;
};
struct udav_cdata {
struct udav_chain udav_tx_chain[UDAV_TX_LIST_CNT];
struct udav_chain udav_rx_chain[UDAV_TX_LIST_CNT];
#if 0
/* XXX: Intrrupt Endpoint is not yet supported! */
struct udav_intrpkg udav_ibuf;
#endif
int udav_tx_prod;
int udav_tx_cons;
int udav_tx_cnt;
int udav_rx_prod;
};
struct udav_softc {
#if defined(__FreeBSD__)
struct arpcom sc_ac ; /* struct ifnet must be top of softc */
@ -221,7 +195,7 @@ struct udav_softc {
#if NRND > 0
rndsource_element_t rnd_source;
#endif
struct udav_cdata sc_cdata;
struct ue_cdata sc_cdata;
int sc_attached;
int sc_dying;

View file

@ -144,18 +144,101 @@ void usb_tx_done(m)
}
struct mbuf *
usb_ether_newbuf(const char *devname)
usb_ether_newbuf(void)
{
struct mbuf *m_new;
m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
if (m_new == NULL) {
printf("%s: no memory for rx list "
"-- packet dropped!\n", devname);
if (m_new == NULL)
return (NULL);
}
m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
m_adj(m_new, ETHER_ALIGN);
return (m_new);
}
int
usb_ether_rx_list_init(void *sc, struct ue_cdata *cd,
usbd_device_handle ue_udev)
{
struct ue_chain *c;
int i;
for (i = 0; i < UE_RX_LIST_CNT; i++) {
c = &cd->ue_rx_chain[i];
c->ue_sc = sc;
c->ue_idx = i;
c->ue_mbuf = usb_ether_newbuf();
if (c->ue_mbuf == NULL)
return (ENOBUFS);
if (c->ue_xfer == NULL) {
c->ue_xfer = usbd_alloc_xfer(ue_udev);
if (c->ue_xfer == NULL)
return (ENOBUFS);
c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ);
if (c->ue_buf == NULL)
return (ENOBUFS);
}
}
return (0);
}
int
usb_ether_tx_list_init(void *sc, struct ue_cdata *cd,
usbd_device_handle ue_udev)
{
struct ue_chain *c;
int i;
for (i = 0; i < UE_TX_LIST_CNT; i++) {
c = &cd->ue_tx_chain[i];
c->ue_sc = sc;
c->ue_idx = i;
c->ue_mbuf = NULL;
if (c->ue_xfer == NULL) {
c->ue_xfer = usbd_alloc_xfer(ue_udev);
if (c->ue_xfer == NULL)
return (ENOBUFS);
c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ);
if (c->ue_buf == NULL)
return (ENOBUFS);
}
}
return (0);
}
void
usb_ether_rx_list_free(struct ue_cdata *cd)
{
int i;
for (i = 0; i < UE_RX_LIST_CNT; i++) {
if (cd->ue_rx_chain[i].ue_mbuf != NULL) {
m_freem(cd->ue_rx_chain[i].ue_mbuf);
cd->ue_rx_chain[i].ue_mbuf = NULL;
}
if (cd->ue_rx_chain[i].ue_xfer != NULL) {
usbd_free_xfer(cd->ue_rx_chain[i].ue_xfer);
cd->ue_rx_chain[i].ue_xfer = NULL;
}
}
}
void
usb_ether_tx_list_free(struct ue_cdata *cd)
{
int i;
for (i = 0; i < UE_RX_LIST_CNT; i++) {
if (cd->ue_tx_chain[i].ue_mbuf != NULL) {
m_freem(cd->ue_tx_chain[i].ue_mbuf);
cd->ue_tx_chain[i].ue_mbuf = NULL;
}
if (cd->ue_tx_chain[i].ue_xfer != NULL) {
usbd_free_xfer(cd->ue_tx_chain[i].ue_xfer);
cd->ue_tx_chain[i].ue_xfer = NULL;
}
}
}

View file

@ -35,14 +35,47 @@
#ifndef _USB_ETHERSUBR_H_
#define _USB_ETHERSUBR_H_
#include <sys/bus.h>
#include <sys/module.h>
#include <dev/usb/usbdi.h>
#define UE_TX_LIST_CNT 1
#define UE_RX_LIST_CNT 1
#define UE_BUFSZ 1536
struct usb_qdat {
struct ifnet *ifp;
void (*if_rxstart) (struct ifnet *);
};
struct ue_chain {
void *ue_sc;
usbd_xfer_handle ue_xfer;
char *ue_buf;
struct mbuf *ue_mbuf;
int ue_idx;
};
struct ue_cdata {
struct ue_chain ue_tx_chain[UE_TX_LIST_CNT];
struct ue_chain ue_rx_chain[UE_RX_LIST_CNT];
void *ue_ibuf;
int ue_tx_prod;
int ue_tx_cons;
int ue_tx_cnt;
int ue_rx_prod;
};
void usb_register_netisr (void);
void usb_ether_input (struct mbuf *);
void usb_tx_done (struct mbuf *);
struct mbuf *usb_ether_newbuf (const char *);
struct mbuf *usb_ether_newbuf (void);
int usb_ether_rx_list_init (void *, struct ue_cdata *,
usbd_device_handle);
int usb_ether_tx_list_init (void *, struct ue_cdata *,
usbd_device_handle);
void usb_ether_rx_list_free (struct ue_cdata *);
void usb_ether_tx_list_free (struct ue_cdata *);
#endif