summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorOlivia Yin-R63875 <r63875@freescale.com>2015-03-13 07:33:41 (GMT)
committerOlivia Yin-R63875 <r63875@freescale.com>2015-03-13 07:33:41 (GMT)
commitebd4f726071e891484e96dab95b63e9b4971c028 (patch)
tree1325c35b90f227bf1e456948af9aef832225c9b0 /drivers
parente2b98fa2f71223315b8bedd58073156e32d2cfe5 (diff)
parent9afc74818962f09450b5008650cce4ac19faacf9 (diff)
downloadlinux-fsl-qoriq-ebd4f726071e891484e96dab95b63e9b4971c028.tar.xz
Merge remote-tracking branch 'dpaa/dpaa-next'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/devres.c63
-rw-r--r--drivers/net/ethernet/freescale/dpa/Kconfig27
-rw-r--r--drivers/net/ethernet/freescale/dpa/Makefile57
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_1588.c11
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c30
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c36
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.h6
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c73
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h10
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c119
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h8
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c290
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h7
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c42
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c6
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c39
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c47
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c1
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c16
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac-api.c10
-rw-r--r--drivers/net/ethernet/freescale/dpa/mac.c71
-rw-r--r--drivers/net/ethernet/freescale/dpa/offline_port.c128
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c2
-rw-r--r--drivers/staging/fsl_qbman/qman_high.c46
25 files changed, 677 insertions, 470 deletions
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 545c4de..8785536 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -805,3 +805,66 @@ void devm_kfree(struct device *dev, void *p)
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_kfree);
+static void devm_percpu_release(struct device *dev, void *pdata)
+{
+ void __percpu *p;
+
+ p = *(void __percpu **)pdata;
+ free_percpu(p);
+}
+
+static int devm_percpu_match(struct device *dev, void *data, void *p)
+{
+ struct devres *devr = container_of(data, struct devres, data);
+
+ return *(void **)devr->data == p;
+}
+
+/**
+ * __devm_alloc_percpu - Resource-managed alloc_percpu
+ * @dev: Device to allocate per-cpu memory for
+ * @size: Size of per-cpu memory to allocate
+ * @align: Alignement of per-cpu memory to allocate
+ *
+ * Managed alloc_percpu. Per-cpu memory allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
+ size_t align)
+{
+ void *p;
+ void __percpu *pcpu;
+
+ pcpu = __alloc_percpu(size, align);
+ if (!pcpu)
+ return NULL;
+
+ p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
+ if (!p)
+ return NULL;
+
+ *(void __percpu **)p = pcpu;
+
+ devres_add(dev, p);
+
+ return pcpu;
+}
+EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
+
+/**
+ * devm_free_percpu - Resource-managed free_percpu
+ * @dev: Device this memory belongs to
+ * @pdata: Per-cpu memory to free
+ *
+ * Free memory allocated with devm_alloc_percpu().
+ */
+void devm_free_percpu(struct device *dev, void __percpu *pdata)
+{
+ WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
+ (void *)pdata));
+}
+EXPORT_SYMBOL_GPL(devm_free_percpu);
+
diff --git a/drivers/net/ethernet/freescale/dpa/Kconfig b/drivers/net/ethernet/freescale/dpa/Kconfig
index a459141..844bdfe 100644
--- a/drivers/net/ethernet/freescale/dpa/Kconfig
+++ b/drivers/net/ethernet/freescale/dpa/Kconfig
@@ -1,5 +1,5 @@
menuconfig FSL_DPAA_ETH
- bool "DPAA Ethernet"
+ tristate "DPAA Ethernet"
depends on FSL_SOC && FSL_BMAN && FSL_QMAN && FSL_FMAN
select PHYLIB
---help---
@@ -49,6 +49,25 @@ config FSL_CAPWAP_BRIDGE_ZMC
endif # FSL_CAPWAP
+config FSL_DPAA_ADVANCED_DRIVERS
+ bool "Advanced DPAA Ethernet drivers"
+ depends on FSL_DPAA_ETH
+ default y
+ ---help---
+ Besides the standard DPAA Ethernet driver there are available other flavours
+ of DPAA drivers that support advanced scenarios:
+ - DPAA Shared MAC driver
+ - DPAA MAC-less driver
+ - DPAA Proxy initialization driver (for USDPAA)
+ Select this to also build the advanced drivers.
+
+config FSL_DPAA_GENERIC_DRIVER
+ bool "Generic DPAA Ethernet driver"
+ depends on FSL_DPAA_ETH
+ default y
+ ---help---
+ This enables the DPAA Generic driver (oNIC).
+
config FSL_DPAA_ETH_JUMBO_FRAME
bool "Optimize for jumbo frames"
default n
@@ -62,14 +81,14 @@ config FSL_DPAA_ETH_JUMBO_FRAME
the system memory.
config FSL_DPAA_TS
- tristate "Linux compliant timestamping"
+ bool "Linux compliant timestamping"
depends on FSL_DPAA_ETH
default n
---help---
Enable Linux API compliant timestamping support.
config FSL_DPAA_1588
- tristate "IEEE 1588-compliant timestamping"
+ bool "IEEE 1588-compliant timestamping"
depends on FSL_DPAA_ETH
select FSL_DPAA_TS
default n
@@ -143,7 +162,7 @@ config FSL_DPAA_INGRESS_CS_THRESHOLD
Traffic piling up above this value will be rejected by QMan and discarded by FMan.
config FSL_DPAA_ETH_DEBUGFS
- tristate "DPAA Ethernet debugfs interface"
+ bool "DPAA Ethernet debugfs interface"
depends on DEBUG_FS && FSL_DPAA_ETH
default y
---help---
diff --git a/drivers/net/ethernet/freescale/dpa/Makefile b/drivers/net/ethernet/freescale/dpa/Makefile
index 929db39..1d1b506 100644
--- a/drivers/net/ethernet/freescale/dpa/Makefile
+++ b/drivers/net/ethernet/freescale/dpa/Makefile
@@ -8,26 +8,47 @@ include $(srctree)/drivers/net/ethernet/freescale/fman/ncsw_config.mk
ccflags-y += -I$(NET_DPA)
-obj-$(CONFIG_FSL_DPAA_1588) += dpaa_1588.o
-# dpaa_debugfs needs to be initialized before dpaa_eth
-obj-$(CONFIG_FSL_DPAA_ETH_DEBUGFS) += dpaa_debugfs.o dpaa_generic_debugfs.o
-obj-$(CONFIG_FSL_DPAA_ETH) += fsl-mac.o fsl-dpa.o fsl-dpa-common.o \
- fsl-dpa-base.o fsl-dpa-shared.o fsl-dpa-proxy.o fsl-dpa-macless.o \
- fsl-dpa-generic.o
-obj-$(CONFIG_FSL_DPAA_OFFLINE_PORTS) += fsl-oh.o
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_mac.o fsl_dpa.o
obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
-fsl-dpa-objs := dpaa_ethtool.o dpaa_eth_sysfs.o \
- dpaa_eth.o dpaa_eth_sg.o
-fsl-dpa-common-objs := dpaa_eth_common.o
-fsl-dpa-base-objs := dpaa_eth_base.o
-fsl-dpa-shared-objs := dpaa_eth_shared.o
-fsl-dpa-proxy-objs := dpaa_eth_proxy.o
-fsl-dpa-macless-objs := dpaa_eth_macless.o
-fsl-dpa-generic-objs := dpaa_eth_generic.o dpaa_eth_generic_sysfs.o \
- dpaa_generic_ethtool.o
-fsl-mac-objs := mac.o mac-api.o
-fsl-oh-objs := offline_port.o
+fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
+ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
+fsl_dpa-objs += dpaa_debugfs.o
+endif
+ifeq ($(CONFIG_FSL_DPAA_1588),y)
+fsl_dpa-objs += dpaa_1588.o
+endif
+
+fsl_mac-objs += mac.o mac-api.o
+
+# Advanced drivers
+ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_advanced.o
+
+fsl_advanced-objs += dpaa_eth_base.o
+# suport for multiple drivers per kernel module comes in kernel 3.14
+# so we are forced to generate several modules for the advanced drivers
+fsl_proxy-objs += dpaa_eth_proxy.o
+fsl_shared-objs += dpaa_eth_shared.o
+fsl_macless-objs += dpaa_eth_macless.o
+
+ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_oh.o
+
+fsl_oh-objs += offline_port.o
+endif
+endif
+
+# Generic driver
+ifeq ($(CONFIG_FSL_DPAA_GENERIC_DRIVER),y)
+obj-$(CONFIG_FSL_DPAA_ETH) += fsl_generic.o
+
+fsl_generic-objs += dpaa_eth_generic.o dpaa_eth_generic_sysfs.o dpaa_generic_ethtool.o
+ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
+fsl_generic-objs += dpaa_generic_debugfs.o
+endif
+endif
+
obj-$(CONFIG_FSL_CAPWAP) += capwap/
# Needed by the tracing framework
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_1588.c b/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
index 9f66640..3bf8cbc 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_1588.c
@@ -578,14 +578,3 @@ void dpa_ptp_cleanup(struct dpa_priv_s *priv)
kfree(tsu);
}
EXPORT_SYMBOL(dpa_ptp_cleanup);
-
-static int __init __cold dpa_ptp_load(void)
-{
- return 0;
-}
-module_init(dpa_ptp_load);
-
-static void __exit __cold dpa_ptp_unload(void)
-{
-}
-module_exit(dpa_ptp_unload);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
index 1f22bd7..59c7338 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
#include <linux/debugfs.h>
-#include <asm/debug.h>
#include "dpaa_debugfs.h"
#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
@@ -308,6 +307,8 @@ static int __cold dpa_debugfs_open(struct inode *inode, struct file *file)
int dpa_netdev_debugfs_create(struct net_device *net_dev)
{
struct dpa_priv_s *priv = netdev_priv(net_dev);
+ static int cnt;
+ char debugfs_file_name[100];
#ifdef CONFIG_FSL_DPAA_DBG_LOOP
char loop_file_name[100];
#endif
@@ -319,30 +320,29 @@ int dpa_netdev_debugfs_create(struct net_device *net_dev)
return -ENOMEM;
}
- priv->debugfs_file = debugfs_create_file(net_dev->name,
+ snprintf(debugfs_file_name, 100, "eth%d", ++cnt);
+ priv->debugfs_file = debugfs_create_file(debugfs_file_name,
S_IRUGO,
dpa_debugfs_root,
net_dev,
&dpa_debugfs_fops);
if (unlikely(priv->debugfs_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
- net_dev->name);
+ debugfs_file_name);
return -ENOMEM;
}
#ifdef CONFIG_FSL_DPAA_DBG_LOOP
- sprintf(loop_file_name, "%s_loop", net_dev->name);
+ sprintf(loop_file_name, "eth%d_loop", cnt);
priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
S_IRUGO,
dpa_debugfs_root,
net_dev,
&dpa_debugfs_lp_fops);
if (unlikely(priv->debugfs_loop_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
loop_file_name);
@@ -362,30 +362,26 @@ void dpa_netdev_debugfs_remove(struct net_device *net_dev)
#endif
}
-static int __init dpa_debugfs_module_init(void)
+int __init dpa_debugfs_module_init(void)
{
int _errno = 0;
pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION " (" VERSION ")\n");
- dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT,
- powerpc_debugfs_root);
+ dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
+
if (unlikely(dpa_debugfs_root == NULL)) {
_errno = -ENOMEM;
pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
KBUILD_BASENAME".c", __LINE__, __func__);
pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
- powerpc_debugfs_root->d_iname, _errno);
+ DPA_ETH_DEBUGFS_ROOT, _errno);
}
return _errno;
}
-static void __exit dpa_debugfs_module_exit(void)
+void __exit dpa_debugfs_module_exit(void)
{
debugfs_remove(dpa_debugfs_root);
}
-
-module_init(dpa_debugfs_module_init);
-module_exit(dpa_debugfs_module_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
index f82cde5..63d3542 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_debugfs.h
@@ -37,5 +37,7 @@
int dpa_netdev_debugfs_create(struct net_device *net_dev);
void dpa_netdev_debugfs_remove(struct net_device *net_dev);
+int __init dpa_debugfs_module_init(void);
+void __exit dpa_debugfs_module_exit(void);
#endif /* DPAA_DEBUGFS_H_ */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index 08d1d3e..4167268 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -373,6 +373,7 @@ int dpaa_eth_poll(struct napi_struct *napi, int budget)
return cleaned;
}
+EXPORT_SYMBOL(dpaa_eth_poll);
static void __hot _dpa_tx_conf(struct net_device *net_dev,
const struct dpa_priv_s *priv,
@@ -718,9 +719,9 @@ void dpa_private_napi_del(struct net_device *net_dev)
}
}
}
+EXPORT_SYMBOL(dpa_private_napi_del);
-static int dpa_private_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev)
+static int dpa_private_netdev_init(struct net_device *net_dev)
{
int i;
struct dpa_priv_s *priv = netdev_priv(net_dev);
@@ -755,7 +756,7 @@ static int dpa_private_netdev_init(struct device_node *dpa_node,
/* Advertise GRO support */
net_dev->features |= NETIF_F_GRO;
- return dpa_netdev_init(dpa_node, net_dev, mac_addr, tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
}
static struct dpa_bp * __cold
@@ -769,7 +770,7 @@ dpa_priv_bp_probe(struct device *dev)
return ERR_PTR(-ENOMEM);
}
- dpa_bp->percpu_count = alloc_percpu(*dpa_bp->percpu_count);
+ dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
dpa_bp->seed_cb = dpa_bp_priv_seed;
@@ -1042,10 +1043,10 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
}
#endif
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -1060,7 +1061,7 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
if (err < 0)
goto napi_add_failed;
- err = dpa_private_netdev_init(dpa_node, net_dev);
+ err = dpa_private_netdev_init(net_dev);
if (err < 0)
goto netdev_init_failed;
@@ -1078,25 +1079,23 @@ dpaa_eth_priv_probe(struct platform_device *_of_dev)
netdev_init_failed:
napi_add_failed:
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
+alloc_percpu_failed:
#ifdef CONFIG_FMAN_PFC
pfc_mapping_failed:
#endif
-alloc_percpu_failed:
dpa_fq_free(dev, &priv->dpa_fq_list);
fq_alloc_failed:
+ qman_delete_cgr_safe(&priv->ingress_cgr);
qman_release_cgrid(priv->ingress_cgr.cgrid);
- qman_delete_cgr(&priv->ingress_cgr);
rx_cgr_init_failed:
+ qman_delete_cgr_safe(&priv->cgr_data.cgr);
qman_release_cgrid(priv->cgr_data.cgr.cgrid);
- qman_delete_cgr(&priv->cgr_data.cgr);
tx_cgr_init_failed:
add_channel_failed:
get_channel_failed:
dpa_bp_free(priv, priv->dpa_bp);
bp_create_failed:
fq_probe_failed:
- devm_kfree(dev, buf_layout);
alloc_failed:
mac_probe_failed:
dev_set_drvdata(dev, NULL);
@@ -1133,6 +1132,10 @@ static int __init __cold dpa_load(void)
pr_info(DPA_DESCRIPTION " (" VERSION ")\n");
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_debugfs_module_init();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
/* initialise dpaa_eth mirror values */
dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
dpa_max_frm = fm_get_max_frm();
@@ -1163,6 +1166,15 @@ static void __exit __cold dpa_unload(void)
platform_driver_unregister(&dpa_driver);
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_debugfs_module_exit();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
+ /* Only one channel is used and needs to be relased after all
+ * interfaces are removed
+ */
+ dpa_release_channel();
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
}
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
index 24504c0..99728f4 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
@@ -36,9 +36,6 @@
#include <linux/fsl_qman.h> /* struct qman_fq */
#include "fm_ext.h"
-#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
-#include "dpaa_debugfs.h"
-#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
#include "dpaa_eth_trace.h"
extern int dpa_rx_extra_headroom;
@@ -471,7 +468,8 @@ dpa_fd_offset(const struct qm_fd *fd)
static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu)
{
if (unlikely(skb->len > mtu))
- if ((skb->protocol != ETH_P_8021Q) || (skb->len > mtu + 4))
+ if ((skb->protocol != htons(ETH_P_8021Q))
+ || (skb->len > mtu + 4))
return -1;
return 0;
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
index 2a744e5..9c2204d 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.c
@@ -29,6 +29,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
+#define pr_fmt(fmt) \
+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
+ KBUILD_BASENAME".c", __LINE__, __func__
+#else
+#define pr_fmt(fmt) \
+ KBUILD_MODNAME ": " fmt
+#endif
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_platform.h>
@@ -43,6 +52,14 @@
#include "dpaa_eth_common.h"
#include "dpaa_eth_base.h"
+#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+uint8_t advanced_debug = -1;
+module_param(advanced_debug, byte, S_IRUGO);
+MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
+
static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
{
return ((struct dpa_bp *)dpa_bp0)->size -
@@ -52,33 +69,24 @@ static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
{
- int i, lenp, na, ns;
+ int i, lenp, na, ns, err;
struct device *dev;
struct device_node *dev_node;
- const phandle *phandle_prop;
- const uint32_t *bpid;
- const uint32_t *bpool_cfg;
+ const __be32 *bpool_cfg;
struct dpa_bp *dpa_bp;
+ u32 bpid;
dev = &_of_dev->dev;
- /* The default is one, if there's no property */
- *count = 1;
-
- /* Get the buffer pools to be used */
- phandle_prop = of_get_property(dev->of_node,
- "fsl,bman-buffer-pools", &lenp);
-
- if (phandle_prop)
- *count = lenp / sizeof(phandle);
- else {
- dev_err(dev,
- "missing fsl,bman-buffer-pools device tree entry\n");
+ *count = of_count_phandle_with_args(dev->of_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (*count < 1) {
+ dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
return ERR_PTR(-EINVAL);
}
dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
- if (unlikely(dpa_bp == NULL)) {
+ if (dpa_bp == NULL) {
dev_err(dev, "devm_kzalloc() failed\n");
return ERR_PTR(-ENOMEM);
}
@@ -92,10 +100,12 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
na = of_n_addr_cells(dev_node);
ns = of_n_size_cells(dev_node);
- for (i = 0; i < *count && phandle_prop; i++) {
+ for (i = 0; i < *count; i++) {
of_node_put(dev_node);
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
- if (unlikely(dev_node == NULL)) {
+
+ dev_node = of_parse_phandle(dev->of_node,
+ "fsl,bman-buffer-pools", i);
+ if (dev_node == NULL) {
dev_err(dev, "of_find_node_by_phandle() failed\n");
return ERR_PTR(-EFAULT);
}
@@ -108,13 +118,13 @@ dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
goto _return_of_node_put;
}
- bpid = of_get_property(dev_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dev, "fsl,bpid property not found.\n");
+ err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
+ if (err) {
+ dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
dpa_bp = ERR_PTR(-EINVAL);
goto _return_of_node_put;
}
- dpa_bp[i].bpid = (uint8_t)*bpid;
+ dpa_bp[i].bpid = (uint8_t)bpid;
bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
&lenp);
@@ -219,3 +229,18 @@ int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
return 0;
}
+static int __init __cold dpa_advanced_load(void)
+{
+ pr_info(DPA_DESCRIPTION " (" VERSION ")\n");
+
+ return 0;
+}
+module_init(dpa_advanced_load);
+
+static void __exit __cold dpa_advanced_unload(void)
+{
+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
+ KBUILD_BASENAME".c", __func__);
+
+}
+module_exit(dpa_advanced_unload);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
index 5b5ef1e..a75e270 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_base.h
@@ -37,10 +37,20 @@
#include <linux/of_platform.h> /* struct platform_device */
#include <linux/net_tstamp.h> /* struct hwtstamp_config */
+extern uint8_t advanced_debug;
+extern const struct dpa_fq_cbs_t shared_fq_cbs;
+extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
+
struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
size_t count);
int dpa_bp_shared_port_seed(struct dpa_bp *bp);
+int __init __cold dpa_proxy_load(void);
+int __init __cold dpa_shared_load(void);
+int __init __cold dpa_macless_load(void);
+void __exit __cold dpa_proxy_unload(void);
+void __exit __cold dpa_shared_unload(void);
+void __exit __cold dpa_macless_unload(void);
#endif /* __DPAA_ETH_BASE_H */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
index 5738160..6e12a81 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.c
@@ -47,6 +47,9 @@
#ifdef CONFIG_FSL_DPAA_1588
#include "dpaa_1588.h"
#endif
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+#include "dpaa_debugfs.h"
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
#include "mac.h"
/* DPAA platforms benefit from hardware-assisted queue management */
@@ -66,14 +69,18 @@ struct ptp_priv_s ptp_priv;
static struct dpa_bp *dpa_bp_array[64];
int dpa_max_frm;
+EXPORT_SYMBOL(dpa_max_frm);
+
int dpa_rx_extra_headroom;
+EXPORT_SYMBOL(dpa_rx_extra_headroom);
+
int dpa_num_cpus = NR_CPUS;
static const struct fqid_cell tx_confirm_fqids[] = {
{0, DPAA_ETH_TX_QUEUES}
};
-static const struct fqid_cell default_fqids[][3] = {
+static struct fqid_cell default_fqids[][3] = {
[RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
[TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
};
@@ -98,10 +105,9 @@ void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
#endif
-int dpa_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev,
- const uint8_t *mac_addr,
- uint16_t tx_timeout)
+int dpa_netdev_init(struct net_device *net_dev,
+ const uint8_t *mac_addr,
+ uint16_t tx_timeout)
{
int err;
struct dpa_priv_s *priv = netdev_priv(net_dev);
@@ -139,6 +145,7 @@ int dpa_netdev_init(struct device_node *dpa_node,
return 0;
}
+EXPORT_SYMBOL(dpa_netdev_init);
int __cold dpa_start(struct net_device *net_dev)
{
@@ -179,6 +186,7 @@ mac_start_failed:
return err;
}
+EXPORT_SYMBOL(dpa_start);
int __cold dpa_stop(struct net_device *net_dev)
{
@@ -212,6 +220,7 @@ int __cold dpa_stop(struct net_device *net_dev)
return _errno;
}
+EXPORT_SYMBOL(dpa_stop);
void __cold dpa_timeout(struct net_device *net_dev)
{
@@ -227,6 +236,7 @@ void __cold dpa_timeout(struct net_device *net_dev)
percpu_priv->stats.tx_errors++;
}
+EXPORT_SYMBOL(dpa_timeout);
/* net_device */
@@ -260,6 +270,7 @@ dpa_get_stats64(struct net_device *net_dev,
return stats;
}
+EXPORT_SYMBOL(dpa_get_stats64);
int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
{
@@ -275,6 +286,7 @@ int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
return 0;
}
+EXPORT_SYMBOL(dpa_change_mtu);
/* .ndo_init callback */
int dpa_ndo_init(struct net_device *net_dev)
@@ -293,6 +305,7 @@ int dpa_ndo_init(struct net_device *net_dev)
return 0;
}
+EXPORT_SYMBOL(dpa_ndo_init);
int dpa_set_features(struct net_device *dev, netdev_features_t features)
{
@@ -300,6 +313,7 @@ int dpa_set_features(struct net_device *dev, netdev_features_t features)
dev->features = features;
return 0;
}
+EXPORT_SYMBOL(dpa_set_features);
netdev_features_t dpa_fix_features(struct net_device *dev,
netdev_features_t features)
@@ -317,6 +331,7 @@ netdev_features_t dpa_fix_features(struct net_device *dev,
return features;
}
+EXPORT_SYMBOL(dpa_fix_features);
#ifdef CONFIG_FSL_DPAA_TS
u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
@@ -478,6 +493,7 @@ int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return ret;
}
+EXPORT_SYMBOL(dpa_ioctl);
int __cold dpa_remove(struct platform_device *of_dev)
{
@@ -498,11 +514,14 @@ int __cold dpa_remove(struct platform_device *of_dev)
err = dpa_fq_free(dev, &priv->dpa_fq_list);
+ qman_delete_cgr_safe(&priv->ingress_cgr);
+ qman_release_cgrid(priv->ingress_cgr.cgrid);
+ qman_delete_cgr_safe(&priv->cgr_data.cgr);
+ qman_release_cgrid(priv->cgr_data.cgr.cgrid);
+
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
dpa_bp_free(priv, priv->dpa_bp);
- devm_kfree(dev, priv->dpa_bp);
if (priv->buf_layout)
devm_kfree(dev, priv->buf_layout);
@@ -521,6 +540,7 @@ int __cold dpa_remove(struct platform_device *of_dev)
return err;
}
+EXPORT_SYMBOL(dpa_remove);
struct mac_device * __cold __must_check
__attribute__((nonnull))
@@ -528,28 +548,20 @@ dpa_mac_probe(struct platform_device *_of_dev)
{
struct device *dpa_dev, *dev;
struct device_node *mac_node;
- int lenp;
- const phandle *phandle_prop;
struct platform_device *of_dev;
struct mac_device *mac_dev;
#ifdef CONFIG_FSL_DPAA_1588
+ int lenp;
struct net_device *net_dev = NULL;
struct dpa_priv_s *priv = NULL;
struct device_node *timer_node;
#endif
- phandle_prop = of_get_property(_of_dev->dev.of_node,
- "fsl,fman-mac", &lenp);
- if (phandle_prop == NULL)
- return NULL;
-
- BUG_ON(lenp != sizeof(phandle));
-
dpa_dev = &_of_dev->dev;
- mac_node = of_find_node_by_phandle(*phandle_prop);
+ mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
if (unlikely(mac_node == NULL)) {
- dev_err(dpa_dev, "of_find_node_by_phandle() failed\n");
+ dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
return ERR_PTR(-EFAULT);
}
@@ -608,6 +620,7 @@ dpa_mac_probe(struct platform_device *_of_dev)
#endif
return mac_dev;
}
+EXPORT_SYMBOL(dpa_mac_probe);
int dpa_set_mac_address(struct net_device *net_dev, void *addr)
{
@@ -640,6 +653,7 @@ int dpa_set_mac_address(struct net_device *net_dev, void *addr)
return 0;
}
+EXPORT_SYMBOL(dpa_set_mac_address);
void dpa_set_rx_mode(struct net_device *net_dev)
{
@@ -663,6 +677,7 @@ void dpa_set_rx_mode(struct net_device *net_dev)
if (unlikely(_errno < 0) && netif_msg_drv(priv))
netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
}
+EXPORT_SYMBOL(dpa_set_rx_mode);
void dpa_set_buffers_layout(struct mac_device *mac_dev,
struct dpa_buffer_layout_s *layout)
@@ -694,6 +709,7 @@ void dpa_set_buffers_layout(struct mac_device *mac_dev,
layout[TX].manip_extra_space = params.manip_extra_space;
layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
}
+EXPORT_SYMBOL(dpa_set_buffers_layout);
int __attribute__((nonnull))
dpa_bp_alloc(struct dpa_bp *dpa_bp)
@@ -764,6 +780,7 @@ pdev_register_failed:
return err;
}
+EXPORT_SYMBOL(dpa_bp_alloc);
void dpa_bp_drain(struct dpa_bp *bp)
{
@@ -832,11 +849,13 @@ dpa_bp_free(struct dpa_priv_s *priv, struct dpa_bp *dpa_bp)
for (i = 0; i < priv->bp_count; i++)
_dpa_bp_free(&priv->dpa_bp[i]);
}
+EXPORT_SYMBOL(dpa_bp_free);
struct dpa_bp *dpa_bpid2pool(int bpid)
{
return dpa_bp_array[bpid];
}
+EXPORT_SYMBOL(dpa_bpid2pool);
void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
{
@@ -859,6 +878,7 @@ u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb)
{
return dpa_get_queue_mapping(skb);
}
+EXPORT_SYMBOL(dpa_select_queue);
#endif
struct dpa_fq *dpa_fq_alloc(struct device *dev,
@@ -880,8 +900,7 @@ struct dpa_fq *dpa_fq_alloc(struct device *dev,
}
#ifdef CONFIG_FMAN_PFC
- if (fq_type == FQ_TYPE_TX ||
- fq_type == FQ_TYPE_TX_RECYCLE)
+ if (fq_type == FQ_TYPE_TX)
for (i = 0; i < fqids->count; i++)
dpa_fq[i].wq = i / dpa_num_cpus;
else
@@ -891,6 +910,7 @@ struct dpa_fq *dpa_fq_alloc(struct device *dev,
return dpa_fq;
}
+EXPORT_SYMBOL(dpa_fq_alloc);
/* Probing of FQs for MACful ports */
int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
@@ -898,8 +918,9 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
bool alloc_tx_conf_fqs,
enum port_type ptype)
{
- const struct fqid_cell *fqids;
- struct dpa_fq *dpa_fq;
+ struct fqid_cell *fqids = NULL;
+ const void *fqids_off = NULL;
+ struct dpa_fq *dpa_fq = NULL;
struct device_node *np = dev->of_node;
int num_ranges;
int i, lenp;
@@ -910,13 +931,26 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
goto fq_alloc_failed;
}
- fqids = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
- if (fqids == NULL) {
+ fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
+ if (fqids_off == NULL) {
/* No dts definition, so use the defaults. */
fqids = default_fqids[ptype];
num_ranges = 3;
} else {
num_ranges = lenp / sizeof(*fqids);
+
+ fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
+ GFP_KERNEL);
+ if (fqids == NULL)
+ goto fqids_alloc_failed;
+
+ /* convert to CPU endianess */
+ for (i = 0; i < num_ranges; i++) {
+ fqids[i].start = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids));
+ fqids[i].count = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids) + sizeof(__be32));
+ }
}
for (i = 0; i < num_ranges; i++) {
@@ -967,7 +1001,8 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
return 0;
fq_alloc_failed:
- dev_err(dev, "dpa_fq_alloc() failed\n");
+fqids_alloc_failed:
+ dev_err(dev, "Cannot allocate memory for frame queues\n");
return -ENOMEM;
invalid_default_queue:
@@ -975,6 +1010,7 @@ invalid_error_queue:
dev_err(dev, "Too many default or error queues\n");
return -EINVAL;
}
+EXPORT_SYMBOL(dpa_fq_probe_mac);
static u32 rx_pool_channel;
static DEFINE_SPINLOCK(rx_pool_channel_init);
@@ -993,6 +1029,13 @@ int dpa_get_channel(void)
return -ENOMEM;
return rx_pool_channel;
}
+EXPORT_SYMBOL(dpa_get_channel);
+
+void dpa_release_channel(void)
+{
+ qman_release_pool(rx_pool_channel);
+}
+EXPORT_SYMBOL(dpa_release_channel);
int dpaa_eth_add_channel(void *__arg)
{
@@ -1007,6 +1050,7 @@ int dpaa_eth_add_channel(void *__arg)
}
return 0;
}
+EXPORT_SYMBOL(dpaa_eth_add_channel);
/**
* Congestion group state change notification callback.
@@ -1015,6 +1059,7 @@ int dpaa_eth_add_channel(void *__arg)
* Also updates some CGR-related stats.
*/
static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
+
int congested)
{
struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
@@ -1077,6 +1122,7 @@ int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
out_error:
return err;
}
+EXPORT_SYMBOL(dpaa_eth_cgr_init);
static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
struct dpa_fq *fq,
@@ -1317,7 +1363,7 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
initfq.fqd.context_a.stashing.annotation_cl = 1;
initfq.fqd.context_a.stashing.context_cl =
DIV_ROUND_UP(sizeof(struct qman_fq), 64);
- };
+ }
_errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
if (_errno < 0) {
@@ -1332,6 +1378,7 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
return 0;
}
+EXPORT_SYMBOL(dpa_fq_init);
static int __cold __attribute__((nonnull))
_dpa_fq_free(struct device *dev, struct qman_fq *fq)
@@ -1381,6 +1428,7 @@ dpa_fq_free(struct device *dev, struct list_head *list)
return _errno;
}
+EXPORT_SYMBOL(dpa_fq_free);
static void
dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
@@ -1467,6 +1515,7 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev,
rx_port_pcd_param.dev = dev;
fm_port_pcd_bind(rxport, &rx_port_pcd_param);
}
+EXPORT_SYMBOL(dpaa_eth_init_ports);
void dpa_release_sgt(struct qm_sg_entry *sgt)
{
@@ -1483,7 +1532,7 @@ void dpa_release_sgt(struct qm_sg_entry *sgt)
DPA_BUG_ON(sgt[i].extension);
bmb[j].hi = sgt[i].addr_hi;
- bmb[j].lo = sgt[i].addr_lo;
+ bmb[j].lo = be32_to_cpu(sgt[i].addr_lo);
j++; i++;
} while (j < ARRAY_SIZE(bmb) &&
@@ -1494,6 +1543,7 @@ void dpa_release_sgt(struct qm_sg_entry *sgt)
cpu_relax();
} while (!sgt[i-1].final);
}
+EXPORT_SYMBOL(dpa_release_sgt);
void __attribute__((nonnull))
dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
@@ -1548,7 +1598,7 @@ void count_ern(struct dpa_percpu_priv_s *percpu_priv,
break;
}
}
-
+EXPORT_SYMBOL(count_ern);
/**
* Turn on HW checksum computation for this outgoing frame.
@@ -1567,8 +1617,8 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
fm_prs_result_t *parse_result;
struct iphdr *iph;
struct ipv6hdr *ipv6h = NULL;
- int l4_proto;
- int ethertype = ntohs(skb->protocol);
+ u8 l4_proto;
+ u16 ethertype = ntohs(skb->protocol);
int retval = 0;
if (skb->ip_summed != CHECKSUM_PARTIAL)
@@ -1597,16 +1647,16 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
*/
switch (ethertype) {
case ETH_P_IP:
- parse_result->l3r = FM_L3_PARSE_RESULT_IPV4;
+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
iph = ip_hdr(skb);
DPA_BUG_ON(iph == NULL);
- l4_proto = ntohs(iph->protocol);
+ l4_proto = iph->protocol;
break;
case ETH_P_IPV6:
- parse_result->l3r = FM_L3_PARSE_RESULT_IPV6;
+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
ipv6h = ipv6_hdr(skb);
DPA_BUG_ON(ipv6h == NULL);
- l4_proto = ntohs(ipv6h->nexthdr);
+ l4_proto = ipv6h->nexthdr;
break;
default:
/* We shouldn't even be here */
@@ -1652,3 +1702,4 @@ int dpa_enable_tx_csum(struct dpa_priv_s *priv,
return_error:
return retval;
}
+EXPORT_SYMBOL(dpa_enable_tx_csum);
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
index 96ceee3..ee1c853 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_common.h
@@ -128,10 +128,9 @@ void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
#endif
-int dpa_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev,
- const uint8_t *mac_addr,
- uint16_t tx_timeout);
+int dpa_netdev_init(struct net_device *net_dev,
+ const uint8_t *mac_addr,
+ uint16_t tx_timeout);
int __cold dpa_start(struct net_device *net_dev);
int __cold dpa_stop(struct net_device *net_dev);
void __cold dpa_timeout(struct net_device *net_dev);
@@ -178,6 +177,7 @@ int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
bool tx_conf_fqs_per_core,
enum port_type ptype);
int dpa_get_channel(void);
+void dpa_release_channel(void);
int dpaa_eth_add_channel(void *__arg);
int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
index 21d177a..f78e176 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
@@ -66,9 +66,9 @@
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_GENERIC_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
+static uint8_t generic_debug = -1;
+module_param(generic_debug, byte, S_IRUGO);
+MODULE_PARM_DESC(generic_debug, "Module/Driver verbosity level");
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
static uint16_t tx_timeout = 1000;
@@ -101,11 +101,10 @@ static const struct net_device_ops dpa_generic_ops = {
.ndo_init = dpa_ndo_init,
.ndo_set_features = dpa_set_features,
.ndo_fix_features = dpa_fix_features,
- .ndo_init = dpa_ndo_init,
.ndo_change_mtu = dpa_change_mtu,
};
-void dpa_generic_draining_timer(unsigned long arg)
+static void dpa_generic_draining_timer(unsigned long arg)
{
struct dpa_generic_priv_s *priv = (struct dpa_generic_priv_s *)arg;
@@ -174,31 +173,27 @@ static struct platform_driver dpa_generic_driver = {
.remove = dpa_generic_remove
};
-int get_port_ref(struct device_node dev_node,
+static int get_port_ref(struct device_node *dev_node,
struct fm_port **port)
{
- const phandle *dpa_port_ref_node = NULL;
- struct platform_device *dpa_port_of_dev = NULL;
+ struct platform_device *port_of_dev = NULL;
struct device *op_dev = NULL;
- struct device_node *dpa_port_node = NULL;
- int lenp = 0;
+ struct device_node *port_node = NULL;
- dpa_port_ref_node = of_get_property(&dev_node,
- "fsl,fman-oh-port", &lenp);
- if (dpa_port_ref_node == NULL)
+ port_node = of_parse_phandle(dev_node, "fsl,fman-oh-port", 0);
+ if (port_node == NULL)
return -EINVAL;
- dpa_port_node = of_find_node_by_phandle(*dpa_port_ref_node);
- if (dpa_port_node == NULL)
- return -EINVAL;
+ port_of_dev = of_find_device_by_node(port_node);
+ of_node_put(port_node);
- dpa_port_of_dev = of_find_device_by_node(dpa_port_node);
- of_node_put(dpa_port_node);
- if (dpa_port_of_dev == NULL)
+ if (port_of_dev == NULL)
return -EINVAL;
- op_dev = &dpa_port_of_dev->dev;
+ /* get the reference to oh port from FMD */
+ op_dev = &port_of_dev->dev;
*port = fm_port_bind(op_dev);
+
if (*port == NULL)
return -EINVAL;
@@ -234,31 +229,25 @@ static void dpaa_generic_napi_disable(struct dpa_generic_priv_s *priv)
static struct device_node *get_rx_op_port_node(struct platform_device *_of_dev)
{
struct device *dev = &_of_dev->dev;
- struct device_node *dev_node = NULL;
- const phandle *ports_handle = NULL;
+ struct device_node *port_node = NULL;
+ struct device_node *onic_node = NULL;
int num_ports = 0;
- int lenp = 0;
- ports_handle = of_get_property(dev->of_node,
- "fsl,oh-ports", &lenp);
- if (ports_handle == NULL) {
- dev_err(dev, "Cannot find node fsl,oh-ports property in device tree\n");
- return ERR_PTR(-EINVAL);
- }
+ onic_node = dev->of_node;
- num_ports = lenp / sizeof(*ports_handle);
- if (num_ports < 1) {
- dev_err(dev, "There should be at least one O/H port in device tree\n");
+ num_ports = of_count_phandle_with_args(onic_node, "fsl,oh-ports", NULL);
+ if (num_ports != 2) {
+ dev_err(dev, "There should be two O/H port handles in the device tree\n");
return ERR_PTR(-EINVAL);
}
- dev_node = of_find_node_by_phandle(*ports_handle);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find node oh port node in device tree\n");
+ port_node = of_parse_phandle(onic_node, "fsl,oh-ports", 0);
+ if (port_node == NULL) {
+ dev_err(dev, "Cannot find O/H port node in the device tree\n");
return ERR_PTR(-EFAULT);
}
- return dev_node;
+ return port_node;
}
static int __cold dpa_generic_start(struct net_device *netdev)
@@ -499,10 +488,10 @@ static void dpa_generic_drain_bp(struct dpa_bp *bp, u8 nbuf)
* Note that this function may modify the fd->cmd field and the skb data buffer
* (the Parse Results area).
*/
-int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
- struct sk_buff *skb,
- struct qm_fd *fd,
- char *parse_results)
+static int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
+ struct sk_buff *skb,
+ struct qm_fd *fd,
+ char *parse_results)
{
fm_prs_result_t *parse_result;
struct iphdr *iph;
@@ -540,13 +529,13 @@ int dpa_generic_tx_csum(struct dpa_generic_priv_s *priv,
parse_result->l3r = FM_L3_PARSE_RESULT_IPV4;
iph = ip_hdr(skb);
BUG_ON(iph == NULL);
- l4_proto = ntohs(iph->protocol);
+ l4_proto = iph->protocol;
break;
case ETH_P_IPV6:
parse_result->l3r = FM_L3_PARSE_RESULT_IPV6;
ipv6h = ipv6_hdr(skb);
BUG_ON(ipv6h == NULL);
- l4_proto = ntohs(ipv6h->nexthdr);
+ l4_proto = ipv6h->nexthdr;
break;
default:
/* We shouldn't even be here */
@@ -718,7 +707,7 @@ static int dpa_generic_napi_add(struct net_device *net_dev)
return 0;
}
-void dpa_generic_napi_del(struct net_device *net_dev)
+static void dpa_generic_napi_del(struct net_device *net_dev)
{
struct dpa_generic_priv_s *priv = netdev_priv(net_dev);
struct dpa_percpu_priv_s *percpu_priv;
@@ -785,82 +774,112 @@ static int dpa_generic_netdev_init(struct device_node *dpa_node,
return 0;
}
-struct dpa_fq_cbs_t generic_fq_cbs = {
+static struct dpa_fq_cbs_t generic_fq_cbs = {
.rx_defq = { .cb = { .dqrr = dpa_generic_rx_dqrr } },
.rx_errq = { .cb = { .dqrr = dpa_generic_rx_err_dqrr } },
.egress_ern = { .cb = { .ern = dpa_generic_ern } }
};
-struct list_head *dpa_generic_fq_probe(struct platform_device *_of_dev,
- struct fm_port *tx_port)
+static struct fqid_cell *__fq_alloc(struct device *dev,
+ int num_ranges,
+ const void *fqids_off)
+{
+ struct fqid_cell *fqids;
+ int i;
+
+ fqids = kzalloc(sizeof(*fqids) * num_ranges, GFP_KERNEL);
+ if (fqids == NULL)
+ return NULL;
+
+ /* convert to CPU endianess */
+ for (i = 0; i < num_ranges; i++) {
+ fqids[i].start = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids));
+ fqids[i].count = be32_to_cpup(fqids_off +
+ i * sizeof(*fqids) + sizeof(__be32));
+ }
+
+ return fqids;
+}
+
+static struct list_head *dpa_generic_fq_probe(struct platform_device *_of_dev,
+ struct fm_port *tx_port)
{
struct device *dev = &_of_dev->dev;
- struct device_node *dev_node = NULL;
- const struct fqid_cell *fqids;
+ struct device_node *oh_node = NULL;
+ struct device_node *onic_node = NULL;
+ struct fqid_cell *fqids;
+ const void *fqids_off;
struct dpa_fq *fq, *tmp;
struct list_head *list;
int num_ranges;
int i, lenp;
- /* RX queues (RX error, RX default) are specified in Rx O/H port node */
- dev_node = get_rx_op_port_node(_of_dev);
+ onic_node = dev->of_node;
+
+ list = devm_kzalloc(dev, sizeof(*list), GFP_KERNEL);
+ if (!list) {
+ dev_err(dev, "Cannot allocate space for frame queues list\n");
+ return ERR_PTR(-ENOMEM);
+ }
- fqids = of_get_property(dev_node, "fsl,qman-frame-queues-oh", &lenp);
- if (fqids == NULL) {
+ INIT_LIST_HEAD(list);
+
+ /* RX queues (RX error, RX default) are specified in Rx O/H port node */
+ oh_node = get_rx_op_port_node(_of_dev);
+ fqids_off = of_get_property(oh_node, "fsl,qman-frame-queues-oh", &lenp);
+ if (fqids_off == NULL) {
dev_err(dev, "Need Rx FQ definition in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
+ of_node_put(oh_node);
- of_node_put(dev_node);
num_ranges = lenp / sizeof(*fqids);
if (num_ranges != 2) {
dev_err(dev, "Need 2 Rx FQ definitions in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
- list = devm_kzalloc(dev, sizeof(*list), GFP_KERNEL);
- if (!list) {
- dev_err(dev, "devm_kzalloc() failed\n");
- return ERR_PTR(-ENOMEM);
- }
-
- INIT_LIST_HEAD(list);
-
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
if (!dpa_fq_alloc(dev, &fqids[0], list, FQ_TYPE_RX_ERROR) ||
!dpa_fq_alloc(dev, &fqids[1], list,
FQ_TYPE_RX_DEFAULT)) {
- dev_err(dev, "_dpa_fq_alloc() failed\n");
+ dev_err(dev, "Cannot allocate space for default frame queues\n");
return ERR_PTR(-ENOMEM);
}
+ kfree(fqids);
/* TX queues */
- fqids = of_get_property(dev->of_node,
- "fsl,qman-frame-queues-tx", &lenp);
- if (fqids == NULL) {
+ fqids_off = of_get_property(onic_node, "fsl,qman-frame-queues-tx",
+ &lenp);
+ if (fqids_off == NULL) {
dev_err(dev, "Need Tx FQ definition in dts for generic devices\n");
return ERR_PTR(-EINVAL);
}
num_ranges = lenp / sizeof(*fqids);
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
for (i = 0; i < num_ranges; i++) {
if (!dpa_fq_alloc(dev, &fqids[i], list, FQ_TYPE_TX)) {
dev_err(dev, "_dpa_fq_alloc() failed\n");
return ERR_PTR(-ENOMEM);
}
}
+ kfree(fqids);
/* optional RX PCD queues */
lenp = 0;
- fqids = of_get_property(dev->of_node,
+ fqids_off = of_get_property(onic_node,
"fsl,qman-frame-queues-rx", &lenp);
-
num_ranges = lenp / sizeof(*fqids);
+ fqids = __fq_alloc(dev, num_ranges, fqids_off);
for (i = 0; i < num_ranges; i++) {
if (!dpa_fq_alloc(dev, &fqids[i], list, FQ_TYPE_RX_PCD)) {
dev_err(dev, "_dpa_fq_alloc() failed\n");
return ERR_PTR(-ENOMEM);
}
}
+ kfree(fqids);
list_for_each_entry_safe(fq, tmp, list, list) {
if (fq->fq_type == FQ_TYPE_TX)
@@ -898,36 +917,33 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
struct dpa_buffer_layout_s **rx_buf_layout)
{
struct device *dev = &_of_dev->dev;
- const phandle *phandle_prop = NULL;
struct fm_port_params params;
struct dpa_bp *bp = NULL;
int bp_count = 0;
- const uint32_t *bpid = NULL;
- const uint32_t *bpool_cfg = NULL;
+ int bpid;
+ const __be32 *bpool_cfg = NULL;
struct device_node *dev_node = NULL;
+ struct device_node *oh_node = NULL;
struct dpa_buffer_layout_s *buf_layout = NULL;
int lenp = 0;
int na = 0, ns = 0;
int err = 0, i = 0;
- dev_node = get_rx_op_port_node(_of_dev);
+ oh_node = get_rx_op_port_node(_of_dev);
- phandle_prop = of_get_property(dev_node,
- "fsl,bman-buffer-pools", &lenp);
- if (!phandle_prop) {
- dev_err(dev, "missing fsl,bman-buffer-pools property from device tree\n");
+ bp_count = of_count_phandle_with_args(oh_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (bp_count <= 0) {
+ dev_err(dev, "Missing buffer pool handles from onic node from device tree\n");
return -EINVAL;
}
- bp_count = lenp / sizeof(*phandle_prop);
-
bp = devm_kzalloc(dev, bp_count * sizeof(*bp), GFP_KERNEL);
if (unlikely(bp == NULL)) {
dev_err(dev, "devm_kzalloc() failed\n");
return -ENOMEM;
}
- of_node_put(dev_node);
dev_node = of_find_node_by_path("/");
if (unlikely(dev_node == NULL)) {
dev_err(dev, "of_find_node_by_path(/) failed\n");
@@ -940,27 +956,20 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
of_node_put(dev_node);
for (i = 0; i < bp_count; i++) {
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "of_find_node_by_phandle() failed\n");
+ dev_node = of_parse_phandle(oh_node,
+ "fsl,bman-buffer-pools", i);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find buffer pool node in the device tree\n");
return -EFAULT;
}
- if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
- dev_err(dev, "!of_device_is_compatible(%s, fsl,bpool)\n",
- dev_node->full_name);
- err = -EINVAL;
+ err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
+ if (err) {
+ dev_err(dev, "Cannot find buffer pool ID in the buffer pool node in the device tree\n");
goto _return_of_node_put;
}
- bpid = of_get_property(dev_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dev, "fsl,bpid property not found.\n");
- err = -EINVAL;
- goto _return_of_node_put;
- }
-
- bp[i].bpid = (uint8_t)*bpid;
+ bp[i].bpid = (uint8_t)bpid;
bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
&lenp);
@@ -976,9 +985,12 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_dev,
goto _return_of_node_put;
}
- bp[i].percpu_count = alloc_percpu(*(bp[i].percpu_count));
+ bp[i].percpu_count = devm_alloc_percpu(dev,
+ *bp[i].percpu_count);
}
+ of_node_put(oh_node);
+
buf_layout = devm_kzalloc(dev, sizeof(*buf_layout), GFP_KERNEL);
if (!buf_layout) {
dev_err(dev, "devm_kzalloc() failed\n");
@@ -1010,10 +1022,10 @@ _return_of_node_put:
return err;
}
-int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
- struct fm_port *tx_port,
- struct dpa_bp **draining_tx_bp,
- struct dpa_buffer_layout_s **tx_buf_layout)
+static int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
+ struct fm_port *tx_port,
+ struct dpa_bp **draining_tx_bp,
+ struct dpa_buffer_layout_s **tx_buf_layout)
{
struct device *dev = &_of_dev->dev;
struct fm_port_params params;
@@ -1042,7 +1054,7 @@ int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
}
bp->size = dpa_bp_size(buf_layout);
- bp->percpu_count = alloc_percpu(*bp->percpu_count);
+ bp->percpu_count = devm_alloc_percpu(dev, *bp->percpu_count);
bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
*draining_tx_bp = bp;
@@ -1051,8 +1063,8 @@ int dpa_generic_tx_bp_probe(struct platform_device *_of_dev,
return 0;
}
-int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
- int *disable_buff_dealloc)
+static int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
+ int *disable_buff_dealloc)
{
struct device *dev = &_of_dev->dev;
const phandle *disable_handle = NULL;
@@ -1067,52 +1079,45 @@ int dpa_generic_buff_dealloc_probe(struct platform_device *_of_dev,
return err;
}
-int dpa_generic_port_probe(struct platform_device *_of_dev,
- struct fm_port **rx_port,
- struct fm_port **tx_port)
+static int dpa_generic_port_probe(struct platform_device *_of_dev,
+ struct fm_port **rx_port,
+ struct fm_port **tx_port)
{
struct device *dev = &_of_dev->dev;
struct device_node *dev_node = NULL;
- const phandle *ports_handle = NULL;
+ struct device_node *onic_node = NULL;
int num_ports = 0;
- int lenp = 0;
int err = 0;
- ports_handle = of_get_property(dev->of_node,
- "fsl,oh-ports", &lenp);
- if (ports_handle == NULL) {
- dev_err(dev, "Cannot find fsl,oh-ports property in device tree\n");
- return -EINVAL;
- }
+ onic_node = dev->of_node;
- num_ports = lenp / sizeof(*ports_handle);
+ num_ports = of_count_phandle_with_args(onic_node, "fsl,oh-ports", NULL);
if (num_ports != 2) {
- /* for the moment, only two ports are supported */
dev_err(dev, "There should be two OH ports in device tree (one for RX, one for TX\n");
return -EINVAL;
}
- dev_node = of_find_node_by_phandle(ports_handle[RX]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find OH port node in device tree\n");
- return -EFAULT;
+ dev_node = of_parse_phandle(onic_node, "fsl,oh-ports", RX);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find Rx OH port node in device tree\n");
+ return err;
}
- err = get_port_ref(*dev_node, rx_port);
- if (err < 0) {
- dev_err(dev, "Cannot read OH port node in device tree\n");
+ err = get_port_ref(dev_node, rx_port);
+ if (err) {
+ dev_err(dev, "Cannot read Rx OH port node in device tree\n");
return err;
}
- dev_node = of_find_node_by_phandle(ports_handle[TX]);
- if (unlikely(dev_node == NULL)) {
- dev_err(dev, "Cannot find OH port node in device tree\n");
+ dev_node = of_parse_phandle(onic_node, "fsl,oh-ports", TX);
+ if (dev_node == NULL) {
+ dev_err(dev, "Cannot find Tx OH port node in device tree\n");
return -EFAULT;
}
- err = get_port_ref(*dev_node, tx_port);
- if (err < 0) {
- dev_err(dev, "Cannot read OH port node in device tree\n");
+ err = get_port_ref(dev_node, tx_port);
+ if (err) {
+ dev_err(dev, "Cannot read Tx OH port node in device tree\n");
return err;
}
@@ -1252,7 +1257,7 @@ static int dpa_generic_fq_init(struct dpa_fq *dpa_fq, int disable_buff_dealloc)
initfq.fqd.context_a.stashing.annotation_cl = 1;
initfq.fqd.context_a.stashing.context_cl =
DIV_ROUND_UP(sizeof(struct qman_fq), 64);
- };
+ }
_errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
if (_errno < 0) {
@@ -1308,12 +1313,12 @@ static int dpa_generic_fq_create(struct net_device *netdev,
return 0;
}
-int dpa_generic_bp_create(struct net_device *net_dev,
- int rx_bp_count,
- struct dpa_bp *rx_bp,
- struct dpa_buffer_layout_s *rx_buf_layout,
- struct dpa_bp *draining_tx_bp,
- struct dpa_buffer_layout_s *tx_buf_layout)
+static int dpa_generic_bp_create(struct net_device *net_dev,
+ int rx_bp_count,
+ struct dpa_bp *rx_bp,
+ struct dpa_buffer_layout_s *rx_buf_layout,
+ struct dpa_bp *draining_tx_bp,
+ struct dpa_buffer_layout_s *tx_buf_layout)
{
struct dpa_generic_priv_s *priv = netdev_priv(net_dev);
int err = 0;
@@ -1365,7 +1370,6 @@ static int dpa_generic_remove(struct platform_device *of_dev)
#endif
dpa_private_napi_del(net_dev);
- free_percpu(priv->percpu_priv);
/* TODO: this is for private dirver also; make generic */
#if 0
@@ -1439,7 +1443,7 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
priv = netdev_priv(netdev);
priv->net_dev = netdev;
sprintf(priv->if_type, "generic%d", generic_idx++);
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(generic_debug, -1);
priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
init_timer(&priv->timer);
@@ -1465,9 +1469,9 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
priv->mac_dev = NULL;
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -1495,8 +1499,6 @@ static int dpa_generic_eth_probe(struct platform_device *_of_dev)
netdev_init_failed:
napi_add_failed:
dpa_generic_napi_del(netdev);
- if (netdev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
if (netdev)
dpa_fq_free(dev, &priv->dpa_fq_list);
@@ -1530,6 +1532,10 @@ static int __init __cold dpa_generic_load(void)
KBUILD_BASENAME".c", __LINE__, __func__, _errno);
}
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_generic_debugfs_module_init();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
@@ -1548,6 +1554,10 @@ static void __exit __cold dpa_generic_unload(void)
platform_driver_unregister(&dpa_generic_driver);
+#ifdef CONFIG_FSL_DPAA_ETH_DEBUGFS
+ dpa_generic_debugfs_module_exit();
+#endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
+
pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
KBUILD_BASENAME".c", __func__);
}
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
index 606812f..aa74edf 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.h
@@ -38,7 +38,7 @@
struct dpa_generic_priv_s {
struct net_device *net_dev;
/* use the same percpu_priv as other DPAA Ethernet drivers */
- struct dpa_percpu_priv_s *percpu_priv;
+ struct dpa_percpu_priv_s __percpu *percpu_priv;
/* up to 4 bps supported for RX */
int rx_bp_count;
@@ -84,10 +84,11 @@ struct dpa_generic_priv_s {
struct timer_list timer;
};
+extern const struct ethtool_ops dpa_generic_ethtool_ops;
void dpaa_eth_generic_sysfs_init(struct device *dev);
void dpaa_eth_generic_sysfs_remove(struct device *dev);
-
-extern const struct ethtool_ops dpa_generic_ethtool_ops;
+int __init dpa_generic_debugfs_module_init(void);
+void __exit dpa_generic_debugfs_module_exit(void);
#endif /* __DPA_ETH_GENERIC_H */
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
index 0258c90..c13e5cd 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_macless.c
@@ -65,18 +65,10 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
-static uint16_t tx_timeout = 1000;
-module_param(tx_timeout, ushort, S_IRUGO);
-MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
-
-/* reused from the shared driver */
-extern const struct dpa_fq_cbs_t shared_fq_cbs;
-int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
+static uint16_t macless_tx_timeout = 1000;
+module_param(macless_tx_timeout, ushort, S_IRUGO);
+MODULE_PARM_DESC(macless_tx_timeout, "The MACless Tx timeout in ms");
/* forward declarations */
static int __cold dpa_macless_start(struct net_device *net_dev);
@@ -88,8 +80,6 @@ static void __cold dpa_macless_set_rx_mode(struct net_device *net_dev);
static int dpaa_eth_macless_probe(struct platform_device *_of_dev);
static netdev_features_t
dpa_macless_fix_features(struct net_device *dev, netdev_features_t features);
-static int dpa_macless_netdev_init(struct device_node *dpa_node,
- struct net_device *net_dev);
static const struct net_device_ops dpa_macless_ops = {
.ndo_open = dpa_macless_start,
@@ -119,7 +109,7 @@ MODULE_DEVICE_TABLE(of, dpa_macless_match);
static struct platform_driver dpa_macless_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME "-macless",
.of_match_table = dpa_macless_match,
.owner = THIS_MODULE,
},
@@ -227,8 +217,8 @@ static int dpa_macless_netdev_init(struct device_node *dpa_node,
net_dev->mem_start = mac_dev->res->start;
net_dev->mem_end = mac_dev->res->end;
- return dpa_netdev_init(dpa_node, net_dev, mac_dev->addr,
- tx_timeout);
+ return dpa_netdev_init(net_dev, mac_dev->addr,
+ macless_tx_timeout);
} else {
/* Get the MAC address from device tree */
mac_addr = of_get_mac_address(dpa_node);
@@ -239,8 +229,8 @@ static int dpa_macless_netdev_init(struct device_node *dpa_node,
return -EINVAL;
}
- return dpa_netdev_init(dpa_node, net_dev, mac_addr,
- tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr,
+ macless_tx_timeout);
}
}
@@ -273,7 +263,8 @@ static int dpa_fq_probe_macless(struct device *dev, struct list_head *list,
return 0;
}
-struct proxy_device *dpa_macless_proxy_probe(struct platform_device *_of_dev)
+ static struct proxy_device *
+dpa_macless_proxy_probe(struct platform_device *_of_dev)
{
struct device *dev;
const phandle *proxy_prop;
@@ -358,7 +349,7 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
priv->net_dev = net_dev;
sprintf(priv->if_type, "macless%d", macless_idx++);
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(advanced_debug, -1);
priv->peer = NULL;
priv->mac_dev = NULL;
@@ -432,10 +423,10 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
priv->tx_headroom = DPA_DEFAULT_TX_HEADROOM;
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -456,8 +447,6 @@ static int dpaa_eth_macless_probe(struct platform_device *_of_dev)
return 0;
netdev_init_failed:
- if (net_dev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
fq_alloc_failed:
if (net_dev)
@@ -497,10 +486,7 @@ static int __init __cold dpa_macless_load(void)
return _errno;
}
-/* waits for proxy to initialize first, in case MAC device reference
- * is needed
- */
-late_initcall(dpa_macless_load);
+module_init(dpa_macless_load);
static void __exit __cold dpa_macless_unload(void)
{
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
index 57aacb9..8f58203 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_proxy.c
@@ -53,10 +53,6 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
#ifdef CONFIG_PM
@@ -329,7 +325,7 @@ MODULE_DEVICE_TABLE(of, dpa_proxy_match);
static struct platform_driver dpa_proxy_driver = {
.driver = {
- .name = KBUILD_MODNAME"-proxy",
+ .name = KBUILD_MODNAME "-proxy",
.of_match_table = dpa_proxy_match,
.owner = THIS_MODULE,
.pm = PROXY_PM_OPS,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
index fd1f2a8..2e541a8 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
@@ -102,6 +102,8 @@ static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
struct device *dev = dpa_bp->dev;
struct sk_buff *skb, **skbh;
+ memset(bmb, 0, sizeof(struct bm_buffer) * 8);
+
for (i = 0; i < 8; i++) {
/* We'll prepend the skb back-pointer; can't use the DPA
* priv space, because FMan will overwrite it (from offset 0)
@@ -182,6 +184,7 @@ int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
}
return 0;
}
+EXPORT_SYMBOL(dpa_bp_priv_seed);
/* Add buffers/(pages) for Rx processing whenever bpool count falls below
* REFILL_THRESHOLD.
@@ -211,6 +214,7 @@ int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
return 0;
}
+EXPORT_SYMBOL(dpaa_eth_refill_bpools);
/* Cleanup function for outgoing frame descriptors that were built on Tx path,
* either contiguous frames or scatter/gather ones.
@@ -229,6 +233,7 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
int i;
struct dpa_bp *dpa_bp = priv->dpa_bp;
dma_addr_t addr = qm_fd_addr(fd);
+ dma_addr_t sg_addr;
struct sk_buff **skbh;
struct sk_buff *skb = NULL;
const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
@@ -261,15 +266,18 @@ struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
#endif /* CONFIG_FSL_DPAA_TS */
/* sgt[0] is from lowmem, was dma_map_single()-ed */
- dma_unmap_single(dpa_bp->dev, (dma_addr_t)sgt[0].addr,
- sgt[0].length, dma_dir);
+ /* TODO: sg_addr should be in CPU endianess */
+ sg_addr = qm_sg_addr(&sgt[0]);
+ dma_unmap_single(dpa_bp->dev, sg_addr,
+ be32_to_cpu(sgt[0].length), dma_dir);
/* remaining pages were mapped with dma_map_page() */
for (i = 1; i < nr_frags; i++) {
DPA_BUG_ON(sgt[i].extension);
-
- dma_unmap_page(dpa_bp->dev, (dma_addr_t)sgt[i].addr,
- sgt[i].length, dma_dir);
+ /* TODO: sg_addr should be in CPU endianess */
+ sg_addr = qm_sg_addr(&sgt[i]);
+ dma_unmap_page(dpa_bp->dev, sg_addr,
+ be32_to_cpu(sgt[i].length), dma_dir);
}
/* Free the page frag that we allocated on Tx */
@@ -435,6 +443,7 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
/* We use a single global Rx pool */
DPA_BUG_ON(dpa_bp != dpa_bpid2pool(sgt[i].bpid));
+ /* TODO: sg_addr should be in CPU endianess */
sg_addr = qm_sg_addr(&sgt[i]);
sg_vaddr = phys_to_virt(sg_addr);
DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
@@ -469,7 +478,7 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
*/
DPA_BUG_ON(fd_off != priv->rx_headroom);
skb_reserve(skb, fd_off);
- skb_put(skb, sgt[i].length);
+ skb_put(skb, be32_to_cpu(sgt[i].length));
} else {
/* Not the first S/G entry; all data from buffer will
* be added in an skb fragment; fragment index is offset
@@ -495,8 +504,8 @@ static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
/* page_offset only refers to the beginning of sgt[i];
* but the buffer itself may have an internal offset.
*/
- frag_offset = sgt[i].offset + page_offset;
- frag_len = sgt[i].length;
+ frag_offset = be16_to_cpu(sgt[i].offset) + page_offset;
+ frag_len = be32_to_cpu(sgt[i].length);
/* skb_add_rx_frag() does no checking on the page; if
* we pass it a tail page, we'll end up with
* bad page accounting and eventually with segafults.
@@ -715,8 +724,8 @@ static int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
netdev_err(net_dev, "dma_map_single() failed\n");
return -EINVAL;
}
- fd->addr_hi = (uint8_t)upper_32_bits(addr);
- fd->addr_lo = lower_32_bits(addr);
+ fd->addr = addr;
+
return 0;
}
@@ -764,7 +773,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
sgt[0].bpid = 0xff;
sgt[0].offset = 0;
- sgt[0].length = skb_headlen(skb);
+ sgt[0].length = cpu_to_be32(skb_headlen(skb));
sgt[0].extension = 0;
sgt[0].final = 0;
addr = dma_map_single(dpa_bp->dev, skb->data, sgt[0].length, dma_dir);
@@ -775,14 +784,14 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
}
sgt[0].addr_hi = (uint8_t)upper_32_bits(addr);
- sgt[0].addr_lo = lower_32_bits(addr);
+ sgt[0].addr_lo = cpu_to_be32(lower_32_bits(addr));
/* populate the rest of SGT entries */
for (i = 1; i <= nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i - 1];
sgt[i].bpid = 0xff;
sgt[i].offset = 0;
- sgt[i].length = frag->size;
+ sgt[i].length = cpu_to_be32(frag->size);
sgt[i].extension = 0;
sgt[i].final = 0;
@@ -797,7 +806,7 @@ static int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
/* keep the offset in the address */
sgt[i].addr_hi = (uint8_t)upper_32_bits(addr);
- sgt[i].addr_lo = lower_32_bits(addr);
+ sgt[i].addr_lo = cpu_to_be32(lower_32_bits(addr));
}
sgt[i - 1].final = 1;
@@ -830,7 +839,7 @@ sgt_map_failed:
sg_map_failed:
for (j = 0; j < i; j++)
dma_unmap_page(dpa_bp->dev, qm_sg_addr(&sgt[j]),
- sgt[j].length, dma_dir);
+ be32_to_cpu(sgt[j].length), dma_dir);
sg0_map_failed:
csum_failed:
put_page(virt_to_head_page(sgt_buf));
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
index 797dac9..1ac0007 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_shared.c
@@ -67,7 +67,6 @@ shared_tx_error_dqrr(struct qman_portal *portal,
static void shared_ern(struct qman_portal *portal,
struct qman_fq *fq,
const struct qm_mr_entry *msg);
-int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
#define DPA_DESCRIPTION "FSL DPAA Shared Ethernet driver"
@@ -75,14 +74,10 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION(DPA_DESCRIPTION);
-static uint8_t debug = -1;
-module_param(debug, byte, S_IRUGO);
-MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
-
/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
-static uint16_t tx_timeout = 1000;
-module_param(tx_timeout, ushort, S_IRUGO);
-MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
+static uint16_t shared_tx_timeout = 1000;
+module_param(shared_tx_timeout, ushort, S_IRUGO);
+MODULE_PARM_DESC(shared_tx_timeout, "The Tx timeout in ms");
static const struct of_device_id dpa_shared_match[];
@@ -274,18 +269,19 @@ shared_rx_dqrr(struct qman_portal *portal, struct qman_fq *fq,
if (fd->format == qm_fd_sg) {
if (dpa_bp->vaddr) {
- sgt = dpa_phys2virt(dpa_bp,
- qm_fd_addr(fd)) + dpa_fd_offset(fd);
+ sgt = dpa_phys2virt(dpa_bp, qm_fd_addr(fd)) +
+ dpa_fd_offset(fd);
for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
+ void *frag_addr = dpa_phys2virt(dpa_bp,
+ qm_sg_addr(&sgt[i]) +
+ be16_to_cpu(sgt[i].offset));
+ u32 frag_length = be32_to_cpu(sgt[i].length);
BUG_ON(sgt[i].extension);
/* copy from sgt[i] */
- memcpy(skb_put(skb, sgt[i].length),
- dpa_phys2virt(dpa_bp,
- qm_sg_addr(&sgt[i]) +
- sgt[i].offset),
- sgt[i].length);
+ memcpy(skb_put(skb, frag_length), frag_addr,
+ frag_length);
if (sgt[i].final)
break;
}
@@ -305,12 +301,13 @@ shared_rx_dqrr(struct qman_portal *portal, struct qman_fq *fq,
dpa_bp->size));
for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
+ u32 frag_length = be32_to_cpu(sgt[i].length);
BUG_ON(sgt[i].extension);
-
copy_from_unmapped_area(
- skb_put(skb, sgt[i].length),
- qm_sg_addr(&sgt[i]) + sgt[i].offset,
- sgt[i].length);
+ skb_put(skb, frag_length),
+ qm_sg_addr(&sgt[i]) +
+ be16_to_cpu(sgt[i].offset),
+ frag_length);
if (sgt[i].final)
break;
@@ -600,7 +597,7 @@ static int dpa_shared_netdev_init(struct device_node *dpa_node,
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_LLTX);
- return dpa_netdev_init(dpa_node, net_dev, mac_addr, tx_timeout);
+ return dpa_netdev_init(net_dev, mac_addr, shared_tx_timeout);
}
#ifdef CONFIG_PM
@@ -717,7 +714,7 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
priv->net_dev = net_dev;
strcpy(priv->if_type, "shared");
- priv->msg_enable = netif_msg_init(debug, -1);
+ priv->msg_enable = netif_msg_init(advanced_debug, -1);
mac_dev = dpa_mac_probe(_of_dev);
if (IS_ERR(mac_dev) || !mac_dev) {
@@ -805,10 +802,10 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
buf_layout, dev);
/* Now we need to initialize either a private or shared interface */
- priv->percpu_priv = alloc_percpu(*priv->percpu_priv);
+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (priv->percpu_priv == NULL) {
- dev_err(dev, "alloc_percpu() failed\n");
+ dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
goto alloc_percpu_failed;
}
@@ -830,8 +827,6 @@ dpaa_eth_shared_probe(struct platform_device *_of_dev)
return 0;
netdev_init_failed:
- if (net_dev)
- free_percpu(priv->percpu_priv);
alloc_percpu_failed:
fq_alloc_failed:
if (net_dev) {
@@ -866,7 +861,7 @@ MODULE_DEVICE_TABLE(of, dpa_shared_match);
static struct platform_driver dpa_shared_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME "-shared",
.of_match_table = dpa_shared_match,
.owner = THIS_MODULE,
.pm = SHARED_PM_OPS,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
index cd8b7d1..36f65a1 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sysfs.c
@@ -233,6 +233,7 @@ void dpaa_eth_sysfs_init(struct device *dev)
return;
}
}
+EXPORT_SYMBOL(dpaa_eth_sysfs_init);
void dpaa_eth_sysfs_remove(struct device *dev)
{
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c b/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
index 6ab1ade..2b655cd 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_generic_debugfs.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/fsl_qman.h>
#include <linux/debugfs.h>
-#include <asm/debug.h>
#include "dpaa_eth_generic.h"
@@ -236,8 +235,7 @@ int dpa_generic_debugfs_create(struct net_device *net_dev)
net_dev,
&dpa_debugfs_fops);
if (unlikely(priv->debugfs_file == NULL)) {
- netdev_err(net_dev, "debugfs_create_file(%s/%s/%s)",
- powerpc_debugfs_root->d_iname,
+ netdev_err(net_dev, "debugfs_create_file(%s/%s)",
dpa_debugfs_root->d_iname,
net_dev->name);
@@ -254,30 +252,26 @@ void dpa_generic_debugfs_remove(struct net_device *net_dev)
debugfs_remove(priv->debugfs_file);
}
-static int __init dpa_generic_debugfs_module_init(void)
+int __init dpa_generic_debugfs_module_init(void)
{
int _errno = 0;
pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION " (" VERSION ")\n");
dpa_debugfs_root = debugfs_create_dir(DPA_GENERIC_ETH_DEBUGFS_ROOT,
- powerpc_debugfs_root);
+ NULL);
if (unlikely(dpa_debugfs_root == NULL)) {
_errno = -ENOMEM;
pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
KBUILD_BASENAME".c", __LINE__, __func__);
pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
- powerpc_debugfs_root->d_iname, _errno);
+ DPA_GENERIC_ETH_DEBUGFS_ROOT, _errno);
}
return _errno;
}
-static void __exit dpa_generic_debugfs_module_exit(void)
+void __exit dpa_generic_debugfs_module_exit(void)
{
debugfs_remove(dpa_debugfs_root);
}
-
-module_init(dpa_generic_debugfs_module_init);
-module_exit(dpa_generic_debugfs_module_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/dpa/mac-api.c b/drivers/net/ethernet/freescale/dpa/mac-api.c
index f5d6c73..1b92e86 100644
--- a/drivers/net/ethernet/freescale/dpa/mac-api.c
+++ b/drivers/net/ethernet/freescale/dpa/mac-api.c
@@ -352,6 +352,7 @@ int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
return _errno;
}
+EXPORT_SYMBOL(set_mac_active_pause);
/* Determine the MAC RX/TX PAUSE frames settings based on PHY
* autonegotiation or values set by eththool.
@@ -403,6 +404,7 @@ void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
if (flowctrl & FLOW_CTRL_TX)
*tx_pause = true;
}
+EXPORT_SYMBOL(get_pause_cfg);
static void adjust_link(struct net_device *net_dev)
{
@@ -447,7 +449,7 @@ static int dtsec_init_phy(struct net_device *net_dev,
/* Remove any features not supported by the controller */
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -478,7 +480,7 @@ static int xgmac_init_phy(struct net_device *net_dev,
}
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -521,7 +523,7 @@ static int memac_init_phy(struct net_device *net_dev,
/* Remove any features not supported by the controller */
phy_dev->supported &= mac_dev->if_support;
- /* Enable the symmetric and asymmetric PAUSE frame advertisments,
+ /* Enable the symmetric and asymmetric PAUSE frame advertisements,
* as most of the PHY drivers do not enable them by default.
*/
phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
@@ -683,7 +685,7 @@ int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
return n;
}
-
+EXPORT_SYMBOL(fm_mac_dump_regs);
static void __cold setup_dtsec(struct mac_device *mac_dev)
{
diff --git a/drivers/net/ethernet/freescale/dpa/mac.c b/drivers/net/ethernet/freescale/dpa/mac.c
index 69b4b6c..e146433 100644
--- a/drivers/net/ethernet/freescale/dpa/mac.c
+++ b/drivers/net/ethernet/freescale/dpa/mac.c
@@ -45,6 +45,7 @@
#include <linux/of_net.h>
#include <linux/device.h>
#include <linux/phy.h>
+#include <linux/io.h>
#include "lnxwrp_fm_ext.h"
@@ -140,7 +141,7 @@ MODULE_DEVICE_TABLE(of, mac_match);
static int __cold mac_probe(struct platform_device *_of_dev)
{
- int _errno, i, lenp;
+ int _errno, i;
struct device *dev;
struct device_node *mac_node, *dev_node;
struct mac_device *mac_dev;
@@ -148,8 +149,8 @@ static int __cold mac_probe(struct platform_device *_of_dev)
struct resource res;
const uint8_t *mac_addr;
const char *char_prop;
- const phandle *phandle_prop;
- const uint32_t *uint32_prop;
+ int nph;
+ u32 cell_index;
const struct of_device_id *match;
dev = &_of_dev->dev;
@@ -232,11 +233,15 @@ static int __cold mac_probe(struct platform_device *_of_dev)
mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
if (mac_dev->tbi_node) {
u32 tbiaddr = TBIPA_DEFAULT_ADDR;
-
- uint32_prop = of_get_property(mac_dev->tbi_node, "reg", NULL);
- if (uint32_prop)
- tbiaddr = *uint32_prop;
- out_be32(mac_dev->vaddr + TBIPA_OFFSET, tbiaddr);
+ const __be32 *tbi_reg;
+ void __iomem *addr;
+
+ tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
+ if (tbi_reg)
+ tbiaddr = be32_to_cpup(tbi_reg);
+ addr = mac_dev->vaddr + TBIPA_OFFSET;
+ /* TODO: out_be32 does not exist on ARM */
+ out_be32(addr, tbiaddr);
}
if (!of_device_is_available(mac_node)) {
@@ -250,15 +255,13 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
/* Get the cell-index */
- uint32_prop = of_get_property(mac_node, "cell-index", &lenp);
- if (unlikely(uint32_prop == NULL)) {
- dev_err(dev, "of_get_property(%s, cell-index) failed\n",
+ _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
+ if (unlikely(_errno)) {
+ dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
mac_node->full_name);
- _errno = -EINVAL;
goto _return_dev_set_drvdata;
}
- BUG_ON(lenp != sizeof(uint32_t));
- mac_dev->cell_index = (uint8_t)*uint32_prop;
+ mac_dev->cell_index = (uint8_t)cell_index;
/* Get the MAC address */
mac_addr = of_get_mac_address(mac_node);
@@ -270,21 +273,27 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
- /* Get the port handles */
- phandle_prop = of_get_property(mac_node, "fsl,port-handles", &lenp);
- if (unlikely(phandle_prop == NULL)) {
- dev_err(dev, "of_get_property(%s, port-handles) failed\n",
+ /* Verify the number of port handles */
+ nph = of_count_phandle_with_args(mac_node, "fsl,port-handles", NULL);
+ if (unlikely(nph < 0)) {
+ dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
+ mac_node->full_name);
+ _errno = nph;
+ goto _return_dev_set_drvdata;
+ }
+
+ if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
+ dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
mac_node->full_name);
_errno = -EINVAL;
goto _return_dev_set_drvdata;
}
- BUG_ON(lenp != sizeof(phandle) * ARRAY_SIZE(mac_dev->port_dev));
for_each_port_device(i, mac_dev->port_dev) {
- /* Find the port node */
- dev_node = of_find_node_by_phandle(phandle_prop[i]);
+ dev_node = of_parse_phandle(mac_node, "fsl,port-handles", i);
if (unlikely(dev_node == NULL)) {
- dev_err(dev, "of_find_node_by_phandle() failed\n");
+ dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
+ mac_node->full_name);
_errno = -EINVAL;
goto _return_of_node_put;
}
@@ -308,11 +317,11 @@ static int __cold mac_probe(struct platform_device *_of_dev)
}
/* Get the PHY connection type */
- char_prop = (const char *)of_get_property(mac_node,
- "phy-connection-type", NULL);
- if (unlikely(char_prop == NULL)) {
+ _errno = of_property_read_string(mac_node, "phy-connection-type",
+ &char_prop);
+ if (unlikely(_errno)) {
dev_warn(dev,
- "of_get_property(%s, phy-connection-type) failed. Defaulting to MII\n",
+ "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
mac_node->full_name);
mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
} else
@@ -339,17 +348,17 @@ static int __cold mac_probe(struct platform_device *_of_dev)
/* Get the rest of the PHY information */
mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
if (mac_dev->phy_node == NULL) {
- int sz;
- const u32 *phy_id = of_get_property(mac_node, "fixed-link",
- &sz);
- if (!phy_id || sz < sizeof(*phy_id)) {
+ u32 phy_id;
+
+ _errno = of_property_read_u32(mac_node, "fixed-link", &phy_id);
+ if (_errno) {
dev_err(dev, "No PHY (or fixed link) found\n");
_errno = -EINVAL;
goto _return_dev_set_drvdata;
}
sprintf(mac_dev->fixed_bus_id, PHY_ID_FMT, "fixed-0",
- phy_id[0]);
+ phy_id);
}
_errno = mac_dev->init(mac_dev);
diff --git a/drivers/net/ethernet/freescale/dpa/offline_port.c b/drivers/net/ethernet/freescale/dpa/offline_port.c
index 042f44a..ddbfdce 100644
--- a/drivers/net/ethernet/freescale/dpa/offline_port.c
+++ b/drivers/net/ethernet/freescale/dpa/offline_port.c
@@ -250,14 +250,13 @@ oh_port_probe(struct platform_device *_of_dev)
struct device_node *dpa_oh_node;
int lenp, _errno = 0, fq_idx, duple_idx;
int n_size, i, j, ret, duples_count;
- const phandle *oh_port_handle, *bpool_handle;
struct platform_device *oh_of_dev;
struct device_node *oh_node, *bpool_node = NULL, *root_node;
struct device *oh_dev;
struct dpa_oh_config_s *oh_config = NULL;
- uint32_t *oh_all_queues;
- uint32_t *channel_ids;
- uint32_t *oh_tx_queues;
+ const __be32 *oh_all_queues;
+ const __be32 *channel_ids;
+ const __be32 *oh_tx_queues;
uint32_t queues_count;
uint32_t crt_fqid_base;
uint32_t crt_fq_count;
@@ -270,17 +269,18 @@ oh_port_probe(struct platform_device *_of_dev)
bool init_oh_port;
const struct of_device_id *match;
- uint32_t crt_ext_pools_count, ext_pool_size;
- const unsigned int *port_id;
- const unsigned int *channel_id;
+ int crt_ext_pools_count;
+ u32 ext_pool_size;
+ u32 port_id;
+ u32 channel_id;
int channel_ids_count;
int channel_idx;
struct fq_duple *fqd;
struct list_head *fq_list, *fq_list_tmp;
- const uint32_t *bpool_cfg;
- const uint32_t *bpid;
+ const __be32 *bpool_cfg;
+ uint32_t bpid;
memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
dpa_oh_dev = &_of_dev->dev;
@@ -294,49 +294,28 @@ oh_port_probe(struct platform_device *_of_dev)
dev_dbg(dpa_oh_dev, "Probing OH port...\n");
/* Find the referenced OH node */
-
- oh_port_handle = of_get_property(dpa_oh_node,
- "fsl,fman-oh-port", &lenp);
- if (oh_port_handle == NULL) {
- dev_err(dpa_oh_dev, "No OH port handle found in node %s\n",
- dpa_oh_node->full_name);
- return -EINVAL;
- }
-
- BUG_ON(lenp % sizeof(*oh_port_handle));
- if (lenp != sizeof(*oh_port_handle)) {
- dev_err(dpa_oh_dev,
- "Found %lu OH port bindings in node %s, only 1 phandle is allowed.\n",
- (unsigned long int)(lenp / sizeof(*oh_port_handle)),
- dpa_oh_node->full_name);
- return -EINVAL;
- }
-
- /* Read configuration for the OH port */
- oh_node = of_find_node_by_phandle(*oh_port_handle);
+ oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
if (oh_node == NULL) {
dev_err(dpa_oh_dev,
"Can't find OH node referenced from node %s\n",
dpa_oh_node->full_name);
return -EINVAL;
}
- dev_info(dpa_oh_dev, "Found OH node handle compatible with %s.\n",
+ dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
match->compatible);
- port_id = of_get_property(oh_node, "cell-index", &lenp);
- if (port_id == NULL) {
+ _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
+ if (_errno) {
dev_err(dpa_oh_dev, "No port id found in node %s\n",
dpa_oh_node->full_name);
- _errno = -EINVAL;
goto return_kfree;
}
- BUG_ON(lenp % sizeof(*port_id));
- channel_id = of_get_property(oh_node, "fsl,qman-channel-id", &lenp);
- if (channel_id == NULL) {
+ _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
+ &channel_id);
+ if (_errno) {
dev_err(dpa_oh_dev, "No channel id found in node %s\n",
dpa_oh_node->full_name);
- _errno = -EINVAL;
goto return_kfree;
}
@@ -383,7 +362,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* FQs that enter OH port */
lenp = 0;
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-ingress", &lenp);
if (lenp % (2 * sizeof(*oh_all_queues))) {
dev_warn(dpa_oh_dev,
@@ -396,8 +375,8 @@ oh_port_probe(struct platform_device *_of_dev)
dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
duples_count);
for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
- crt_fqid_base = oh_all_queues[2 * duple_idx];
- crt_fq_count = oh_all_queues[2 * duple_idx + 1];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
fqd = devm_kzalloc(dpa_oh_dev,
sizeof(struct fq_duple), GFP_KERNEL);
@@ -423,7 +402,7 @@ oh_port_probe(struct platform_device *_of_dev)
for (j = 0; j < crt_fq_count; j++)
(fqd->fqs + j)->fqid = crt_fqid_base + j;
fqd->fqs_count = crt_fq_count;
- fqd->channel_id = (uint16_t)*channel_id;
+ fqd->channel_id = (uint16_t)channel_id;
list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
}
@@ -448,7 +427,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* FQs that exit OH port */
lenp = 0;
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-egress", &lenp);
if (lenp % (2 * sizeof(*oh_all_queues))) {
dev_warn(dpa_oh_dev,
@@ -461,8 +440,8 @@ oh_port_probe(struct platform_device *_of_dev)
dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
duples_count);
for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
- crt_fqid_base = oh_all_queues[2 * duple_idx];
- crt_fq_count = oh_all_queues[2 * duple_idx + 1];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
fqd = devm_kzalloc(dpa_oh_dev,
sizeof(struct fq_duple), GFP_KERNEL);
@@ -499,7 +478,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* channel_ids for FQs that exit OH port */
lenp = 0;
- channel_ids = (uint32_t *)of_get_property(dpa_oh_node,
+ channel_ids = of_get_property(dpa_oh_node,
"fsl,qman-channel-ids-egress", &lenp);
channel_ids_count = lenp / (sizeof(*channel_ids));
@@ -515,7 +494,8 @@ oh_port_probe(struct platform_device *_of_dev)
if (channel_idx + 1 > channel_ids_count)
break;
fqd = list_entry(fq_list, struct fq_duple, fq_list);
- fqd->channel_id = (uint16_t)channel_ids[channel_idx++];
+ fqd->channel_id =
+ (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
}
/* create egress queues */
@@ -543,7 +523,7 @@ oh_port_probe(struct platform_device *_of_dev)
}
/* Read FQ ids/nums for the DPA OH node */
- oh_all_queues = (uint32_t *)of_get_property(dpa_oh_node,
+ oh_all_queues = of_get_property(dpa_oh_node,
"fsl,qman-frame-queues-oh", &lenp);
if (oh_all_queues == NULL) {
dev_err(dpa_oh_dev,
@@ -569,8 +549,8 @@ oh_port_probe(struct platform_device *_of_dev)
fq_idx = 0;
/* Error FQID - must be present */
- crt_fqid_base = oh_all_queues[fq_idx++];
- crt_fq_count = oh_all_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
if (crt_fq_count != 1) {
dev_err(dpa_oh_dev,
"Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
@@ -584,8 +564,8 @@ oh_port_probe(struct platform_device *_of_dev)
oh_config->error_fqid, oh_node->full_name);
/* Default FQID - must be present */
- crt_fqid_base = oh_all_queues[fq_idx++];
- crt_fq_count = oh_all_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
if (crt_fq_count != 1) {
dev_err(dpa_oh_dev,
"Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
@@ -599,8 +579,8 @@ oh_port_probe(struct platform_device *_of_dev)
oh_config->default_fqid, oh_node->full_name);
/* TX FQID - presence is optional */
- oh_tx_queues = (uint32_t *)of_get_property(dpa_oh_node,
- "fsl,qman-frame-queues-tx", &lenp);
+ oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
+ &lenp);
if (oh_tx_queues == NULL) {
dev_dbg(dpa_oh_dev,
"No tx queues have been defined for OH node %s referenced from node %s\n",
@@ -619,19 +599,9 @@ oh_port_probe(struct platform_device *_of_dev)
goto return_kfree;
}
- /* Read channel id for the queues */
- channel_id = of_get_property(oh_node, "fsl,qman-channel-id", &lenp);
- if (channel_id == NULL) {
- dev_err(dpa_oh_dev, "No channel id found in node %s\n",
- dpa_oh_node->full_name);
- _errno = -EINVAL;
- goto return_kfree;
- }
- BUG_ON(lenp % sizeof(*channel_id));
-
fq_idx = 0;
- crt_fqid_base = oh_tx_queues[fq_idx++];
- crt_fq_count = oh_tx_queues[fq_idx++];
+ crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
+ crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
oh_config->egress_cnt = crt_fq_count;
/* Allocate TX queues */
@@ -649,7 +619,7 @@ oh_port_probe(struct platform_device *_of_dev)
/* Create TX queues */
for (i = 0; i < crt_fq_count; i++) {
ret = oh_fq_create(oh_config->egress_fqs + i,
- crt_fqid_base + i, (uint16_t)*channel_id, 3);
+ crt_fqid_base + i, (uint16_t)channel_id, 3);
if (ret != 0) {
dev_err(dpa_oh_dev,
"Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
@@ -673,10 +643,11 @@ config_port:
}
oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
- bpool_handle = of_get_property(dpa_oh_node,
- "fsl,bman-buffer-pools", &lenp);
- if (bpool_handle == NULL) {
+ /* read the pool handlers */
+ crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
+ "fsl,bman-buffer-pools", NULL);
+ if (crt_ext_pools_count <= 0) {
dev_info(dpa_oh_dev,
"OH port %s has no buffer pool. Fragmentation will not be enabled\n",
oh_node->full_name);
@@ -694,29 +665,29 @@ config_port:
n_size = of_n_size_cells(root_node);
of_node_put(root_node);
- crt_ext_pools_count = lenp / sizeof(phandle);
- dev_dbg(dpa_oh_dev, "OH port number of pools = %u\n",
+ dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
crt_ext_pools_count);
oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
for (i = 0; i < crt_ext_pools_count; i++) {
- bpool_node = of_find_node_by_phandle(bpool_handle[i]);
+ bpool_node = of_parse_phandle(dpa_oh_node,
+ "fsl,bman-buffer-pools", i);
if (bpool_node == NULL) {
dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
_errno = -EINVAL;
goto return_kfree;
}
- bpid = of_get_property(bpool_node, "fsl,bpid", &lenp);
- if ((bpid == NULL) || (lenp != sizeof(*bpid))) {
- dev_err(dpa_oh_dev, "Invalid Buffer pool Id\n");
+ _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
+ if (_errno) {
+ dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
_errno = -EINVAL;
goto return_kfree;
}
- oh_port_tx_params.pool_param[i].id = (uint8_t)*bpid;
- dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", *bpid);
+ oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
+ dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
bpool_cfg = of_get_property(bpool_node,
"fsl,bpool-ethernet-cfg", &lenp);
@@ -726,7 +697,6 @@ config_port:
goto return_kfree;
}
- of_read_number(bpool_cfg, n_size);
ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
@@ -741,7 +711,7 @@ config_port:
frag_enabled = true;
dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
- *port_id);
+ port_id);
init_port:
of_node_put(oh_node);
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
index d7f94ab..67e64d0 100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -156,11 +156,13 @@ int fm_get_max_frm()
{
return fsl_fm_max_frm;
}
+EXPORT_SYMBOL(fm_get_max_frm);
int fm_get_rx_extra_headroom()
{
return ALIGN(fsl_fm_rx_extra_headroom, 16);
}
+EXPORT_SYMBOL(fm_get_rx_extra_headroom);
static int __init fm_set_max_frm(char *str)
{
diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
index 374ebf6..c3a341c 100644
--- a/drivers/staging/fsl_qbman/qman_high.c
+++ b/drivers/staging/fsl_qbman/qman_high.c
@@ -2556,6 +2556,8 @@ EXPORT_SYMBOL(qman_modify_cgr);
QM_CHANNEL_SWPORTAL0))
#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
+static u8 qman_cgr_cpus[__CGR_NUM];
+
int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
struct qm_mcc_initcgr *opts)
{
@@ -2572,7 +2574,10 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
if (cgr->cgrid >= __CGR_NUM)
return -EINVAL;
+ preempt_disable();
p = get_affine_portal();
+ qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
+ preempt_enable();
memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
cgr->chan = p->config->public_cfg.channel;
@@ -2715,6 +2720,47 @@ put_portal:
}
EXPORT_SYMBOL(qman_delete_cgr);
+struct cgr_comp {
+ struct qman_cgr *cgr;
+ struct completion completion;
+};
+
+static int qman_delete_cgr_thread(void *p)
+{
+ struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
+ int res;
+
+ res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
+ complete(&cgr_comp->completion);
+
+ return res;
+}
+
+void qman_delete_cgr_safe(struct qman_cgr *cgr)
+{
+ struct task_struct *thread;
+ struct cgr_comp cgr_comp;
+
+ preempt_disable();
+ if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
+ init_completion(&cgr_comp.completion);
+ cgr_comp.cgr = cgr;
+ thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
+ "cgr_del");
+
+ if (likely(!IS_ERR(thread))) {
+ kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
+ wake_up_process(thread);
+ wait_for_completion(&cgr_comp.completion);
+ preempt_enable();
+ return;
+ }
+ }
+ qman_delete_cgr(cgr);
+ preempt_enable();
+}
+EXPORT_SYMBOL(qman_delete_cgr_safe);
+
int qm_get_clock(u64 *clock_hz)
{
if (!qman_clk) {