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