diff options
-rw-r--r-- | sys/dev/pci/if_txp.c | 87 | ||||
-rw-r--r-- | sys/dev/pci/if_txpreg.h | 77 |
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; }; |