diff options
Diffstat (limited to 'sys/arch/socppc/dev')
-rw-r--r-- | sys/arch/socppc/dev/com_obio.c | 89 | ||||
-rw-r--r-- | sys/arch/socppc/dev/ehci_obio.c | 135 | ||||
-rw-r--r-- | sys/arch/socppc/dev/if_tsec.c | 1335 | ||||
-rw-r--r-- | sys/arch/socppc/dev/ipic.c | 410 | ||||
-rw-r--r-- | sys/arch/socppc/dev/obio.c | 101 | ||||
-rw-r--r-- | sys/arch/socppc/dev/pciide_machdep.c | 40 | ||||
-rw-r--r-- | sys/arch/socppc/dev/sociic.c | 299 | ||||
-rw-r--r-- | sys/arch/socppc/dev/socpcic.c | 441 | ||||
-rw-r--r-- | sys/arch/socppc/dev/wdc_mainbus.c | 178 |
9 files changed, 0 insertions, 3028 deletions
diff --git a/sys/arch/socppc/dev/com_obio.c b/sys/arch/socppc/dev/com_obio.c deleted file mode 100644 index 9cf656754be..00000000000 --- a/sys/arch/socppc/dev/com_obio.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $OpenBSD: com_obio.c,v 1.3 2009/09/06 20:09:34 kettenis Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/tty.h> - -#include <machine/autoconf.h> - -#include <dev/ofw/openfirm.h> - -#include <dev/ic/comreg.h> -#include <dev/ic/comvar.h> - -int com_obio_match(struct device *, void *, void *); -void com_obio_attach(struct device *, struct device *, void *); - -struct cfattach com_obio_ca = { - sizeof(struct com_softc), com_obio_match, com_obio_attach -}; - -struct cfdriver com_obio_cd = { - NULL, "com", DV_DULL -}; - -int -com_obio_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "serial") != 0) - return (0); - - if (OF_getprop(oa->oa_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "ns16550") != 0) - return (0); - - return (1); -} - -void -com_obio_attach(struct device *parent, struct device *self, void *aux) -{ - struct com_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - int freq; - - if (OF_getprop(oa->oa_node, "clock-frequency", &freq, - sizeof(freq))!= sizeof(freq)) { - printf(": unknown clock frequency\n"); - return; - } - - sc->sc_iot = oa->oa_iot; - sc->sc_iobase = oa->oa_offset; - sc->sc_frequency = freq; - - if (sc->sc_iobase != comconsaddr) { - if (bus_space_map(sc->sc_iot, sc->sc_iobase, - COM_NPORTS, 0, &sc->sc_ioh)) { - printf(": can't map registers\n"); - return; - } - } else - sc->sc_ioh = comconsioh; - - com_attach_subr(sc); - - intr_establish(oa->oa_ivec, IST_LEVEL, IPL_TTY, comintr, - sc, sc->sc_dev.dv_xname); -} diff --git a/sys/arch/socppc/dev/ehci_obio.c b/sys/arch/socppc/dev/ehci_obio.c deleted file mode 100644 index c8ff01859a7..00000000000 --- a/sys/arch/socppc/dev/ehci_obio.c +++ /dev/null @@ -1,135 +0,0 @@ -/* $OpenBSD: ehci_obio.c,v 1.5 2015/01/24 20:59:42 kettenis Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/rwlock.h> -#include <sys/timeout.h> - -#include <machine/autoconf.h> - -#include <dev/ofw/openfirm.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_mem.h> - -#include <dev/usb/ehcireg.h> -#include <dev/usb/ehcivar.h> - -#include <dev/pci/pcidevs.h> - -#define USB_EHCI_OFFSET 0x00100 -#define USB_SNOOP1 0x00400 - USB_EHCI_OFFSET -#define USB_SNOOP_2GB 0x1e000000 -#define USB_CONTROL 0x00500 - USB_EHCI_OFFSET -#define USB_CONTROL_USB_EN 0x04000000 - -int ehci_obio_match(struct device *, void *, void *); -void ehci_obio_attach(struct device *, struct device *, void *); - -struct cfattach ehci_obio_ca = { - sizeof(struct ehci_softc), ehci_obio_match, ehci_obio_attach -}; - -struct cfdriver ehci_obio_cd = { - NULL, "ehci", DV_DULL -}; - -struct powerpc_bus_dma_tag ehci_bus_dma_tag = { - NULL, - _dmamap_create, - _dmamap_destroy, - _dmamap_load, - _dmamap_load_mbuf, - _dmamap_load_uio, - _dmamap_load_raw, - _dmamap_unload, - _dmamap_sync, - _dmamem_alloc, - _dmamem_alloc_range, - _dmamem_free, - _dmamem_map, - _dmamem_unmap, - _dmamem_mmap -}; - -int -ehci_obio_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "fsl-usb2-mph") != 0) - return (0); - - return (1); -} - -void -ehci_obio_attach(struct device *parent, struct device *self, void *aux) -{ - struct ehci_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - usbd_status r; - int s; - - sc->iot = oa->oa_iot; - sc->sc_size = 1028; - if (bus_space_map(sc->iot, oa->oa_offset + USB_EHCI_OFFSET, - sc->sc_size, 0, &sc->ioh)) { - printf(": can't map registers\n"); - return; - } - - sc->sc_id_vendor = PCI_VENDOR_FREESCALE; - strlcpy(sc->sc_vendor, "Freescale", sizeof sc->sc_vendor); - - sc->sc_bus.dmatag = &ehci_bus_dma_tag; - - bus_space_write_4(sc->iot, sc->ioh, USB_CONTROL, USB_CONTROL_USB_EN); - bus_space_write_4(sc->iot, sc->ioh, USB_SNOOP1, USB_SNOOP_2GB); - - s = splhardusb(); - sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); - EOWRITE2(sc, EHCI_USBINTR, 0); - - intr_establish(oa->oa_ivec, IST_LEVEL, IPL_USB, ehci_intr, sc, - sc->sc_bus.bdev.dv_xname); - - r = ehci_init(sc); - if (r != USBD_NORMAL_COMPLETION) { - printf(": init failed, error=%d\n", r); - goto unmap_ret; - } - splx(s); - - printf("\n"); - - /* Attach usb device. */ - config_found(self, &sc->sc_bus, usbctlprint); - - return; - -unmap_ret: - bus_space_unmap(sc->iot, sc->ioh, sc->sc_size); - splx(s); -} diff --git a/sys/arch/socppc/dev/if_tsec.c b/sys/arch/socppc/dev/if_tsec.c deleted file mode 100644 index 832345ade8d..00000000000 --- a/sys/arch/socppc/dev/if_tsec.c +++ /dev/null @@ -1,1335 +0,0 @@ -/* $OpenBSD: if_tsec.c,v 1.44 2017/01/22 10:17:37 dlg Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Driver for the TSEC interface on the MPC8349E processors. - */ - -#include "bpfilter.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/queue.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/timeout.h> - -#include <machine/autoconf.h> -#include <machine/bus.h> - -#include <net/if.h> -#include <net/if_media.h> - -#include <dev/ofw/openfirm.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#if NBPFILTER > 0 -#include <net/bpf.h> -#endif - -#include <netinet/in.h> -#include <netinet/if_ether.h> - -extern void myetheraddr(u_char *); - -/* - * TSEC registers. - */ - -#define TSEC_IEVENT 0x010 -#define TSEC_IEVENT_BABR 0x80000000 -#define TSEC_IEVENT_RXC 0x40000000 -#define TSEC_IEVENT_BSY 0x20000000 -#define TSEC_IEVENT_EBERR 0x10000000 -#define TSEC_IEVENT_MSRO 0x04000000 -#define TSEC_IEVENT_GTSC 0x02000000 -#define TSEC_IEVENT_BABT 0x01000000 -#define TSEC_IEVENT_TXC 0x00800000 -#define TSEC_IEVENT_TXE 0x00400000 -#define TSEC_IEVENT_TXB 0x00200000 -#define TSEC_IEVENT_TXF 0x00100000 -#define TSEC_IEVENT_LC 0x00040000 -#define TSEC_IEVENT_CRL 0x00020000 -#define TSEC_IEVENT_DXA TSEC_IEVENT_CRL -#define TSEC_IEVENT_XFUN 0x00010000 -#define TSEC_IEVENT_RXB 0x00008000 -#define TSEC_IEVENT_MMRD 0x00000400 -#define TSEC_IEVENT_MMWR 0x00000200 -#define TSEC_IEVENT_GRSC 0x00000100 -#define TSEC_IEVENT_RXF 0x00000080 -#define TSEC_IEVENT_FMT "\020" "\040BABR" "\037RXC" "\036BSY" \ - "\035EBERR" "\033MSRO" "\032GTSC" "\031BABT" "\030TXC" "\027TXE" \ - "\026TXB" "\025TXF" "\023LC" "\022CRL/XDA" "\021XFUN" "\020RXB" \ - "\013MMRD" "\012MMRW" "\011GRSC" "\010RXF" -#define TSEC_IMASK 0x014 -#define TSEC_IMASK_BREN 0x80000000 -#define TSEC_IMASK_RXCEN 0x40000000 -#define TSEC_IMASK_BSYEN 0x20000000 -#define TSEC_IMASK_EBERREN 0x10000000 -#define TSEC_IMASK_MSROEN 0x04000000 -#define TSEC_IMASK_GTSCEN 0x02000000 -#define TSEC_IMASK_BTEN 0x01000000 -#define TSEC_IMASK_TXCEN 0x00800000 -#define TSEC_IMASK_TXEEN 0x00400000 -#define TSEC_IMASK_TXBEN 0x00200000 -#define TSEC_IMASK_TXFEN 0x00100000 -#define TSEC_IMASK_LCEN 0x00040000 -#define TSEC_IMASK_CRLEN 0x00020000 -#define TSEC_IMASK_DXAEN TSEC_IMASK_CRLEN -#define TSEC_IMASK_XFUNEN 0x00010000 -#define TSEC_IMASK_RXBEN 0x00008000 -#define TSEC_IMASK_MMRD 0x00000400 -#define TSEC_IMASK_MMWR 0x00000200 -#define TSEC_IMASK_GRSCEN 0x00000100 -#define TSEC_IMASK_RXFEN 0x00000080 -#define TSEC_EDIS 0x018 -#define TSEC_ECNTRL 0x020 -#define TSEC_ECNTRL_R100M 0x00000008 /* RGMII 100 mode */ -#define TSEC_MINFLR 0x024 -#define TSEC_PTV 0x028 -#define TSEC_DMACTRL 0x02c -#define TSEC_DMACTRL_TDSEN 0x00000080 -#define TSEC_DMACTRL_TBDSEN 0x00000040 -#define TSEC_DMACTRL_GRS 0x00000010 /* Graceful receive stop */ -#define TSEC_DMACTRL_GTS 0x00000008 /* Graceful transmit stop */ -#define TSEC_DMACTRL_WWR 0x00000002 -#define TSEC_DMACTRL_WOP 0x00000001 -#define TSEC_TBIPA 0x030 - -#define TSEC_TCTRL 0x100 -#define TSEC_TSTAT 0x104 -#define TSEC_TSTAT_THLT 0x80000000 -#define TSEC_TBPTR 0x184 -#define TSEC_TBASE 0x204 - -#define TSEC_RCTRL 0x300 -#define TSEC_RCTRL_PROM 0x00000008 -#define TSEC_RSTAT 0x304 -#define TSEC_RSTAT_QHLT 0x00800000 -#define TSEC_MRBLR 0x340 -#define TSEC_RBPTR 0x384 -#define TSEC_RBASE 0x404 - -#define TSEC_MACCFG1 0x500 -#define TSEC_MACCFG1_TXEN 0x00000001 -#define TSEC_MACCFG1_RXEN 0x00000004 -#define TSEC_MACCFG1_RESET 0x80000000 -#define TSEC_MACCFG2 0x504 -#define TSEC_MACCFG2_IF_MODE 0x00000300 /* I/F mode */ -#define TSEC_MACCFG2_IF_MII 0x00000100 /* I/F mode */ -#define TSEC_MACCFG2_IF_GMII 0x00000200 /* I/F mode */ -#define TSEC_MACCFG2_PAD 0x00000004 -#define TSEC_MACCFG2_CRC 0x00000002 -#define TSEC_MACCFG2_FDX 0x00000001 /* Full duplex */ -#define TSEC_MIIMCFG 0x520 -#define TSEC_MIIMCFG_RESET 0x80000000 /* Reset */ -#define TSEC_MIIMCOM 0x524 -#define TSEC_MIIMCOM_READ 0x00000001 /* Read cycle */ -#define TSEC_MIIMCOM_SCAN 0x00000002 /* Scan cycle */ -#define TSEC_MIIMADD 0x528 -#define TSEC_MIIMCON 0x52c -#define TSEC_MIIMSTAT 0x530 -#define TSEC_MIIMIND 0x534 -#define TSEC_MIIMIND_BUSY 0x00000001 /* Busy */ -#define TSEC_MIIMIND_SCAN 0x00000002 /* Scan in progress */ -#define TSEC_MIIMIND_NOTVALID 0x00000004 /* Not valid */ -#define TSEC_MACSTNADDR1 0x540 -#define TSEC_MACSTNADDR2 0x544 -#define TSEC_IADDR0 0x800 -#define TSEC_IADDR1 0x804 -#define TSEC_IADDR2 0x818 -#define TSEC_IADDR3 0x81c -#define TSEC_IADDR4 0x810 -#define TSEC_IADDR5 0x814 -#define TSEC_IADDR6 0x818 -#define TSEC_IADDR7 0x81c -#define TSEC_GADDR0 0x880 -#define TSEC_GADDR1 0x884 -#define TSEC_GADDR2 0x888 -#define TSEC_GADDR3 0x88c -#define TSEC_GADDR4 0x890 -#define TSEC_GADDR5 0x894 -#define TSEC_GADDR6 0x898 -#define TSEC_GADDR7 0x89c - -#define TSEC_ATTR 0xbf8 -#define TSEC_ATTR_RDSEN 0x00000080 -#define TSEC_ATTR_RBDSEN 0x00000040 - -/* - * TSEC descriptors. - */ - -struct tsec_desc { - uint16_t td_status; - uint16_t td_len; - uint32_t td_addr; -}; - -/* Tx status bits. */ -#define TSEC_TX_TXTRUNC 0x0001 /* TX truncation */ -#define TSEC_TX_UN 0x0002 /* Underrun */ -#define TSEC_TX_RC 0x003c /* Retry count */ -#define TSEC_TX_RL 0x0040 /* Retransmission limit */ -#define TSEC_TX_HFE 0x0080 /* Huge frame enable/late collision */ -#define TSEC_TX_LC TSEC_TX_HFE -#define TSEC_TX_TO1 0x0100 /* Transmit software ownership bit */ -#define TSEC_TX_DEF 0x0200 /* Defer indication */ -#define TSEC_TX_TC 0x0400 /* Tx CRC */ -#define TSEC_TX_L 0x0800 /* Last in frame */ -#define TSEC_TX_I 0x1000 /* Interrupt */ -#define TSEC_TX_W 0x2000 /* Wrap */ -#define TSEC_TX_PAD 0x4000 /* PAD/CRC */ -#define TSEC_TX_R 0x8000 /* Ready */ - -/* Rx status bits */ -#define TSEC_RX_TR 0x0001 /* Truncation */ -#define TSEC_RX_OV 0x0002 /* Overrun */ -#define TSEC_RX_CR 0x0004 /* Rx CRC error */ -#define TSEC_RX_SH 0x0008 /* Short frame */ -#define TSEC_RX_NO 0x0010 /* Rx non-octet aligned frame */ -#define TSEC_RX_LG 0x0020 /* Rx framelength violation */ -#define TSEC_RX_MC 0x0040 /* Multicast */ -#define TSEC_RX_BC 0x0080 /* Broadcast */ -#define TSEC_RX_M 0x0100 /* Miss */ -#define TSEC_RX_F 0x0400 /* First in frame */ -#define TSEC_RX_L 0x0800 /* Last in frame */ -#define TSEC_RX_I TSEC_TX_I -#define TSEC_RX_W TSEC_TX_W -#define TSEC_RX_RO1 0x4000 /* Receive software ownership bit */ -#define TSEC_RX_E 0x8000 /* Empty */ - -struct tsec_buf { - bus_dmamap_t tb_map; - struct mbuf *tb_m; -}; - -#define TSEC_NTXDESC 256 -#define TSEC_NTXSEGS 16 - -#define TSEC_NRXDESC 256 - -struct tsec_dmamem { - bus_dmamap_t tdm_map; - bus_dma_segment_t tdm_seg; - size_t tdm_size; - caddr_t tdm_kva; -}; -#define TSEC_DMA_MAP(_tdm) ((_tdm)->tdm_map) -#define TSEC_DMA_LEN(_tdm) ((_tdm)->tdm_size) -#define TSEC_DMA_DVA(_tdm) ((_tdm)->tdm_map->dm_segs[0].ds_addr) -#define TSEC_DMA_KVA(_tdm) ((void *)(_tdm)->tdm_kva) - -struct tsec_softc { - struct device sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_space_handle_t sc_mii_ioh; - bus_dma_tag_t sc_dmat; - - struct arpcom sc_ac; -#define sc_lladdr sc_ac.ac_enaddr - struct mii_data sc_mii; -#define sc_media sc_mii.mii_media - int sc_link; - - struct tsec_dmamem *sc_txring; - struct tsec_buf *sc_txbuf; - struct tsec_desc *sc_txdesc; - int sc_tx_prod; - int sc_tx_cnt; - int sc_tx_cons; - - struct tsec_dmamem *sc_rxring; - struct tsec_buf *sc_rxbuf; - struct tsec_desc *sc_rxdesc; - int sc_rx_prod; - struct if_rxring sc_rx_ring; - int sc_rx_cons; - - struct timeout sc_tick; -}; - -#define DEVNAME(_s) ((_s)->sc_dev.dv_xname) - -int tsec_match(struct device *, void *, void *); -void tsec_attach(struct device *, struct device *, void *); - -struct cfattach tsec_ca = { - sizeof(struct tsec_softc), tsec_match, tsec_attach -}; - -struct cfdriver tsec_cd = { - NULL, "tsec", DV_IFNET -}; - -int tsec_find_phy(int, int); - -uint32_t tsec_read(struct tsec_softc *, bus_addr_t); -void tsec_write(struct tsec_softc *, bus_addr_t, uint32_t); -uint32_t tsec_mii_read(struct tsec_softc *, bus_addr_t); -void tsec_mii_write(struct tsec_softc *, bus_addr_t, uint32_t); - -int tsec_ioctl(struct ifnet *, u_long, caddr_t); -void tsec_start(struct ifnet *); -void tsec_watchdog(struct ifnet *); - -int tsec_media_change(struct ifnet *); -void tsec_media_status(struct ifnet *, struct ifmediareq *); - -int tsec_mii_readreg(struct device *, int, int); -void tsec_mii_writereg(struct device *, int, int, int); -void tsec_mii_statchg(struct device *); - -void tsec_lladdr_write(struct tsec_softc *); - -void tsec_tick(void *); - -int tsec_txintr(void *); -int tsec_rxintr(void *); -int tsec_errintr(void *); - -void tsec_tx_proc(struct tsec_softc *); -void tsec_rx_proc(struct tsec_softc *); - -void tsec_up(struct tsec_softc *); -void tsec_down(struct tsec_softc *); -void tsec_iff(struct tsec_softc *); -int tsec_encap(struct tsec_softc *, struct mbuf *, int *); - -void tsec_reset(struct tsec_softc *); -void tsec_stop_dma(struct tsec_softc *); - -struct tsec_dmamem * - tsec_dmamem_alloc(struct tsec_softc *, bus_size_t, bus_size_t); -void tsec_dmamem_free(struct tsec_softc *, struct tsec_dmamem *); -struct mbuf *tsec_alloc_mbuf(struct tsec_softc *, bus_dmamap_t); -void tsec_fill_rx_ring(struct tsec_softc *); - -/* - * The MPC8349E processor has two TSECs but only one external - * management interface to control external PHYs. The registers - * controlling the management interface are part of TSEC1. So to - * control a PHY attached to TSEC2, one needs to access TSEC1's - * registers. To deal with this, the first TSEC that attaches maps - * the register space for both TSEC1 and TSEC2 and stores the bus - * space tag and bus space handle in these global variables. We use - * these to create subregions for each individual interface and the - * management interface. - */ -bus_space_tag_t tsec_iot; -bus_space_handle_t tsec_ioh; - -int -tsec_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "network") != 0) - return (0); - - if (OF_getprop(oa->oa_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "gianfar") != 0) - return (0); - - return (1); -} - -void -tsec_attach(struct device *parent, struct device *self, void *aux) -{ - struct tsec_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - struct ifnet *ifp; - int phy, n; - - if (OF_getprop(oa->oa_node, "phy-handle", &phy, - sizeof(phy)) == sizeof(phy)) { - int node, reg; - - node = tsec_find_phy(OF_peer(0), phy); - if (node == -1 || OF_getprop(node, "reg", ®, - sizeof(reg)) != sizeof(reg)) { - printf(": can't find PHY\n"); - return; - } - - oa->oa_phy = reg; - } - - /* Map registers for TSEC1 & TSEC2 if they're not mapped yet. */ - if (oa->oa_iot != tsec_iot) { - tsec_iot = oa->oa_iot; - if (bus_space_map(tsec_iot, oa->oa_offset & 0xffffc000, - 8192, 0, &tsec_ioh)) { - printf(": can't map registers\n"); - return; - } - } - - sc->sc_iot = tsec_iot; - sc->sc_dmat = oa->oa_dmat; - - /* Ethernet Controller registers. */ - bus_space_subregion(tsec_iot, tsec_ioh, oa->oa_offset & 0x3fff, - 3072, &sc->sc_ioh); - - /* MII Management registers. */ - bus_space_subregion(tsec_iot, tsec_ioh, 0, 3072, &sc->sc_mii_ioh); - - myetheraddr(sc->sc_lladdr); - printf(": address %s\n", ether_sprintf(sc->sc_lladdr)); - - timeout_set(&sc->sc_tick, tsec_tick, sc); - - ifp = &sc->sc_ac.ac_if; - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = tsec_ioctl; - ifp->if_start = tsec_start; - ifp->if_watchdog = tsec_watchdog; - IFQ_SET_MAXLEN(&ifp->if_snd, TSEC_NTXDESC - 1); - bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); - - ifp->if_capabilities = IFCAP_VLAN_MTU; - - sc->sc_mii.mii_ifp = ifp; - sc->sc_mii.mii_readreg = tsec_mii_readreg; - sc->sc_mii.mii_writereg = tsec_mii_writereg; - sc->sc_mii.mii_statchg = tsec_mii_statchg; - - ifmedia_init(&sc->sc_media, 0, tsec_media_change, tsec_media_status); - - tsec_reset(sc); - - /* Reset management. */ - tsec_write(sc, TSEC_MIIMCFG, TSEC_MIIMCFG_RESET); - tsec_write(sc, TSEC_MIIMCFG, 0x00000003); - for (n = 0; n < 100; n++) { - if ((tsec_read(sc, TSEC_MIIMIND) & TSEC_MIIMIND_BUSY) == 0) - break; - } - - mii_attach(self, &sc->sc_mii, 0xffffffff, oa->oa_phy, - MII_OFFSET_ANY, 0); - if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { - printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); - ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); - ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); - } else - ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); - - if_attach(ifp); - ether_ifattach(ifp); - - intr_establish(oa->oa_ivec, IST_LEVEL, IPL_NET, tsec_txintr, sc, - sc->sc_dev.dv_xname); - intr_establish(oa->oa_ivec + 1, IST_LEVEL, IPL_NET, tsec_rxintr, sc, - sc->sc_dev.dv_xname); - intr_establish(oa->oa_ivec + 2, IST_LEVEL, IPL_NET, tsec_errintr, sc, - sc->sc_dev.dv_xname); -} - -int -tsec_find_phy(int node, int phy) -{ - int child, handle; - - if (OF_getprop(node, "linux,phandle", &handle, - sizeof(handle)) == sizeof(handle) && phy == handle) - return (node); - - for (child = OF_child(node); child != 0; child = OF_peer(child)) { - node = tsec_find_phy(child, phy); - if (node != -1) - return node; - } - - return (-1); -} - -uint32_t -tsec_read(struct tsec_softc *sc, bus_addr_t addr) -{ - return (letoh32(bus_space_read_4(sc->sc_iot, sc->sc_ioh, addr))); -} - -void -tsec_write(struct tsec_softc *sc, bus_addr_t addr, uint32_t data) -{ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, addr, htole32(data)); -} - -uint32_t -tsec_mii_read(struct tsec_softc *sc, bus_addr_t addr) -{ - return (letoh32(bus_space_read_4(sc->sc_iot, sc->sc_mii_ioh, addr))); -} - -void -tsec_mii_write(struct tsec_softc *sc, bus_addr_t addr, uint32_t data) -{ - bus_space_write_4(sc->sc_iot, sc->sc_mii_ioh, addr, htole32(data)); -} - -void -tsec_lladdr_write(struct tsec_softc *sc) -{ - uint32_t addr1, addr2; - - addr1 = sc->sc_lladdr[5] << 24 | sc->sc_lladdr[4] << 16 | - sc->sc_lladdr[3] << 8 | sc->sc_lladdr[2]; - addr2 = sc->sc_lladdr[1] << 24 | sc->sc_lladdr[0] << 16; - tsec_write(sc, TSEC_MACSTNADDR1, addr1); - tsec_write(sc, TSEC_MACSTNADDR2, addr2); -} - -void -tsec_start(struct ifnet *ifp) -{ - struct tsec_softc *sc = ifp->if_softc; - struct mbuf *m; - int error, idx; - - if (!(ifp->if_flags & IFF_RUNNING)) - return; - if (ifq_is_oactive(&ifp->if_snd)) - return; - if (IFQ_IS_EMPTY(&ifp->if_snd)) - return; - if (!sc->sc_link) - return; - - idx = sc->sc_tx_prod; - while ((sc->sc_txdesc[idx].td_status & TSEC_TX_TO1) == 0) { - m = ifq_deq_begin(&ifp->if_snd); - if (m == NULL) - break; - - error = tsec_encap(sc, m, &idx); - if (error == ENOBUFS) { - ifq_deq_rollback(&ifp->if_snd, m); - ifq_set_oactive(&ifp->if_snd); - break; - } - if (error == EFBIG) { - ifq_deq_commit(&ifp->if_snd, m); - m_freem(m); /* give up: drop it */ - ifp->if_oerrors++; - continue; - } - - /* Now we are committed to transmit the packet. */ - ifq_deq_commit(&ifp->if_snd, m); - -#if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); -#endif - } - - if (sc->sc_tx_prod != idx) { - sc->sc_tx_prod = idx; - - /* Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; - } -} - -int -tsec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) -{ - struct tsec_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)addr; - int error = 0, s; - - s = splnet(); - - switch (cmd) { - case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - /* FALLTHROUGH */ - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_flags & IFF_RUNNING) - error = ENETRESET; - else - tsec_up(sc); - } else { - if (ifp->if_flags & IFF_RUNNING) - tsec_down(sc); - } - break; - - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); - break; - - case SIOCGIFRXR: - error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data, - NULL, MCLBYTES, &sc->sc_rx_ring); - break; - - default: - error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr); - break; - } - - if (error == ENETRESET) { - if (ifp->if_flags & IFF_RUNNING) - tsec_iff(sc); - error = 0; - } - - splx(s); - return (error); -} - -void -tsec_watchdog(struct ifnet *ifp) -{ - printf("%s\n", __func__); -} - -int -tsec_media_change(struct ifnet *ifp) -{ - struct tsec_softc *sc = ifp->if_softc; - - if (LIST_FIRST(&sc->sc_mii.mii_phys)) - mii_mediachg(&sc->sc_mii); - - return (0); -} - -void -tsec_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct tsec_softc *sc = ifp->if_softc; - - if (LIST_FIRST(&sc->sc_mii.mii_phys)) { - mii_pollstat(&sc->sc_mii); - ifmr->ifm_active = sc->sc_mii.mii_media_active; - ifmr->ifm_status = sc->sc_mii.mii_media_status; - } -} - -int -tsec_mii_readreg(struct device *self, int phy, int reg) -{ - struct tsec_softc *sc = (void *)self; - uint32_t v; - int n; - - tsec_mii_write(sc, TSEC_MIIMADD, (phy << 8) | reg); - tsec_mii_write(sc, TSEC_MIIMCOM, 0); - tsec_mii_write(sc, TSEC_MIIMCOM, TSEC_MIIMCOM_READ); - for (n = 0; n < 100; n++) { - v = tsec_mii_read(sc, TSEC_MIIMIND); - if ((v & (TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY)) == 0) - return (tsec_mii_read(sc, TSEC_MIIMSTAT)); - delay(10); - } - - printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname); - return (0); -} - -void -tsec_mii_writereg(struct device *self, int phy, int reg, int val) -{ - struct tsec_softc *sc = (void *)self; - uint32_t v; - int n; - - tsec_mii_write(sc, TSEC_MIIMADD, (phy << 8) | reg); - tsec_mii_write(sc, TSEC_MIIMCON, val); - for (n = 0; n < 100; n++) { - v = tsec_mii_read(sc, TSEC_MIIMIND); - if ((v & TSEC_MIIMIND_BUSY) == 0) - return; - delay(10); - } - - printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname); -} - -void -tsec_mii_statchg(struct device *self) -{ - struct tsec_softc *sc = (void *)self; - uint32_t maccfg2, ecntrl; - - ecntrl = tsec_read(sc, TSEC_ECNTRL); - maccfg2 = tsec_read(sc, TSEC_MACCFG2); - maccfg2 &= ~TSEC_MACCFG2_IF_MODE; - - switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { - case IFM_1000_SX: - case IFM_1000_LX: - case IFM_1000_CX: - case IFM_1000_T: - maccfg2 |= TSEC_MACCFG2_IF_GMII; - sc->sc_link = 1; - break; - case IFM_100_TX: - ecntrl |= TSEC_ECNTRL_R100M; - maccfg2 |= TSEC_MACCFG2_IF_MII; - sc->sc_link = 1; - break; - case IFM_10_T: - ecntrl &= ~TSEC_ECNTRL_R100M; - maccfg2 |= TSEC_MACCFG2_IF_MII; - sc->sc_link = 1; - break; - default: - sc->sc_link = 0; - return; - } - - if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) - maccfg2 |= TSEC_MACCFG2_FDX; - else - maccfg2 &= ~TSEC_MACCFG2_FDX; - - tsec_write(sc, TSEC_MACCFG2, maccfg2); - tsec_write(sc, TSEC_ECNTRL, ecntrl); -} - -void -tsec_tick(void *arg) -{ - struct tsec_softc *sc = arg; - int s; - - s = splnet(); - mii_tick(&sc->sc_mii); - splx(s); - - timeout_add_sec(&sc->sc_tick, 1); -} - -int -tsec_txintr(void *arg) -{ - struct tsec_softc *sc = arg; - uint32_t ievent; - - ievent = tsec_read(sc, TSEC_IEVENT); - if ((ievent & (TSEC_IEVENT_TXC | TSEC_IEVENT_TXE | - TSEC_IEVENT_TXB | TSEC_IEVENT_TXF)) == 0) - printf("%s: tx %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT); - ievent &= (TSEC_IEVENT_TXC | TSEC_IEVENT_TXE | - TSEC_IEVENT_TXB | TSEC_IEVENT_TXF); - tsec_write(sc, TSEC_IEVENT, ievent); - - tsec_tx_proc(sc); - - return (1); -} - -int -tsec_rxintr(void *arg) -{ - struct tsec_softc *sc = arg; - uint32_t ievent; - - ievent = tsec_read(sc, TSEC_IEVENT); - if ((ievent & (TSEC_IEVENT_RXB | TSEC_IEVENT_RXF)) == 0) - printf("%s: rx %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT); - ievent &= (TSEC_IEVENT_RXB | TSEC_IEVENT_RXF); - tsec_write(sc, TSEC_IEVENT, ievent); - - tsec_rx_proc(sc); - - return (1); -} - -int -tsec_errintr(void *arg) -{ - struct tsec_softc *sc = arg; - struct ifnet *ifp = &sc->sc_ac.ac_if; - uint32_t ievent; - - ievent = tsec_read(sc, TSEC_IEVENT); - if ((ievent & TSEC_IEVENT_BSY) == 0) - printf("%s: err %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT); - ievent &= TSEC_IEVENT_BSY; - tsec_write(sc, TSEC_IEVENT, ievent); - - if (ievent & TSEC_IEVENT_BSY) { - /* - * We ran out of buffers and dropped one (or more) - * packets. We must clear RSTAT[QHLT] after - * processing the ring to get things started again. - */ - tsec_rx_proc(sc); - tsec_write(sc, TSEC_RSTAT, TSEC_RSTAT_QHLT); - ifp->if_ierrors++; - } - - return (1); -} - -void -tsec_tx_proc(struct tsec_softc *sc) -{ - struct ifnet *ifp = &sc->sc_ac.ac_if; - struct tsec_desc *txd; - struct tsec_buf *txb; - int idx; - - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_txring), 0, - TSEC_DMA_LEN(sc->sc_txring), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - while (sc->sc_tx_cnt > 0) { - idx = sc->sc_tx_cons; - KASSERT(idx < TSEC_NTXDESC); - - txd = &sc->sc_txdesc[idx]; - if (txd->td_status & TSEC_TX_R) - break; - - txb = &sc->sc_txbuf[idx]; - if (txb->tb_m) { - bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, - txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, txb->tb_map); - - m_freem(txb->tb_m); - txb->tb_m = NULL; - } - - ifq_clr_oactive(&ifp->if_snd); - - sc->sc_tx_cnt--; - - if (txd->td_status & TSEC_TX_W) - sc->sc_tx_cons = 0; - else - sc->sc_tx_cons++; - - __asm volatile("eieio" ::: "memory"); - txd->td_status &= TSEC_TX_W; - } - - if (sc->sc_tx_cnt == 0) - ifp->if_timer = 0; -} - -void -tsec_rx_proc(struct tsec_softc *sc) -{ - struct ifnet *ifp = &sc->sc_ac.ac_if; - struct tsec_desc *rxd; - struct tsec_buf *rxb; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); - struct mbuf *m; - int idx, len; - - if ((ifp->if_flags & IFF_RUNNING) == 0) - return; - - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_rxring), 0, - TSEC_DMA_LEN(sc->sc_rxring), - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - - while (if_rxr_inuse(&sc->sc_rx_ring) > 0) { - idx = sc->sc_rx_cons; - KASSERT(idx < TSEC_NRXDESC); - - rxd = &sc->sc_rxdesc[idx]; - if (rxd->td_status & TSEC_RX_E) - break; - - len = rxd->td_len; - rxb = &sc->sc_rxbuf[idx]; - KASSERT(rxb->tb_m); - - bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, - len, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); - - /* Strip off CRC. */ - len -= ETHER_CRC_LEN; - KASSERT(len > 0); - - m = rxb->tb_m; - rxb->tb_m = NULL; - m->m_pkthdr.len = m->m_len = len; - - ml_enqueue(&ml, m); - - if_rxr_put(&sc->sc_rx_ring, 1); - if (rxd->td_status & TSEC_RX_W) - sc->sc_rx_cons = 0; - else - sc->sc_rx_cons++; - } - - tsec_fill_rx_ring(sc); - - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_rxring), 0, - TSEC_DMA_LEN(sc->sc_rxring), - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - - if_input(ifp, &ml); -} - -void -tsec_up(struct tsec_softc *sc) -{ - struct ifnet *ifp = &sc->sc_ac.ac_if; - struct tsec_desc *txd, *rxd; - struct tsec_buf *txb, *rxb; - uint32_t maccfg1, maccfg2, ecntrl, dmactrl, attr; - int i; - - /* Allocate Tx descriptor ring. */ - sc->sc_txring = tsec_dmamem_alloc(sc, - TSEC_NTXDESC * sizeof(struct tsec_desc), 8); - sc->sc_txdesc = TSEC_DMA_KVA(sc->sc_txring); - - sc->sc_txbuf = malloc(sizeof(struct tsec_buf) * TSEC_NTXDESC, - M_DEVBUF, M_WAITOK); - for (i = 0; i < TSEC_NTXDESC; i++) { - txb = &sc->sc_txbuf[i]; - bus_dmamap_create(sc->sc_dmat, MCLBYTES, TSEC_NTXSEGS, - MCLBYTES, 0, BUS_DMA_WAITOK, &txb->tb_map); - txb->tb_m = NULL; - } - - /* Set wrap bit on last descriptor. */ - txd = &sc->sc_txdesc[TSEC_NTXDESC - 1]; - txd->td_status = TSEC_TX_W; - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_txring), - (TSEC_NTXDESC - 1) * sizeof(*txd), sizeof(*txd), - BUS_DMASYNC_PREWRITE); - - sc->sc_tx_prod = sc->sc_tx_cons = 0; - sc->sc_tx_cnt = 0; - - tsec_write(sc, TSEC_TBASE, TSEC_DMA_DVA(sc->sc_txring)); - - /* Allocate Rx descriptor ring. */ - sc->sc_rxring = tsec_dmamem_alloc(sc, - TSEC_NRXDESC * sizeof(struct tsec_desc), 8); - sc->sc_rxdesc = TSEC_DMA_KVA(sc->sc_rxring); - - sc->sc_rxbuf = malloc(sizeof(struct tsec_buf) * TSEC_NRXDESC, - M_DEVBUF, M_WAITOK); - - for (i = 0; i < TSEC_NRXDESC; i++) { - rxb = &sc->sc_rxbuf[i]; - bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, - MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->tb_map); - rxb->tb_m = NULL; - } - - /* Set wrap bit on last descriptor. */ - rxd = &sc->sc_rxdesc[TSEC_NRXDESC - 1]; - rxd->td_status |= TSEC_RX_W; - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_rxring), - 0, TSEC_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_PREWRITE); - - sc->sc_rx_prod = sc->sc_rx_cons = 0; - - if_rxr_init(&sc->sc_rx_ring, 2, TSEC_NRXDESC); - tsec_fill_rx_ring(sc); - - tsec_write(sc, TSEC_MRBLR, MCLBYTES); - - tsec_write(sc, TSEC_RBASE, TSEC_DMA_DVA(sc->sc_rxring)); - - tsec_lladdr_write(sc); - - tsec_write(sc, TSEC_IADDR0, 0); - tsec_write(sc, TSEC_IADDR1, 0); - tsec_write(sc, TSEC_IADDR2, 0); - tsec_write(sc, TSEC_IADDR3, 0); - tsec_write(sc, TSEC_IADDR4, 0); - tsec_write(sc, TSEC_IADDR5, 0); - tsec_write(sc, TSEC_IADDR6, 0); - tsec_write(sc, TSEC_IADDR7, 0); - tsec_write(sc, TSEC_GADDR0, 0); - tsec_write(sc, TSEC_GADDR1, 0); - tsec_write(sc, TSEC_GADDR2, 0); - tsec_write(sc, TSEC_GADDR3, 0); - tsec_write(sc, TSEC_GADDR4, 0); - tsec_write(sc, TSEC_GADDR5, 0); - tsec_write(sc, TSEC_GADDR6, 0); - tsec_write(sc, TSEC_GADDR7, 0); - - maccfg1 = tsec_read(sc, TSEC_MACCFG1); - maccfg1 |= TSEC_MACCFG1_TXEN; - maccfg1 |= TSEC_MACCFG1_RXEN; - tsec_write(sc, TSEC_MACCFG1, maccfg1); - - /* - * Default to full-duplex MII mode, which is the mode most - * likely used by a directly connected integrated switch. For - * a real PHY the mode will be set later, based on the - * parameters negotiaded by the PHY. - */ - maccfg2 = tsec_read(sc, TSEC_MACCFG2); - maccfg2 &= ~TSEC_MACCFG2_IF_MODE; - maccfg2 |= TSEC_MACCFG2_IF_MII | TSEC_MACCFG2_FDX; - tsec_write(sc, TSEC_MACCFG2, maccfg2 | TSEC_MACCFG2_PAD); - - ecntrl = tsec_read(sc, TSEC_ECNTRL); - tsec_write(sc, TSEC_ECNTRL, ecntrl | TSEC_ECNTRL_R100M); - - dmactrl = tsec_read(sc, TSEC_DMACTRL); - dmactrl |= TSEC_DMACTRL_TDSEN; - dmactrl |= TSEC_DMACTRL_TBDSEN; - dmactrl |= TSEC_DMACTRL_WWR; - dmactrl |= TSEC_DMACTRL_WOP; - dmactrl &= ~(TSEC_DMACTRL_GTS | TSEC_DMACTRL_GRS); - tsec_write(sc, TSEC_DMACTRL, dmactrl); - - attr = tsec_read(sc, TSEC_ATTR); - attr |= TSEC_ATTR_RDSEN; - attr |= TSEC_ATTR_RBDSEN; - tsec_write(sc, TSEC_ATTR, attr); - - tsec_write(sc, TSEC_TSTAT, TSEC_TSTAT_THLT); - tsec_write(sc, TSEC_RSTAT, TSEC_RSTAT_QHLT); - - /* Configure media. */ - if (LIST_FIRST(&sc->sc_mii.mii_phys)) - mii_mediachg(&sc->sc_mii); - - /* Program promiscuous mode and multicast filters. */ - tsec_iff(sc); - - ifp->if_flags |= IFF_RUNNING; - ifq_clr_oactive(&ifp->if_snd); - - tsec_write(sc, TSEC_IMASK, TSEC_IMASK_TXEEN | - TSEC_IMASK_TXBEN | TSEC_IMASK_TXFEN | - TSEC_IMASK_RXBEN | TSEC_IMASK_RXFEN | TSEC_IMASK_BSYEN); - - timeout_add_sec(&sc->sc_tick, 1); -} - -void -tsec_down(struct tsec_softc *sc) -{ - struct ifnet *ifp = &sc->sc_ac.ac_if; - struct tsec_buf *txb, *rxb; - uint32_t maccfg1; - int i; - - timeout_del(&sc->sc_tick); - - ifp->if_flags &= ~IFF_RUNNING; - ifq_clr_oactive(&ifp->if_snd); - ifp->if_timer = 0; - - tsec_stop_dma(sc); - - maccfg1 = tsec_read(sc, TSEC_MACCFG1); - maccfg1 &= ~TSEC_MACCFG1_TXEN; - maccfg1 &= ~TSEC_MACCFG1_RXEN; - tsec_write(sc, TSEC_MACCFG1, maccfg1); - - for (i = 0; i < TSEC_NTXDESC; i++) { - txb = &sc->sc_txbuf[i]; - if (txb->tb_m) { - bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, - txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, txb->tb_map); - m_freem(txb->tb_m); - } - bus_dmamap_destroy(sc->sc_dmat, txb->tb_map); - } - - tsec_dmamem_free(sc, sc->sc_txring); - free(sc->sc_txbuf, M_DEVBUF, 0); - - for (i = 0; i < TSEC_NRXDESC; i++) { - rxb = &sc->sc_rxbuf[i]; - if (rxb->tb_m) { - bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, - rxb->tb_map->dm_mapsize, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); - m_freem(rxb->tb_m); - } - bus_dmamap_destroy(sc->sc_dmat, rxb->tb_map); - } - - tsec_dmamem_free(sc, sc->sc_rxring); - free(sc->sc_rxbuf, M_DEVBUF, 0); -} - -void -tsec_iff(struct tsec_softc *sc) -{ - struct arpcom *ac = &sc->sc_ac; - struct ifnet *ifp = &sc->sc_ac.ac_if; - struct ether_multi *enm; - struct ether_multistep step; - uint32_t crc, hash[8]; - uint32_t rctrl; - int i; - - rctrl = tsec_read(sc, TSEC_RCTRL); - rctrl &= ~TSEC_RCTRL_PROM; - ifp->if_flags &= ~IFF_ALLMULTI; - - if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { - ifp->if_flags |= IFF_ALLMULTI; - rctrl |= TSEC_RCTRL_PROM; - bzero(hash, sizeof(hash)); - } else { - ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { - crc = ether_crc32_be(enm->enm_addrlo, - ETHER_ADDR_LEN); - - crc >>= 24; - hash[crc / 32] |= 1 << (31 - (crc % 32)); - - ETHER_NEXT_MULTI(step, enm); - } - } - - for (i = 0; i < nitems(hash); i++) - tsec_write(sc, TSEC_GADDR0 + i * 4, hash[i]); - - tsec_write(sc, TSEC_RCTRL, rctrl); -} - -int -tsec_encap(struct tsec_softc *sc, struct mbuf *m, int *idx) -{ - struct tsec_desc *txd; - bus_dmamap_t map; - int cur, frag, i; - uint16_t status; - - cur = frag = *idx; - map = sc->sc_txbuf[cur].tb_map; - - if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) { - if (m_defrag(m, M_DONTWAIT)) - return (EFBIG); - if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) - return (EFBIG); - } - - if (map->dm_nsegs > (TSEC_NTXDESC - sc->sc_tx_cnt - 2)) { - bus_dmamap_unload(sc->sc_dmat, map); - return (ENOBUFS); - } - - /* Sync the DMA map. */ - bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, - BUS_DMASYNC_PREWRITE); - - txd = &sc->sc_txdesc[frag]; - for (i = 0; i < map->dm_nsegs; i++) { - status = txd->td_status & TSEC_TX_W; - status |= TSEC_TX_TO1; - if (i == (map->dm_nsegs - 1)) - status |= TSEC_TX_L; - txd->td_len = map->dm_segs[i].ds_len; - txd->td_addr = map->dm_segs[i].ds_addr; - __asm volatile("eieio" ::: "memory"); - txd->td_status = status | TSEC_TX_R | TSEC_TX_I | TSEC_TX_TC; - - bus_dmamap_sync(sc->sc_dmat, TSEC_DMA_MAP(sc->sc_txring), - frag * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE); - - cur = frag; - if (status & TSEC_TX_W) { - txd = &sc->sc_txdesc[0]; - frag = 0; - } else { - txd++; - frag++; - } - KASSERT(frag != sc->sc_tx_cons); - - tsec_write(sc, TSEC_TSTAT, TSEC_TSTAT_THLT); - } - - KASSERT(sc->sc_txbuf[cur].tb_m == NULL); - sc->sc_txbuf[*idx].tb_map = sc->sc_txbuf[cur].tb_map; - sc->sc_txbuf[cur].tb_map = map; - sc->sc_txbuf[cur].tb_m = m; - - sc->sc_tx_cnt += map->dm_nsegs; - *idx = frag; - - return (0); -} - -void -tsec_reset(struct tsec_softc *sc) -{ - tsec_stop_dma(sc); - - /* Set, then clear MACCFG1[Soft_Reset]. */ - tsec_write(sc, TSEC_MACCFG1, TSEC_MACCFG1_RESET); - tsec_write(sc, TSEC_MACCFG1, 0); - - /* Clear IEVENT. */ - tsec_write(sc, TSEC_IEVENT, 0xffffffff); -} - -void -tsec_stop_dma(struct tsec_softc *sc) -{ - uint32_t dmactrl, ievent; - int n; - - /* Stop DMA. */ - dmactrl = tsec_read(sc, TSEC_DMACTRL); - dmactrl |= TSEC_DMACTRL_GTS; - tsec_write(sc, TSEC_DMACTRL, dmactrl); - - for (n = 0; n < 100; n++) { - ievent = tsec_read(sc, TSEC_IEVENT); - if (ievent & TSEC_IEVENT_GTSC) - break; - } - KASSERT(n != 100); - - dmactrl = tsec_read(sc, TSEC_DMACTRL); - dmactrl |= TSEC_DMACTRL_GRS; - tsec_write(sc, TSEC_DMACTRL, dmactrl); - - for (n = 0; n < 100; n++) { - ievent = tsec_read(sc, TSEC_IEVENT); - if (ievent & TSEC_IEVENT_GRSC) - break; - } - KASSERT(n != 100); -} - -struct tsec_dmamem * -tsec_dmamem_alloc(struct tsec_softc *sc, bus_size_t size, bus_size_t align) -{ - struct tsec_dmamem *tdm; - int nsegs; - - tdm = malloc(sizeof(*tdm), M_DEVBUF, M_WAITOK | M_ZERO); - tdm->tdm_size = size; - - if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0) - goto tdmfree; - - if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &tdm->tdm_seg, 1, - &nsegs, BUS_DMA_WAITOK) != 0) - goto destroy; - - if (bus_dmamem_map(sc->sc_dmat, &tdm->tdm_seg, nsegs, size, - &tdm->tdm_kva, BUS_DMA_WAITOK) != 0) - goto free; - - if (bus_dmamap_load(sc->sc_dmat, tdm->tdm_map, tdm->tdm_kva, size, - NULL, BUS_DMA_WAITOK) != 0) - goto unmap; - - bzero(tdm->tdm_kva, size); - - return (tdm); - -unmap: - bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, size); -free: - bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); -destroy: - bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); -tdmfree: - free(tdm, M_DEVBUF, 0); - - return (NULL); -} - -void -tsec_dmamem_free(struct tsec_softc *sc, struct tsec_dmamem *tdm) -{ - bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, tdm->tdm_size); - bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); - bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); - free(tdm, M_DEVBUF, 0); -} - -struct mbuf * -tsec_alloc_mbuf(struct tsec_softc *sc, bus_dmamap_t map) -{ - struct mbuf *m = NULL; - - m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES); - if (!m) - return (NULL); - m->m_len = m->m_pkthdr.len = MCLBYTES; - - if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) { - printf("%s: could not load mbuf DMA map", DEVNAME(sc)); - m_freem(m); - return (NULL); - } - - bus_dmamap_sync(sc->sc_dmat, map, 0, - m->m_pkthdr.len, BUS_DMASYNC_PREREAD); - - return (m); -} - -void -tsec_fill_rx_ring(struct tsec_softc *sc) -{ - struct tsec_desc *rxd; - struct tsec_buf *rxb; - u_int slots; - - for (slots = if_rxr_get(&sc->sc_rx_ring, TSEC_NRXDESC); - slots > 0; slots--) { - rxb = &sc->sc_rxbuf[sc->sc_rx_prod]; - rxb->tb_m = tsec_alloc_mbuf(sc, rxb->tb_map); - if (rxb->tb_m == NULL) - break; - - rxd = &sc->sc_rxdesc[sc->sc_rx_prod]; - rxd->td_len = 0; - rxd->td_addr = rxb->tb_map->dm_segs[0].ds_addr; - __asm volatile("eieio" ::: "memory"); - rxd->td_status |= TSEC_RX_E | TSEC_RX_I; - - if (rxd->td_status & TSEC_RX_W) - sc->sc_rx_prod = 0; - else - sc->sc_rx_prod++; - } - if_rxr_put(&sc->sc_rx_ring, slots); -} diff --git a/sys/arch/socppc/dev/ipic.c b/sys/arch/socppc/dev/ipic.c deleted file mode 100644 index 669bd3289c5..00000000000 --- a/sys/arch/socppc/dev/ipic.c +++ /dev/null @@ -1,410 +0,0 @@ -/* $OpenBSD: ipic.c,v 1.18 2015/06/24 11:58:06 mpi Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/malloc.h> - -#include <machine/autoconf.h> -#include <machine/intr.h> - -#include <dev/ofw/openfirm.h> - -#define IPIC_SICFR 0x00 -#define IPIC_SIVCR 0x04 -#define IPIC_SIPNR_H 0x08 -#define IPIC_SIPNR_L 0x0c -#define IPIC_SIPRR_A 0x10 -#define IPIC_SIPRR_D 0x1c -#define IPIC_SIMSR_H 0x20 -#define IPIC_SIMSR_L 0x24 -#define IPIC_SICNR 0x28 -#define IPIC_SEPNR 0x2c -#define IPIC_SMPRR_A 0x30 -#define IPIC_SMPRR_B 0x34 -#define IPIC_SEMSR 0x38 -#define IPIC_SECNR 0x3c -#define IPIC_SERSR 0x40 -#define IPIC_SERMR 0x44 -#define IPIC_SERCR 0x48 -#define IPIC_SIFCR_H 0x50 -#define IPIC_SIFCR_L 0x54 -#define IPIC_SEFCR 0x58 -#define IPIC_SERFR 0x5c -#define IPIC_SCVCR 0x60 -#define IPIC_SMVCR 0x64 - -#define IPIC_NVEC 128 - -#define IPIC_EXTERNAL(ivec) ((ivec) >= 17 && (ivec) <= 23) - -struct ipic_softc { - struct device sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - - uint32_t sc_simsr_h[IPL_NUM]; - uint32_t sc_simsr_l[IPL_NUM]; - uint32_t sc_semsr[IPL_NUM]; -}; - -uint32_t ipic_imask; -struct intrq ipic_handler[IPIC_NVEC]; -struct ipic_softc *ipic_sc; -int ipic_preinit_done; /* defaults to 0 - not initialized */ - -int ipic_match(struct device *, void *, void *); -void ipic_attach(struct device *, struct device *, void *); - -struct cfattach ipic_ca = { - sizeof(struct ipic_softc), ipic_match, ipic_attach -}; - -struct cfdriver ipic_cd = { - NULL, "ipic", DV_DULL -}; - -void ipic_preinit(void); -uint32_t ipic_read(struct ipic_softc *, bus_addr_t); -void ipic_write(struct ipic_softc *, bus_addr_t, uint32_t); -uint32_t ipic_simsr_h(int); -uint32_t ipic_simsr_l(int); -uint32_t ipic_semsr(int); -void ipic_calc_masks(void); - -void ext_intr(void); - -ppc_splraise_t ipic_splraise; -ppc_spllower_t ipic_spllower; -ppc_splx_t ipic_splx; - -void ipic_setipl(int); - -void -ipic_preinit(void) -{ - int i; - struct intrq *iq; - - for (i = 0; i < IPIC_NVEC; i++) { - iq = &ipic_handler[i]; - TAILQ_INIT(&iq->iq_list); - } - ipic_preinit_done = 1; -} - -int -ipic_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "ipic") != 0) - return (0); - - return (1); -} - -void -ipic_attach(struct device *parent, struct device *self, void *aux) -{ - struct ipic_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - int ivec; - struct intrq *iq; - - sc->sc_iot = oa->oa_iot; - if (bus_space_map(sc->sc_iot, oa->oa_offset, 128, 0, &sc->sc_ioh)) { - printf(": can't map registers\n"); - return; - } - - ipic_sc = sc; - - /* if ipic_preinit has not happened, do it here */ - if (ipic_preinit_done == 0) - ipic_preinit(); - - /* - * Deal with pre-established interrupts. - */ - for (ivec = 0; ivec < IPIC_NVEC; ivec++) { - iq = &ipic_handler[ivec]; - if (!TAILQ_EMPTY(&iq->iq_list)) { - int level = TAILQ_FIRST(&iq->iq_list)->ih_level; - - sc->sc_simsr_h[level] |= ipic_simsr_h(ivec); - sc->sc_simsr_l[level] |= ipic_simsr_l(ivec); - sc->sc_semsr[level] |= ipic_semsr(ivec); - ipic_calc_masks(); - } - } - - ppc_smask_init(); - ppc_intr_func.raise = ipic_splraise; - ppc_intr_func.lower = ipic_spllower; - ppc_intr_func.x = ipic_splx; - - printf("\n"); -} - -uint32_t -ipic_read(struct ipic_softc *sc, bus_addr_t addr) -{ - return (letoh32(bus_space_read_4(sc->sc_iot, sc->sc_ioh, addr))); -} - -void -ipic_write(struct ipic_softc *sc, bus_addr_t addr, uint32_t data) -{ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, addr, htole32(data)); -} - -uint32_t -ipic_simsr_h(int ivec) -{ - switch (ivec) { - case 9: - return 0x00000080; - case 10: - return 0x00000040; - case 32: - return 0x80000000; - case 33: - return 0x40000000; - case 34: - return 0x20000000; - case 35: - return 0x10000000; - case 36: - return 0x08000000; - case 37: - return 0x04000000; - case 39: - return 0x01000000; - } - - return 0; -} - -uint32_t -ipic_simsr_l(int ivec) -{ - return 0; -} - -uint32_t -ipic_semsr(int ivec) -{ - switch (ivec) { - case 17: - return 0x40000000; - case 18: - return 0x20000000; - case 19: - return 0x10000000; - case 20: - return 0x08000000; - case 21: - return 0x04000000; - case 22: - return 0x02000000; - case 23: - return 0x01000000; - case 48: - return 0x80000000; - } - - return 0; -} - -void -ipic_calc_masks(void) -{ - struct ipic_softc *sc = ipic_sc; - - sc->sc_simsr_h[IPL_NET] |= sc->sc_simsr_h[IPL_BIO]; - sc->sc_simsr_h[IPL_TTY] |= sc->sc_simsr_h[IPL_NET]; - sc->sc_simsr_h[IPL_VM] |= sc->sc_simsr_h[IPL_TTY]; - sc->sc_simsr_h[IPL_CLOCK] |= sc->sc_simsr_h[IPL_VM]; - sc->sc_simsr_h[IPL_HIGH] |= sc->sc_simsr_h[IPL_CLOCK]; - - sc->sc_simsr_l[IPL_NET] |= sc->sc_simsr_l[IPL_BIO]; - sc->sc_simsr_l[IPL_TTY] |= sc->sc_simsr_l[IPL_NET]; - sc->sc_simsr_l[IPL_VM] |= sc->sc_simsr_l[IPL_TTY]; - sc->sc_simsr_l[IPL_CLOCK] |= sc->sc_simsr_l[IPL_VM]; - sc->sc_simsr_l[IPL_HIGH] |= sc->sc_simsr_l[IPL_CLOCK]; - - sc->sc_semsr[IPL_NET] |= sc->sc_semsr[IPL_BIO]; - sc->sc_semsr[IPL_TTY] |= sc->sc_semsr[IPL_NET]; - sc->sc_semsr[IPL_VM] |= sc->sc_semsr[IPL_TTY]; - sc->sc_semsr[IPL_CLOCK] |= sc->sc_semsr[IPL_VM]; - sc->sc_semsr[IPL_HIGH] |= sc->sc_semsr[IPL_CLOCK]; -} - -void * -intr_establish(int ivec, int type, int level, - int (*ih_fun)(void *), void *ih_arg, const char *name) -{ - struct ipic_softc *sc = ipic_sc; - struct intrhand *ih; - struct intrq *iq; - int s, flags; - - if (ipic_preinit_done == 0) - ipic_preinit(); - - ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); - if (ih == NULL) - panic("%s: malloc failed", __func__); - iq = &ipic_handler[ivec]; - - if (ivec < 0 || ivec >= IPIC_NVEC) - panic("%s: invalid vector %d", __func__, ivec); - - if (sc) { - sc->sc_simsr_h[level] |= ipic_simsr_h(ivec); - sc->sc_simsr_l[level] |= ipic_simsr_l(ivec); - sc->sc_semsr[level] |= ipic_semsr(ivec); - ipic_calc_masks(); - } - - flags = level & IPL_MPSAFE; - level &= ~IPL_MPSAFE; - - KASSERT(level <= IPL_TTY || level >= IPL_CLOCK || flags & IPL_MPSAFE); - - ih->ih_fun = ih_fun; - ih->ih_arg = ih_arg; - ih->ih_level = level; - ih->ih_flags = flags; - ih->ih_irq = ivec; - - evcount_attach(&ih->ih_count, name, &ih->ih_irq); - - /* - * Append handler to end of list - */ - s = ppc_intr_disable(); - TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list); - - /* Unmask the interrupt. */ - if (sc) - ipic_setipl(curcpu()->ci_cpl); - ppc_intr_enable(s); - - return (ih); -} - -void -ext_intr(void) -{ - struct cpu_info *ci = curcpu(); - struct ipic_softc *sc = ipic_sc; - struct intrhand *ih; - struct intrq *iq; - int pcpl; - int ivec; - - pcpl = ci->ci_cpl; - ivec = ipic_read(sc, IPIC_SIVCR) & 0x7f; - - iq = &ipic_handler[ivec]; - TAILQ_FOREACH(ih, &iq->iq_list, ih_list) { - if (ih->ih_level <= pcpl) { - panic("irq handler called at wrong level %d %d", - ih->ih_level, pcpl); - continue; - } - - ipic_splraise(ih->ih_level); - ppc_intr_enable(1); - - KERNEL_LOCK(); - if ((*ih->ih_fun)(ih->ih_arg)) - ih->ih_count.ec_count++; - KERNEL_UNLOCK(); - - ppc_intr_disable(); - } - - splx(pcpl); -} - -int -ipic_splraise(int newcpl) -{ - struct cpu_info *ci = curcpu(); - int ocpl = ci->ci_cpl; - int s; - - if (ocpl > newcpl) - newcpl = ocpl; - - s = ppc_intr_disable(); - ipic_setipl(newcpl); - ppc_intr_enable(s); - - return (ocpl); -} - -int -ipic_spllower(int newcpl) -{ - struct cpu_info *ci = curcpu(); - int ocpl = ci->ci_cpl; - - ipic_splx(newcpl); - - return (ocpl); -} - -void -ipic_splx(int newcpl) -{ - struct cpu_info *ci = curcpu(); - int intr, s; - - intr = ppc_intr_disable(); - ipic_setipl(newcpl); - if (newcpl < IPL_SOFTTTY && (ci->ci_ipending & ppc_smask[newcpl])) { - s = splsofttty(); - dosoftint(newcpl); - ipic_setipl(s); /* no-overhead splx */ - } - ppc_intr_enable(intr); -} - -/* Must be called with interrupt disable. */ -void -ipic_setipl(int ipl) -{ - struct cpu_info *ci = curcpu(); - struct ipic_softc *sc = ipic_sc; - uint32_t mask; - - ci->ci_cpl = ipl; - mask = sc->sc_simsr_h[IPL_HIGH] & ~sc->sc_simsr_h[ipl]; - ipic_write(sc, IPIC_SIMSR_H, mask); - mask = sc->sc_simsr_l[IPL_HIGH] & ~sc->sc_simsr_l[ipl]; - ipic_write(sc, IPIC_SIMSR_L, mask); - mask = sc->sc_semsr[IPL_HIGH] & ~sc->sc_semsr[ipl]; - ipic_write(sc, IPIC_SEMSR, mask); -} diff --git a/sys/arch/socppc/dev/obio.c b/sys/arch/socppc/dev/obio.c deleted file mode 100644 index 77b517208d0..00000000000 --- a/sys/arch/socppc/dev/obio.c +++ /dev/null @@ -1,101 +0,0 @@ -/* $OpenBSD: obio.c,v 1.6 2014/05/09 18:16:15 miod Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> - -#include <machine/autoconf.h> - -#include <dev/ofw/openfirm.h> - -int obio_match(struct device *, void *, void *); -void obio_attach(struct device *, struct device *, void *); - -struct cfattach obio_ca = { - sizeof(struct device), obio_match, obio_attach -}; - -struct cfdriver obio_cd = { - NULL, "obio", DV_DULL -}; - -int obio_print(void *, const char *); - -int -obio_match(struct device *parent, void *cfdata, void *aux) -{ - struct mainbus_attach_args *ma = aux; - char buf[32]; - - if (OF_getprop(ma->ma_node, "device_type", buf, sizeof(buf)) <= 0) - return (0); - - if (strcmp(buf, "soc") == 0) - return (1); - - return (0); -} - -void -obio_attach(struct device *parent, struct device *self, void *aux) -{ - struct mainbus_attach_args *ma = aux; - struct obio_attach_args oa; - char name[32]; - int node; - - printf("\n"); - - for (node = OF_child(ma->ma_node); node != 0; node = OF_peer(node)) { - int reg, ivec; - - if (OF_getprop(node, "name", name, sizeof(name)) <= 0) - continue; - - if (OF_getprop(node, "reg", ®, sizeof(reg)) <= 0) - reg = 0; - - if (OF_getprop(node, "interrupts", &ivec, sizeof(ivec)) <= 0) - ivec = -1; - - bzero(&oa, sizeof oa); - oa.oa_iot = ma->ma_iot; - oa.oa_dmat = ma->ma_dmat; - oa.oa_name = name; - oa.oa_node = node; - oa.oa_offset = reg; - oa.oa_ivec = ivec; - config_found(self, &oa, obio_print); - } -} - -int -obio_print(void *aux, const char *name) -{ - struct obio_attach_args *oa = aux; - - if (name) - printf("\"%s\" at %s", oa->oa_name, name); - if (oa->oa_offset) - printf(" offset 0x%05lx", oa->oa_offset); - if (oa->oa_ivec != -1) - printf(" ivec %d", oa->oa_ivec); - - return (UNCONF); -} diff --git a/sys/arch/socppc/dev/pciide_machdep.c b/sys/arch/socppc/dev/pciide_machdep.c deleted file mode 100644 index b9b3ab8a9c9..00000000000 --- a/sys/arch/socppc/dev/pciide_machdep.c +++ /dev/null @@ -1,40 +0,0 @@ -/* $OpenBSD: pciide_machdep.c,v 1.1 2008/05/10 12:02:20 kettenis Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pciidereg.h> -#include <dev/pci/pciidevar.h> - -#include <machine/autoconf.h> - -void * -pciide_machdep_compat_intr_establish(struct device *dev, - struct pci_attach_args *pa, int chan, int (*func)(void *), void *arg) -{ - return (NULL); -} - -void -pciide_machdep_compat_intr_disestablish(pci_chipset_tag_t pc, void *cookie) -{ -} diff --git a/sys/arch/socppc/dev/sociic.c b/sys/arch/socppc/dev/sociic.c deleted file mode 100644 index 36d41c2dadd..00000000000 --- a/sys/arch/socppc/dev/sociic.c +++ /dev/null @@ -1,299 +0,0 @@ -/* $OpenBSD: sociic.c,v 1.2 2009/09/06 20:09:34 kettenis Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Driver for the I2C interface on the MPC8349E processors. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/rwlock.h> - -#include <machine/autoconf.h> -#include <machine/bus.h> - -#include <dev/ofw/openfirm.h> - -#include <dev/i2c/i2cvar.h> - -#define I2C_ADR 0x00 /* Address Register */ -#define I2C_FDR 0x04 /* Fequency Divider Register */ -#define I2C_CR 0x08 /* Control Register */ -#define I2C_CR_MEN 0x80 -#define I2C_CR_MIEN 0x40 -#define I2C_CR_MSTA 0x20 -#define I2C_CR_MTX 0x10 -#define I2C_CR_TXAK 0x08 -#define I2C_CR_RSTA 0x04 -#define I2C_CR_BCST 0x01 -#define I2C_SR 0x0c /* Status Register */ -#define I2C_SR_MCF 0x80 -#define I2C_SR_MAAS 0x40 -#define I2C_SR_MBB 0x20 -#define I2C_SR_MAL 0x10 -#define I2C_SR_BCSTM 0x08 -#define I2C_SR_SRW 0x04 -#define I2C_SR_MIF 0x02 -#define I2C_SR_RXAK 0x01 -#define I2C_DR 0x10 /* Data Register */ -#define I2C_DFSRR 0x14 /* Digital Filter Sampling Rate Register */ - -struct sociic_softc { - struct device sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - - struct i2c_controller sc_i2c; - struct rwlock sc_lock; -}; - -int sociic_match(struct device *, void *, void *); -void sociic_attach(struct device *, struct device *, void *); - -struct cfattach sociic_ca = { - sizeof(struct sociic_softc), sociic_match, sociic_attach -}; - -struct cfdriver sociic_cd = { - NULL, "sociic", DV_DULL -}; - -void sociic_write(struct sociic_softc *, bus_addr_t, uint8_t); -uint8_t sociic_read(struct sociic_softc *, bus_addr_t); -int sociic_wait(struct sociic_softc *, int); -int sociic_wait_bus(struct sociic_softc *); -int sociic_i2c_acquire_bus(void *, int); -void sociic_i2c_release_bus(void *, int); -int sociic_i2c_exec(void *, i2c_op_t, i2c_addr_t, - const void *, size_t, void *, size_t, int); - -int -sociic_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "fsl-i2c") != 0) - return (0); - - return (1); -} - -void -sociic_attach(struct device *parent, struct device *self, void *aux) -{ - struct sociic_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - struct i2cbus_attach_args iba; - - sc->sc_iot = oa->oa_iot; - if (bus_space_map(sc->sc_iot, oa->oa_offset, 24, 0, &sc->sc_ioh)) { - printf(": can't map registers\n"); - return; - } - - printf("\n"); - - rw_init(&sc->sc_lock, "iiclk"); - sc->sc_i2c.ic_cookie = sc; - sc->sc_i2c.ic_acquire_bus = sociic_i2c_acquire_bus; - sc->sc_i2c.ic_release_bus = sociic_i2c_release_bus; - sc->sc_i2c.ic_exec = sociic_i2c_exec; - - bzero(&iba, sizeof iba); - iba.iba_name = "iic"; - iba.iba_tag = &sc->sc_i2c; - config_found(&sc->sc_dev, &iba, iicbus_print); -} - -void -sociic_write(struct sociic_softc *sc, bus_addr_t addr, uint8_t data) -{ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, addr, data); -} - -uint8_t -sociic_read(struct sociic_softc *sc, bus_addr_t addr) -{ - return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, addr)); -} - -int -sociic_wait(struct sociic_softc *sc, int flags) -{ - uint8_t sr; - int i; - - for (i = 0; i < 1000; i++) { - sr = sociic_read(sc, I2C_SR); - if (sr & I2C_SR_MIF) { - sociic_write(sc, I2C_SR, 0); - - if (sr & I2C_SR_MAL) - return (EIO); - - if ((sr & I2C_SR_MCF) == 0) - return (EIO); - - if ((flags & I2C_F_READ) == 0 && (sr & I2C_SR_RXAK)) - return (EIO); - - return (0); - } - delay(100); - } - - return (ETIMEDOUT); -} - -int -sociic_wait_bus(struct sociic_softc *sc) -{ - uint8_t sr; - int i; - - for (i = 0; i < 1000; i++) { - sr = sociic_read(sc, I2C_SR); - if ((sr & I2C_SR_MBB) == 0) - return (0); - delay(1000); - } - - return (ETIMEDOUT); -} - -int -sociic_i2c_acquire_bus(void *arg, int flags) -{ - struct sociic_softc *sc = arg; - - if (cold || (flags & I2C_F_POLL)) - return (0); - - return (rw_enter(&sc->sc_lock, RW_WRITE | RW_INTR)); -} - -void -sociic_i2c_release_bus(void *arg, int flags) -{ - struct sociic_softc *sc = arg; - - if (cold || (flags & I2C_F_POLL)) - return; - - rw_exit(&sc->sc_lock); -} - -int -sociic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr, - const void *vcmdbuf, size_t cmdlen, void *vbuf, size_t buflen, int flags) -{ - struct sociic_softc *sc = arg; - const uint8_t *cmdbuf = vcmdbuf; - uint8_t *buf = vbuf; - int err = 0; - size_t len; - uint8_t val; - - /* Clear the bus. */ - sociic_write(sc, I2C_SR, 0); - sociic_write(sc, I2C_CR, I2C_CR_MEN); - err = sociic_wait_bus(sc); - if (err) - return (err); - - if (cmdlen > 0) { - sociic_write(sc, I2C_CR, I2C_CR_MEN|I2C_CR_MSTA|I2C_CR_MTX); - sociic_write(sc, I2C_DR, addr << 1); - err = sociic_wait(sc, I2C_F_WRITE); - if (err) - goto out; - - len = cmdlen; - while (len--) { - sociic_write(sc, I2C_DR, *cmdbuf++); - err = sociic_wait(sc, I2C_F_WRITE); - if (err) - goto out; - } - } - - if (I2C_OP_READ_P(op) && buflen > 0) { - /* RESTART if we did write a command above. */ - val = I2C_CR_MEN|I2C_CR_MSTA|I2C_CR_MTX; - if (cmdlen > 0) - val |= I2C_CR_RSTA; - sociic_write(sc, I2C_CR, val); - sociic_write(sc, I2C_DR, (addr << 1) | 1); - err = sociic_wait(sc, I2C_F_WRITE); - if (err) - goto out; - - /* NACK if we're only sending one byte. */ - val = I2C_CR_MEN|I2C_CR_MSTA; - if (buflen == 1) - val |= I2C_CR_TXAK; - sociic_write(sc, I2C_CR, val); - - /* Dummy read. */ - sociic_read(sc, I2C_DR); - - len = buflen; - while (len--) { - err = sociic_wait(sc, I2C_F_READ); - if (err) - goto out; - - /* NACK on last byte. */ - if (len == 1) - sociic_write(sc, I2C_CR, - I2C_CR_MEN|I2C_CR_MSTA|I2C_CR_TXAK); - /* STOP after last byte. */ - if (len == 0) - sociic_write(sc, I2C_CR, - I2C_CR_MEN|I2C_CR_TXAK); - *buf++ = sociic_read(sc, I2C_DR); - } - } - - if (I2C_OP_WRITE_P(op) && cmdlen == 0 && buflen > 0) { - /* START if we didn't write a command. */ - sociic_write(sc, I2C_CR, I2C_CR_MEN|I2C_CR_MSTA|I2C_CR_MTX); - sociic_write(sc, I2C_DR, addr << 1); - err = sociic_wait(sc, I2C_F_WRITE); - if (err) - goto out; - } - - if (I2C_OP_WRITE_P(op) && buflen > 0) { - len = buflen; - while (len--) { - sociic_write(sc, I2C_DR, *buf++); - err = sociic_wait(sc, I2C_F_WRITE); - if (err) - goto out; - } - } - -out: - /* STOP if we're still holding the bus. */ - sociic_write(sc, I2C_CR, I2C_CR_MEN); - return (err); -} diff --git a/sys/arch/socppc/dev/socpcic.c b/sys/arch/socppc/dev/socpcic.c deleted file mode 100644 index ad319baa25e..00000000000 --- a/sys/arch/socppc/dev/socpcic.c +++ /dev/null @@ -1,441 +0,0 @@ -/* $OpenBSD: socpcic.c,v 1.10 2016/01/21 08:03:08 jsg Exp $ */ - -/* - * Copyright (c) 2008 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> - -#include <machine/autoconf.h> -#include <machine/bus.h> - -#include <dev/ofw/openfirm.h> -#include <dev/ofw/ofw_pci.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -struct socpcic_softc { - struct device sc_dev; - - int sc_node; - - bus_space_tag_t sc_iot; - bus_space_handle_t sc_cfg_ioh; - struct ppc_bus_space sc_mem_bus_space; - struct ppc_bus_space sc_io_bus_space; - bus_dma_tag_t sc_dmat; - struct ppc_pci_chipset sc_pc; - - /* Interrupt mapping. */ - int sc_map_mask[4]; - int *sc_map; - int sc_map_len; - - /* Addres space. */ - uint32_t *sc_ranges; - int sc_ranges_len; -}; - -int socpcic_mainbus_match(struct device *, void *, void *); -void socpcic_mainbus_attach(struct device *, struct device *, void *); -int socpcic_obio_match(struct device *, void *, void *); -void socpcic_obio_attach(struct device *, struct device *, void *); - -struct cfattach socpcic_mainbus_ca = { - sizeof(struct socpcic_softc), - socpcic_mainbus_match, socpcic_mainbus_attach -}; - -struct cfattach socpcic_obio_ca = { - sizeof(struct socpcic_softc), - socpcic_obio_match, socpcic_obio_attach -}; - -struct cfdriver socpcic_cd = { - NULL, "socpcic", DV_DULL -}; - -void socpcic_attach(struct socpcic_softc *sc); -void socpcic_attach_hook(struct device *, struct device *, - struct pcibus_attach_args *); -int socpcic_bus_maxdevs(void *, int); -pcitag_t socpcic_make_tag(void *, int, int, int); -void socpcic_decompose_tag(void *, pcitag_t, int *, int *, int *); -int socpcic_conf_size(void *, pcitag_t); -pcireg_t socpcic_conf_read(void *, pcitag_t, int); -void socpcic_conf_write(void *, pcitag_t, int, pcireg_t); -int socpcic_intr_map(void *, pcitag_t, int, int, pci_intr_handle_t *); -const char *socpcic_intr_string(void *, pci_intr_handle_t); -int socpcic_intr_line(void *, pci_intr_handle_t); -void *socpcic_intr_establish(void *, pci_intr_handle_t, int, - int (*)(void *), void *, const char *); -void socpcic_intr_disestablish(void *, void *); -int socpcic_ether_hw_addr(struct ppc_pci_chipset *, u_int8_t *); - -int socpcic_print(void *, const char *); - -int -socpcic_mainbus_match(struct device *parent, void *cfdata, void *aux) -{ - struct mainbus_attach_args *ma = aux; - char buf[32]; - - if (OF_getprop(ma->ma_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "pci") != 0) - return (0); - - if (OF_getprop(ma->ma_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "fsl,mpc8349-pci") != 0) - return (0); - - return (1); -} - -void -socpcic_mainbus_attach(struct device *parent, struct device *self, void *aux) -{ - struct socpcic_softc *sc = (void *)self; - struct mainbus_attach_args *ma = aux; - int reg[4]; - - if (OF_getprop(ma->ma_node, "reg", ®, sizeof(reg)) < sizeof(reg)) { - printf(": missing registers\n"); - return; - } - - sc->sc_iot = ma->ma_iot; - if (bus_space_map(sc->sc_iot, reg[2], 16, 0, &sc->sc_cfg_ioh)) { - printf(": can't map configuration registers\n"); - return; - } - - sc->sc_node = ma->ma_node; - sc->sc_dmat = ma->ma_dmat; - socpcic_attach(sc); -} - -int -socpcic_obio_match(struct device *parent, void *cfdata, void *aux) -{ - struct obio_attach_args *oa = aux; - char buf[32]; - - if (OF_getprop(oa->oa_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "pci") != 0) - return (0); - - if (OF_getprop(oa->oa_node, "compatible", buf, sizeof(buf)) <= 0 || - strcmp(buf, "83xx") != 0) - return (0); - - return (1); -} - -void -socpcic_obio_attach(struct device *parent, struct device *self, void *aux) -{ - struct socpcic_softc *sc = (void *)self; - struct obio_attach_args *oa = aux; - - if (oa->oa_offset == 0x8500) - oa->oa_offset = 0x8300; - - sc->sc_iot = oa->oa_iot; - if (bus_space_map(sc->sc_iot, oa->oa_offset, 16, 0, &sc->sc_cfg_ioh)) { - printf(": can't map configuration registers\n"); - return; - } - - sc->sc_node = oa->oa_node; - sc->sc_dmat = oa->oa_dmat; - socpcic_attach(sc); -} - -void -socpcic_attach(struct socpcic_softc *sc) -{ - struct pcibus_attach_args pba; - struct extent *io_ex; - struct extent *mem_ex; - bus_addr_t io_base, mem_base; - bus_size_t io_size, mem_size; - uint32_t *ranges; - int len; - - if (OF_getprop(sc->sc_node, "interrupt-map-mask", sc->sc_map_mask, - sizeof(sc->sc_map_mask)) != sizeof(sc->sc_map_mask)) { - printf(": missing interrupt-map-mask\n"); - return; - } - - sc->sc_map_len = OF_getproplen(sc->sc_node, "interrupt-map"); - if (sc->sc_map_len > 0) { - sc->sc_map = malloc(sc->sc_map_len, M_DEVBUF, M_NOWAIT); - if (sc->sc_map == NULL) - panic("out of memory"); - - len = OF_getprop(sc->sc_node, "interrupt-map", - sc->sc_map, sc->sc_map_len); - KASSERT(len == sc->sc_map_len); - } - - sc->sc_ranges_len = OF_getproplen(sc->sc_node, "ranges"); - if (sc->sc_ranges_len <= 0) { - printf(": missing ranges\n"); - return; - } - - sc->sc_ranges = malloc(sc->sc_ranges_len, M_DEVBUF, M_NOWAIT); - if (sc->sc_ranges == NULL) - panic("out of memory"); - - len = OF_getprop(sc->sc_node, "ranges", sc->sc_ranges, - sc->sc_ranges_len); - KASSERT(len == sc->sc_ranges_len); - - ranges = sc->sc_ranges; - while (len >= 6 * sizeof(uint32_t)) { - switch (ranges[0] & OFW_PCI_PHYS_HI_SPACEMASK) { - case OFW_PCI_PHYS_HI_SPACE_IO: - KASSERT(ranges[1] == 0); - KASSERT(ranges[4] == 0); - sc->sc_io_bus_space.bus_base = ranges[3]; - sc->sc_io_bus_space.bus_size = ranges[5]; - sc->sc_io_bus_space.bus_io = 1; - io_base = ranges[2]; - io_size = ranges[5]; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM32: - KASSERT(ranges[1] == 0); - KASSERT(ranges[4] == 0); - sc->sc_mem_bus_space.bus_base = ranges[3]; - sc->sc_mem_bus_space.bus_size = ranges[5]; - sc->sc_mem_bus_space.bus_io = 0; - mem_base = ranges[2]; - mem_size = ranges[5]; - break; - } - len -= 6 * sizeof(uint32_t); - ranges += 6; - } - - sc->sc_pc.pc_conf_v = sc; - sc->sc_pc.pc_attach_hook = socpcic_attach_hook; - sc->sc_pc.pc_bus_maxdevs = socpcic_bus_maxdevs; - sc->sc_pc.pc_make_tag = socpcic_make_tag; - sc->sc_pc.pc_decompose_tag = socpcic_decompose_tag; - sc->sc_pc.pc_conf_size = socpcic_conf_size; - sc->sc_pc.pc_conf_read = socpcic_conf_read; - sc->sc_pc.pc_conf_write = socpcic_conf_write; - - sc->sc_pc.pc_intr_v = sc; - sc->sc_pc.pc_intr_map = socpcic_intr_map; - sc->sc_pc.pc_intr_string = socpcic_intr_string; - sc->sc_pc.pc_intr_line = socpcic_intr_line; - sc->sc_pc.pc_intr_establish = socpcic_intr_establish; - sc->sc_pc.pc_intr_disestablish = socpcic_intr_disestablish; - sc->sc_pc.pc_ether_hw_addr = socpcic_ether_hw_addr; - - io_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF, NULL, 0, - EX_NOWAIT | EX_FILLED); - if (io_ex != NULL && io_size) - extent_free(io_ex, io_base, io_size, EX_NOWAIT); - mem_ex = extent_create("pcimem", 0, 0xffffffff, M_DEVBUF, NULL, 0, - EX_NOWAIT | EX_FILLED); - if (mem_ex != NULL) - extent_free(mem_ex, mem_base, mem_size, EX_NOWAIT); - - bzero(&pba, sizeof(pba)); - pba.pba_busname = "pci"; - pba.pba_iot = &sc->sc_io_bus_space; - pba.pba_memt = &sc->sc_mem_bus_space; - pba.pba_dmat = sc->sc_dmat; - pba.pba_ioex = io_ex; - pba.pba_memex = mem_ex; - pba.pba_pc = &sc->sc_pc; - pba.pba_domain = pci_ndomains++; - pba.pba_bus = 0; - - printf("\n"); - - config_found((struct device *)sc, &pba, socpcic_print); -} - -void -socpcic_attach_hook(struct device *parent, struct device *self, - struct pcibus_attach_args *pba) -{ -} - -int -socpcic_bus_maxdevs(void *cpv, int bus) -{ - return (32); -} - -pcitag_t -socpcic_make_tag(void *cpv, int bus, int dev, int fun) -{ - return ((bus << 16) | (dev << 11) | (fun << 8)); -} - -void -socpcic_decompose_tag(void *cpv, pcitag_t tag, int *busp, int *devp, int *funp) -{ - if (busp) - *busp = (tag >> 16) & 0xff; - if (devp) - *devp = (tag >> 11) & 0x1f; - if (funp) - *funp = (tag >> 8) & 0x7; -} - -int -socpcic_conf_size(void *cpv, pcitag_t tag) -{ - return PCI_CONFIG_SPACE_SIZE; -} - -pcireg_t -socpcic_conf_read(void *cpv, pcitag_t tag, int offset) -{ - struct socpcic_softc *sc = cpv; - int bus, dev, fun; - pcireg_t addr, data; - - socpcic_decompose_tag(sc, tag, &bus, &dev, &fun); - if (bus == 0) { - if (dev > 0 && dev < 11) - return (0xffffffff); - if (dev == 31) - tag = (10 << 11) | (fun << 8); - } - - addr = 0x80000000 | tag | offset; - bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, 0, addr); - bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, 0); - data = bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, 4); - bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, 0, 0); - bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, 0); - - return (data); -} - -void -socpcic_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data) -{ - struct socpcic_softc *sc = cpv; - int bus, dev, fun; - pcireg_t addr; - - socpcic_decompose_tag(sc, tag, &bus, &dev, &fun); - if (bus == 0) { - if (dev > 0 && dev < 11) - return; - if (dev == 31) - tag = (10 << 11) | (fun << 8); - } - - addr = 0x80000000 | tag | offset; - bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, 0, addr); - bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, 0); - bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, 4, data); - bus_space_write_4(sc->sc_iot, sc->sc_cfg_ioh, 0, 0); - bus_space_read_4(sc->sc_iot, sc->sc_cfg_ioh, 0); -} - -int -socpcic_intr_map(void *cpv, pcitag_t tag, int pin, int line, - pci_intr_handle_t *ihp) -{ - struct socpcic_softc *sc = cpv; - int bus, dev, func; - int reg[4]; - int *map; - int len; - - pci_decompose_tag(&sc->sc_pc, tag, &bus, &dev, &func); - - reg[0] = (dev << 11) | (func << 8); - reg[1] = reg[2] = 0; - reg[3] = pin; - - map = sc->sc_map; - len = sc->sc_map_len; - while (len >= 7 * sizeof(int)) { - if ((reg[0] & sc->sc_map_mask[0]) == map[0] && - (reg[1] & sc->sc_map_mask[1]) == map[1] && - (reg[2] & sc->sc_map_mask[2]) == map[2] && - (reg[3] & sc->sc_map_mask[3]) == map[3]) { - *ihp = map[5]; - return (0); - } - len -= 7 * sizeof(int); - map += 7; - } - - return (1); -} - -const char * -socpcic_intr_string(void *cpv, pci_intr_handle_t ih) -{ - static char str[16]; - - snprintf(str, sizeof str, "ivec %ld", ih); - return (str); -} - -int -socpcic_intr_line(void *cpv, pci_intr_handle_t ih) -{ - return (ih); -} - -void * -socpcic_intr_establish(void *cpv, pci_intr_handle_t ih, int level, - int (*func)(void *), void *arg, const char *name) -{ - return (intr_establish(ih, IST_LEVEL, level, func, arg, name)); -} - -void -socpcic_intr_disestablish(void *lcv, void *cookie) -{ -} - -int -socpcic_ether_hw_addr(struct ppc_pci_chipset *lcpc, u_int8_t *oaddr) -{ - oaddr[0] = oaddr[1] = oaddr[2] = 0xff; - oaddr[3] = oaddr[4] = oaddr[5] = 0xff; - - return (0); -} - -int -socpcic_print(void *aux, const char *pnp) -{ - struct pcibus_attach_args *pba = aux; - - if (pnp) - printf("%s at %s", pba->pba_busname, pnp); - printf(" bus %d", pba->pba_bus); - return (UNCONF); -} diff --git a/sys/arch/socppc/dev/wdc_mainbus.c b/sys/arch/socppc/dev/wdc_mainbus.c deleted file mode 100644 index dfe3470ed37..00000000000 --- a/sys/arch/socppc/dev/wdc_mainbus.c +++ /dev/null @@ -1,178 +0,0 @@ -/* $OpenBSD: wdc_mainbus.c,v 1.2 2011/05/09 22:33:54 matthew Exp $ */ - -/* - * Copyright (c) 2009 Mark Kettenis - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Driver for Compact Flash interface on the local bus of a PowerQUICC - * MPC8343E processor as found on the RouterBOARD 600. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/malloc.h> - -#include <machine/autoconf.h> - -#include <dev/ofw/openfirm.h> - -#include <dev/ata/atavar.h> -#include <dev/ic/wdcvar.h> - -struct wdc_mainbus_softc { - struct wdc_softc sc_wdcdev; - struct channel_softc *sc_chanptr; - struct channel_softc sc_channel; - - void *sc_ih; -}; - -int wdc_mainbus_match(struct device *, void *, void *); -void wdc_mainbus_attach(struct device *, struct device *, void *); - -struct cfattach wdc_mainbus_ca = { - sizeof(struct wdc_mainbus_softc), wdc_mainbus_match, wdc_mainbus_attach -}; - -/* - * The CF slots on the RouterBOARD 600 are wired up in a completely - * retarded way. Instead of using the obvious address lines it uses - * LAD[11:15], which means we need to waste more than 0.5 MB of - * address space to map 10 8-bit registers. - */ -#define WDC_MAINBUS_REG_NPORTS WDC_NREG -#define WDC_MAINBUS_REG_SIZE (WDC_MAINBUS_REG_NPORTS << 16) -#define WDC_MAINBUS_REG_OFFSET (8 << 17) -#define WDC_MAINBUS_AUXREG_NPORTS 2 -#define WDC_MAINBUS_AUXREG_SIZE (WDC_MAINBUS_AUXREG_NPORTS << 16) -#define WDC_MAINBUS_AUXREG_OFFSET (6 << 16) - -u_int8_t wdc_mainbus_read_reg(struct channel_softc *chp, enum wdc_regs reg); -void wdc_mainbus_write_reg(struct channel_softc *chp, enum wdc_regs reg, - u_int8_t val); - -struct channel_softc_vtbl wdc_mainbus_vtbl = { - wdc_mainbus_read_reg, - wdc_mainbus_write_reg, - wdc_default_lba48_write_reg, - wdc_default_read_raw_multi_2, - wdc_default_write_raw_multi_2, - wdc_default_read_raw_multi_4, - wdc_default_write_raw_multi_4 -}; - -int -wdc_mainbus_match(struct device *parent, void *cfdata, void *aux) -{ - struct mainbus_attach_args *ma = aux; - char buf[32]; - - if (OF_getprop(ma->ma_node, "device_type", buf, sizeof(buf)) <= 0 || - strcmp(buf, "rb,cf") != 0) - return (0); - - return (1); -} - -void -wdc_mainbus_attach(struct device *parent, struct device *self, void *aux) -{ - struct wdc_mainbus_softc *sc = (void *)self; - struct mainbus_attach_args *ma = aux; - struct channel_softc *chp = &sc->sc_channel; - int reg[2]; - int ivec; - - if (OF_getprop(ma->ma_node, "reg", ®, sizeof(reg)) < sizeof(reg)) { - printf(": missing registers\n"); - return; - } - - if (OF_getprop(ma->ma_node, "interrupts", &ivec, sizeof(ivec)) <= 0) { - printf(": missing interrupts\n"); - return; - } - - chp->cmd_iot = chp->ctl_iot = ma->ma_iot; - chp->_vtbl = &wdc_mainbus_vtbl; - - if (bus_space_map(chp->cmd_iot, reg[0] + WDC_MAINBUS_REG_OFFSET, - WDC_MAINBUS_REG_SIZE, 0, &chp->cmd_ioh)) { - printf(": can't map registers\n"); - return; - } - if (bus_space_map(chp->ctl_iot, reg[0] + WDC_MAINBUS_AUXREG_OFFSET, - WDC_MAINBUS_AUXREG_SIZE, 0, &chp->ctl_ioh)) { - printf(": can't map registers\n"); - return; - } - - sc->sc_ih = intr_establish(ivec, IST_LEVEL, IPL_BIO, wdcintr, - chp, self->dv_xname); - - sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_PREATA; - sc->sc_wdcdev.PIO_cap = 0; - sc->sc_chanptr = chp; - sc->sc_wdcdev.channels = &sc->sc_chanptr; - sc->sc_wdcdev.nchannels = 1; - chp->channel = 0; - chp->wdc = &sc->sc_wdcdev; - - chp->ch_queue = wdc_alloc_queue(); - if (chp->ch_queue == NULL) { - printf("%s: cannot allocate channel queue\n", - self->dv_xname); - /* XXX disestablish interrupt */ - return; - } - - printf("\n"); - - wdcattach(chp); - wdc_print_current_modes(chp); -} - -u_int8_t -wdc_mainbus_read_reg(struct channel_softc *chp, enum wdc_regs reg) -{ - uint8_t val; - - if (reg & _WDC_AUX) { - val = bus_space_read_1(chp->ctl_iot, chp->ctl_ioh, - (reg & _WDC_REGMASK) << 16); - if (val == 0xf9 && reg == wdr_altsts) - val = 0x7f; - } else { - val = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, - (reg & _WDC_REGMASK) << 16); - if (val == 0xf9 && reg == wdr_status) - val = 0x7f; - } - return val; -} - -void -wdc_mainbus_write_reg(struct channel_softc *chp, enum wdc_regs reg, - u_int8_t val) -{ - if (reg & _WDC_AUX) - bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, - (reg & _WDC_REGMASK) << 16, val); - else - bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, - (reg & _WDC_REGMASK) << 16, val); -} |