[PATCH] classic networking: adapt FXP driver to work with actual PCI
Pavel Pisa
ppisa4lists at pikron.com
Tue Sep 20 22:30:39 UTC 2016
From: Pavel Pisa <pisa at cmp.felk.cvut.cz>
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 35d7c07..4d9d983 100644
--- a/c/src/libchip/network/if_fxp.c
+++ b/c/src/libchip/network/if_fxp.c
@@ -76,6 +76,7 @@
#include <sys/systm.h>
#include <bsp.h>
#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
#include <rtems/pci.h>
#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 8584477..f29f52c 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
--
1.9.1
More information about the devel
mailing list