From be809330f0a332616639af47b767a94058d4fcdf Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Fri, 7 Jun 2013 18:05:17 +0300 Subject: dpaa_eth: separate dpa_eth probe() functions Separated the probe functions for the private, shared and MACless interfaces. Signed-off-by: Madalin Bucur Change-Id: I86a05ba2dc80709b543583e5168694748e75fd05 Reviewed-on: http://git.am.freescale.net:8181/3081 Reviewed-by: Sovaiala Cristian-Constantin-B39531 Reviewed-by: Radulescu Ruxandra Ioana-B05472 Reviewed-by: Fleming Andrew-AFLEMING Tested-by: Fleming Andrew-AFLEMING 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", -- cgit v0.10.2