xref: /haiku/src/add-ons/kernel/drivers/network/ether/sis19x/glue.c (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
1cbe0a0c4SAugustin Cavalier /*
2cbe0a0c4SAugustin Cavalier  * Copyright 2009 S.Zharski <imker@gmx.li>
3cbe0a0c4SAugustin Cavalier  * Copyright 2018, Haiku, Inc. All rights reserved.
4cbe0a0c4SAugustin Cavalier  * Distributed under the terms of the MIT License.
5cbe0a0c4SAugustin Cavalier  */
6cbe0a0c4SAugustin Cavalier 
7cbe0a0c4SAugustin Cavalier 
8cbe0a0c4SAugustin Cavalier #include <PCI.h>
9cbe0a0c4SAugustin Cavalier 
10cbe0a0c4SAugustin Cavalier #include <sys/bus.h>
11cbe0a0c4SAugustin Cavalier #include <sys/rman.h>
12cbe0a0c4SAugustin Cavalier #include <sys/systm.h>
13cbe0a0c4SAugustin Cavalier 
14cbe0a0c4SAugustin Cavalier #include <machine/bus.h>
15cbe0a0c4SAugustin Cavalier 
16cbe0a0c4SAugustin Cavalier #include <net/if.h>
17cbe0a0c4SAugustin Cavalier #include <net/if_media.h>
18cbe0a0c4SAugustin Cavalier 
19cbe0a0c4SAugustin Cavalier #include <dev/pci/pcivar.h>
20cbe0a0c4SAugustin Cavalier #include <dev/sge/if_sgereg.h>
21cbe0a0c4SAugustin Cavalier 
22a5c0d1a8SPulkoMandy #include "glue.h"
23a5c0d1a8SPulkoMandy 
24cbe0a0c4SAugustin Cavalier 
25cbe0a0c4SAugustin Cavalier HAIKU_FBSD_DRIVER_GLUE(sis19x, sge, pci);
26*b0719130SAugustin Cavalier HAIKU_DRIVER_REQUIREMENTS(0);
27cbe0a0c4SAugustin Cavalier NO_HAIKU_REENABLE_INTERRUPTS();
28cbe0a0c4SAugustin Cavalier 
29cbe0a0c4SAugustin Cavalier 
30cbe0a0c4SAugustin Cavalier extern pci_module_info *gPci;
31cbe0a0c4SAugustin Cavalier extern driver_t* DRIVER_MODULE_NAME(ukphy, miibus);
32cbe0a0c4SAugustin Cavalier 
33cbe0a0c4SAugustin Cavalier 
34cbe0a0c4SAugustin Cavalier driver_t *
__haiku_select_miibus_driver(device_t dev)35cbe0a0c4SAugustin Cavalier __haiku_select_miibus_driver(device_t dev)
36cbe0a0c4SAugustin Cavalier {
37cbe0a0c4SAugustin Cavalier 	driver_t *drivers[] = {
38cbe0a0c4SAugustin Cavalier 		DRIVER_MODULE_NAME(ukphy, miibus),
39cbe0a0c4SAugustin Cavalier 		NULL
40cbe0a0c4SAugustin Cavalier 	};
41cbe0a0c4SAugustin Cavalier 
42cbe0a0c4SAugustin Cavalier 	return __haiku_probe_miibus(dev, drivers);
43cbe0a0c4SAugustin Cavalier }
44cbe0a0c4SAugustin Cavalier 
45cbe0a0c4SAugustin Cavalier 
46cbe0a0c4SAugustin Cavalier int
HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)47cbe0a0c4SAugustin Cavalier HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
48cbe0a0c4SAugustin Cavalier {
49cbe0a0c4SAugustin Cavalier 	struct sge_softc *sc = device_get_softc(dev);
50cbe0a0c4SAugustin Cavalier 	uint32_t status;
51cbe0a0c4SAugustin Cavalier 
52cbe0a0c4SAugustin Cavalier 	status = CSR_READ_4(sc, IntrStatus);
53cbe0a0c4SAugustin Cavalier 	if (status == 0xFFFFFFFF || (status & SGE_INTRS) == 0) {
54cbe0a0c4SAugustin Cavalier 		/* Not ours. */
55cbe0a0c4SAugustin Cavalier 		return 0;
56cbe0a0c4SAugustin Cavalier 	}
57cbe0a0c4SAugustin Cavalier 
58cbe0a0c4SAugustin Cavalier 	/* Acknowledge interrupts. */
59cbe0a0c4SAugustin Cavalier 	CSR_WRITE_4(sc, IntrStatus, status);
60cbe0a0c4SAugustin Cavalier 	/* Disable further interrupts. */
61cbe0a0c4SAugustin Cavalier 	CSR_WRITE_4(sc, IntrMask, 0);
62cbe0a0c4SAugustin Cavalier 
63cbe0a0c4SAugustin Cavalier 	sc->haiku_interrupt_status = status;
64cbe0a0c4SAugustin Cavalier 	return 1;
65cbe0a0c4SAugustin Cavalier }
66cbe0a0c4SAugustin Cavalier 
67cbe0a0c4SAugustin Cavalier 
68cbe0a0c4SAugustin Cavalier int
haiku_sge_get_mac_addr_apc(device_t dev,uint8_t * dest,int * rgmii)69cbe0a0c4SAugustin Cavalier haiku_sge_get_mac_addr_apc(device_t dev, uint8_t* dest, int* rgmii)
70cbe0a0c4SAugustin Cavalier {
71cbe0a0c4SAugustin Cavalier 	// SiS96x can use APC CMOS RAM to store MAC address,
72cbe0a0c4SAugustin Cavalier 	// this is accessed through ISA bridge.
73cbe0a0c4SAugustin Cavalier 
74cbe0a0c4SAugustin Cavalier 	// look for PCI-ISA bridge
75cbe0a0c4SAugustin Cavalier 	uint16 ids[] = { 0x0965, 0x0966, 0x0968 };
76cbe0a0c4SAugustin Cavalier 
77cbe0a0c4SAugustin Cavalier 	pci_info pciInfo = {0};
78cbe0a0c4SAugustin Cavalier 	long i;
79cbe0a0c4SAugustin Cavalier 	for (i = 0; B_OK == (*gPci->get_nth_pci_info)(i, &pciInfo); i++) {
80cbe0a0c4SAugustin Cavalier 		size_t idx;
81cbe0a0c4SAugustin Cavalier 		if (pciInfo.vendor_id != 0x1039)
82cbe0a0c4SAugustin Cavalier 			continue;
83cbe0a0c4SAugustin Cavalier 
84cbe0a0c4SAugustin Cavalier 		for (idx = 0; idx < B_COUNT_OF(ids); idx++) {
85cbe0a0c4SAugustin Cavalier 			if (pciInfo.device_id == ids[idx]) {
86cbe0a0c4SAugustin Cavalier 				size_t i;
87cbe0a0c4SAugustin Cavalier 				// enable ports 0x78 0x79 to access APC registers
88cbe0a0c4SAugustin Cavalier 				uint32 reg = gPci->read_pci_config(pciInfo.bus,
89cbe0a0c4SAugustin Cavalier 					pciInfo.device, pciInfo.function, 0x48, 1);
90cbe0a0c4SAugustin Cavalier 				reg &= ~0x02;
91cbe0a0c4SAugustin Cavalier 				gPci->write_pci_config(pciInfo.bus,
92cbe0a0c4SAugustin Cavalier 					pciInfo.device, pciInfo.function, 0x48, 1, reg);
93cbe0a0c4SAugustin Cavalier 				snooze(50);
94cbe0a0c4SAugustin Cavalier 				reg = gPci->read_pci_config(pciInfo.bus,
95cbe0a0c4SAugustin Cavalier 					pciInfo.device, pciInfo.function, 0x48, 1);
96cbe0a0c4SAugustin Cavalier 
97cbe0a0c4SAugustin Cavalier 				// read factory MAC address
98cbe0a0c4SAugustin Cavalier 				for (i = 0; i < 6; i++) {
99cbe0a0c4SAugustin Cavalier 					gPci->write_io_8(0x78, 0x09 + i);
100cbe0a0c4SAugustin Cavalier 					dest[i] = gPci->read_io_8(0x79);
101cbe0a0c4SAugustin Cavalier 				}
102cbe0a0c4SAugustin Cavalier 
103cbe0a0c4SAugustin Cavalier 				// check MII/RGMII
104cbe0a0c4SAugustin Cavalier 				gPci->write_io_8(0x78, 0x12);
105cbe0a0c4SAugustin Cavalier 				if ((gPci->read_io_8(0x79) & 0x80) != 0)
106cbe0a0c4SAugustin Cavalier 					*rgmii = 1;
107cbe0a0c4SAugustin Cavalier 
108cbe0a0c4SAugustin Cavalier 				// close access to APC registers
109cbe0a0c4SAugustin Cavalier 				gPci->write_pci_config(pciInfo.bus,
110cbe0a0c4SAugustin Cavalier 					pciInfo.device, pciInfo.function, 0x48, 1, reg);
111cbe0a0c4SAugustin Cavalier 
112cbe0a0c4SAugustin Cavalier 				return B_OK;
113cbe0a0c4SAugustin Cavalier 			}
114cbe0a0c4SAugustin Cavalier 		}
115cbe0a0c4SAugustin Cavalier 	}
116cbe0a0c4SAugustin Cavalier 
117cbe0a0c4SAugustin Cavalier 	return B_ERROR;
118cbe0a0c4SAugustin Cavalier }
119