summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_txp.c87
-rw-r--r--sys/dev/pci/if_txpreg.h77
2 files changed, 144 insertions, 20 deletions
diff --git a/sys/dev/pci/if_txp.c b/sys/dev/pci/if_txp.c
index ef70e09659c..cafb959d8e7 100644
--- a/sys/dev/pci/if_txp.c
+++ b/sys/dev/pci/if_txp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txp.c,v 1.14 2001/04/12 20:36:06 jason Exp $ */
+/* $OpenBSD: if_txp.c,v 1.15 2001/04/12 22:40:12 jason Exp $ */
/*
* Copyright (c) 2001
@@ -119,6 +119,7 @@ void txp_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
int txp_ifmedia_upd __P((struct ifnet *));
void txp_show_descriptor __P((void *));
void txp_tx_reclaim __P((struct txp_softc *, struct txp_tx_ring *, u_int32_t));
+void txp_rxbuf_claim __P((struct txp_softc *));
struct cfattach txp_ca = {
sizeof(struct txp_softc), txp_probe, txp_attach,
@@ -531,6 +532,7 @@ txp_intr(vsc)
claimed = 1;
WRITE_REG(sc, TXP_ISR, isr);
+ txp_rxbuf_claim(sc);
txp_tx_reclaim(sc, &sc->sc_txhir, hv->hv_tx_hi_desc_read_idx);
txp_tx_reclaim(sc, &sc->sc_txlor, hv->hv_tx_lo_desc_read_idx);
@@ -545,6 +547,49 @@ txp_intr(vsc)
return (claimed);
}
+void
+txp_rxbuf_claim(sc)
+ struct txp_softc *sc;
+{
+ struct txp_hostvar *hv = sc->sc_hostvar;
+ struct txp_rxbuf_desc *rbd;
+ struct mbuf *m;
+ u_int32_t i, end;
+
+ i = TXP_OFFSET2IDX(hv->hv_rx_buf_read_idx);
+ end = TXP_OFFSET2IDX(hv->hv_rx_buf_write_idx);
+
+ while (i != end) {
+ rbd = &sc->sc_rxbufs[i];
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ printf("%s: rxbuf alloc failed\n",
+ sc->sc_dev.dv_xname);
+ break;
+ }
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ printf("%s: rxbuf cluster alloc failed\n",
+ sc->sc_dev.dv_xname);
+ break;
+ }
+
+ printf("%s: rxbuf claim\n", i);
+
+ rbd->rb_vaddrlo = (u_int32_t)m;
+ rbd->rb_vaddrhi = 0;
+ rbd->rb_paddrlo = vtophys(m->m_data);
+ rbd->rb_paddrhi = 0;
+
+ if (++i == RXBUF_ENTRIES)
+ i = 0;
+ }
+
+ hv->hv_rx_buf_write_idx = TXP_IDX2OFFSET(i);
+}
+
/*
* Reclaim mbufs and entries from a transmit ring.
*/
@@ -705,10 +750,41 @@ txp_alloc_rings(sc)
sc->sc_rspring.size = RSP_ENTRIES * sizeof(struct txp_rsp_desc);
sc->sc_rspring.lastwrite = 0;
+ /* receive buffer ring */
+ if (txp_dma_malloc(sc, sizeof(struct txp_rxbuf_desc) * RXBUF_ENTRIES,
+ &sc->sc_rxbufring_dma)) {
+ printf(": can't allocate rx buffer ring\n");
+ goto bail_rspring;
+ }
+ bzero(sc->sc_rxbufring_dma.dma_vaddr, sc->sc_rxbufring_dma.dma_siz);
+ boot->br_rxbuf_lo = sc->sc_rxbufring_dma.dma_paddr & 0xffffffff;
+ boot->br_rxbuf_hi = sc->sc_rxbufring_dma.dma_paddr >> 32;
+ boot->br_rxbuf_siz = RXBUF_ENTRIES * sizeof(struct txp_rxbuf_desc);
+ sc->sc_rxbufs = (struct txp_rxbuf_desc *)sc->sc_rxbufring_dma.dma_vaddr;
+ for (i = 0; i < RXBUF_ENTRIES; i++) {
+ struct mbuf *m;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ printf(": rxbuf allocation failed\n");
+ goto bail_rspring;
+ }
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0) {
+ printf(": rxbuf cluster allocation failed\n");
+ m_freem(m);
+ goto bail_rspring;
+ }
+ sc->sc_rxbufs[i].rb_vaddrlo = (u_int32_t)m;
+ sc->sc_rxbufs[i].rb_vaddrhi = 0;
+ sc->sc_rxbufs[i].rb_paddrlo = vtophys(m->m_data);
+ sc->sc_rxbufs[i].rb_paddrhi = 0;
+ }
+
/* zero dma */
if (txp_dma_malloc(sc, sizeof(u_int32_t), &sc->sc_zero_dma)) {
printf(": can't allocate response ring\n");
- goto bail_rspring;
+ goto bail_rxbufring;
}
bzero(sc->sc_zero_dma.dma_vaddr, sc->sc_zero_dma.dma_siz);
boot->br_zero_lo = sc->sc_zero_dma.dma_paddr & 0xffffffff;
@@ -751,6 +827,8 @@ txp_alloc_rings(sc)
bail:
txp_dma_free(sc, &sc->sc_zero_dma);
+bail_rxbufring:
+ txp_dma_free(sc, &sc->sc_rxbufring_dma);
bail_rspring:
txp_dma_free(sc, &sc->sc_rspring_dma);
bail_cmdring:
@@ -915,11 +993,12 @@ txp_init(sc)
s = splimp();
-#if 0
txp_set_filter(sc);
-#endif
txp_command(sc, TXP_CMD_TX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
+#if 0
+ txp_command(sc, TXP_CMD_RX_ENABLE, 0, 0, 0, NULL, NULL, NULL, 1);
+#endif
WRITE_REG(sc, TXP_IER, TXP_INT_RESERVED | TXP_INT_SELF |
TXP_INT_A2H_7 | TXP_INT_A2H_6 | TXP_INT_A2H_5 | TXP_INT_A2H_4 |
diff --git a/sys/dev/pci/if_txpreg.h b/sys/dev/pci/if_txpreg.h
index ffd941553f7..692cb2e7bb9 100644
--- a/sys/dev/pci/if_txpreg.h
+++ b/sys/dev/pci/if_txpreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txpreg.h,v 1.14 2001/04/12 15:01:19 jason Exp $ */
+/* $OpenBSD: if_txpreg.h,v 1.15 2001/04/12 22:40:12 jason Exp $ */
/*
* Copyright (c) 2001 Aaron Campbell <aaron@monkey.org>.
@@ -253,20 +253,62 @@ struct txp_tx_desc {
#define TX_PFLAGS_VLANPRI_M 0x00300000 /* vlan priority mask */
struct txp_rx_desc {
- u_int8_t rx_desctype:3,
- rx_rcvtype:2,
- rx_rsvdA:1,
- rx_error:1,
- rx_rsvdB:1;
-
- u_int8_t rx_num;
- u_int16_t rx_len;
- u_int32_t rx_addrlo;
- u_int32_t rx_addrhi;
- u_int32_t rx_stat;
- u_int16_t rx_filter;
- u_int16_t rx_ipsechash;
- u_int32_t rx_vlan;
+ volatile u_int8_t rx_flags; /* type/descriptor flags */
+ volatile u_int8_t rx_numdesc; /* number of descriptors */
+ volatile u_int16_t rx_len; /* frame length */
+ volatile u_int32_t rx_vaddrlo; /* virtual address, lo word */
+ volatile u_int32_t rx_vaddrhi; /* virtual address, hi word */
+ volatile u_int32_t rx_stat; /* status */
+ volatile u_int16_t rx_filter; /* filter status */
+ volatile u_int16_t rx_hash; /* hash status */
+ volatile u_int32_t rx_vlan; /* vlan tag/priority */
+};
+
+/* txp_rx_desc.rx_flags */
+#define RX_FLAGS_TYPE_M 0x07 /* type mask */
+#define RX_FLAGS_TYPE_FRAG 0x00 /* type: fragment */
+#define RX_FLAGS_TYPE_DATA 0x01 /* type: data frame */
+#define RX_FLAGS_TYPE_CMD 0x02 /* type: command frame */
+#define RX_FLAGS_TYPE_OPT 0x03 /* type: options */
+#define RX_FLAGS_TYPE_RX 0x04 /* type: command */
+#define RX_FLAGS_TYPE_RESP 0x05 /* type: response */
+#define RX_FLAGS_RCV_TYPE_M 0x18 /* rcvtype mask */
+#define RX_FLAGS_RCV_TYPE_RX 0x00 /* rcvtype: receive */
+#define RX_FLAGS_RCV_TYPE_RSP 0x08 /* rcvtype: response */
+#define RX_FLAGS_ERROR 0x40 /* error in packet */
+
+/* txp_rx_desc.rx_stat (if rx_flags & RX_FLAGS_ERROR bit set) */
+#define RX_ERROR_ADAPTER 0x00000000 /* adapter internal error */
+#define RX_ERROR_FIFO 0x00000001 /* fifo underrun */
+#define RX_ERROR_BADSSD 0x00000002 /* bad ssd */
+#define RX_ERROR_RUNT 0x00000003 /* runt packet */
+#define RX_ERROR_CRC 0x00000004 /* bad crc */
+#define RX_ERROR_OVERSIZE 0x00000005 /* oversized packet */
+#define RX_ERROR_ALIGN 0x00000006 /* alignment error */
+#define RX_ERROR_DRIBBLE 0x00000007 /* dribble bit */
+
+/* txp_rx_desc.rx_stat (if rx_flags & RX_FLAGS_ERROR bit set) */
+#define RX_STAT_PROTO_M 0x00000003 /* protocol mask */
+#define RX_STAT_PROTO_UK 0x00000000 /* unknown protocol */
+#define RX_STAT_PROTO_IPX 0x00000001 /* IPX */
+#define RX_STAT_PROTO_IP 0x00000002 /* IP */
+#define RX_STAT_PROTO_RSV 0x00000003 /* reserved */
+#define RX_STAT_VLAN 0x00000004 /* vlan tag (in rxd) */
+#define RX_STAT_IPFRAG 0x00000008 /* fragment, ipsec not done */
+#define RX_STAT_IPSEC 0x00000010 /* ipsec decoded packet */
+#define RX_STAT_IPCKSUMBAD 0x00000020 /* ip checksum failed */
+#define RX_STAT_TCPCKSUMBAD 0x00000040 /* tcp checksum failed */
+#define RX_STAT_UDPCKSUMBAD 0x00000080 /* udp checksum failed */
+#define RX_STAT_IPCKSUMGOOD 0x00000100 /* ip checksum succeeded */
+#define RX_STAT_TCPCKSUMGOOD 0x00000200 /* tcp checksum succeeded */
+#define RX_STAT_UDPCKSUMGOOD 0x00000400 /* udp checksum succeeded */
+
+
+struct txp_rxbuf_desc {
+ volatile u_int32_t rb_paddrlo;
+ volatile u_int32_t rb_paddrhi;
+ volatile u_int32_t rb_vaddrlo;
+ volatile u_int32_t rb_vaddrhi;
};
struct txp_cmd_desc {
@@ -451,7 +493,8 @@ struct txp_hostvar {
#define STAT_HALTED 0x00000014
#define TX_ENTRIES 256
-#define RX_ENTRIES 256
+#define RX_ENTRIES 128
+#define RXBUF_ENTRIES 256
#define CMD_ENTRIES 32
#define RSP_ENTRIES 32
@@ -511,12 +554,14 @@ struct txp_softc {
struct timeout sc_tick_tmo;
struct ifmedia sc_ifmedia;
struct txp_tx_ring sc_txhir, sc_txlor;
+ struct txp_rxbuf_desc *sc_rxbufs;
u_int16_t sc_xcvr;
u_int16_t sc_seq;
struct txp_dma_alloc sc_boot_dma, sc_host_dma, sc_zero_dma;
struct txp_dma_alloc sc_rxhiring_dma, sc_rxloring_dma;
struct txp_dma_alloc sc_txhiring_dma, sc_txloring_dma;
struct txp_dma_alloc sc_cmdring_dma, sc_rspring_dma;
+ struct txp_dma_alloc sc_rxbufring_dma;
int sc_cold;
};