summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadalin Bucur <madalin.bucur@freescale.com>2013-06-07 15:05:17 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-07-15 21:46:36 (GMT)
commitbe809330f0a332616639af47b767a94058d4fcdf (patch)
tree4fe5a1e62d81f171a07be15c26f61b1fca4a8a5d
parent0a899f8c2acd8e217d24933d6261ad3fb0a21e26 (diff)
downloadlinux-fsl-qoriq-be809330f0a332616639af47b767a94058d4fcdf.tar.xz
dpaa_eth: separate dpa_eth probe() functions
Separated the probe functions for the private, shared and MACless interfaces. Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com> Change-Id: I86a05ba2dc80709b543583e5168694748e75fd05 Reviewed-on: http://git.am.freescale.net:8181/3081 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.c503
1 files changed, 418 insertions, 85 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 3ad46bc..413a91d 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -3997,7 +3997,7 @@ out_error:
static const struct of_device_id dpa_match[];
static int
-dpaa_eth_probe(struct platform_device *_of_dev)
+dpaa_eth_priv_probe(struct platform_device *_of_dev)
{
int err = 0, i;
struct device *dev;
@@ -4012,10 +4012,6 @@ dpaa_eth_probe(struct platform_device *_of_dev)
struct dpa_buffer_layout_s *buf_layout = NULL;
struct mac_device *mac_dev;
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;
dev = &_of_dev->dev;
@@ -4029,8 +4025,6 @@ dpaa_eth_probe(struct platform_device *_of_dev)
if (IS_ERR(dpa_bp))
return PTR_ERR(dpa_bp);
- is_private = (dpa_bp->kernel_pool != 0);
-
/*
* Allocate this early, so we can store relevant information in
* the private area (needed by 1588 code in dpa_mac_probe)
@@ -4056,64 +4050,37 @@ dpaa_eth_probe(struct platform_device *_of_dev)
goto mac_probe_failed;
}
- is_macless = mac_dev == NULL;
- is_shared = (dpa_bp->kernel_pool == 0) && !is_macless;
- /* Now the interface type is known */
-
- if (!is_macless) {
- /* 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");
- goto alloc_failed;
- }
- dpa_set_buffers_layout(mac_dev, buf_layout);
+ /* 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");
+ goto alloc_failed;
}
+ dpa_set_buffers_layout(mac_dev, buf_layout);
- if (is_private) {
- /* For private ports, need to compute the size of the default
- * buffer pool, based on FMan port buffer layout;also update
- * the maximum buffer size for private ports if necessary
- */
- dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
- if (dpa_bp->size > default_buf_size)
- default_buf_size = dpa_bp->size;
- }
+ /* For private ports, need to compute the size of the default
+ * buffer pool, based on FMan port buffer layout;also update
+ * the maximum buffer size for private ports if necessary
+ */
+ dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
+ if (dpa_bp->size > default_buf_size)
+ default_buf_size = dpa_bp->size;
INIT_LIST_HEAD(&priv->dpa_fq_list);
memset(&port_fqs, 0, sizeof(port_fqs));
- if (!is_macless) {
- err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs,
- is_shared, RX);
- if (!err)
- err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
- &port_fqs, is_shared, TX);
- } else {
- err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list, RX);
- if (!err)
- err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list,
- TX);
- }
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, false, RX);
+ if (!err)
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
+ &port_fqs, false, TX);
if (err < 0)
goto fq_probe_failed;
- /*
- * Now we have all of the configuration information.
- * We support a number of configurations:
- * 1) Private interface - An optimized linux ethernet driver with
- * a real network connection.
- * 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 */
err = dpa_bp_create(net_dev, dpa_bp, count);
@@ -4148,14 +4115,11 @@ dpaa_eth_probe(struct platform_device *_of_dev)
* 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;
- }
+ 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 */
@@ -4165,20 +4129,14 @@ dpaa_eth_probe(struct platform_device *_of_dev)
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;
- }
+ priv->buf_layout = buf_layout;
+ priv->tx_headroom =
+ dpa_get_headroom(&priv->buf_layout[TX]);
/* All real interfaces need their ports initialized */
- if (!is_macless)
- dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
- buf_layout, dev);
+ dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
+ buf_layout, dev);
- /* Now we need to initialize either a private or shared interface */
priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
if (priv->percpu_priv == NULL) {
@@ -4191,14 +4149,7 @@ dpaa_eth_probe(struct platform_device *_of_dev)
memset(percpu_priv, 0, sizeof(*percpu_priv));
}
- if (is_shared)
- err = dpa_shared_netdev_init(dpa_node, net_dev);
-
- if (is_macless)
- err = dpa_macless_netdev_init(dpa_node, net_dev);
-
- if (!is_shared && !is_macless)
- err = dpa_private_netdev_init(dpa_node, net_dev);
+ err = dpa_private_netdev_init(dpa_node, net_dev);
if (err < 0)
goto netdev_init_failed;
@@ -4207,7 +4158,7 @@ dpaa_eth_probe(struct platform_device *_of_dev)
#ifdef CONFIG_FSL_DPAA_ETH_UNIT_TESTS
/* The unit test is designed to test private interfaces */
- if (!priv->shared && !tx_unit_test_ran) {
+ if (!tx_unit_test_ran) {
err = dpa_tx_unit_test(net_dev);
WARN_ON(err);
@@ -4242,6 +4193,324 @@ mac_probe_failed:
return err;
}
+static const struct of_device_id dpa_shared_match[];
+static int
+dpaa_eth_shared_probe(struct platform_device *_of_dev)
+{
+ int err = 0, i;
+ struct device *dev;
+ struct device_node *dpa_node;
+ struct dpa_bp *dpa_bp;
+ struct dpa_fq *dpa_fq, *tmp;
+ size_t count;
+ struct net_device *net_dev = NULL;
+ struct dpa_priv_s *priv = NULL;
+ struct dpa_percpu_priv_s *percpu_priv;
+ struct fm_port_fqs port_fqs;
+ struct dpa_buffer_layout_s *buf_layout = NULL;
+ struct mac_device *mac_dev;
+ struct task_struct *kth;
+
+ 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);
+
+ /* Allocate this early, so we can store relevant information in
+ * the private area (needed by 1588 code in dpa_mac_probe)
+ */
+ 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);
+
+ priv = netdev_priv(net_dev);
+ priv->net_dev = net_dev;
+
+ priv->msg_enable = netif_msg_init(debug, -1);
+
+ mac_dev = dpa_mac_probe(_of_dev);
+ if (IS_ERR(mac_dev)) {
+ err = PTR_ERR(mac_dev);
+ goto mac_probe_failed;
+ }
+
+ /* 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");
+ goto alloc_failed;
+ }
+ dpa_set_buffers_layout(mac_dev, buf_layout);
+
+ INIT_LIST_HEAD(&priv->dpa_fq_list);
+
+ memset(&port_fqs, 0, sizeof(port_fqs));
+
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs,
+ true, RX);
+ if (!err)
+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
+ &port_fqs, true, TX);
+ if (err < 0)
+ goto fq_probe_failed;
+
+ /* bp init */
+
+ err = dpa_bp_create(net_dev, dpa_bp, count);
+
+ if (err < 0)
+ goto bp_create_failed;
+
+ priv->mac_dev = mac_dev;
+
+ priv->channel = dpa_get_channel(dev, dpa_node);
+
+ 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;
+ }
+
+ 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.
+ */
+ 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, &priv->dpa_fq_list, list) {
+ err = dpa_fq_init(dpa_fq);
+ if (err < 0)
+ goto fq_alloc_failed;
+ }
+
+ priv->buf_layout = buf_layout;
+ priv->tx_headroom =
+ dpa_get_headroom(&priv->buf_layout[TX]);
+
+ /* All real interfaces need their ports initialized */
+ dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
+ buf_layout, dev);
+
+ /* Now we need to initialize either a private or shared interface */
+ priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+
+ if (priv->percpu_priv == NULL) {
+ dev_err(dev, "alloc_percpu() failed\n");
+ err = -ENOMEM;
+ goto alloc_percpu_failed;
+ }
+ for_each_online_cpu(i) {
+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
+ memset(percpu_priv, 0, sizeof(*percpu_priv));
+ }
+
+ err = dpa_shared_netdev_init(dpa_node, net_dev);
+
+ if (err < 0)
+ goto netdev_init_failed;
+
+ dpaa_eth_sysfs_init(&net_dev->dev);
+
+ return 0;
+
+netdev_init_failed:
+ if (net_dev)
+ free_percpu(priv->percpu_priv);
+alloc_percpu_failed:
+fq_alloc_failed:
+ if (net_dev) {
+ dpa_fq_free(dev, &priv->dpa_fq_list);
+ qman_release_cgrid(priv->cgr_data.cgr.cgrid);
+ qman_delete_cgr(&priv->cgr_data.cgr);
+ }
+cgr_init_failed:
+add_channel_failed:
+get_channel_failed:
+ if (net_dev)
+ dpa_bp_free(priv, priv->dpa_bp);
+bp_create_failed:
+fq_probe_failed:
+alloc_failed:
+mac_probe_failed:
+ dev_set_drvdata(dev, NULL);
+ if (net_dev)
+ free_netdev(net_dev);
+
+ return err;
+}
+
+static const struct of_device_id dpa_macless_match[];
+static int
+dpaa_eth_macless_probe(struct platform_device *_of_dev)
+{
+ int err = 0, i;
+ struct device *dev;
+ struct device_node *dpa_node;
+ struct dpa_bp *dpa_bp;
+ struct dpa_fq *dpa_fq, *tmp;
+ size_t count;
+ struct net_device *net_dev = NULL;
+ struct dpa_priv_s *priv = NULL;
+ struct dpa_percpu_priv_s *percpu_priv;
+ struct fm_port_fqs port_fqs;
+ struct task_struct *kth;
+
+ 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);
+
+ /* Allocate this early, so we can store relevant information in
+ * the private area (needed by 1588 code in dpa_mac_probe)
+ */
+ 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);
+
+ priv = netdev_priv(net_dev);
+ priv->net_dev = net_dev;
+
+ priv->msg_enable = netif_msg_init(debug, -1);
+
+ INIT_LIST_HEAD(&priv->dpa_fq_list);
+
+ memset(&port_fqs, 0, sizeof(port_fqs));
+
+ err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list, RX);
+ if (!err)
+ err = dpa_fq_probe_macless(dev, &priv->dpa_fq_list,
+ TX);
+ if (err < 0)
+ goto fq_probe_failed;
+
+ /* bp init */
+
+ err = dpa_bp_create(net_dev, dpa_bp, count);
+
+ if (err < 0)
+ goto bp_create_failed;
+
+ priv->mac_dev = NULL;
+
+ priv->channel = dpa_get_channel(dev, dpa_node);
+
+ 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;
+ }
+
+ dpa_fq_setup(priv);
+
+ /* 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;
+ }
+
+ priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
+
+ priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+
+ if (priv->percpu_priv == NULL) {
+ dev_err(dev, "alloc_percpu() failed\n");
+ err = -ENOMEM;
+ goto alloc_percpu_failed;
+ }
+ for_each_online_cpu(i) {
+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
+ memset(percpu_priv, 0, sizeof(*percpu_priv));
+ }
+
+ err = dpa_macless_netdev_init(dpa_node, net_dev);
+ if (err < 0)
+ goto netdev_init_failed;
+
+ dpaa_eth_sysfs_init(&net_dev->dev);
+
+ return 0;
+
+netdev_init_failed:
+ if (net_dev)
+ free_percpu(priv->percpu_priv);
+alloc_percpu_failed:
+fq_alloc_failed:
+ if (net_dev) {
+ dpa_fq_free(dev, &priv->dpa_fq_list);
+ qman_release_cgrid(priv->cgr_data.cgr.cgrid);
+ qman_delete_cgr(&priv->cgr_data.cgr);
+ }
+add_channel_failed:
+get_channel_failed:
+ if (net_dev)
+ dpa_bp_free(priv, priv->dpa_bp);
+bp_create_failed:
+fq_probe_failed:
+ dev_set_drvdata(dev, NULL);
+ if (net_dev)
+ free_netdev(net_dev);
+
+ return err;
+}
+
static const struct of_device_id dpa_proxy_match[];
static int
dpaa_eth_proxy_probe(struct platform_device *_of_dev)
@@ -4320,14 +4589,28 @@ dpaa_eth_proxy_probe(struct platform_device *_of_dev)
static const struct of_device_id dpa_match[] = {
{
- .compatible = "fsl,dpa-ethernet",
- .compatible = "fsl,dpa-ethernet-shared",
- .compatible = "fsl,dpa-ethernet-macless"
+ .compatible = "fsl,dpa-ethernet"
},
{}
};
MODULE_DEVICE_TABLE(of, dpa_match);
+static const struct of_device_id dpa_shared_match[] = {
+ {
+ .compatible = "fsl,dpa-ethernet-shared"
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, dpa_shared_match);
+
+static const struct of_device_id dpa_macless_match[] = {
+ {
+ .compatible = "fsl,dpa-ethernet-macless"
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, dpa_macless_match);
+
static const struct of_device_id dpa_proxy_match[] = {
{
.compatible = "fsl,dpa-ethernet-init"
@@ -4386,7 +4669,27 @@ static struct platform_driver dpa_driver = {
.of_match_table = dpa_match,
.owner = THIS_MODULE,
},
- .probe = dpaa_eth_probe,
+ .probe = dpaa_eth_priv_probe,
+ .remove = dpa_remove
+};
+
+static struct platform_driver dpa_shared_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = dpa_shared_match,
+ .owner = THIS_MODULE,
+ },
+ .probe = dpaa_eth_shared_probe,
+ .remove = dpa_remove
+};
+
+static struct platform_driver dpa_macless_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = dpa_macless_match,
+ .owner = THIS_MODULE,
+ },
+ .probe = dpaa_eth_macless_probe,
.remove = dpa_remove
};
@@ -4420,6 +4723,26 @@ static int __init __cold dpa_load(void)
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
+ _errno = platform_driver_register(&dpa_shared_driver);
+ if (unlikely(_errno < 0)) {
+ pr_err(KBUILD_MODNAME"-shared"
+ ": %s:%hu:%s(): platform_driver_register() = %d\n",
+ KBUILD_BASENAME".c", __LINE__, __func__, _errno);
+ }
+
+ pr_debug(KBUILD_MODNAME"-shared" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
+
+ _errno = platform_driver_register(&dpa_macless_driver);
+ if (unlikely(_errno < 0)) {
+ pr_err(KBUILD_MODNAME"-macless"
+ ": %s:%hu:%s(): platform_driver_register() = %d\n",
+ KBUILD_BASENAME".c", __LINE__, __func__, _errno);
+ }
+
+ pr_debug(KBUILD_MODNAME"-macless" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
+
_errno = platform_driver_register(&dpa_proxy_driver);
if (unlikely(_errno < 0)) {
pr_err(KBUILD_MODNAME"-proxy"
@@ -4444,6 +4767,16 @@ static void __exit __cold dpa_unload(void)
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
+ platform_driver_unregister(&dpa_shared_driver);
+
+ pr_debug(KBUILD_MODNAME"-shared" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
+
+ platform_driver_unregister(&dpa_macless_driver);
+
+ pr_debug(KBUILD_MODNAME"-macless" ": %s:%s() ->\n",
+ KBUILD_BASENAME".c", __func__);
+
platform_driver_unregister(&dpa_proxy_driver);
pr_debug(KBUILD_MODNAME"-proxy" ": %s:%s() ->\n",