xref: /haiku/src/add-ons/kernel/drivers/network/ether/dec21xxx/glue.c (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2011, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Author(s):
6  *		Axel Dörfler <axeld@pinc-software.de>
7  *		Siarzhuk Zharski <imker@gmx.li>
8  */
9 
10 
11 #include <sys/bus.h>
12 #include <sys/mutex.h>
13 #include <sys/systm.h>
14 #include <machine/bus.h>
15 #include <shared.h>
16 
17 #include "if_dcreg.h"
18 
19 
20 int check_disable_interrupts_dc(device_t dev);
21 void reenable_interrupts_dc(device_t dev);
22 
23 extern int check_disable_interrupts_de(device_t dev);
24 extern void reenable_interrupts_de(device_t dev);
25 
26 
27 HAIKU_FBSD_DRIVERS_GLUE(dec21xxx);
28 
29 HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_FAST_TASKQUEUE | FBSD_SWI_TASKQUEUE);
30 
31 
32 extern driver_t *DRIVER_MODULE_NAME(dc, pci);
33 extern driver_t *DRIVER_MODULE_NAME(de, pci);
34 
35 status_t
36 __haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[]))
37 {
38 	driver_t *drivers[] = {
39 		DRIVER_MODULE_NAME(dc, pci),
40 		DRIVER_MODULE_NAME(de, pci),
41 		NULL
42 	};
43 	return (*handler)(drivers);
44 }
45 
46 
47 extern driver_t *DRIVER_MODULE_NAME(acphy, miibus);
48 extern driver_t *DRIVER_MODULE_NAME(amphy, miibus);
49 extern driver_t *DRIVER_MODULE_NAME(dcphy, miibus);
50 extern driver_t *DRIVER_MODULE_NAME(pnphy, miibus);
51 extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
52 
53 driver_t *
54 __haiku_select_miibus_driver(device_t dev)
55 {
56 	driver_t *drivers[] = {
57 		DRIVER_MODULE_NAME(acphy, miibus),
58 		DRIVER_MODULE_NAME(amphy, miibus),
59 		DRIVER_MODULE_NAME(dcphy, miibus),
60 		DRIVER_MODULE_NAME(pnphy, miibus),
61 		DRIVER_MODULE_NAME(ukphy, miibus),
62 		NULL
63 	};
64 
65 	return __haiku_probe_miibus(dev, drivers);
66 }
67 
68 
69 int
70 HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
71 {
72 	uint16 name = *(uint16*)dev->device_name;
73 	switch (name) {
74 		case 'cd':
75 			return check_disable_interrupts_dc(dev);
76 		case 'ed':
77 			return check_disable_interrupts_de(dev);
78 		default:
79 			break;
80 	}
81 
82 	panic("Unsupported device: %#x (%s)!", name, dev->device_name);
83 	return 0;
84 }
85 
86 
87 void
88 HAIKU_REENABLE_INTERRUPTS(device_t dev)
89 {
90 	uint16 name = *(uint16*)dev->device_name;
91 	switch (name) {
92 		case 'cd':
93 			reenable_interrupts_dc(dev);
94 			break;
95 		case 'ed':
96 			reenable_interrupts_de(dev);
97 			break;
98 		default:
99 			panic("Unsupported device: %#x (%s)!", name, dev->device_name);
100 			break;
101 	}
102 }
103 
104 
105 int
106 check_disable_interrupts_dc(device_t dev)
107 {
108 	struct dc_softc *sc = device_get_softc(dev);
109 	uint16_t status;
110 	HAIKU_INTR_REGISTER_STATE;
111 
112 	HAIKU_INTR_REGISTER_ENTER();
113 
114 	status = CSR_READ_4(sc, DC_ISR);
115 	if (status == 0xffff) {
116 		HAIKU_INTR_REGISTER_LEAVE();
117 		return 0;
118 	}
119 
120 	if (status != 0 && (status & DC_INTRS) == 0) {
121 		CSR_WRITE_4(sc, DC_ISR, status);
122 		HAIKU_INTR_REGISTER_LEAVE();
123 		return 0;
124 	}
125 
126 	if ((status & DC_INTRS) == 0) {
127 		HAIKU_INTR_REGISTER_LEAVE();
128 		return 0;
129 	}
130 
131 	CSR_WRITE_4(sc, DC_IMR, 0);
132 
133 	HAIKU_INTR_REGISTER_LEAVE();
134 
135 	return 1;
136 }
137 
138 
139 void
140 reenable_interrupts_dc(device_t dev)
141 {
142 	struct dc_softc *sc = device_get_softc(dev);
143 	DC_LOCK(sc);
144 	CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
145 	DC_UNLOCK(sc);
146 }
147 
148