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 23 HAIKU_FBSD_DRIVER_GLUE(sis19x, sge, pci); 24 HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_FAST_TASKQUEUE); 25 NO_HAIKU_REENABLE_INTERRUPTS(); 26 27 28 extern pci_module_info *gPci; 29 extern driver_t* DRIVER_MODULE_NAME(ukphy, miibus); 30 31 32 driver_t * 33 __haiku_select_miibus_driver(device_t dev) 34 { 35 driver_t *drivers[] = { 36 DRIVER_MODULE_NAME(ukphy, miibus), 37 NULL 38 }; 39 40 return __haiku_probe_miibus(dev, drivers); 41 } 42 43 44 int 45 HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) 46 { 47 struct sge_softc *sc = device_get_softc(dev); 48 uint32_t status; 49 50 status = CSR_READ_4(sc, IntrStatus); 51 if (status == 0xFFFFFFFF || (status & SGE_INTRS) == 0) { 52 /* Not ours. */ 53 return 0; 54 } 55 56 /* Acknowledge interrupts. */ 57 CSR_WRITE_4(sc, IntrStatus, status); 58 /* Disable further interrupts. */ 59 CSR_WRITE_4(sc, IntrMask, 0); 60 61 sc->haiku_interrupt_status = status; 62 return 1; 63 } 64 65 66 int 67 haiku_sge_get_mac_addr_apc(device_t dev, uint8_t* dest, int* rgmii) 68 { 69 // SiS96x can use APC CMOS RAM to store MAC address, 70 // this is accessed through ISA bridge. 71 72 // look for PCI-ISA bridge 73 uint16 ids[] = { 0x0965, 0x0966, 0x0968 }; 74 75 pci_info pciInfo = {0}; 76 long i; 77 for (i = 0; B_OK == (*gPci->get_nth_pci_info)(i, &pciInfo); i++) { 78 size_t idx; 79 if (pciInfo.vendor_id != 0x1039) 80 continue; 81 82 for (idx = 0; idx < B_COUNT_OF(ids); idx++) { 83 if (pciInfo.device_id == ids[idx]) { 84 size_t i; 85 // enable ports 0x78 0x79 to access APC registers 86 uint32 reg = gPci->read_pci_config(pciInfo.bus, 87 pciInfo.device, pciInfo.function, 0x48, 1); 88 reg &= ~0x02; 89 gPci->write_pci_config(pciInfo.bus, 90 pciInfo.device, pciInfo.function, 0x48, 1, reg); 91 snooze(50); 92 reg = gPci->read_pci_config(pciInfo.bus, 93 pciInfo.device, pciInfo.function, 0x48, 1); 94 95 // read factory MAC address 96 for (i = 0; i < 6; i++) { 97 gPci->write_io_8(0x78, 0x09 + i); 98 dest[i] = gPci->read_io_8(0x79); 99 } 100 101 // check MII/RGMII 102 gPci->write_io_8(0x78, 0x12); 103 if ((gPci->read_io_8(0x79) & 0x80) != 0) 104 *rgmii = 1; 105 106 // close access to APC registers 107 gPci->write_pci_config(pciInfo.bus, 108 pciInfo.device, pciInfo.function, 0x48, 1, reg); 109 110 return B_OK; 111 } 112 } 113 } 114 115 return B_ERROR; 116 } 117