diff options
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_mx.c | 176 | ||||
-rw-r--r-- | sys/dev/pci/if_mxreg.h | 65 | ||||
-rw-r--r-- | sys/dev/pci/if_pn.c | 3 |
3 files changed, 166 insertions, 78 deletions
diff --git a/sys/dev/pci/if_mx.c b/sys/dev/pci/if_mx.c index 0e8e0029cee..64a342eb17d 100644 --- a/sys/dev/pci/if_mx.c +++ b/sys/dev/pci/if_mx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mx.c,v 1.5 1999/03/03 22:51:46 jason Exp $ */ +/* $OpenBSD: if_mx.c,v 1.6 1999/06/28 20:51:09 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_mx.c,v 1.11 1999/02/01 21:25:51 wpaul Exp $ + * $FreeBSD: if_mx.c,v 1.19 1999/06/16 16:27:30 wpaul Exp $ */ /* @@ -123,8 +123,8 @@ static void mx_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); static void mx_delay __P((struct mx_softc *)); static void mx_eeprom_idle __P((struct mx_softc *)); -static void mx_eeprom_putbyte __P((struct mx_softc *, u_int8_t)); -static void mx_eeprom_getword __P((struct mx_softc *, u_int8_t, u_int16_t *)); +static void mx_eeprom_putbyte __P((struct mx_softc *, int)); +static void mx_eeprom_getword __P((struct mx_softc *, int, u_int16_t *)); static void mx_read_eeprom __P((struct mx_softc *, caddr_t, int, int, int)); @@ -135,7 +135,7 @@ static void mx_mii_send __P((struct mx_softc *, u_int32_t, int)); static int mx_mii_readreg __P((struct mx_softc *, struct mx_mii_frame *)); static int mx_mii_writereg __P((struct mx_softc *, struct mx_mii_frame *)); static u_int16_t mx_phy_readreg __P((struct mx_softc *, int)); -static void mx_phy_writereg __P((struct mx_softc *, u_int16_t, u_int16_t)); +static void mx_phy_writereg __P((struct mx_softc *, int, int)); static void mx_autoneg_xmit __P((struct mx_softc *)); static void mx_autoneg_mii __P((struct mx_softc *, int, int)); @@ -143,8 +143,8 @@ static void mx_autoneg __P((struct mx_softc *, int, int)); static void mx_setmode_mii __P((struct mx_softc *, int)); static void mx_setmode __P((struct mx_softc *, int, int)); static void mx_getmode_mii __P((struct mx_softc *)); -static void mx_setcfg __P((struct mx_softc *, u_int16_t)); -static u_int32_t mx_calchash __P((u_int8_t *)); +static void mx_setcfg __P((struct mx_softc *, int)); +static u_int32_t mx_calchash __P((struct mx_softc *, caddr_t)); static void mx_setfilt __P((struct mx_softc *)); static void mx_reset __P((struct mx_softc *)); static int mx_list_rx_init __P((struct mx_softc *)); @@ -210,7 +210,7 @@ static void mx_eeprom_idle(sc) */ static void mx_eeprom_putbyte(sc, addr) struct mx_softc *sc; - u_int8_t addr; + int addr; { register int d, i; @@ -240,7 +240,7 @@ static void mx_eeprom_putbyte(sc, addr) */ static void mx_eeprom_getword(sc, addr, dest) struct mx_softc *sc; - u_int8_t addr; + int addr; u_int16_t *dest; { register int i; @@ -511,8 +511,8 @@ static u_int16_t mx_phy_readreg(sc, reg) static void mx_phy_writereg(sc, reg, data) struct mx_softc *sc; - u_int16_t reg; - u_int16_t data; + int reg; + int data; { struct mx_mii_frame frame; u_int32_t cfg; @@ -531,11 +531,13 @@ static void mx_phy_writereg(sc, reg, data) return; } -#define MX_POLY 0xEDB88320 -#define MX_BITS 9 +#define MX_POLY 0xEDB88320 +#define MX_BITS 9 +#define MX_BITS_PNIC_II 7 -static u_int32_t mx_calchash(addr) - u_int8_t *addr; +static u_int32_t mx_calchash(sc, addr) + struct mx_softc *sc; + caddr_t addr; { u_int32_t idx, bit, data, crc; @@ -547,6 +549,10 @@ static u_int32_t mx_calchash(addr) crc = (crc >> 1) ^ (((crc ^ data) & 1) ? MX_POLY : 0); } + /* The hash table on the PNIC II is only 128 bits wide. */ + if (sc->mx_info.mx_vid == PN_VENDORID) + return (crc & ((1 << MX_BITS_PNIC_II) - 1)); + return (crc & ((1 << MX_BITS) - 1)); } @@ -1076,12 +1082,12 @@ void mx_setfilt(sc) ETHER_FIRST_MULTI(step, ac, enm); while (enm != NULL) { - h = mx_calchash(enm->enm_addrlo); + h = mx_calchash(sc, (caddr_t)&enm->enm_addrlo); ETHER_NEXT_MULTI(step, enm); } if (ifp->if_flags & IFF_BROADCAST) { - h = mx_calchash(etherbroadcastaddr); + h = mx_calchash(sc, (caddr_t)ðerbroadcastaddr); sp[h >> 4] |= 1 << (h & 0xF); } @@ -1118,7 +1124,7 @@ void mx_setfilt(sc) */ static void mx_setcfg(sc, bmcr) struct mx_softc *sc; - u_int16_t bmcr; + int bmcr; { int i, restart = 0; @@ -1224,7 +1230,7 @@ static int mx_list_rx_init(sc) for (i = 0; i < MX_RX_LIST_CNT; i++) { cd->mx_rx_chain[i].mx_ptr = - (volatile struct mx_desc *)&ld->mx_rx_list[i]; + (struct mx_desc *)&ld->mx_rx_list[i]; if (mx_newbuf(sc, &cd->mx_rx_chain[i]) == ENOBUFS) return(ENOBUFS); if (i == (MX_RX_LIST_CNT - 1)) { @@ -1339,10 +1345,43 @@ static void mx_rxeof(sc) continue; } +#ifdef __alpha__ + /* + * Deal with alignment on alpha. + */ + MGETHDR(m0, M_DONTWAIT, MT_DATA); + if (m0 == NULL) { + ifp->if_ierrors++; + cur_rx->mx_ptr->mx_status = MX_RXSTAT; + cur_rx->mx_ptr->mx_ctl = + MX_RXCTL_RLINK | (MCLBYTES - 1); + bzero((char *)mtod(cur_rx->mx_mbuf, char *), MCLBYTES); + continue; + } + + m0->m_data += 2; + if (total_len <= (MHLEN - 2)) { + bcopy(mtod(m, caddr_t), mtod(m0, caddr_t), total_len); + m = m0; + m->m_pkthdr.len = m->m_len = total_len; + } else { + bcopy(mtod(m, caddr_t), mtod(m0, caddr_t), + (MHLEN - 2)); + m->m_len = total_len - (MHLEN - 2); + m->m_data += (MHLEN - 2); + m0->m_next = m; + m0->m_len = (MHLEN - 2); + m = m0; + m->m_pkthdr.len = total_len; + } +#else + m->m_pkthdr.len = m->m_len = total_len; +#endif + ifp->if_ipackets++; eh = mtod(m, struct ether_header *); m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = total_len; + #if NBPFILTER > 0 /* * Handle BPF listeners. Let the BPF user see the packet, but @@ -1403,7 +1442,7 @@ static void mx_txeof(sc) cur_tx = sc->mx_cdata.mx_tx_head; txstat = MX_TXSTATUS(cur_tx); - if ((txstat & MX_TXSTAT_OWN) || txstat == MX_UNSENT) + if (txstat & MX_TXSTAT_OWN) break; if (txstat & MX_TXSTAT_ERRSUM) { @@ -1454,12 +1493,6 @@ static void mx_txeoc(sc) else mx_autoneg(sc, MX_FLAG_DELAYTIMEO, 1); } - } else { - if (MX_TXOWN(sc->mx_cdata.mx_tx_head) == MX_UNSENT) { - MX_TXOWN(sc->mx_cdata.mx_tx_head) = MX_TXSTAT_OWN; - ifp->if_timer = 5; - CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); - } } return; @@ -1551,7 +1584,7 @@ static int mx_encap(sc, c, m_head) struct mbuf *m_head; { int frag = 0; - volatile struct mx_desc *f = NULL; + struct mx_desc *f = NULL; int total_len; struct mbuf *m; @@ -1628,7 +1661,7 @@ static int mx_encap(sc, c, m_head) c->mx_mbuf = m_head; c->mx_lastdesc = frag - 1; - MX_TXCTL(c) |= MX_TXCTL_LASTFRAG; + MX_TXCTL(c) |= MX_TXCTL_LASTFRAG|MX_TXCTL_FINT; MX_TXNEXT(c) = vtophys(&c->mx_nextdesc->mx_ptr->mx_frag[0]); return(0); } @@ -1654,6 +1687,9 @@ static void mx_start(ifp) return; } + if (ifp->if_flags & IFF_OACTIVE) + return; + /* * Check for an available queue slot. If there are none, * punt. @@ -1687,6 +1723,8 @@ static void mx_start(ifp) if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, cur_tx->mx_mbuf); #endif + MX_TXOWN(cur_tx) = MX_TXSTAT_OWN; + CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); } /* @@ -1695,23 +1733,10 @@ static void mx_start(ifp) if (cur_tx == NULL) return; - /* - * Place the request for the upload interrupt - * in the last descriptor in the chain. This way, if - * we're chaining several packets at once, we'll only - * get an interupt once for the whole chain rather than - * once for each packet. - */ - MX_TXCTL(cur_tx) |= MX_TXCTL_FINT; sc->mx_cdata.mx_tx_tail = cur_tx; - if (sc->mx_cdata.mx_tx_head == NULL) { + if (sc->mx_cdata.mx_tx_head == NULL) sc->mx_cdata.mx_tx_head = start_tx; - MX_TXOWN(start_tx) = MX_TXSTAT_OWN; - CSR_WRITE_4(sc, MX_TXSTART, 0xFFFFFFFF); - } else { - MX_TXOWN(start_tx) = MX_UNSENT; - } /* * Set a timeout in case the chip goes out to lunch. @@ -1746,11 +1771,27 @@ static void mx_init(xsc) /* * Set cache alignment and burst length. */ - CSR_WRITE_4(sc, MX_BUSCTL, MX_BUSCTL_CONFIG); + CSR_WRITE_4(sc, MX_BUSCTL, MX_BUSCTL_MUSTBEONE|MX_BUSCTL_ARBITRATION); + MX_SETBIT(sc, MX_BUSCTL, MX_BURSTLEN_16LONG); + switch(sc->mx_cachesize) { + case 32: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_32LONG); + break; + case 16: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_16LONG); + break; + case 8: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_8LONG); + break; + case 0: + default: + MX_SETBIT(sc, MX_BUSCTL, MX_CACHEALIGN_NONE); + break; + } MX_SETBIT(sc, MX_NETCFG, MX_NETCFG_NO_RXCRC); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_HEARTBEAT); - MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_STORENFWD); + MX_SETBIT(sc, MX_NETCFG, MX_NETCFG_STORENFWD); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_TX_BACKOFF); /* @@ -1774,7 +1815,7 @@ static void mx_init(xsc) mx_setmode(sc, sc->ifmedia.ifm_media, 0); MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_TX_THRESH); - MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_SPEEDSEL); + /*MX_CLRBIT(sc, MX_NETCFG, MX_NETCFG_SPEEDSEL);*/ if (IFM_SUBTYPE(sc->ifmedia.ifm_media) == IFM_10_T) MX_SETBIT(sc, MX_NETCFG, MX_TXTHRESH_160BYTES); @@ -2080,6 +2121,20 @@ mx_probe(parent, match, aux) } } + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_COMPEX) { + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_COMPEX_98713: + return (1); + } + } + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON) { + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_LITEON_PNICII: + return (1); + } + } + return (0); } @@ -2155,17 +2210,24 @@ mx_attach(parent, self, aux) } printf(": %s", intrstr); - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_MACRONIX) { - if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713) { - if (PCI_REVISION(pa->pa_class) < MX_REVISION_98713A) - sc->mx_type = MX_TYPE_98713; - else - sc->mx_type = MX_TYPE_98713A; - } - if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98715) { - sc->mx_type = MX_TYPE_987x5; - } - } + if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713 && + PCI_REVISION(pa->pa_class) < MX_REVISION_98713A) + sc->mx_type = MX_TYPE_98713; + else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_COMPEX_98713 && + PCI_REVISION(pa->pa_class) < MX_REVISION_98713A) + sc->mx_type = MX_TYPE_98713; + else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713 && + PCI_REVISION(pa->pa_class) >= MX_REVISION_98713A) + sc->mx_type = MX_TYPE_98713A; + else + sc->mx_type = MX_TYPE_987x5; + + /* Save the cache line size. */ + sc->mx_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, + MX_PCI_CACHELEN) & 0xFF; + + sc->mx_info.mx_vid = PCI_VENDOR(pa->pa_id); + sc->mx_info.mx_did = PCI_PRODUCT(pa->pa_id); mx_reset(sc); diff --git a/sys/dev/pci/if_mxreg.h b/sys/dev/pci/if_mxreg.h index fa758f41a70..4bbdda4ab7b 100644 --- a/sys/dev/pci/if_mxreg.h +++ b/sys/dev/pci/if_mxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mxreg.h,v 1.2 1999/03/03 22:51:48 jason Exp $ */ +/* $OpenBSD: if_mxreg.h,v 1.3 1999/06/28 20:51:11 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_mxreg.h,v 1.2 1998/12/04 21:48:12 wpaul Exp $ + * $FreeBSD: if_mxreg.h,v 1.7 1999/05/28 18:43:14 wpaul Exp $ */ /* @@ -95,7 +95,8 @@ #define MX_BUSCTL_BUF_BIGENDIAN 0x00000080 #define MX_BUSCTL_BURSTLEN 0x00003F00 #define MX_BUSCTL_CACHEALIGN 0x0000C000 -#define MX_BUSCTL_XMITPOLL 0x00060000 +#define MX_BUSCTL_TXPOLL 0x000E0000 +#define MX_BUSCTL_MUSTBEONE 0x04000000 #define MX_SKIPLEN_1LONG 0x00000004 #define MX_SKIPLEN_2LONG 0x00000008 @@ -103,6 +104,7 @@ #define MX_SKIPLEN_4LONG 0x00000020 #define MX_SKIPLEN_5LONG 0x00000040 +#define MX_CACHEALIGN_NONE 0x00000000 #define MX_CACHEALIGN_8LONG 0x00004000 #define MX_CACHEALIGN_16LONG 0x00008000 #define MX_CACHEALIGN_32LONG 0x0000C000 @@ -334,10 +336,10 @@ */ struct mx_desc { - volatile u_int32_t mx_status; - volatile u_int32_t mx_ctl; - volatile u_int32_t mx_ptr1; - volatile u_int32_t mx_ptr2; + u_int32_t mx_status; + u_int32_t mx_ctl; + u_int32_t mx_ptr1; + u_int32_t mx_ptr2; }; #define mx_data mx_ptr1 @@ -408,7 +410,7 @@ struct mx_desc { * back to back. */ struct mx_txdesc { - volatile struct mx_desc mx_frag[MX_MAXFRAGS]; + struct mx_desc mx_frag[MX_MAXFRAGS]; }; #define MX_TXNEXT(x) x->mx_ptr->mx_frag[x->mx_lastdesc].mx_next @@ -418,22 +420,20 @@ struct mx_txdesc { #define MX_TXOWN(x) x->mx_ptr->mx_frag[0].mx_status -#define MX_UNSENT 0x12341234 - struct mx_list_data { - volatile struct mx_desc mx_rx_list[MX_RX_LIST_CNT]; - volatile struct mx_txdesc mx_tx_list[MX_TX_LIST_CNT]; + struct mx_desc mx_rx_list[MX_RX_LIST_CNT]; + struct mx_txdesc mx_tx_list[MX_TX_LIST_CNT]; }; struct mx_chain { - volatile struct mx_txdesc *mx_ptr; - struct mbuf *mx_mbuf; - struct mx_chain *mx_nextdesc; - u_int8_t mx_lastdesc; + struct mx_txdesc *mx_ptr; + struct mbuf *mx_mbuf; + struct mx_chain *mx_nextdesc; + u_int8_t mx_lastdesc; }; struct mx_chain_onefrag { - volatile struct mx_desc *mx_ptr; + struct mx_desc *mx_ptr; struct mbuf *mx_mbuf; struct mx_chain_onefrag *mx_nextdesc; }; @@ -486,7 +486,7 @@ struct mx_softc { struct ifmedia ifmedia; /* media info */ bus_space_handle_t mx_bhandle; /* bus space handle */ bus_space_tag_t mx_btag; /* bus space tag */ - struct mx_type *mx_info; /* Macronix adapter info */ + struct mx_type mx_info; /* Macronix adapter info */ u_int8_t mx_hasmii; /* whether we have mii */ u_int8_t mx_unit; /* interface number */ u_int8_t mx_type; @@ -494,7 +494,7 @@ struct mx_softc { u_int8_t mx_tx_pend; /* TX pending */ u_int8_t mx_want_auto; u_int8_t mx_autoneg; - u_int8_t mx_singlebuf; + u_int8_t mx_cachesize; caddr_t mx_ldata_ptr; struct mx_list_data *mx_ldata; struct mx_chain_data mx_cdata; @@ -533,6 +533,27 @@ struct mx_softc { #define MX_DEVICEID_987x5 0x0531 /* + * Compex PCI vendor ID + */ +#define CP_VENDORID 0x11F6 + +/* + * Compex PMAC PCI device IDs. + */ +#define CP_DEVICEID_98713 0x9881 + +/* + * Lite-On PNIC PCI vendor ID + */ +#define PN_VENDORID 0x11AD + +/* + * Lite-On PNIC II device ID. Note: this is actually a Macronix 98715A + * with wake on lan/magic packet support. + */ +#define PN_DEVICEID_PNIC_II 0xc115 + +/* * Texas Instruments PHY identifiers */ #define TI_PHY_VENDORID 0x4000 @@ -575,6 +596,7 @@ struct mx_softc { #define MX_PCI_STATUS 0x06 #define MX_PCI_REVID 0x08 #define MX_PCI_CLASSCODE 0x09 +#define MX_PCI_CACHELEN 0x0C #define MX_PCI_LATENCY_TIMER 0x0D #define MX_PCI_HEADER_TYPE 0x0E #define MX_PCI_LOIO 0x10 @@ -700,6 +722,11 @@ struct mx_softc { #define PHY_BMSR_JABBER 0x0002 #define PHY_BMSR_EXTENDED 0x0001 +#ifdef __alpha__ +#undef vtophys +#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) +#endif + #ifndef ETHER_CRC_LEN #define ETHER_CRC_LEN 4 #endif diff --git a/sys/dev/pci/if_pn.c b/sys/dev/pci/if_pn.c index 9ef43fcc22f..cc958eb0da1 100644 --- a/sys/dev/pci/if_pn.c +++ b/sys/dev/pci/if_pn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pn.c,v 1.4 1999/03/03 22:51:48 jason Exp $ */ +/* $OpenBSD: if_pn.c,v 1.5 1999/06/28 20:51:10 jason Exp $ */ /* * Copyright (c) 1997, 1998 @@ -2073,7 +2073,6 @@ pn_probe(parent, match, aux) if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON) { switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_LITEON_PNIC: - case PCI_PRODUCT_LITEON_PNICII: return (1); } } |