summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1999-06-29 06:02:38 +0000
committerJason Wright <jason@cvs.openbsd.org>1999-06-29 06:02:38 +0000
commitc9f6e45f33dce0db4be178f97632054f28b29691 (patch)
treee63cdc0569cb0ab8be807c16baca2a7f344d4fb6
parent4b90e05c6c5e2b3d61ee7ad7162bde87e5c68a88 (diff)
merge with FreeBSD:
support for delta, addtron, and SiS 8139 boards initialize if_snd.ifq_maxlen correctly chipset now works on alpha
-rw-r--r--sys/dev/pci/if_rl.c287
-rw-r--r--sys/dev/pci/if_rlreg.h99
2 files changed, 171 insertions, 215 deletions
diff --git a/sys/dev/pci/if_rl.c b/sys/dev/pci/if_rl.c
index 259649c6947..d8a3e47e99e 100644
--- a/sys/dev/pci/if_rl.c
+++ b/sys/dev/pci/if_rl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rl.c,v 1.14 1999/03/03 22:51:49 jason Exp $ */
+/* $OpenBSD: if_rl.c,v 1.15 1999/06/29 06:02:36 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: if_rl.c,v 1.12 1999/02/23 15:38:25 wpaul Exp $
+ * $FreeBSD: if_rl.c,v 1.17 1999/06/19 20:17:37 wpaul Exp $
*/
/*
@@ -155,12 +155,10 @@ static int rl_mii_read __P((struct device *, int, int));
static void rl_mii_write __P((struct device *, int, int, int));
static void rl_mii_statchg __P((struct device *));
-static int rl_encap __P((struct rl_softc *, struct rl_chain *,
- struct mbuf * ));
+static int rl_encap __P((struct rl_softc *, struct mbuf * ));
static void rl_rxeof __P((struct rl_softc *));
static void rl_txeof __P((struct rl_softc *));
-static void rl_txeoc __P((struct rl_softc *));
static void rl_start __P((struct ifnet *));
static int rl_ioctl __P((struct ifnet *, u_long, caddr_t));
static void rl_init __P((void *));
@@ -602,17 +600,13 @@ static int rl_list_tx_init(sc)
cd = &sc->rl_cdata;
for (i = 0; i < RL_TX_LIST_CNT; i++) {
- cd->rl_tx_chain[i].rl_desc = i * 4;
- CSR_WRITE_4(sc, RL_TXADDR0 + cd->rl_tx_chain[i].rl_desc, 0);
- CSR_WRITE_4(sc, RL_TXSTAT0 + cd->rl_tx_chain[i].rl_desc, 0);
- if (i == (RL_TX_LIST_CNT - 1))
- cd->rl_tx_chain[i].rl_next = &cd->rl_tx_chain[0];
- else
- cd->rl_tx_chain[i].rl_next = &cd->rl_tx_chain[i + 1];
+ cd->rl_tx_chain[i] = NULL;
+ CSR_WRITE_4(sc,
+ RL_TXADDR0 + (i * sizeof(u_int32_t)), 0x0000000);
}
- sc->rl_cdata.rl_tx_cnt = 0;
- cd->rl_tx_cur = cd->rl_tx_free = &cd->rl_tx_chain[0];
+ sc->rl_cdata.cur_tx = 0;
+ sc->rl_cdata.last_tx = 0;
return(0);
}
@@ -633,6 +627,16 @@ static int rl_list_tx_init(sc)
* the status word) is also 32-bit aligned. The frame length is in the
* first 16 bits of the status word; the lower 15 bits correspond with
* the 'rx status register' mentioned in the datasheet.
+ *
+ * Note: to make the Alpha happy, the frame payload needs to be aligned
+ * on a 32-bit boundary. To achieve this, we cheat a bit by copying from
+ * the ring buffer starting at an address two bytes before the actual
+ * data location. We can then shave off the first two bytes using m_adj().
+ * The reason we do this is because m_devget() doesn't let us specify an
+ * offset into the mbuf storage space, so we have to artificially create
+ * one. The ring is allocated in such a way that there are a few unused
+ * bytes of space preceecing it so that it will be safe for us to do the
+ * 2-byte backstep even if reading from the ring at offset 0.
*/
static void rl_rxeof(sc)
struct rl_softc *sc;
@@ -721,17 +725,23 @@ static void rl_rxeof(sc)
wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos;
if (total_len > wrap) {
- m = m_devget(rxbufpos, wrap, 0, ifp, NULL);
+ m = m_devget(rxbufpos - RL_ETHER_ALIGN,
+ wrap + RL_ETHER_ALIGN, 0, ifp, NULL);
if (m == NULL)
ifp->if_ierrors++;
- else
+ else {
+ m_adj(m, RL_ETHER_ALIGN);
m_copyback(m, wrap, total_len - wrap,
sc->rl_cdata.rl_rx_buf);
+ }
cur_rx = (total_len - wrap + ETHER_CRC_LEN);
} else {
- m = m_devget(rxbufpos, total_len, 0, ifp, NULL);
+ m = m_devget(rxbufpos - RL_ETHER_ALIGN,
+ total_len + RL_ETHER_ALIGN, 0, ifp, NULL);
if (m == NULL)
ifp->if_ierrors++;
+ else
+ m_adj(m, RL_ETHER_ALIGN);
cur_rx += total_len + 4 + ETHER_CRC_LEN;
}
@@ -769,7 +779,6 @@ static void rl_rxeof(sc)
static void rl_txeof(sc)
struct rl_softc *sc;
{
- struct rl_chain *cur_tx;
struct ifnet *ifp;
u_int32_t txstat;
@@ -782,83 +791,29 @@ static void rl_txeof(sc)
* Go through our tx list and free mbufs for those
* frames that have been uploaded.
*/
- if (sc->rl_cdata.rl_tx_free == NULL)
- return;
-
- while(sc->rl_cdata.rl_tx_free->rl_mbuf != NULL) {
- cur_tx = sc->rl_cdata.rl_tx_free;
- txstat = CSR_READ_4(sc, RL_TXSTAT0 + cur_tx->rl_desc);
-
- if (!(txstat & RL_TXSTAT_TX_OK))
+ do {
+ txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc));
+ if (!(txstat & (RL_TXSTAT_TX_OK|
+ RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT)))
break;
- if (txstat & RL_TXSTAT_COLLCNT)
- ifp->if_collisions +=
- (txstat & RL_TXSTAT_COLLCNT) >> 24;
-
- sc->rl_cdata.rl_tx_free = cur_tx->rl_next;
-
- sc->rl_cdata.rl_tx_cnt--;
- m_freem(cur_tx->rl_mbuf);
- cur_tx->rl_mbuf = NULL;
- ifp->if_opackets++;
- }
+ ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
- if (!sc->rl_cdata.rl_tx_cnt) {
- ifp->if_flags &= ~IFF_OACTIVE;
- } else {
- if (ifp->if_snd.ifq_head != NULL)
- rl_start(ifp);
- }
-
- return;
-}
-
-/*
- * TX error handler.
- */
-static void rl_txeoc(sc)
- struct rl_softc *sc;
-{
- u_int32_t txstat;
- struct rl_chain *cur_tx;
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
-
- if (sc->rl_cdata.rl_tx_free == NULL)
- return;
-
- while(sc->rl_cdata.rl_tx_free->rl_mbuf != NULL) {
- cur_tx = sc->rl_cdata.rl_tx_free;
- txstat = CSR_READ_4(sc, RL_TXSTAT0 + cur_tx->rl_desc);
-
- if (!(txstat & RL_TXSTAT_OWN))
- break;
-
- if (!(txstat & RL_TXSTAT_TX_OK)) {
- ifp->if_oerrors++;
- if (txstat & RL_TXSTAT_COLLCNT)
- ifp->if_collisions +=
- (txstat & RL_TXSTAT_COLLCNT) >> 24;
- CSR_WRITE_4(sc, RL_TXADDR0 + cur_tx->rl_desc,
- vtophys(mtod(cur_tx->rl_mbuf, caddr_t)));
- CSR_WRITE_4(sc, RL_TXSTAT0 + cur_tx->rl_desc,
- RL_TX_EARLYTHRESH |
- cur_tx->rl_mbuf->m_pkthdr.len);
- break;
- } else {
- if (txstat & RL_TXSTAT_COLLCNT)
- ifp->if_collisions +=
- (txstat & RL_TXSTAT_COLLCNT) >> 24;
- sc->rl_cdata.rl_tx_free = cur_tx->rl_next;
-
- sc->rl_cdata.rl_tx_cnt--;
- m_freem(cur_tx->rl_mbuf);
- cur_tx->rl_mbuf = NULL;
+ if (RL_LAST_TXMBUF(sc) != NULL) {
+ m_freem(RL_LAST_TXMBUF(sc));
+ RL_LAST_TXMBUF(sc) = NULL;
+ }
+ if (txstat & RL_TXSTAT_TX_OK)
ifp->if_opackets++;
+ else {
+ ifp->if_oerrors++;
+ if ((txstat & RL_TXSTAT_TXABRT) ||
+ (txstat & RL_TXSTAT_OUTOFWIN))
+ CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
}
- }
+ RL_INC(sc->rl_cdata.last_tx);
+ ifp->if_flags &= ~IFF_OACTIVE;
+ } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx);
return;
}
@@ -892,12 +847,9 @@ static int rl_intr(arg)
if (status & RL_ISR_RX_ERR)
rl_rxeof(sc);
- if (status & RL_ISR_TX_OK)
+ if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR))
rl_txeof(sc);
- if (status & RL_ISR_TX_ERR)
- rl_txeoc(sc);
-
if (status & RL_ISR_SYSTEM_ERR) {
rl_reset(sc);
rl_init(sc);
@@ -919,29 +871,18 @@ static int rl_intr(arg)
* Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
* pointers to the fragment pointers.
*/
-static int rl_encap(sc, c, m_head)
+static int rl_encap(sc, m_head)
struct rl_softc *sc;
- struct rl_chain *c;
struct mbuf *m_head;
{
- struct mbuf *m;
struct mbuf *m_new = NULL;
/*
- * There are two possible encapsulation mechanisms
- * that we can use: an efficient one, and a very lossy
- * one. The efficient one only happens very rarely,
- * whereas the lossy one can and most likely will happen
- * all the time.
- * The efficient case happens if:
- * - the packet fits in a single mbuf
- * - the packet is 32-bit aligned within the mbuf data area
- * In this case, we can DMA from the mbuf directly.
- * The lossy case covers everything else. Bah.
+ * The RealTek is brain damaged and wants longword-aligned
+ * TX buffers, plus we can only have one fragment buffer
+ * per packet. We have to copy pretty much all the time.
*/
- m = m_head;
-
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL)
return(1);
@@ -966,7 +907,7 @@ static int rl_encap(sc, c, m_head)
m_head->m_len = m_head->m_pkthdr.len;
}
- c->rl_mbuf = m_head;
+ RL_CUR_TXMBUF(sc) = m_head;
return(0);
}
@@ -980,32 +921,16 @@ static void rl_start(ifp)
{
struct rl_softc *sc;
struct mbuf *m_head = NULL;
- struct rl_chain *cur_tx = NULL;
sc = ifp->if_softc;
- /*
- * Check for an available queue slot. If there are none,
- * punt.
- */
- if (sc->rl_cdata.rl_tx_cur->rl_mbuf != NULL) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
-
- while(sc->rl_cdata.rl_tx_cur->rl_mbuf == NULL) {
+ while(RL_CUR_TXMBUF(sc) == NULL) {
IF_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
-
- /* Pick a descriptor off the free list. */
- cur_tx = sc->rl_cdata.rl_tx_cur;
- sc->rl_cdata.rl_tx_cur = cur_tx->rl_next;
- sc->rl_cdata.rl_tx_cnt++;
-
/* Pack the data into the descriptor. */
- rl_encap(sc, cur_tx, m_head);
+ rl_encap(sc, m_head);
#if NBPFILTER > 0
/*
@@ -1013,18 +938,28 @@ static void rl_start(ifp)
* to him.
*/
if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, cur_tx->rl_mbuf);
+ bpf_mtap(ifp->if_bpf, RL_CUR_TXMBUF(sc));
#endif
/*
* Transmit the frame.
*/
- CSR_WRITE_4(sc, RL_TXADDR0 + cur_tx->rl_desc,
- vtophys(mtod(cur_tx->rl_mbuf, caddr_t)));
- CSR_WRITE_4(sc, RL_TXSTAT0 + cur_tx->rl_desc,
- RL_TX_EARLYTHRESH | cur_tx->rl_mbuf->m_pkthdr.len);
+ 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_INC(sc->rl_cdata.cur_tx);
}
/*
+ * We broke out of the loop because all our TX slots are
+ * full. Mark the NIC as busy until it drains some of the
+ * packets from the queue.
+ */
+ if (RL_CUR_TXMBUF(sc) != NULL)
+ ifp->if_flags |= IFF_OACTIVE;
+
+ /*
* Set a timeout in case the chip goes out to lunch.
*/
ifp->if_timer = 5;
@@ -1064,8 +999,9 @@ static void rl_init(xsc)
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
/*
- * Set the buffer size values.
+ * Set the inital TX and RX configuration.
*/
+ CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG);
/* Set the individual bit to receive frames for this host only. */
@@ -1217,7 +1153,6 @@ static void rl_watchdog(ifp)
printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
- rl_txeoc(sc);
rl_txeof(sc);
rl_rxeof(sc);
rl_init(sc);
@@ -1245,11 +1180,10 @@ static void rl_stop(sc)
* Free the TX list buffers.
*/
for (i = 0; i < RL_TX_LIST_CNT; i++) {
- if (sc->rl_cdata.rl_tx_chain[i].rl_mbuf != NULL) {
- m_freem(sc->rl_cdata.rl_tx_chain[i].rl_mbuf);
- sc->rl_cdata.rl_tx_chain[i].rl_mbuf = NULL;
- CSR_WRITE_4(sc, RL_TXADDR0 +
- sc->rl_cdata.rl_tx_chain[i].rl_desc, 0x00000000);
+ if (sc->rl_cdata.rl_tx_chain[i] != NULL) {
+ m_freem(sc->rl_cdata.rl_tx_chain[i]);
+ sc->rl_cdata.rl_tx_chain[i] = NULL;
+ CSR_WRITE_4(sc, RL_TXADDR0 + i, 0x00000000);
}
}
@@ -1266,27 +1200,28 @@ rl_probe(parent, match, aux)
{
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ACCTON &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_5030)
+ return (1);
+
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADDTRON &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADDTRON_8139)
+ return (1);
+
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DELTA &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DELTA_8139)
+ return (1);
+
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK) {
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_REALTEK_RT8129:
case PCI_PRODUCT_REALTEK_RT8139:
- return 1;
- }
- }
-
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ACCTON) {
- switch (PCI_PRODUCT(pa->pa_id)) {
- case PCI_PRODUCT_ACCTON_5030:
- return 1;
+ return (1);
}
}
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DELTA &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DELTA_8139)
- return (1);
-
- if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADDTRON &&
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADDTRON_8139)
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS &&
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_900)
return (1);
return 0;
@@ -1306,9 +1241,6 @@ rl_attach(parent, self, aux)
struct ifnet *ifp = &sc->arpcom.ac_if;
bus_addr_t iobase;
bus_size_t iosize;
- bus_dma_segment_t seg;
- int rseg;
- caddr_t kva;
u_int32_t command;
u_int16_t rl_did;
@@ -1378,7 +1310,8 @@ rl_attach(parent, self, aux)
rl_read_eeprom(sc, (caddr_t)&rl_did, RL_EE_PCI_DID, 1, 0);
if (rl_did == RT_DEVICEID_8139 || rl_did == ACCTON_DEVICEID_5030 ||
- rl_did == DELTA_DEVICEID_8139)
+ rl_did == DELTA_DEVICEID_8139 || rl_did == ADDTRON_DEVICEID_8139 ||
+ rl_did == SIS_DEVICEID_8139)
sc->rl_type = RL_8139;
else if (rl_did == RT_DEVICEID_8129)
sc->rl_type = RL_8129;
@@ -1388,37 +1321,14 @@ rl_attach(parent, self, aux)
return;
}
- sc->sc_dmat = pa->pa_dmat;
- if (bus_dmamem_alloc(sc->sc_dmat, RL_RXBUFLEN + 16, PAGE_SIZE, 0, &seg,
- 1, &rseg, BUS_DMA_NOWAIT)) {
- printf("\n%s: can't alloc rx buffers\n", sc->sc_dev.dv_xname);
- return;
- }
- if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, RL_RXBUFLEN + 16, &kva,
- BUS_DMA_NOWAIT | BUS_DMAMEM_NOSYNC)) {
- printf("\n%s: can't map dma buffers (%d bytes)\n",
- sc->sc_dev.dv_xname, RL_RXBUFLEN + 16);
- bus_dmamem_free(sc->sc_dmat, &seg, rseg);
- return;
- }
- sc->sc_dma_mapsize = RL_RXBUFLEN + 16;
- if (bus_dmamap_create(sc->sc_dmat, RL_RXBUFLEN + 16, 1,
- RL_RXBUFLEN + 16, 0, BUS_DMA_NOWAIT, &sc->sc_dma_mem)) {
- printf("\n%s: can't create dma map\n");
- bus_dmamem_unmap(sc->sc_dmat, kva, RL_RXBUFLEN + 16);
- bus_dmamem_free(sc->sc_dmat, &seg, rseg);
- return;
- }
- if (bus_dmamap_load(sc->sc_dmat, sc->sc_dma_mem, kva,
- RL_RXBUFLEN + 16, NULL, BUS_DMA_NOWAIT)) {
- printf("\n%s: can't load dma map\n");
- bus_dmamem_unmap(sc->sc_dmat, kva, RL_RXBUFLEN + 16);
- bus_dmamem_free(sc->sc_dmat, &seg, rseg);
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_dma_mem);
- }
- sc->rl_cdata.rl_rx_buf = (caddr_t) kva;
+ sc->rl_cdata.rl_rx_buf = (caddr_t) vm_page_alloc_contig(
+ RL_RXBUFLEN + 32, 0x100000, 0xffffffff, PAGE_SIZE);
bzero(sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN + 16);
+ /* Leave a few bytes before the start of the RX ring buffer. */
+ sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf;
+ sc->rl_cdata.rl_rx_buf += sizeof(u_int64_t);
+
ifp->if_softc = sc;
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -1427,7 +1337,8 @@ rl_attach(parent, self, aux)
ifp->if_start = rl_start;
ifp->if_watchdog = rl_watchdog;
ifp->if_baudrate = 10000000;
- ifp->if_snd.ifq_maxlen = RL_TX_LIST_CNT - 1;
+ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
/*
diff --git a/sys/dev/pci/if_rlreg.h b/sys/dev/pci/if_rlreg.h
index 688cac6f20a..0f2835373ae 100644
--- a/sys/dev/pci/if_rlreg.h
+++ b/sys/dev/pci/if_rlreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rlreg.h,v 1.7 1999/02/26 21:25:43 jason Exp $ */
+/* $OpenBSD: if_rlreg.h,v 1.8 1999/06/29 06:02:37 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: if_rlreg.h,v 1.5 1999/02/23 15:38:25 wpaul Exp $
+ * $FreeBSD: if_rlreg.h,v 1.9 1999/06/20 18:56:09 wpaul Exp $
*/
/*
@@ -106,14 +106,19 @@
* TX config register bits
*/
#define RL_TXCFG_CLRABRT 0x00000001 /* retransmit aborted pkt */
-#define RL_TXCFG_MXDMA0 0x00000100 /* max DMA burst size */
-#define RL_TXCFG_MXDMA1 0x00000200
-#define RL_TXCFG_MXDMA2 0x00000400
+#define RL_TXCFG_MAXDMA 0x00000700 /* max DMA burst size */
#define RL_TXCFG_CRCAPPEND 0x00010000 /* CRC append (0 = yes) */
-#define RL_TXCFG_LOOPBKTST0 0x00020000 /* loopback test */
-#define RL_TXCFG_LOOPBKTST1 0x00040000 /* loopback test */
-#define RL_TXCFG_IFG0 0x01000000 /* interframe gap */
-#define RL_TXCFG_IFG1 0x02000000 /* interframe gap */
+#define RL_TXCFG_LOOPBKTST 0x00060000 /* loopback test */
+#define RL_TXCFG_IFG 0x03000000 /* interframe gap */
+
+#define RL_TXDMA_16BYTES 0x00000000
+#define RL_TXDMA_32BYTES 0x00000100
+#define RL_TXDMA_64BYTES 0x00000200
+#define RL_TXDMA_128BYTES 0x00000300
+#define RL_TXDMA_256BYTES 0x00000400
+#define RL_TXDMA_512BYTES 0x00000500
+#define RL_TXDMA_1024BYTES 0x00000600
+#define RL_TXDMA_2048BYTES 0x00000700
/*
* Transmit descriptor status register bits.
@@ -167,15 +172,33 @@
#define RL_RXCFG_RX_RUNT 0x00000010
#define RL_RXCFG_RX_ERRPKT 0x00000020
#define RL_RXCFG_WRAP 0x00000080
-#define RL_RXCFG_MAXDMA (0x00000100|0x00000200|0x00000400)
-#define RL_RXCFG_BUFSZ (0x00000800|0x00001000)
-#define RL_RXCFG_FIFOTHRESH (0x00002000|0x00004000|0x00008000)
-#define RL_RXCFG_EARLYTHRESH (0x01000000|0x02000000|0x04000000)
+#define RL_RXCFG_MAXDMA 0x00000700
+#define RL_RXCFG_BURSZ 0x00001800
+#define RL_RXCFG_FIFOTHRESH 0x0000E000
+#define RL_RXCFG_EARLYTHRESH 0x07000000
+
+#define RL_RXDMA_16BYTES 0x00000000
+#define RL_RXDMA_32BYTES 0x00000100
+#define RL_RXDMA_64BYTES 0x00000200
+#define RL_RXDMA_128BYTES 0x00000300
+#define RL_RXDMA_256BYTES 0x00000400
+#define RL_RXDMA_512BYTES 0x00000500
+#define RL_RXDMA_1024BYTES 0x00000600
+#define RL_RXDMA_UNLIMITED 0x00000700
#define RL_RXBUF_8 0x00000000
#define RL_RXBUF_16 0x00000800
#define RL_RXBUF_32 0x00001000
-#define RL_RXBUF_64 (0x00001000|0x00000800)
+#define RL_RXBUF_64 0x00001800
+
+#define RL_RXFIFO_16BYTES 0x00000000
+#define RL_RXFIFO_32BYTES 0x00002000
+#define RL_RXFIFO_64BYTES 0x00004000
+#define RL_RXFIFO_128BYTES 0x00006000
+#define RL_RXFIFO_256BYTES 0x00008000
+#define RL_RXFIFO_512BYTES 0x0000A000
+#define RL_RXFIFO_1024BYTES 0x0000C000
+#define RL_RXFIFO_NOTHRESH 0x0000E000
/*
* Bits in RX status header (included with RX'ed packet
@@ -278,28 +301,34 @@
#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 0x80000 /* 256 << 11 */
-#define RL_RX_FIFOTHRESH 0x8000 /* 4 << 13 */
-#define RL_RX_MAXDMA 0x00000400
+#define RL_TX_EARLYTHRESH (256 << 11)
+#define RL_RX_FIFOTHRESH RL_RXFIFO_256BYTES
+#define RL_RX_MAXDMA RL_RXDMA_256BYTES
+#define RL_TX_MAXDMA RL_TXDMA_256BYTES
-#define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_BUF_SZ)
+#define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_MAXDMA|RL_RX_BUF_SZ)
+#define RL_TXCFG_CONFIG (RL_TXCFG_IFG|RL_TX_MAXDMA)
-struct rl_chain {
- char rl_desc; /* descriptor register idx */
- struct mbuf *rl_mbuf;
- struct rl_chain *rl_next;
-};
+#define RL_ETHER_ALIGN 2
struct rl_chain_data {
u_int16_t cur_rx;
caddr_t rl_rx_buf;
- struct rl_chain rl_tx_chain[RL_TX_LIST_CNT];
+ caddr_t rl_rx_buf_ptr;
- int rl_tx_cnt;
- struct rl_chain *rl_tx_cur;
- struct rl_chain *rl_tx_free;
+ struct mbuf *rl_tx_chain[RL_TX_LIST_CNT];
+ u_int8_t last_tx;
+ u_int8_t cur_tx;
};
+#define RL_INC(x) (x = (x + 1) % RL_TX_LIST_CNT)
+#define RL_CUR_TXADDR(x) ((x->rl_cdata.cur_tx * 4) + RL_TXADDR0)
+#define RL_CUR_TXSTAT(x) ((x->rl_cdata.cur_tx * 4) + RL_TXSTAT0)
+#define RL_CUR_TXMBUF(x) (x->rl_cdata.rl_tx_chain[x->rl_cdata.cur_tx])
+#define RL_LAST_TXADDR(x) ((x->rl_cdata.last_tx * 4) + RL_TXADDR0)
+#define RL_LAST_TXSTAT(x) ((x->rl_cdata.last_tx * 4) + RL_TXSTAT0)
+#define RL_LAST_TXMBUF(x) (x->rl_cdata.rl_tx_chain[x->rl_cdata.last_tx])
+
struct rl_type {
u_int16_t rl_vid;
u_int16_t rl_did;
@@ -335,9 +364,11 @@ struct rl_softc {
void * sc_ih; /* interrupt vectoring */
bus_space_handle_t rl_bhandle; /* bus space handle */
bus_space_tag_t rl_btag; /* bus space tag */
+#if 0
bus_dma_tag_t sc_dmat;
bus_dmamap_t sc_dma_mem;
size_t sc_dma_mapsize;
+#endif
struct arpcom arpcom; /* interface info */
struct mii_data sc_mii; /* MII information */
u_int8_t rl_type;
@@ -407,6 +438,16 @@ struct rl_softc {
#define ADDTRON_DEVICEID_8139 0x1360
/*
+ * SiS vendor ID.
+ */
+#define SIS_VENDORID 0x1039
+
+/*
+ * SiS device IDs.
+ */
+#define SIS_DEVICEID_8139 0x0900
+
+/*
* Texas Instruments PHY identifiers
*/
#define TI_PHY_VENDORID 0x4000
@@ -580,3 +621,7 @@ struct rl_softc {
#define ETHER_CRC_LEN 4
#endif
+#ifdef __alpha__
+#undef vtophys
+#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
+#endif