xref: /haiku/src/add-ons/kernel/drivers/network/ether/pcnet/glue.c (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
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 
16 HAIKU_FBSD_DRIVERS_GLUE(pcnet);
17 HAIKU_DRIVER_REQUIREMENTS(0);
18 
19 extern driver_t *DRIVER_MODULE_NAME(nsphy, miibus);
20 extern driver_t *DRIVER_MODULE_NAME(nsphyter, miibus);
21 extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
22 
23 
24 driver_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 
37 int check_disable_interrupts_le(device_t dev);
38 void reenable_interrupts_le(device_t dev);
39 
40 extern int check_disable_interrupts_pcn(device_t dev);
41 extern void reenable_interrupts_pcn(device_t dev);
42 
43 
44 extern driver_t *DRIVER_MODULE_NAME(le, pci);
45 extern driver_t *DRIVER_MODULE_NAME(pcn, pci);
46 
47 
48 status_t
49 __haiku_handle_fbsd_drivers_list(status_t (*handler)(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);
57 }
58 
59 
60 int
61 HAIKU_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 
78 void
79 HAIKU_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 
100 struct 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 
113 int
114 check_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