/*
* Copyright (c) 2000 Matthew R. Green
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* PCI front-end device driver for the HME ethernet device.
*/
csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_HME_BASEADDR);
/*
* enable io/memory-space accesses. this is kinda of gross; but
* the hme comes up with neither IO space enabled, or memory space.
*/
switch (type) {
case PCI_MAPREG_TYPE_MEM:
csr |= PCI_COMMAND_MEM_ENABLE;
sc->sc_bustag = pa->pa_memt;
break;
case PCI_MAPREG_TYPE_IO:
csr |= PCI_COMMAND_IO_ENABLE;
sc->sc_bustag = pa->pa_iot;
break;
}
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
csr | PCI_COMMAND_MEM_ENABLE);
sc->sc_dmatag = pa->pa_dmat;
sc->sc_pci = 1; /* XXXXX should all be done in bus_dma. */
/*
* Map five register banks:
*
* bank 0: HME SEB registers: +0x0000
* bank 1: HME ETX registers: +0x2000
* bank 2: HME ERX registers: +0x4000
* bank 3: HME MAC registers: +0x6000
* bank 4: HME MIF registers: +0x7000
*
*/
if (pci_mapreg_map(pa, PCI_HME_BASEADDR, type, 0,
&hsc->hsc_memt, &hsc->hsc_memh, NULL, NULL) != 0) {
aprint_error_dev(self, "unable to map device registers\n");
return;
}
sc->sc_seb = hsc->hsc_memh;
if (bus_space_subregion(hsc->hsc_memt, hsc->hsc_memh, 0x2000,
0x1000, &sc->sc_etx)) {
aprint_error_dev(self, "unable to subregion ETX registers\n");
return;
}
if (bus_space_subregion(hsc->hsc_memt, hsc->hsc_memh, 0x4000,
0x1000, &sc->sc_erx)) {
aprint_error_dev(self, "unable to subregion ERX registers\n");
return;
}
if (bus_space_subregion(hsc->hsc_memt, hsc->hsc_memh, 0x6000,
0x1000, &sc->sc_mac)) {
aprint_error_dev(self, "unable to subregion MAC registers\n");
return;
}
if (bus_space_subregion(hsc->hsc_memt, hsc->hsc_memh, 0x7000,
0x1000, &sc->sc_mif)) {
aprint_error_dev(self, "unable to subregion MIF registers\n");
return;
}
/*
* Check if we got a mac-address property passed
*/
eaddrprop = prop_dictionary_get(device_properties(self), "mac-address");
/*
* Dig out VPD (vital product data) and acquire Ethernet address.
* The VPD of hme resides in the Boot PROM (PCI FCode) attached
* to the EBus interface.
*/
/*
* ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
* chapter 2 describes the data structure.
*/
enaddr = NULL;
/* get a PCI tag for the EBus bridge (function 0 of the same device) */
ebus_pa = *pa;
ebus_pa.pa_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0);