mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Refactor userspace init/teardown code
This commit is contained in:
parent
fb258467e7
commit
23cd700a3f
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
276
utils/mqnic.c
276
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user