mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Add port management code to driver
This commit is contained in:
parent
0fd9bc7376
commit
d8a2efc756
@ -1,7 +1,7 @@
|
||||
|
||||
# object files to build
|
||||
obj-m += mqnic.o
|
||||
mqnic-objs += mqnic_main.o mqnic_dev.o mqnic_netdev.o mqnic_ethtool.o mqnic_i2c.o mqnic_ptp.o mqnic_tx.o mqnic_rx.o mqnic_cq.o mqnic_eq.o
|
||||
mqnic-objs += mqnic_main.o mqnic_dev.o mqnic_netdev.o mqnic_port.o mqnic_ethtool.o mqnic_i2c.o mqnic_ptp.o mqnic_tx.o mqnic_rx.o mqnic_cq.o mqnic_eq.o
|
||||
|
||||
all:
|
||||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||
|
@ -209,6 +209,22 @@ struct mqnic_eq_ring {
|
||||
u8 __iomem *hw_tail_ptr;
|
||||
};
|
||||
|
||||
struct mqnic_port {
|
||||
struct device *dev;
|
||||
struct net_device *ndev;
|
||||
|
||||
int index;
|
||||
|
||||
u32 port_id;
|
||||
u32 port_features;
|
||||
u32 sched_count;
|
||||
u32 sched_offset;
|
||||
u32 sched_stride;
|
||||
u32 sched_type;
|
||||
|
||||
u8 __iomem *hw_addr;
|
||||
};
|
||||
|
||||
struct mqnic_priv {
|
||||
struct device *dev;
|
||||
struct net_device *ndev;
|
||||
@ -243,6 +259,7 @@ struct mqnic_priv {
|
||||
struct mqnic_cq_ring *tx_cpl_ring[MQNIC_MAX_TX_CPL_RINGS];
|
||||
struct mqnic_ring *rx_ring[MQNIC_MAX_RX_RINGS];
|
||||
struct mqnic_cq_ring *rx_cpl_ring[MQNIC_MAX_RX_CPL_RINGS];
|
||||
struct mqnic_port *ports[MQNIC_MAX_PORTS];
|
||||
|
||||
struct hwtstamp_config hwts_config;
|
||||
};
|
||||
@ -258,6 +275,10 @@ void mqnic_update_stats(struct net_device *ndev);
|
||||
int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr);
|
||||
void mqnic_destroy_netdev(struct net_device *ndev);
|
||||
|
||||
// mqnic_port.c
|
||||
int mqnic_create_port(struct mqnic_priv *priv, struct mqnic_port **port_ptr, int index, u8 __iomem *hw_addr);
|
||||
void mqnic_destroy_port(struct mqnic_priv *priv, struct mqnic_port **port_ptr);
|
||||
|
||||
// mqnic_ptp.c
|
||||
void mqnic_register_phc(struct mqnic_dev *mdev);
|
||||
void mqnic_unregister_phc(struct mqnic_dev *mdev);
|
||||
|
@ -37,6 +37,7 @@ either expressed or implied, of The Regents of the University of California.
|
||||
#include <linux/types.h>
|
||||
|
||||
#define MQNIC_MAX_IF 8
|
||||
#define MQNIC_MAX_PORTS 8
|
||||
|
||||
#define MQNIC_MAX_EVENT_RINGS 256
|
||||
#define MQNIC_MAX_TX_RINGS 256
|
||||
|
@ -406,6 +406,9 @@ int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr)
|
||||
if (priv->rx_cpl_queue_count > MQNIC_MAX_RX_CPL_RINGS)
|
||||
priv->rx_cpl_queue_count = MQNIC_MAX_RX_CPL_RINGS;
|
||||
|
||||
if (priv->port_count > MQNIC_MAX_PORTS)
|
||||
priv->port_count = MQNIC_MAX_PORTS;
|
||||
|
||||
// TODO use all queues
|
||||
priv->event_queue_count = 1;
|
||||
priv->tx_queue_count = 1;
|
||||
@ -489,10 +492,14 @@ int mqnic_init_netdev(struct mqnic_dev *mdev, int port, u8 __iomem *hw_addr)
|
||||
}
|
||||
}
|
||||
|
||||
// scheduler queue enable
|
||||
iowrite32(0xffffffff, hw_addr+priv->port_offset+0x0200);
|
||||
// scheduler global enable
|
||||
iowrite32(0xffffffff, hw_addr+priv->port_offset+0x0300);
|
||||
for (k = 0; k < priv->port_count; k++)
|
||||
{
|
||||
ret = mqnic_create_port(priv, &priv->ports[k], k, hw_addr+priv->port_offset+k*priv->port_stride);
|
||||
if (ret)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
// entry points
|
||||
ndev->netdev_ops = &mqnic_netdev_ops;
|
||||
@ -591,6 +598,14 @@ void mqnic_destroy_netdev(struct net_device *ndev)
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < MQNIC_MAX_PORTS; k++)
|
||||
{
|
||||
if (priv->ports[k])
|
||||
{
|
||||
mqnic_destroy_port(priv, &priv->ports[k]);
|
||||
}
|
||||
}
|
||||
|
||||
pci_free_irq(mdev->pdev, priv->port, priv);
|
||||
free_netdev(ndev);
|
||||
}
|
||||
|
98
modules/mqnic/mqnic_port.c
Normal file
98
modules/mqnic/mqnic_port.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
|
||||
Copyright 2019, The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
|
||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of The Regents of the University of California.
|
||||
|
||||
*/
|
||||
|
||||
#include "mqnic.h"
|
||||
|
||||
int mqnic_create_port(struct mqnic_priv *priv, struct mqnic_port **port_ptr, int index, u8 __iomem *hw_addr)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
struct mqnic_port *port;
|
||||
int k;
|
||||
|
||||
port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port)
|
||||
{
|
||||
dev_err(dev, "Failed to allocate port");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
port->dev = dev;
|
||||
port->ndev = priv->ndev;
|
||||
|
||||
port->index = index;
|
||||
|
||||
port->hw_addr = hw_addr;
|
||||
|
||||
// read ID registers
|
||||
port->port_id = ioread32(port->hw_addr+MQNIC_PORT_REG_PORT_ID);
|
||||
dev_info(dev, "Port ID: 0x%08x", port->port_id);
|
||||
|
||||
port->sched_count = ioread32(port->hw_addr+MQNIC_PORT_REG_SCHED_COUNT);
|
||||
dev_info(dev, "Scheduler count: %d", port->sched_count);
|
||||
port->sched_offset = ioread32(port->hw_addr+MQNIC_PORT_REG_SCHED_OFFSET);
|
||||
dev_info(dev, "Scheduler offset: 0x%08x", port->sched_offset);
|
||||
port->sched_stride = ioread32(port->hw_addr+MQNIC_PORT_REG_SCHED_STRIDE);
|
||||
dev_info(dev, "Scheduler stride: 0x%08x", port->sched_stride);
|
||||
port->sched_type = ioread32(port->hw_addr+MQNIC_PORT_REG_SCHED_TYPE);
|
||||
dev_info(dev, "Scheduler type: 0x%08x", port->sched_type);
|
||||
|
||||
// disable schedulers
|
||||
iowrite32(0, port->hw_addr+MQNIC_PORT_REG_SCHED_ENABLE);
|
||||
|
||||
// enable schedulers
|
||||
iowrite32(0xffffffff, port->hw_addr+MQNIC_PORT_REG_SCHED_ENABLE);
|
||||
|
||||
for (k = 0; k < 32; k++)
|
||||
{
|
||||
iowrite32(1, port->hw_addr+port->sched_offset+k*4);
|
||||
}
|
||||
|
||||
// scheduler queue enable
|
||||
iowrite32(0xffffffff, port->hw_addr+port->sched_offset+0x0200);
|
||||
// scheduler global enable
|
||||
iowrite32(0xffffffff, port->hw_addr+port->sched_offset+0x0300);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mqnic_destroy_port(struct mqnic_priv *priv, struct mqnic_port **port_ptr)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
struct mqnic_port *port = *port_ptr;
|
||||
*port_ptr = NULL;
|
||||
|
||||
mqnic_deactivate_port(priv, port);
|
||||
|
||||
kfree(port);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user