From 4d3c866aecef67fd236d8114185a45fb934cfe80 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Wed, 21 Sep 2016 00:14:45 +0200 Subject: classic networking: adapt FXP driver to work with actual PCI and IRQ code. Tested to work with QEMU provided Intel i82557b network controller emulation. qemu-system-x86_64 -enable-kvm -kernel $APP_BINARY \ -vga cirrus \ -append "--console=/dev/com1" \ -serial stdio \ -net nic,vlan=1,macaddr=be:be:be:10:00:01,model=i82557b \ -net tap,ifname=tap1,vlan=1,script=no,downscript=no --- c/src/libchip/network/if_fxp.c | 186 ++++++++++++++++++-------------------- c/src/libchip/network/if_fxpvar.h | 18 ++-- 2 files changed, 98 insertions(+), 106 deletions(-) diff --git a/c/src/libchip/network/if_fxp.c b/c/src/libchip/network/if_fxp.c index 35d7c072a4..4d9d983b52 100644 --- a/c/src/libchip/network/if_fxp.c +++ b/c/src/libchip/network/if_fxp.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #ifdef NS @@ -221,7 +222,7 @@ int fxp_output (struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); -static rtems_isr fxp_intr(rtems_vector_number v); +static void fxp_intr(void *arg); static void fxp_init(void *xsc); static void fxp_tick(void *xsc); static void fxp_start(struct ifnet *ifp); @@ -285,7 +286,7 @@ static __inline u_int8_t fxp_csr_read_1(struct fxp_softc *sc,int reg) { inport_byte(sc->pci_regs_base + reg,val); } else { - val = *(u_int8_t*)(sc->pci_regs_base+reg); + val = *(volatile u_int8_t*)(sc->pci_regs_base+reg); } return val; } @@ -295,7 +296,7 @@ static __inline u_int32_t fxp_csr_read_2(struct fxp_softc *sc,int reg) { inport_word(sc->pci_regs_base + reg,val); } else { - val = *(u_int16_t*)(sc->pci_regs_base+reg); + val = *(volatile u_int16_t*)(sc->pci_regs_base+reg); } return val; } @@ -305,7 +306,7 @@ static __inline u_int32_t fxp_csr_read_4(struct fxp_softc *sc,int reg) { inport_long(sc->pci_regs_base + reg,val); } else { - val = *(u_int32_t*)(sc->pci_regs_base+reg); + val = *(volatile u_int32_t*)(sc->pci_regs_base+reg); } return val; } @@ -322,7 +323,8 @@ fxp_scb_wait(struct fxp_softc *sc) while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i) DELAY(2); if (i == 0) - device_printf(sc->dev, "SCB timeout: 0x%x 0x%x 0x%x 0x%x\n", + device_printf(sc->dev, "SCB timeout: 0x%d 0x%d" + "0x%d" PRIx32 "0x%" PRIx32 "\n", CSR_READ_1(sc, FXP_CSR_SCB_COMMAND), CSR_READ_1(sc, FXP_CSR_SCB_STATACK), CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS), @@ -351,86 +353,61 @@ fxp_dma_wait(volatile u_int16_t *status, struct fxp_softc *sc) device_printf(sc->dev, "DMA timeout\n"); } -/* - * These macros and instantiations define PCI Configuration Space accessors - * which use the legacy API based on the PCI BIOS only used by pc386. - * This was the only device driver using these. - * - * TBD: It may be worth it to fix this driver to use the current PCI API rather - * than this legacy PC386 API. - */ -#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff) -#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f) -#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7) -#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f)) -#define PCI_CONF_ACCESSOR(_confop, _baseop, _type) \ - /* prototype before body */ \ - static inline int _confop ( \ - int signature, \ - int offset, \ - _type data ); \ +#define FXP_PCI_CONF_ACCESSOR(_confop, _baseop, _type) \ \ static inline int _confop ( \ - int signature, \ + struct fxp_softc *sc, \ int offset, \ _type data ) \ { \ _baseop( \ - PCIB_DEVSIG_BUS(signature), \ - PCIB_DEVSIG_DEV(signature), \ - PCIB_DEVSIG_FUNC(signature), \ + sc->pci_bus, \ + sc->pci_dev, \ + sc->pci_fun, \ offset, \ data \ ); \ return PCIB_ERR_SUCCESS; \ } -PCI_CONF_ACCESSOR( pcib_conf_read8, pci_read_config_byte, uint8_t * ); -PCI_CONF_ACCESSOR( pcib_conf_read16, pci_read_config_word, uint16_t * ); -PCI_CONF_ACCESSOR( pcib_conf_read32, pci_read_config_dword, uint32_t * ); -PCI_CONF_ACCESSOR( pcib_conf_write8, pci_write_config_byte, uint8_t ); -PCI_CONF_ACCESSOR( pcib_conf_write16, pci_write_config_word, uint16_t ); -PCI_CONF_ACCESSOR( pcib_conf_write32, pci_write_config_dword, uint32_t ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read8, pci_read_config_byte, uint8_t * ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read16, pci_read_config_word, uint16_t * ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read32, pci_read_config_dword, uint32_t * ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write8, pci_write_config_byte, uint8_t ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write16, pci_write_config_word, uint16_t ); +FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write32, pci_write_config_dword, uint32_t ); -static __inline unsigned int pci_get_vendor(struct fxp_softc *sc) { +static __inline unsigned int fxp_pci_get_vendor(struct fxp_softc *sc) { u_int16_t vendor; - pcib_conf_read16(sc->pci_signature,0,&vendor); + fxp_pci_conf_read16(sc, PCI_VENDOR_ID, &vendor); return vendor; } -static __inline unsigned int pci_get_device(struct fxp_softc *sc) { +static __inline unsigned int fxp_pci_get_device(struct fxp_softc *sc) { u_int16_t device; - pcib_conf_read16(sc->pci_signature,2,&device); + fxp_pci_conf_read16(sc, PCI_DEVICE_ID, &device); return device; } -static __inline unsigned int pci_get_subvendor(struct fxp_softc *sc) { +static __inline unsigned int fxp_pci_get_subvendor(struct fxp_softc *sc) { u_int16_t subvendor; - pcib_conf_read16(sc->pci_signature,0x2c,&subvendor); + fxp_pci_conf_read16(sc, PCI_SUBSYSTEM_VENDOR_ID, &subvendor); return subvendor; } -static __inline unsigned int pci_get_subdevice(struct fxp_softc *sc) { +static __inline unsigned int fxp_pci_get_subdevice(struct fxp_softc *sc) { u_int16_t subdevice; - pcib_conf_read16(sc->pci_signature,0x2e,&subdevice); + fxp_pci_conf_read16(sc, PCI_SUBSYSTEM_ID, &subdevice); return subdevice; } -static __inline unsigned int pci_get_revid(struct fxp_softc *sc) { +static __inline unsigned int fxp_pci_get_revid(struct fxp_softc *sc) { u_int8_t revid; - pcib_conf_read8(sc->pci_signature,0x08,&revid); + fxp_pci_conf_read8(sc, PCI_REVISION_ID, &revid); return revid; } -static void nopOn(const rtems_irq_connect_data* notUsed) -{ - /* - * code should be moved from fxp_Enet_initialize_hardware - * to this location - */ -} - int rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) { @@ -485,25 +462,27 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) /* * find device on pci bus */ - { int j; int pbus, pdev, pfun; - - for (j=0; fxp_ident_table[j].devid; j++ ) { - i = pci_find_device( 0x8086, fxp_ident_table[j].devid, - unitNumber-1, &pbus, &pdev, &pfun ); - sc->pci_signature = PCIB_DEVSIG_MAKE( pbus, pdev, pfun ); - DBGLVL_PRINTK(2,"fxp_attach: find_devid returned %d " - "and pci signature 0x%x\n", - i,sc->pci_signature); - if (PCIB_ERR_SUCCESS == i) { - if ( UNTESTED == fxp_ident_table[j].warn ) { - device_printf(dev, + { int j; int pbus, pdev, pfun; + + for (j=0; fxp_ident_table[j].devid; j++ ) { + i = pci_find_device( 0x8086, fxp_ident_table[j].devid, + unitNumber-1, &pbus, &pdev, &pfun ); + sc->pci_bus = pbus; + sc->pci_dev = pdev; + sc->pci_fun = pfun; + DBGLVL_PRINTK(2,"fxp_attach: find_devid returned %d ," + "pci bus %d dev %d fun %d \n", + i, sc->pci_bus, sc->pci_dev, sc->pci_fun); + if (PCIB_ERR_SUCCESS == i) { + if ( UNTESTED == fxp_ident_table[j].warn ) { + device_printf(dev, "WARNING: this chip version has NOT been reported to work under RTEMS yet.\n"); - device_printf(dev, + device_printf(dev, " If it works OK, report it as tested in 'c/src/libchip/network/if_fxp.c'\n"); - } - break; - } - } + } + break; + } + } } /* @@ -519,11 +498,11 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) * Enable bus mastering. Enable memory space too, in case * BIOS/Prom forgot about it. */ - pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16); + fxp_pci_conf_read16(sc, PCI_COMMAND,&val16); val16 |= (PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER); - pcib_conf_write16(sc->pci_signature, PCI_COMMAND, val16); + fxp_pci_conf_write16(sc, PCI_COMMAND, val16); DBGLVL_PRINTK(3,"fxp_attach: PCI_COMMAND_write = 0x%x\n",val16); - pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16); + fxp_pci_conf_read16(sc, PCI_COMMAND,&val16); DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read = 0x%x\n",val16); /* @@ -594,20 +573,16 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) /* * get mapping and base address of registers */ - pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16); + fxp_pci_conf_read16(sc, PCI_COMMAND,&val16); DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read = 0x%x\n",val16); if((val16 & PCI_COMMAND_IO) != 0) { sc->pci_regs_are_io = true; - pcib_conf_read32(sc->pci_signature, - PCI_BASE_ADDRESS_1, - &val32); + fxp_pci_conf_read32(sc, PCI_BASE_ADDRESS_1, &val32); sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_IO_MASK; } else { sc->pci_regs_are_io = false; - pcib_conf_read32(sc->pci_signature, - PCI_BASE_ADDRESS_0, - &val32); + fxp_pci_conf_read32(sc, PCI_BASE_ADDRESS_0, &val32); sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_MEM_MASK; } DBGLVL_PRINTK(3,"fxp_attach: CSR registers are mapped in %s space" @@ -618,9 +593,9 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) /* * get interrupt level to be used */ - pcib_conf_read8(sc->pci_signature, 60, &interrupt); + fxp_pci_conf_read8(sc, PCI_INTERRUPT_LINE, &interrupt); DBGLVL_PRINTK(3,"fxp_attach: interrupt = 0x%x\n",interrupt); - sc->irqInfo.name = (rtems_irq_number)interrupt; + sc->irq_num = interrupt; /* * Reset to a stable state. CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); @@ -693,9 +668,9 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) * See Intel 82801BA/82801BAM Specification Update, Errata #30. */ #ifdef NOTUSED - i = pci_get_device(dev); + i = fxp_pci_get_device(dev); #else - pcib_conf_read16(sc->pci_signature,2,&dev_id); + fxp_pci_conf_read16(sc, PCI_DEVICE_ID, &dev_id); DBGLVL_PRINTK(3,"fxp_attach: device id = 0x%x\n",dev_id); #endif if (dev_id == 0x2449 || (dev_id > 0x1030 && dev_id < 0x1039)) { @@ -751,8 +726,7 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) * is a valid cacheline size (8 or 16 dwords), then tell * the board to turn on MWI. */ - pcib_conf_read8(sc->pci_signature, - PCI_CACHE_LINE_SIZE,&tmp_val); + fxp_pci_conf_read8(sc, PCI_CACHE_LINE_SIZE, &tmp_val); DBGLVL_PRINTK(3,"fxp_attach: CACHE_LINE_SIZE = %d\n",tmp_val); if (val16 & PCI_COMMAND_MEMORY && tmp_val != 0) @@ -781,9 +755,9 @@ rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching) ((u_int8_t*)sc->arpcom.ac_enaddr)[5], sc->flags & FXP_FLAG_SERIAL_MEDIA ? ", 10Mbps" : ""); device_printf(dev, "PCI IDs: 0x%x 0x%x 0x%x 0x%x 0x%x\n", - pci_get_vendor(sc), pci_get_device(sc), - pci_get_subvendor(sc), pci_get_subdevice(sc), - pci_get_revid(sc)); + fxp_pci_get_vendor(sc), fxp_pci_get_device(sc), + fxp_pci_get_subvendor(sc), fxp_pci_get_subdevice(sc), + fxp_pci_get_revid(sc)); device_printf(dev, "Chip Type: %d\n", sc->chip); } @@ -1156,6 +1130,7 @@ fxp_start(struct ifnet *ifp) { struct fxp_softc *sc = ifp->if_softc; struct fxp_cb_tx *txp; + rtems_interrupt_level level; DBGLVL_PRINTK(3,"fxp_start called\n"); @@ -1165,6 +1140,7 @@ fxp_start(struct ifnet *ifp) * of the command chain). */ if (sc->need_mcsetup) { + DBGLVL_PRINTK(3,"fxp_start need_mcsetup\n"); return; } @@ -1299,17 +1275,25 @@ tbdinit: fxp_scb_wait(sc); fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); } + + /* + * reenable interrupts + */ + rtems_interrupt_disable (level); + CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); + bsp_interrupt_vector_enable(sc->irq_num); + rtems_interrupt_enable (level); } /* * Process interface interrupts. */ -static rtems_isr fxp_intr(rtems_vector_number v) +static void fxp_intr(void *arg) { /* - * FIXME: currently only works with one interface... + * Obtain device state */ - struct fxp_softc *sc = &(fxp_softc[0]); + struct fxp_softc *sc = (struct fxp_softc *)arg; /* * disable interrupts @@ -1336,7 +1320,8 @@ static void fxp_daemon(void *xsc) #endif for (;;) { - DBGLVL_PRINTK(4,"fxp_daemon waiting for event\n"); + DBGLVL_PRINTK(4,"fxp_daemon waiting for event, INTRCNTL 0x%02x\n", + CSR_READ_1(sc, FXP_CSR_SCB_INTRCNTL)); /* * wait for event to receive from interrupt function */ @@ -1475,6 +1460,7 @@ rcvloop: */ rtems_interrupt_disable (level); CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); + bsp_interrupt_vector_enable(sc->irq_num); rtems_interrupt_enable (level); } } @@ -1697,6 +1683,7 @@ fxp_init(void *xsc) struct fxp_cb_ias *cb_ias; struct fxp_cb_tx *txp; int i, prm, s, rv; + rtems_status_code statcode; rtems_task_wake_after(100); DBGLVL_PRINTK(2,"fxp_init called\n"); @@ -1925,14 +1912,17 @@ rtems_task_wake_after(100); /* * Set up interrupts */ - sc->irqInfo.hdl = (rtems_irq_hdl)fxp_intr; - sc->irqInfo.on = nopOn; - sc->irqInfo.off = nopOn; - sc->irqInfo.isOn = NULL; - rv = BSP_install_rtems_irq_handler (&sc->irqInfo); - if (rv != 1) { + statcode = rtems_interrupt_handler_install( + sc->irq_num, + "fxp_intr", + RTEMS_INTERRUPT_SHARED, + fxp_intr, + sc + ); + + if ( statcode != RTEMS_SUCCESSFUL ) { rtems_panic ("Can't attach fxp interrupt handler for irq %d\n", - sc->irqInfo.name); + sc->irq_num); } } diff --git a/c/src/libchip/network/if_fxpvar.h b/c/src/libchip/network/if_fxpvar.h index 85844773e1..f29f52c080 100644 --- a/c/src/libchip/network/if_fxpvar.h +++ b/c/src/libchip/network/if_fxpvar.h @@ -104,11 +104,13 @@ struct fxp_softc { bus_space_tag_t sc_st; /* bus space tag */ bus_space_handle_t sc_sh; /* bus space handle */ #else - int pci_signature; /* RTEMS i386 PCI signature */ - bool pci_regs_are_io; /* RTEMS dev regs are I/O mapped */ - u_int32_t pci_regs_base; /* RTEMS i386 register base */ - rtems_id daemonTid; /* Task ID of deamon */ - rtems_irq_connect_data irqInfo; + unsigned char pci_bus; /* RTEMS PCI bus number */ + unsigned char pci_dev; /* RTEMS PCI slot/device number */ + unsigned char pci_fun; /* RTEMS PCI function number */ + bool pci_regs_are_io; /* RTEMS dev regs are I/O mapped */ + u_int32_t pci_regs_base; /* RTEMS i386 register base */ + rtems_id daemonTid; /* Task ID of deamon */ + rtems_vector_number irq_num; #endif struct mbuf *rfa_headm; /* first mbuf in receive frame area */ @@ -175,7 +177,7 @@ struct fxp_softc { if ((sc)->pci_regs_are_io) \ outport_byte((sc)->pci_regs_base+(reg),val); \ else \ - *((u_int8_t*)((sc)->pci_regs_base)+(reg)) = val; \ + *((volatile u_int8_t*)((sc)->pci_regs_base)+(reg)) = val; \ }while (0) #define CSR_WRITE_2(sc, reg, val) \ @@ -183,7 +185,7 @@ struct fxp_softc { if ((sc)->pci_regs_are_io) \ outport_word((sc)->pci_regs_base+(reg),val); \ else \ - *((u_int16_t*)((u_int8_t*)((sc)->pci_regs_base)+(reg))) = val; \ + *((volatile u_int16_t*)((u_int8_t*)((sc)->pci_regs_base)+(reg))) = val; \ }while (0) #define CSR_WRITE_4(sc, reg, val) \ @@ -191,7 +193,7 @@ struct fxp_softc { if ((sc)->pci_regs_are_io) \ outport_long((sc)->pci_regs_base+(reg),val); \ else \ - *((u_int32_t*)((u_int8_t*)((sc)->pci_regs_base)+(reg))) = val; \ + *((volatile u_int32_t*)((u_int8_t*)((sc)->pci_regs_base)+(reg))) = val; \ }while (0) #endif -- cgit v1.2.3