mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
Make some tweaks to the RealTek driver:
- Fix a bug in rl_rxeof() handler: in the case where the packet wraps from the end of the receive buffer back to the beginning, we need to insure that at least sizeof(ether_header) bytes make it into the first mbuf. If we don't, then doing eh = mtod(m, struct ether_header *) loses. To avoid this, we use m_pullup() to suck at least MHLEN - RL_ETHER_ALIGN bytes into the first mbuf, which should also help small packets fit into a single mbuf. Pointed out by: Philip A. Prindeville <philipp@zembu.com> - Make the transmit threshold autotuning: start off with a small value and jack it up when TX underruns are detected. - Also improve TX error recovery: kick the chip in the head with a reset/init sequence to make sure it recovers afer a transmit error.
This commit is contained in:
parent
86a4b08dc7
commit
11ad85d1f5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52426
@ -988,7 +988,7 @@ static int rl_detach(dev)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_res);
|
||||
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
|
||||
|
||||
free(sc->rl_cdata.rl_rx_buf, M_DEVBUF);
|
||||
contigfree(sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN + 32, M_DEVBUF);
|
||||
|
||||
splx(s);
|
||||
|
||||
@ -1125,12 +1125,12 @@ static void rl_rxeof(sc)
|
||||
if (m == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
printf("rl%d: out of mbufs, tried to "
|
||||
"copy %d bytes\n", sc->rl_unit, wrap);
|
||||
}
|
||||
else {
|
||||
"copy %d bytes\n", sc->rl_unit, wrap);
|
||||
} else {
|
||||
m_adj(m, RL_ETHER_ALIGN);
|
||||
m_copyback(m, wrap, total_len - wrap,
|
||||
sc->rl_cdata.rl_rx_buf);
|
||||
m_pullup(m, MHLEN - RL_ETHER_ALIGN);
|
||||
}
|
||||
cur_rx = (total_len - wrap + ETHER_CRC_LEN);
|
||||
} else {
|
||||
@ -1139,7 +1139,7 @@ static void rl_rxeof(sc)
|
||||
if (m == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
printf("rl%d: out of mbufs, tried to "
|
||||
"copy %d bytes\n", sc->rl_unit, total_len);
|
||||
"copy %d bytes\n", sc->rl_unit, total_len);
|
||||
} else
|
||||
m_adj(m, RL_ETHER_ALIGN);
|
||||
cur_rx += total_len + 4 + ETHER_CRC_LEN;
|
||||
@ -1216,10 +1216,22 @@ static void rl_txeof(sc)
|
||||
if (txstat & RL_TXSTAT_TX_OK)
|
||||
ifp->if_opackets++;
|
||||
else {
|
||||
int oldthresh;
|
||||
ifp->if_oerrors++;
|
||||
if ((txstat & RL_TXSTAT_TXABRT) ||
|
||||
(txstat & RL_TXSTAT_OUTOFWIN))
|
||||
CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
|
||||
oldthresh = sc->rl_txthresh;
|
||||
/* error recovery */
|
||||
rl_reset(sc);
|
||||
rl_init(sc);
|
||||
/*
|
||||
* If there was a transmit underrun,
|
||||
* bump the TX threshold.
|
||||
*/
|
||||
if (txstat & RL_TXSTAT_TX_UNDERRUN)
|
||||
sc->rl_txthresh = oldthresh + 32;
|
||||
return;
|
||||
}
|
||||
RL_INC(sc->rl_cdata.last_tx);
|
||||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
@ -1290,9 +1302,8 @@ static void rl_intr(arg)
|
||||
/* Re-enable interrupts. */
|
||||
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
|
||||
|
||||
if (ifp->if_snd.ifq_head != NULL) {
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
rl_start(ifp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1327,8 +1338,7 @@ static int rl_encap(sc, m_head)
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
m_copydata(m_head, 0, m_head->m_pkthdr.len,
|
||||
mtod(m_new, caddr_t));
|
||||
m_copydata(m_head, 0, m_head->m_pkthdr.len, mtod(m_new, caddr_t));
|
||||
m_new->m_pkthdr.len = m_new->m_len = m_head->m_pkthdr.len;
|
||||
m_freem(m_head);
|
||||
m_head = m_new;
|
||||
@ -1336,7 +1346,7 @@ static int rl_encap(sc, m_head)
|
||||
/* Pad frames to at least 60 bytes. */
|
||||
if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) {
|
||||
m_head->m_pkthdr.len +=
|
||||
(RL_MIN_FRAMELEN - m_head->m_pkthdr.len);
|
||||
(RL_MIN_FRAMELEN - m_head->m_pkthdr.len);
|
||||
m_head->m_len = m_head->m_pkthdr.len;
|
||||
}
|
||||
|
||||
@ -1377,7 +1387,8 @@ static void rl_start(ifp)
|
||||
CSR_WRITE_4(sc, RL_CUR_TXADDR(sc),
|
||||
vtophys(mtod(RL_CUR_TXMBUF(sc), caddr_t)));
|
||||
CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc),
|
||||
RL_TX_EARLYTHRESH | RL_CUR_TXMBUF(sc)->m_pkthdr.len);
|
||||
RL_TXTHRESH(sc->rl_txthresh) |
|
||||
RL_CUR_TXMBUF(sc)->m_pkthdr.len);
|
||||
|
||||
RL_INC(sc->rl_cdata.cur_tx);
|
||||
}
|
||||
@ -1472,6 +1483,9 @@ static void rl_init(xsc)
|
||||
*/
|
||||
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
|
||||
|
||||
/* Set initial TX threshold */
|
||||
sc->rl_txthresh = RL_TX_THRESH_INIT;
|
||||
|
||||
/* Start RX/TX process. */
|
||||
CSR_WRITE_4(sc, RL_MISSEDPKT, 0);
|
||||
|
||||
|
@ -299,7 +299,8 @@
|
||||
#define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13))
|
||||
#define RL_TX_LIST_CNT 4
|
||||
#define RL_MIN_FRAMELEN 60
|
||||
#define RL_TX_EARLYTHRESH (256 << 11)
|
||||
#define RL_TXTHRESH(x) ((x) << 11)
|
||||
#define RL_TX_THRESH_INIT 96
|
||||
#define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES
|
||||
#define RL_RX_MAXDMA RL_RXDMA_UNLIMITED
|
||||
#define RL_TX_MAXDMA RL_TXDMA_2048BYTES
|
||||
@ -364,6 +365,7 @@ struct rl_softc {
|
||||
u_int8_t rl_unit; /* interface number */
|
||||
u_int8_t rl_type;
|
||||
u_int8_t rl_stats_no_timeout;
|
||||
int rl_txthresh;
|
||||
struct rl_chain_data rl_cdata;
|
||||
struct callout_handle rl_stat_ch;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user