Tweak the vr_start() and vr_rxeof() routines a little to improve
performance and reliability a little. There was a condition before where transmission would stall during periods of heavy traffic exchange between two hosts. Also set the 'want interrupt' bit in receive descriptor control words.
This commit is contained in:
parent
53809e8652
commit
6c70e5b472
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42491
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_vr.c,v 1.5 1998/12/24 18:03:17 wpaul Exp $
|
||||
* $Id: if_vr.c,v 1.16 1999/01/10 18:06:10 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -97,7 +97,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id: if_vr.c,v 1.5 1998/12/24 18:03:17 wpaul Exp $";
|
||||
"$Id: if_vr.c,v 1.16 1999/01/10 18:06:10 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1214,7 +1214,7 @@ static int vr_newbuf(sc, c)
|
||||
c->vr_mbuf = m_new;
|
||||
c->vr_ptr->vr_status = VR_RXSTAT;
|
||||
c->vr_ptr->vr_data = vtophys(mtod(m_new, caddr_t));
|
||||
c->vr_ptr->vr_ctl = VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
c->vr_ptr->vr_ctl = VR_RXCTL | VR_RXLEN;
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -1276,8 +1276,7 @@ static void vr_rxeof(sc)
|
||||
break;
|
||||
}
|
||||
cur_rx->vr_ptr->vr_status = VR_RXSTAT;
|
||||
cur_rx->vr_ptr->vr_ctl =
|
||||
VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
cur_rx->vr_ptr->vr_ctl = VR_RXCTL|VR_RXLEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1304,8 +1303,7 @@ static void vr_rxeof(sc)
|
||||
if (vr_newbuf(sc, cur_rx) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->vr_ptr->vr_status = VR_RXSTAT;
|
||||
cur_rx->vr_ptr->vr_ctl =
|
||||
VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
cur_rx->vr_ptr->vr_ctl = VR_RXCTL|VR_RXLEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1383,7 +1381,7 @@ static void vr_txeof(sc)
|
||||
cur_tx = sc->vr_cdata.vr_tx_head;
|
||||
txstat = cur_tx->vr_ptr->vr_status;
|
||||
|
||||
if ((txstat & VR_TXSTAT_OWN) || txstat == VR_UNSENT)
|
||||
if (txstat & VR_TXSTAT_OWN)
|
||||
break;
|
||||
|
||||
if (txstat & VR_TXSTAT_ERRSUM) {
|
||||
@ -1429,12 +1427,6 @@ static void vr_txeoc(sc)
|
||||
sc->vr_cdata.vr_tx_tail = NULL;
|
||||
if (sc->vr_want_auto)
|
||||
vr_autoneg_mii(sc, VR_FLAG_SCHEDDELAY, 1);
|
||||
} else {
|
||||
if (VR_TXOWN(sc->vr_cdata.vr_tx_head) == VR_UNSENT) {
|
||||
VR_TXOWN(sc->vr_cdata.vr_tx_head) = VR_TXSTAT_OWN;
|
||||
ifp->if_timer = 5;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1571,7 +1563,7 @@ static int vr_encap(sc, c, m_head)
|
||||
}
|
||||
|
||||
c->vr_mbuf = m_head;
|
||||
c->vr_ptr->vr_ctl |= VR_TXCTL_LASTFRAG;
|
||||
c->vr_ptr->vr_ctl |= VR_TXCTL_LASTFRAG|VR_TXCTL_FINT;
|
||||
c->vr_ptr->vr_next = vtophys(c->vr_nextdesc->vr_ptr);
|
||||
|
||||
return(0);
|
||||
@ -1632,6 +1624,8 @@ static void vr_start(ifp)
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, cur_tx->vr_mbuf);
|
||||
#endif
|
||||
VR_TXOWN(cur_tx) = VR_TXSTAT_OWN;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1640,23 +1634,10 @@ static void vr_start(ifp)
|
||||
if (cur_tx == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Place the request for the upload interrupt
|
||||
* in the last descriptor in the chain. This way, if
|
||||
* we're chaining several packets at once, we'll only
|
||||
* get an interupt once for the whole chain rather than
|
||||
* once for each packet.
|
||||
*/
|
||||
cur_tx->vr_ptr->vr_ctl |= VR_TXCTL_FINT;
|
||||
sc->vr_cdata.vr_tx_tail = cur_tx;
|
||||
|
||||
if (sc->vr_cdata.vr_tx_head == NULL) {
|
||||
if (sc->vr_cdata.vr_tx_head == NULL)
|
||||
sc->vr_cdata.vr_tx_head = start_tx;
|
||||
VR_TXOWN(start_tx) = VR_TXSTAT_OWN;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
} else {
|
||||
VR_TXOWN(start_tx) = VR_UNSENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_vrreg.h,v 1.8 1998/12/01 22:08:11 wpaul Exp $
|
||||
* $Id: if_vrreg.h,v 1.9 1999/01/10 18:06:10 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -311,6 +311,7 @@ struct vr_desc {
|
||||
#define VR_RXCTL_CHAIN 0x00008000
|
||||
#define VR_RXCTL_RX_INTR 0x00800000
|
||||
|
||||
#define VR_RXCTL (VR_RXCTL_CHAIN|VR_RXCTL_RX_INTR)
|
||||
|
||||
#define VR_TXSTAT_DEFER 0x00000001
|
||||
#define VR_TXSTAT_UNDERRUN 0x00000002
|
||||
@ -337,9 +338,9 @@ struct vr_desc {
|
||||
#define VR_TX_LIST_CNT 64
|
||||
#define VR_MIN_FRAMELEN 60
|
||||
#define VR_FRAMELEN 1536
|
||||
#define VR_RXLEN 1520
|
||||
|
||||
#define VR_TXOWN(x) x->vr_ptr->vr_status
|
||||
#define VR_UNSENT 0x12341234
|
||||
|
||||
struct vr_list_data {
|
||||
struct vr_desc vr_rx_list[VR_RX_LIST_CNT];
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_vr.c,v 1.5 1998/12/24 18:03:17 wpaul Exp $
|
||||
* $Id: if_vr.c,v 1.16 1999/01/10 18:06:10 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -97,7 +97,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id: if_vr.c,v 1.5 1998/12/24 18:03:17 wpaul Exp $";
|
||||
"$Id: if_vr.c,v 1.16 1999/01/10 18:06:10 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1214,7 +1214,7 @@ static int vr_newbuf(sc, c)
|
||||
c->vr_mbuf = m_new;
|
||||
c->vr_ptr->vr_status = VR_RXSTAT;
|
||||
c->vr_ptr->vr_data = vtophys(mtod(m_new, caddr_t));
|
||||
c->vr_ptr->vr_ctl = VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
c->vr_ptr->vr_ctl = VR_RXCTL | VR_RXLEN;
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -1276,8 +1276,7 @@ static void vr_rxeof(sc)
|
||||
break;
|
||||
}
|
||||
cur_rx->vr_ptr->vr_status = VR_RXSTAT;
|
||||
cur_rx->vr_ptr->vr_ctl =
|
||||
VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
cur_rx->vr_ptr->vr_ctl = VR_RXCTL|VR_RXLEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1304,8 +1303,7 @@ static void vr_rxeof(sc)
|
||||
if (vr_newbuf(sc, cur_rx) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->vr_ptr->vr_status = VR_RXSTAT;
|
||||
cur_rx->vr_ptr->vr_ctl =
|
||||
VR_RXCTL_CHAIN | (MCLBYTES - 1);
|
||||
cur_rx->vr_ptr->vr_ctl = VR_RXCTL|VR_RXLEN;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1383,7 +1381,7 @@ static void vr_txeof(sc)
|
||||
cur_tx = sc->vr_cdata.vr_tx_head;
|
||||
txstat = cur_tx->vr_ptr->vr_status;
|
||||
|
||||
if ((txstat & VR_TXSTAT_OWN) || txstat == VR_UNSENT)
|
||||
if (txstat & VR_TXSTAT_OWN)
|
||||
break;
|
||||
|
||||
if (txstat & VR_TXSTAT_ERRSUM) {
|
||||
@ -1429,12 +1427,6 @@ static void vr_txeoc(sc)
|
||||
sc->vr_cdata.vr_tx_tail = NULL;
|
||||
if (sc->vr_want_auto)
|
||||
vr_autoneg_mii(sc, VR_FLAG_SCHEDDELAY, 1);
|
||||
} else {
|
||||
if (VR_TXOWN(sc->vr_cdata.vr_tx_head) == VR_UNSENT) {
|
||||
VR_TXOWN(sc->vr_cdata.vr_tx_head) = VR_TXSTAT_OWN;
|
||||
ifp->if_timer = 5;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1571,7 +1563,7 @@ static int vr_encap(sc, c, m_head)
|
||||
}
|
||||
|
||||
c->vr_mbuf = m_head;
|
||||
c->vr_ptr->vr_ctl |= VR_TXCTL_LASTFRAG;
|
||||
c->vr_ptr->vr_ctl |= VR_TXCTL_LASTFRAG|VR_TXCTL_FINT;
|
||||
c->vr_ptr->vr_next = vtophys(c->vr_nextdesc->vr_ptr);
|
||||
|
||||
return(0);
|
||||
@ -1632,6 +1624,8 @@ static void vr_start(ifp)
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, cur_tx->vr_mbuf);
|
||||
#endif
|
||||
VR_TXOWN(cur_tx) = VR_TXSTAT_OWN;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1640,23 +1634,10 @@ static void vr_start(ifp)
|
||||
if (cur_tx == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Place the request for the upload interrupt
|
||||
* in the last descriptor in the chain. This way, if
|
||||
* we're chaining several packets at once, we'll only
|
||||
* get an interupt once for the whole chain rather than
|
||||
* once for each packet.
|
||||
*/
|
||||
cur_tx->vr_ptr->vr_ctl |= VR_TXCTL_FINT;
|
||||
sc->vr_cdata.vr_tx_tail = cur_tx;
|
||||
|
||||
if (sc->vr_cdata.vr_tx_head == NULL) {
|
||||
if (sc->vr_cdata.vr_tx_head == NULL)
|
||||
sc->vr_cdata.vr_tx_head = start_tx;
|
||||
VR_TXOWN(start_tx) = VR_TXSTAT_OWN;
|
||||
VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_ON|VR_CMD_TX_GO);
|
||||
} else {
|
||||
VR_TXOWN(start_tx) = VR_UNSENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_vrreg.h,v 1.8 1998/12/01 22:08:11 wpaul Exp $
|
||||
* $Id: if_vrreg.h,v 1.9 1999/01/10 18:06:10 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -311,6 +311,7 @@ struct vr_desc {
|
||||
#define VR_RXCTL_CHAIN 0x00008000
|
||||
#define VR_RXCTL_RX_INTR 0x00800000
|
||||
|
||||
#define VR_RXCTL (VR_RXCTL_CHAIN|VR_RXCTL_RX_INTR)
|
||||
|
||||
#define VR_TXSTAT_DEFER 0x00000001
|
||||
#define VR_TXSTAT_UNDERRUN 0x00000002
|
||||
@ -337,9 +338,9 @@ struct vr_desc {
|
||||
#define VR_TX_LIST_CNT 64
|
||||
#define VR_MIN_FRAMELEN 60
|
||||
#define VR_FRAMELEN 1536
|
||||
#define VR_RXLEN 1520
|
||||
|
||||
#define VR_TXOWN(x) x->vr_ptr->vr_status
|
||||
#define VR_UNSENT 0x12341234
|
||||
|
||||
struct vr_list_data {
|
||||
struct vr_desc vr_rx_list[VR_RX_LIST_CNT];
|
||||
|
Loading…
Reference in New Issue
Block a user