1#include <sys/bus.h>
2#include <sys/mutex.h>
3#include <sys/rman.h>
4
5#include <net/ethernet.h>
6#include <net/if.h>
7#include <net/if_media.h>
8
9#include <machine/bus.h>
10#include <shared.h>
11
12#include <dev/le/lancereg.h>
13#include <dev/le/lancevar.h>
14#include <dev/le/am79900var.h>
15
16HAIKU_FBSD_DRIVERS_GLUE(pcnet);
17HAIKU_DRIVER_REQUIREMENTS(0);
18
19extern driver_t *DRIVER_MODULE_NAME(nsphy, miibus);
20extern driver_t *DRIVER_MODULE_NAME(nsphyter, miibus);
21extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
22
23
24driver_t *
25__haiku_select_miibus_driver(device_t dev)
26{
27	driver_t *drivers[] = {
28		DRIVER_MODULE_NAME(nsphy, miibus),
29		DRIVER_MODULE_NAME(nsphyter, miibus),
30		DRIVER_MODULE_NAME(ukphy, miibus),
31		NULL
32	};
33
34	return __haiku_probe_miibus(dev, drivers);
35}
36
37int check_disable_interrupts_le(device_t dev);
38void reenable_interrupts_le(device_t dev);
39
40extern int check_disable_interrupts_pcn(device_t dev);
41extern void reenable_interrupts_pcn(device_t dev);
42
43
44extern driver_t *DRIVER_MODULE_NAME(le, pci);
45extern driver_t *DRIVER_MODULE_NAME(pcn, pci);
46
47
48status_t
49__haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[], driver_t *[]))
50{
51	driver_t *drivers[] = {
52		DRIVER_MODULE_NAME(le, pci),
53		DRIVER_MODULE_NAME(pcn, pci),
54		NULL
55	};
56	return (*handler)(drivers, NULL);
57}
58
59
60int
61HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
62{
63	switch (dev->device_name[0]) {
64		case 'l':
65			return check_disable_interrupts_le(dev);
66		case 'p':
67			return check_disable_interrupts_pcn(dev);
68		default:
69			break;
70	}
71
72	panic("Unsupported device: %#x (%s)!", dev->device_name[0],
73		dev->device_name);
74	return 0;
75}
76
77
78void
79HAIKU_REENABLE_INTERRUPTS(device_t dev)
80{
81	switch (dev->device_name[0]) {
82		case 'l':
83			break;
84		case 'p':
85			reenable_interrupts_pcn(dev);
86			break;
87		default:
88			panic("Unsupported device: %#x (%s)!", dev->device_name[0],
89				dev->device_name);
90			break;
91	}
92}
93
94
95
96/* from if_le_pci.c */
97#define	PCNET_PCI_RDP	0x10
98#define	PCNET_PCI_RAP	0x12
99
100struct le_pci_softc {
101	struct am79900_softc	sc_am79900;	/* glue to MI code */
102
103	struct resource		*sc_rres;
104
105	struct resource		*sc_ires;
106	void				*sc_ih;
107
108	bus_dma_tag_t		sc_pdmat;
109	bus_dma_tag_t		sc_dmat;
110	bus_dmamap_t		sc_dmam;
111};
112
113int
114check_disable_interrupts_le(device_t dev)
115{
116	struct le_pci_softc *lesc = (struct le_pci_softc *)device_get_softc(dev);
117	HAIKU_INTR_REGISTER_STATE;
118	uint16_t isr;
119
120	HAIKU_INTR_REGISTER_ENTER();
121
122	/* get current flags */
123	bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, LE_CSR0);
124	bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE);
125	isr = (bus_read_2(lesc->sc_rres, PCNET_PCI_RDP));
126
127	/* is there a pending interrupt? */
128	if ((isr & LE_C0_INTR) == 0) {
129		HAIKU_INTR_REGISTER_LEAVE();
130		return 0;
131	}
132
133	/* set the new flags, disable interrupts */
134	bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, LE_CSR0);
135	bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE);
136	bus_write_2(lesc->sc_rres, PCNET_PCI_RDP, isr & ~(LE_C0_INEA));
137
138	lesc->sc_am79900.lsc.sc_lastisr |= isr;
139
140	HAIKU_INTR_REGISTER_LEAVE();
141
142	return 1;
143}
144