summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadalin Bucur <madalin.bucur@freescale.com>2013-05-29 16:20:33 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-07-15 21:45:42 (GMT)
commit9aff690585755943190d2698580d3d9d8aaff8eb (patch)
treec534beef7113c5bc6737d928f1e42133dc6ac64a
parent2c1b994b69ed78e54e5cfca480da13bf17dc64c6 (diff)
downloadlinux-fsl-qoriq-9aff690585755943190d2698580d3d9d8aaff8eb.tar.xz
dpaa_eth: separate probe function for proxy interfaces
Use a separate probe function for the proxy interfaces. Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com> Change-Id: I365812e7c36383bd5c1952e16e60e8a5048e0d04 Reviewed-on: http://git.am.freescale.net:8181/3075 Reviewed-by: Sovaiala Cristian-Constantin-B39531 <Cristian.Sovaiala@freescale.com> Reviewed-by: Radulescu Ruxandra Ioana-B05472 <ruxandra.radulescu@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c310
1 files changed, 193 insertions, 117 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 3307675..c776ec2 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -3890,10 +3890,6 @@ dpaa_eth_probe(struct platform_device *_of_dev)
struct device_node *dpa_node;
struct dpa_bp *dpa_bp;
struct dpa_fq *dpa_fq, *tmp;
- struct list_head rxfqlist;
- struct list_head txfqlist;
- struct list_head proxy_fq_list;
- struct list_head *fq_list;
size_t count;
struct net_device *net_dev = NULL;
struct dpa_priv_s *priv = NULL;
@@ -3903,30 +3899,19 @@ dpaa_eth_probe(struct platform_device *_of_dev)
struct fm_port *txport = NULL;
struct dpa_buffer_layout_s *buf_layout = NULL;
struct mac_device *mac_dev;
- const struct of_device_id *match;
+ struct task_struct *kth;
/* Interface type results as a side effect of the probing process */
bool is_private = false;
bool is_macless = false;
bool is_shared = false;
- bool is_proxy = false;
dev = &_of_dev->dev;
dpa_node = dev->of_node;
- match = of_match_device(dpa_match, dev);
- if (!match)
- return -EINVAL;
-
if (!of_device_is_available(dpa_node))
return -ENODEV;
- /* If it's not an fsl,dpa-ethernet node, we just serve as a proxy
- * initializer driver, and don't do any linux device setup
- * proxy interfaces have fsl,dpa-ethernet-init as compatible string
- */
- is_proxy = strcmp(match->compatible, "fsl,dpa-ethernet") != 0;
-
/* Get the buffer pools assigned to this interface */
dpa_bp = dpa_bp_probe(_of_dev, &count);
if (IS_ERR(dpa_bp))
@@ -3938,22 +3923,20 @@ dpaa_eth_probe(struct platform_device *_of_dev)
* Allocate this early, so we can store relevant information in
* the private area (needed by 1588 code in dpa_mac_probe)
*/
- if (!is_proxy) {
- net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
- if (!net_dev) {
- dev_err(dev, "alloc_etherdev_mq() failed\n");
- return -ENOMEM;
- }
+ net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
+ if (!net_dev) {
+ dev_err(dev, "alloc_etherdev_mq() failed\n");
+ return -ENOMEM;
+ }
- /* Do this here, so we can be verbose early */
- SET_NETDEV_DEV(net_dev, dev);
- dev_set_drvdata(dev, net_dev);
+ /* Do this here, so we can be verbose early */
+ SET_NETDEV_DEV(net_dev, dev);
+ dev_set_drvdata(dev, net_dev);
- priv = netdev_priv(net_dev);
- priv->net_dev = net_dev;
+ priv = netdev_priv(net_dev);
+ priv->net_dev = net_dev;
- priv->msg_enable = netif_msg_init(debug, -1);
- }
+ priv->msg_enable = netif_msg_init(debug, -1);
mac_dev = dpa_mac_probe(_of_dev);
if (IS_ERR(mac_dev)) {
@@ -3992,29 +3975,21 @@ dpaa_eth_probe(struct platform_device *_of_dev)
default_buf_size = dpa_bp->size;
}
- INIT_LIST_HEAD(&rxfqlist);
- INIT_LIST_HEAD(&txfqlist);
-
- if (is_proxy) {
- INIT_LIST_HEAD(&proxy_fq_list);
- fq_list = &proxy_fq_list;
- } else {
- INIT_LIST_HEAD(&priv->dpa_fq_list);
- fq_list = &priv->dpa_fq_list;
- }
+ INIT_LIST_HEAD(&priv->dpa_fq_list);
memset(&port_fqs, 0, sizeof(port_fqs));
if (!is_macless) {
- err = dpa_fq_probe_mac(dev, fq_list, &port_fqs,
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs,
is_shared, RX);
if (!err)
- err = dpa_fq_probe_mac(dev, fq_list, &port_fqs,
- is_shared, TX);
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
+ &port_fqs, is_shared, TX);
} else {
- err = dpa_fq_probe_macless(dev, fq_list, RX);
+ err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list, RX);
if (!err)
- err = dpa_fq_probe_macless(dev, fq_list, TX);
+ err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list,
+ TX);
}
if (err < 0)
@@ -4025,72 +4000,69 @@ dpaa_eth_probe(struct platform_device *_of_dev)
* We support a number of configurations:
* 1) Private interface - An optimized linux ethernet driver with
* a real network connection.
- * 2) Shared interface - A device intended for virtual connections
- * or for a real interface that is shared between partitions
- * 3) Proxy initializer - Just configures the MAC on behalf of
- * another partition.
- * 4) MAC-less interface - A netdevice over configurable FQs.
+ * 2) Shared interface - A device for a real interface that is shared
+ * between partitions.
+ * 3) MAC-less interface - A netdevice over configurable FQs intended
+ * for virtual connections.
*/
/* bp init */
- if (!is_proxy) {
- struct task_struct *kth;
- err = dpa_bp_create(net_dev, dpa_bp, count);
+ err = dpa_bp_create(net_dev, dpa_bp, count);
- if (err < 0)
- goto bp_create_failed;
+ if (err < 0)
+ goto bp_create_failed;
- priv->mac_dev = mac_dev;
+ priv->mac_dev = mac_dev;
- priv->channel = dpa_get_channel(dev, dpa_node);
+ priv->channel = dpa_get_channel(dev, dpa_node);
- if (priv->channel < 0) {
- err = priv->channel;
- goto get_channel_failed;
- }
+ if (priv->channel < 0) {
+ err = priv->channel;
+ goto get_channel_failed;
+ }
- /* Start a thread that will walk the cpus with affine portals
- * and add this pool channel to each's dequeue mask. */
- kth = kthread_run(dpaa_eth_add_channel,
- (void *)(unsigned long)priv->channel,
- "dpaa_%p:%d", net_dev, priv->channel);
- if (!kth) {
- err = -ENOMEM;
- goto add_channel_failed;
- }
+ /* Start a thread that will walk the cpus with affine portals
+ * and add this pool channel to each's dequeue mask.
+ */
+ kth = kthread_run(dpaa_eth_add_channel,
+ (void *)(unsigned long)priv->channel,
+ "dpaa_%p:%d", net_dev, priv->channel);
+ if (!kth) {
+ err = -ENOMEM;
+ goto add_channel_failed;
+ }
- dpa_fq_setup(priv);
+ dpa_fq_setup(priv);
- /*
- * Create a congestion group for this netdev, with
- * dynamically-allocated CGR ID.
- * Must be executed after probing the MAC, but before
- * assigning the egress FQs to the CGRs.
- * Don't create a congestion group for MAC-less interfaces.
- */
- if (!is_macless) {
- err = dpaa_eth_cgr_init(priv);
- if (err < 0) {
- dev_err(dev, "Error initializing CGR\n");
- goto cgr_init_failed;
- }
+ /*
+ * Create a congestion group for this netdev, with
+ * dynamically-allocated CGR ID.
+ * Must be executed after probing the MAC, but before
+ * assigning the egress FQs to the CGRs.
+ * Don't create a congestion group for MAC-less interfaces.
+ */
+ if (!is_macless) {
+ err = dpaa_eth_cgr_init(priv);
+ if (err < 0) {
+ dev_err(dev, "Error initializing CGR\n");
+ goto cgr_init_failed;
}
+ }
- /* Add the FQs to the interface, and make them active */
- list_for_each_entry_safe(dpa_fq, tmp, fq_list, list) {
- err = dpa_fq_init(dpa_fq);
- if (err < 0)
- goto fq_alloc_failed;
- }
+ /* Add the FQs to the interface, and make them active */
+ list_for_each_entry_safe(dpa_fq, tmp, &priv->dpa_fq_list, list) {
+ err = dpa_fq_init(dpa_fq);
+ if (err < 0)
+ goto fq_alloc_failed;
+ }
- if (!is_macless) {
- priv->buf_layout = buf_layout;
- priv->tx_headroom =
- dpa_get_headroom(&priv->buf_layout[TX]);
- } else {
- priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
- }
+ if (!is_macless) {
+ priv->buf_layout = buf_layout;
+ priv->tx_headroom =
+ dpa_get_headroom(&priv->buf_layout[TX]);
+ } else {
+ priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
}
/* All real interfaces need their ports initialized */
@@ -4108,26 +4080,6 @@ dpaa_eth_probe(struct platform_device *_of_dev)
fm_port_pcd_bind(rxport, &rx_port_pcd_param);
}
- /*
- * Proxy interfaces need to be started, and the allocated
- * memory freed
- */
- if (is_proxy) {
- devm_kfree(dev, dpa_bp);
-
- /* Free FQ structures */
- devm_kfree(dev, port_fqs.rx_defq);
- devm_kfree(dev, port_fqs.rx_errq);
- devm_kfree(dev, port_fqs.tx_defq);
- devm_kfree(dev, port_fqs.tx_errq);
-
- if (!is_macless)
- for_each_port_device(i, mac_dev->port_dev)
- fm_port_enable(mac_dev->port_dev[i]);
-
- return 0; /* Proxy interface initialization ended */
- }
-
/* Now we need to initialize either a private or shared interface */
priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
@@ -4188,16 +4140,115 @@ mac_probe_failed:
return err;
}
+static const struct of_device_id dpa_proxy_match[];
+static int
+dpaa_eth_proxy_probe(struct platform_device *_of_dev)
+{
+ int err = 0, i;
+ struct device *dev;
+ struct device_node *dpa_node;
+ struct dpa_bp *dpa_bp;
+ struct list_head proxy_fq_list;
+ size_t count;
+ struct dpa_priv_s *priv = NULL;
+ struct fm_port_fqs port_fqs;
+ struct fm_port *rxport = NULL;
+ struct fm_port *txport = NULL;
+ struct dpa_buffer_layout_s *buf_layout = NULL;
+ struct mac_device *mac_dev;
+
+ dev = &_of_dev->dev;
+
+ dpa_node = dev->of_node;
+
+ if (!of_device_is_available(dpa_node))
+ return -ENODEV;
+
+ /* Get the buffer pools assigned to this interface */
+ dpa_bp = dpa_bp_probe(_of_dev, &count);
+ if (IS_ERR(dpa_bp))
+ return PTR_ERR(dpa_bp);
+
+ mac_dev = dpa_mac_probe(_of_dev);
+ if (IS_ERR(mac_dev))
+ return PTR_ERR(mac_dev);
+
+ rxport = mac_dev->port_dev[RX];
+ txport = mac_dev->port_dev[TX];
+
+ /* We have physical ports, so we need to establish
+ * the buffer layout.
+ */
+ buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
+ GFP_KERNEL);
+ if (!buf_layout) {
+ dev_err(dev, "devm_kzalloc() failed\n");
+ return -ENOMEM;
+ }
+ dpa_set_buffer_layout(priv, rxport, &buf_layout[RX], RX);
+ dpa_set_buffer_layout(priv, txport, &buf_layout[TX], TX);
+
+ INIT_LIST_HEAD(&proxy_fq_list);
+
+ memset(&port_fqs, 0, sizeof(port_fqs));
+
+ err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, false, RX);
+ if (!err)
+ err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, false,
+ TX);
+
+ if (err < 0)
+ return err;
+
+ /* Proxy initializer - Just configures the MAC on behalf of
+ * another partition.
+ */
+
+ /* All real interfaces need their ports initialized */
+ dpaa_eth_init_tx_port(txport, port_fqs.tx_errq,
+ port_fqs.tx_defq, &buf_layout[TX]);
+ dpaa_eth_init_rx_port(rxport, dpa_bp, count, port_fqs.rx_errq,
+ port_fqs.rx_defq, &buf_layout[RX]);
+ {
+ struct fm_port_pcd_param rx_port_pcd_param;
+
+ rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
+ rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
+ rx_port_pcd_param.dev = dev;
+ fm_port_pcd_bind(rxport, &rx_port_pcd_param);
+ }
+ /* Proxy interfaces need to be started, and the allocated
+ * memory freed
+ */
+ devm_kfree(dev, dpa_bp);
+
+ /* Free FQ structures */
+ devm_kfree(dev, port_fqs.rx_defq);
+ devm_kfree(dev, port_fqs.rx_errq);
+ devm_kfree(dev, port_fqs.tx_defq);
+ devm_kfree(dev, port_fqs.tx_errq);
+
+ for_each_port_device(i, mac_dev->port_dev)
+ fm_port_enable(mac_dev->port_dev[i]);
+
+ return 0; /* Proxy interface initialization ended */
+}
+
static const struct of_device_id dpa_match[] = {
{
.compatible = "fsl,dpa-ethernet"
},
+ {}
+};
+MODULE_DEVICE_TABLE(of, dpa_match);
+
+static const struct of_device_id dpa_proxy_match[] = {
{
.compatible = "fsl,dpa-ethernet-init"
},
{}
};
-MODULE_DEVICE_TABLE(of, dpa_match);
+MODULE_DEVICE_TABLE(of, dpa_proxy_match);
static int __cold dpa_remove(struct platform_device *of_dev)
{
@@ -4251,6 +4302,16 @@ static struct platform_driver dpa_driver = {
.remove = dpa_remove
};
+static struct platform_driver dpa_proxy_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME"-proxy",
+ .of_match_table = dpa_proxy_match,
+ .owner = THIS_MODULE,
+ },
+ .probe = dpaa_eth_proxy_probe,
+ .remove = dpa_remove
+};
+
static int __init __cold dpa_load(void)
{
int _errno;
@@ -4271,6 +4332,16 @@ static int __init __cold dpa_load(void)
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
+ _errno = platform_driver_register(&dpa_proxy_driver);
+ if (unlikely(_errno < 0)) {
+ pr_err(KBUILD_MODNAME"-proxy"
+ ": %s:%hu:%s(): platform_driver_register() = %d\n",
+ KBUILD_BASENAME".c", __LINE__, __func__, _errno);
+ }
+
+ pr_debug(KBUILD_MODNAME"-proxy" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
+
return _errno;
}
module_init(dpa_load);
@@ -4284,5 +4355,10 @@ static void __exit __cold dpa_unload(void)
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
+
+ platform_driver_unregister(&dpa_proxy_driver);
+
+ pr_debug(KBUILD_MODNAME"-proxy" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
}
module_exit(dpa_unload);