diff --git a/utils/mqnic-config.c b/utils/mqnic-config.c index e5b3cfaf0..3e49cda77 100644 --- a/utils/mqnic-config.c +++ b/utils/mqnic-config.c @@ -165,7 +165,13 @@ int main(int argc, char *argv[]) goto err; } - struct mqnic_if *dev_interface = &dev->interfaces[interface]; + struct mqnic_if *dev_interface = dev->interfaces[interface]; + + if (!dev_interface) + { + fprintf(stderr, "Invalid interface\n"); + goto err; + } printf("IF ID: 0x%08x\n", dev_interface->if_id); @@ -189,7 +195,13 @@ int main(int argc, char *argv[]) goto err; } - struct mqnic_port *dev_port = &dev_interface->ports[port]; + struct mqnic_port *dev_port = dev_interface->ports[port]; + + if (!dev_port) + { + fprintf(stderr, "Invalid port\n"); + goto err; + } printf("Port ID: 0x%08x\n", dev_port->port_id); diff --git a/utils/mqnic-dump.c b/utils/mqnic-dump.c index f22a4f765..f8c5e9ea9 100644 --- a/utils/mqnic-dump.c +++ b/utils/mqnic-dump.c @@ -139,7 +139,14 @@ int main(int argc, char *argv[]) goto err; } - struct mqnic_if *dev_interface = &dev->interfaces[interface]; + struct mqnic_if *dev_interface = dev->interfaces[interface]; + + if (!dev_interface) + { + fprintf(stderr, "Invalid interface\n"); + ret = -1; + goto err; + } printf("IF ID: 0x%08x\n", dev_interface->if_id); printf("IF features: 0x%08x\n", dev_interface->if_features); @@ -165,7 +172,14 @@ int main(int argc, char *argv[]) goto err; } - struct mqnic_port *dev_port = &dev_interface->ports[port]; + struct mqnic_port *dev_port = dev_interface->ports[port]; + + if (!dev_port) + { + fprintf(stderr, "Invalid port\n"); + ret = -1; + goto err; + } printf("Port ID: 0x%08x\n", dev_port->port_id); printf("Port features: 0x%08x\n", dev_port->port_features); @@ -289,7 +303,7 @@ int main(int argc, char *argv[]) printf("Port %d scheduler %d\n", port, k); for (int l = 0; l < dev_interface->tx_queue_count; l++) { - printf("Sched %2d queue %4d state: 0x%08x\n", k, l, mqnic_reg_read32(dev_port->sched[k].regs, l*4)); + printf("Sched %2d queue %4d state: 0x%08x\n", k, l, mqnic_reg_read32(dev_port->sched[k]->regs, l*4)); } } diff --git a/utils/mqnic.c b/utils/mqnic.c index 43cbddf79..913287870 100644 --- a/utils/mqnic.c +++ b/utils/mqnic.c @@ -142,83 +142,20 @@ struct mqnic *mqnic_open(const char *dev_name) for (int k = 0; k < dev->if_count; k++) { - struct mqnic_if *interface = &dev->interfaces[k]; - interface->regs = dev->regs + k*dev->if_stride; - interface->csr_regs = interface->regs + dev->if_csr_offset; + struct mqnic_if *interface = mqnic_if_open(dev, k, dev->regs + k*dev->if_stride); - if (interface->regs >= dev->regs+dev->regs_size) - goto fail_range; - if (interface->csr_regs >= dev->regs+dev->regs_size) - goto fail_range; + if (!interface) + goto fail; - interface->if_id = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_IF_ID); - interface->if_features = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_IF_FEATURES); - - interface->event_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_EVENT_QUEUE_COUNT); - interface->event_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_EVENT_QUEUE_OFFSET); - interface->tx_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_QUEUE_COUNT); - interface->tx_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_QUEUE_OFFSET); - interface->tx_cpl_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_CPL_QUEUE_COUNT); - interface->tx_cpl_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_CPL_QUEUE_OFFSET); - interface->rx_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_QUEUE_COUNT); - interface->rx_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_QUEUE_OFFSET); - interface->rx_cpl_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_CPL_QUEUE_COUNT); - interface->rx_cpl_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_CPL_QUEUE_OFFSET); - - interface->port_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_COUNT); - interface->port_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_OFFSET); - interface->port_stride = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_STRIDE); - - if (interface->event_queue_count > MQNIC_MAX_EVENT_RINGS) - interface->event_queue_count = MQNIC_MAX_EVENT_RINGS; - if (interface->tx_queue_count > MQNIC_MAX_TX_RINGS) - interface->tx_queue_count = MQNIC_MAX_TX_RINGS; - if (interface->tx_cpl_queue_count > MQNIC_MAX_TX_CPL_RINGS) - interface->tx_cpl_queue_count = MQNIC_MAX_TX_CPL_RINGS; - if (interface->rx_queue_count > MQNIC_MAX_RX_RINGS) - interface->rx_queue_count = MQNIC_MAX_RX_RINGS; - if (interface->rx_cpl_queue_count > MQNIC_MAX_RX_CPL_RINGS) - interface->rx_cpl_queue_count = MQNIC_MAX_RX_CPL_RINGS; - - if (interface->port_count > MQNIC_MAX_PORTS) - interface->port_count = MQNIC_MAX_PORTS; - - for (int l = 0; l < interface->port_count; l++) - { - struct mqnic_port *port = &interface->ports[l]; - port->regs = interface->regs + interface->port_offset + interface->port_stride*l; - - if (port->regs >= dev->regs+dev->regs_size) - goto fail_range; - - port->port_id = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_ID); - port->port_features = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_FEATURES); - port->port_mtu = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_MTU); - - port->sched_count = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_COUNT); - port->sched_offset = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_OFFSET); - port->sched_stride = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_STRIDE); - port->sched_type = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_TYPE); - - port->tdma_timeslot_count = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_TDMA_TIMESLOT_COUNT); - - for (int m = 0; m < port->sched_count; m++) - { - struct mqnic_sched *sched = &port->sched[m]; - sched->regs = port->regs + port->sched_offset + port->sched_stride*m; - - if (sched->regs >= dev->regs+dev->regs_size) - goto fail_range; - } - } + dev->interfaces[k] = interface; } return dev; -fail_range: - fprintf(stderr, "Error: computed pointer out of range\n"); +fail: fail_reset: - munmap((void *)dev->regs, dev->regs_size); + mqnic_close(dev); + return NULL; fail_mmap_regs: fail_ioctl: fail_fstat: @@ -234,8 +171,207 @@ void mqnic_close(struct mqnic *dev) if (!dev) return; + for (int k = 0; k < dev->if_count; k++) + { + if (!dev->interfaces[k]) + continue; + + mqnic_if_close(dev->interfaces[k]); + dev->interfaces[k] = NULL; + } + munmap((void *)dev->regs, dev->regs_size); close(dev->fd); free(dev); } + +struct mqnic_if *mqnic_if_open(struct mqnic *dev, int index, volatile uint8_t *regs) +{ + struct mqnic_if *interface = calloc(1, sizeof(struct mqnic_if)); + + if (!interface) + return NULL; + + interface->mqnic = dev; + + interface->index = index; + + interface->regs_size = dev->if_stride; + interface->regs = regs; + interface->csr_regs = interface->regs + dev->if_csr_offset; + + if (interface->regs >= dev->regs+dev->regs_size || interface->csr_regs >= dev->regs+dev->regs_size) + { + fprintf(stderr, "Error: computed pointer out of range\n"); + goto fail; + } + + interface->if_id = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_IF_ID); + interface->if_features = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_IF_FEATURES); + + interface->event_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_EVENT_QUEUE_COUNT); + interface->event_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_EVENT_QUEUE_OFFSET); + interface->tx_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_QUEUE_COUNT); + interface->tx_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_QUEUE_OFFSET); + interface->tx_cpl_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_CPL_QUEUE_COUNT); + interface->tx_cpl_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_TX_CPL_QUEUE_OFFSET); + interface->rx_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_QUEUE_COUNT); + interface->rx_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_QUEUE_OFFSET); + interface->rx_cpl_queue_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_CPL_QUEUE_COUNT); + interface->rx_cpl_queue_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_RX_CPL_QUEUE_OFFSET); + + interface->port_count = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_COUNT); + interface->port_offset = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_OFFSET); + interface->port_stride = mqnic_reg_read32(interface->csr_regs, MQNIC_IF_REG_PORT_STRIDE); + + if (interface->event_queue_count > MQNIC_MAX_EVENT_RINGS) + interface->event_queue_count = MQNIC_MAX_EVENT_RINGS; + if (interface->tx_queue_count > MQNIC_MAX_TX_RINGS) + interface->tx_queue_count = MQNIC_MAX_TX_RINGS; + if (interface->tx_cpl_queue_count > MQNIC_MAX_TX_CPL_RINGS) + interface->tx_cpl_queue_count = MQNIC_MAX_TX_CPL_RINGS; + if (interface->rx_queue_count > MQNIC_MAX_RX_RINGS) + interface->rx_queue_count = MQNIC_MAX_RX_RINGS; + if (interface->rx_cpl_queue_count > MQNIC_MAX_RX_CPL_RINGS) + interface->rx_cpl_queue_count = MQNIC_MAX_RX_CPL_RINGS; + + if (interface->port_count > MQNIC_MAX_PORTS) + interface->port_count = MQNIC_MAX_PORTS; + + for (int k = 0; k < interface->port_count; k++) + { + struct mqnic_port *port = mqnic_port_open(interface, k, interface->regs + interface->port_offset + k*interface->port_stride); + + if (!port) + goto fail; + + interface->ports[k] = port; + } + + return interface; + +fail: + mqnic_if_close(interface); + return NULL; +} + +void mqnic_if_close(struct mqnic_if *interface) +{ + if (!interface) + return; + + for (int k = 0; k < interface->port_count; k++) + { + if (!interface->ports[k]) + continue; + + mqnic_port_close(interface->ports[k]); + interface->ports[k] = NULL; + } + + free(interface); +} + +struct mqnic_port *mqnic_port_open(struct mqnic_if *interface, int index, volatile uint8_t *regs) +{ + struct mqnic_port *port = calloc(1, sizeof(struct mqnic_port)); + + if (!port) + return NULL; + + port->mqnic = interface->mqnic; + port->interface = interface; + + port->index = index; + + port->regs_size = interface->port_stride; + port->regs = regs; + + if (port->regs >= interface->regs+interface->regs_size) + { + fprintf(stderr, "Error: computed pointer out of range\n"); + goto fail; + } + + port->port_id = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_ID); + port->port_features = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_FEATURES); + port->port_mtu = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_PORT_MTU); + + port->sched_count = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_COUNT); + port->sched_offset = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_OFFSET); + port->sched_stride = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_STRIDE); + port->sched_type = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_SCHED_TYPE); + + port->tdma_timeslot_count = mqnic_reg_read32(port->regs, MQNIC_PORT_REG_TDMA_TIMESLOT_COUNT); + + for (int k = 0; k < port->sched_count; k++) + { + struct mqnic_sched *sched = mqnic_sched_open(port, k, port->regs + port->sched_offset + k*port->sched_stride); + + if (!sched) + goto fail; + + port->sched[k] = sched; + } + + return port; + +fail: + mqnic_port_close(port); + return NULL; +} + +void mqnic_port_close(struct mqnic_port *port) +{ + if (!port) + return; + + for (int k = 0; k < port->sched_count; k++) + { + if (!port->sched[k]) + continue; + + mqnic_sched_close(port->sched[k]); + port->sched[k] = NULL; + } + + free(port); +} + +struct mqnic_sched *mqnic_sched_open(struct mqnic_port *port, int index, volatile uint8_t *regs) +{ + struct mqnic_sched *sched = calloc(1, sizeof(struct mqnic_sched)); + + if (!sched) + return NULL; + + sched->mqnic = port->mqnic; + sched->interface = port->interface; + sched->port = port; + + sched->index = index; + + sched->regs_size = port->sched_stride; + sched->regs = regs; + + if (sched->regs >= port->interface->regs+port->interface->regs_size) + { + fprintf(stderr, "Error: computed pointer out of range\n"); + goto fail; + } + + return sched; + +fail: + mqnic_sched_close(sched); + return NULL; +} + +void mqnic_sched_close(struct mqnic_sched *sched) +{ + if (!sched) + return; + + free(sched); +} diff --git a/utils/mqnic.h b/utils/mqnic.h index 870365b36..bf3da251d 100644 --- a/utils/mqnic.h +++ b/utils/mqnic.h @@ -47,16 +47,22 @@ struct mqnic; struct mqnic_sched { struct mqnic *mqnic; - struct mqnic_if *mqnic_if; - struct mqnic_port *mqnic_port; + struct mqnic_if *interface; + struct mqnic_port *port; + int index; + + size_t regs_size; volatile uint8_t *regs; }; struct mqnic_port { struct mqnic *mqnic; - struct mqnic_if *mqnic_if; + struct mqnic_if *interface; + int index; + + size_t regs_size; volatile uint8_t *regs; uint32_t port_id; @@ -70,12 +76,15 @@ struct mqnic_port { uint32_t tdma_timeslot_count; - struct mqnic_sched sched[MQNIC_MAX_SCHED]; + struct mqnic_sched *sched[MQNIC_MAX_SCHED]; }; struct mqnic_if { struct mqnic *mqnic; + int index; + + size_t regs_size; volatile uint8_t *regs; volatile uint8_t *csr_regs; @@ -97,7 +106,7 @@ struct mqnic_if { uint32_t port_offset; uint32_t port_stride; - struct mqnic_port ports[MQNIC_MAX_PORTS]; + struct mqnic_port *ports[MQNIC_MAX_PORTS]; }; struct mqnic { @@ -120,10 +129,19 @@ struct mqnic { uint32_t if_stride; uint32_t if_csr_offset; - struct mqnic_if interfaces[MQNIC_MAX_IF]; + struct mqnic_if *interfaces[MQNIC_MAX_IF]; }; struct mqnic *mqnic_open(const char *dev_name); void mqnic_close(struct mqnic *dev); +struct mqnic_if *mqnic_if_open(struct mqnic *dev, int index, volatile uint8_t *regs); +void mqnic_if_close(struct mqnic_if *interface); + +struct mqnic_port *mqnic_port_open(struct mqnic_if *interface, int index, volatile uint8_t *regs); +void mqnic_port_close(struct mqnic_port *port); + +struct mqnic_sched *mqnic_sched_open(struct mqnic_port *port, int index, volatile uint8_t *regs); +void mqnic_sched_close(struct mqnic_sched *sched); + #endif /* MQNIC_H */