diff options
Diffstat (limited to 'nic3com.c')
-rw-r--r-- | nic3com.c | 111 |
1 files changed, 66 insertions, 45 deletions
@@ -14,12 +14,11 @@ * GNU General Public License for more details. */ -#if defined(__i386__) || defined(__x86_64__) - #include <stdlib.h> #include "flash.h" #include "programmer.h" -#include "hwaccess.h" +#include "hwaccess_x86_io.h" +#include "platform/pci.h" #define BIOS_ROM_ADDR 0x04 #define BIOS_ROM_DATA 0x08 @@ -29,17 +28,19 @@ #define PCI_VENDOR_ID_3COM 0x10b7 -static uint32_t io_base_addr = 0; -static uint32_t internal_conf; -static uint16_t id; +struct nic3com_data { + uint32_t io_base_addr; + uint32_t internal_conf; + uint16_t id; +}; -const struct dev_entry nics_3com[] = { +static const struct dev_entry nics_3com[] = { /* 3C90xB */ {0x10b7, 0x9055, OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX"}, {0x10b7, 0x9001, NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-T4" }, {0x10b7, 0x9004, OK, "3COM", "3C90xB: PCI 10BASE-T (TPO)" }, {0x10b7, 0x9005, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI (COMBO)" }, - {0x10b7, 0x9006, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)" }, + {0x10b7, 0x9006, OK, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)" }, {0x10b7, 0x900a, NT, "3COM", "3C90xB: PCI 10BASE-FL" }, {0x10b7, 0x905a, NT, "3COM", "3C90xB: PCI 10BASE-FX" }, {0x10b7, 0x9058, OK, "3COM", "3C905B: Cyclone 10/100/BNC" }, @@ -54,41 +55,57 @@ const struct dev_entry nics_3com[] = { }; static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val, - chipaddr addr); + chipaddr addr) +{ + struct nic3com_data *data = flash->mst->par.data; + + OUTL((uint32_t)addr, data->io_base_addr + BIOS_ROM_ADDR); + OUTB(val, data->io_base_addr + BIOS_ROM_DATA); +} + static uint8_t nic3com_chip_readb(const struct flashctx *flash, - const chipaddr addr); -static const struct par_master par_master_nic3com = { - .chip_readb = nic3com_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nic3com_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, -}; + const chipaddr addr) +{ + struct nic3com_data *data = flash->mst->par.data; + + OUTL((uint32_t)addr, data->io_base_addr + BIOS_ROM_ADDR); + return INB(data->io_base_addr + BIOS_ROM_DATA); +} -static int nic3com_shutdown(void *data) +static int nic3com_shutdown(void *par_data) { + struct nic3com_data *data = par_data; + const uint16_t id = data->id; + /* 3COM 3C90xB cards need a special fixup. */ if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005 || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) { /* Select register window 3 and restore the receiver status. */ - OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS); - OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG); + OUTW(SELECT_REG_WINDOW + 3, data->io_base_addr + INT_STATUS); + OUTL(data->internal_conf, data->io_base_addr + INTERNAL_CONFIG); } + free(data); return 0; } -int nic3com_init(void) +static const struct par_master par_master_nic3com = { + .chip_readb = nic3com_chip_readb, + .chip_writeb = nic3com_chip_writeb, + .shutdown = nic3com_shutdown, +}; + +static int nic3com_init(const struct programmer_cfg *cfg) { struct pci_dev *dev = NULL; + uint32_t io_base_addr = 0; + uint32_t internal_conf = 0; + uint16_t id; if (rget_io_perms()) return 1; - dev = pcidev_init(nics_3com, PCI_BASE_ADDRESS_0); + dev = pcidev_init(cfg, nics_3com, PCI_BASE_ADDRESS_0); if (!dev) return 1; @@ -116,29 +133,33 @@ int nic3com_init(void) */ OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS); - if (register_shutdown(nic3com_shutdown, NULL)) - return 1; + struct nic3com_data *data = calloc(1, sizeof(*data)); + if (!data) { + msg_perr("Unable to allocate space for PAR master data\n"); + goto init_err_cleanup_exit; + } + data->io_base_addr = io_base_addr; + data->internal_conf = internal_conf; + data->id = id; max_rom_decode.parallel = 128 * 1024; - register_par_master(&par_master_nic3com, BUS_PARALLEL); - return 0; -} - -static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val, - chipaddr addr) -{ - OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR); - OUTB(val, io_base_addr + BIOS_ROM_DATA); -} + return register_par_master(&par_master_nic3com, BUS_PARALLEL, data); -static uint8_t nic3com_chip_readb(const struct flashctx *flash, - const chipaddr addr) -{ - OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR); - return INB(io_base_addr + BIOS_ROM_DATA); +init_err_cleanup_exit: + /* 3COM 3C90xB cards need a special fixup. */ + if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005 + || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) { + /* Select register window 3 and restore the receiver status. */ + OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS); + OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG); + } + return 1; } -#else -#error PCI port I/O access is not supported on this architecture yet. -#endif +const struct programmer_entry programmer_nic3com = { + .name = "nic3com", + .type = PCI, + .devs.dev = nics_3com, + .init = nic3com_init, +}; |