aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/pci/if_sis.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index a924e99e48ec..196e1f99c51a 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -64,6 +64,7 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
+#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -198,6 +199,12 @@ static driver_t sis_driver = {
static devclass_t sis_devclass;
+#ifdef __i386__
+static int sis_quick=1;
+SYSCTL_INT(_hw, OID_AUTO, sis_quick, CTLFLAG_RW,
+ &sis_quick,0,"do not mdevget in sis driver");
+#endif
+
DRIVER_MODULE(if_sis, pci, sis_driver, sis_devclass, 0, 0);
DRIVER_MODULE(miibus, sis, miibus_driver, miibus_devclass, 0, 0);
@@ -1133,27 +1140,19 @@ static int sis_list_tx_init(sc)
{
struct sis_list_data *ld;
struct sis_ring_data *cd;
- int i;
+ int i, nexti;
cd = &sc->sis_cdata;
ld = &sc->sis_ldata;
for (i = 0; i < SIS_TX_LIST_CNT; i++) {
- if (i == (SIS_TX_LIST_CNT - 1)) {
- ld->sis_tx_list[i].sis_nextdesc =
- &ld->sis_tx_list[0];
- bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
- sc->sis_ldata.sis_tx_dmamap, &ld->sis_tx_list[0],
- sizeof(struct sis_desc), sis_dma_map_desc_next,
- &ld->sis_tx_list[i], 0);
- } else {
+ nexti = (i == (SIS_TX_LIST_CNT - 1)) ? 0 : i+1 ;
ld->sis_tx_list[i].sis_nextdesc =
- &ld->sis_tx_list[i + 1];
+ &ld->sis_tx_list[nexti];
bus_dmamap_load(sc->sis_ldata.sis_tx_tag,
sc->sis_ldata.sis_tx_dmamap,
- &ld->sis_tx_list[i + 1], sizeof(struct sis_desc),
+ &ld->sis_tx_list[nexti], sizeof(struct sis_desc),
sis_dma_map_desc_next, &ld->sis_tx_list[i], 0);
- }
ld->sis_tx_list[i].sis_mbuf = NULL;
ld->sis_tx_list[i].sis_ptr = 0;
ld->sis_tx_list[i].sis_ctl = 0;
@@ -1177,7 +1176,7 @@ static int sis_list_rx_init(sc)
{
struct sis_list_data *ld;
struct sis_ring_data *cd;
- int i;
+ int i,nexti;
ld = &sc->sis_ldata;
cd = &sc->sis_cdata;
@@ -1185,24 +1184,15 @@ static int sis_list_rx_init(sc)
for (i = 0; i < SIS_RX_LIST_CNT; i++) {
if (sis_newbuf(sc, &ld->sis_rx_list[i], NULL) == ENOBUFS)
return(ENOBUFS);
- if (i == (SIS_RX_LIST_CNT - 1)) {
+ nexti = (i == (SIS_RX_LIST_CNT - 1)) ? 0 : i+1 ;
ld->sis_rx_list[i].sis_nextdesc =
- &ld->sis_rx_list[0];
- bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
- sc->sis_ldata.sis_rx_dmamap, &ld->sis_rx_list[0],
- sizeof(struct sis_desc), sis_dma_map_desc_next,
- &ld->sis_rx_list[i], 0);
-
- } else {
- ld->sis_rx_list[i].sis_nextdesc =
- &ld->sis_rx_list[i + 1];
+ &ld->sis_rx_list[nexti];
bus_dmamap_load(sc->sis_ldata.sis_rx_tag,
sc->sis_ldata.sis_rx_dmamap,
- &ld->sis_rx_list[i + 1],
+ &ld->sis_rx_list[nexti],
sizeof(struct sis_desc), sis_dma_map_desc_next,
&ld->sis_rx_list[i], 0);
}
- }
bus_dmamap_sync(sc->sis_ldata.sis_rx_tag,
sc->sis_ldata.sis_rx_dmamap, BUS_DMASYNC_PREWRITE);
@@ -1227,16 +1217,11 @@ static int sis_newbuf(sc, c, m)
if (m == NULL) {
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL) {
- printf("sis%d: no memory for rx list "
- "-- packet dropped!\n", sc->sis_unit);
+ if (m_new == NULL)
return(ENOBUFS);
- }
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
- printf("sis%d: no memory for rx list "
- "-- packet dropped!\n", sc->sis_unit);
m_freem(m_new);
return(ENOBUFS);
}
@@ -1279,7 +1264,6 @@ static void sis_rxeof(sc)
i = sc->sis_cdata.sis_rx_prod;
while(SIS_OWNDESC(&sc->sis_ldata.sis_rx_list[i])) {
- struct mbuf *m0 = NULL;
cur_rx = &sc->sis_ldata.sis_rx_list[i];
rxstat = cur_rx->sis_rxstat;
@@ -1307,14 +1291,32 @@ static void sis_rxeof(sc)
}
/* No errors; receive the packet. */
- m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
- NULL);
- sis_newbuf(sc, cur_rx, m);
- if (m0 == NULL) {
- ifp->if_ierrors++;
- continue;
+#ifdef __i386__
+ /*
+ * On the x86 we do not have alignment problems, so try to
+ * allocate a new buffer for the receive ring, and pass up
+ * the one where the packet is already, saving the expensive
+ * copy done in m_devget().
+ * If we are on an architecture with alignment problems, or
+ * if the allocation fails, then use m_devget and leave the
+ * existing buffer in the receive ring.
+ */
+ if (sis_quick && sis_newbuf(sc, cur_rx, NULL) == 0) {
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = m->m_len = total_len;
+ } else
+#endif
+ {
+ struct mbuf *m0;
+ m0 = m_devget(mtod(m, char *), total_len,
+ ETHER_ALIGN, ifp, NULL);
+ sis_newbuf(sc, cur_rx, m);
+ if (m0 == NULL) {
+ ifp->if_ierrors++;
+ continue;
+ }
+ m = m0;
}
- m = m0;
ifp->if_ipackets++;
eh = mtod(m, struct ether_header *);