mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-21 09:13:37 +00:00
Move Rx/Tx lists management routines into central location.
This commit is contained in:
parent
7d2832e654
commit
d521dc21e7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=144104
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue