summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/dpa
diff options
context:
space:
mode:
authorRotariu Marian Cristian-B44860 <marian.rotariu@freescale.com>2014-10-09 12:02:06 (GMT)
committerMadalin Bucur <madalin.bucur@freescale.com>2015-03-11 16:05:51 (GMT)
commitc1f241ed11f1d78c19af6e0b49443d87f19f04c5 (patch)
tree15a15aed8e6acabc3b3ffaa6458abb87421e0f77 /drivers/net/ethernet/freescale/dpa
parentbca3555cb1307652b5efa509c598f2abe699579f (diff)
downloadlinux-fsl-qoriq-c1f241ed11f1d78c19af6e0b49443d87f19f04c5.tar.xz
dpaa_eth: make onic dt parser unaware of endianess
The device tree values are stored in BE format. It is the of parser and driver parser job to convert the data into CPU endianness. This patch converts bpid, fqids values and phandles to CPU endianness. Change-Id: I0ea0453151f7e175c5112f145c47c6bc182a6694 Signed-off-by: Rotariu Marian Cristian-B44860 <marian.rotariu@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/20909 Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/32499
Diffstat (limited to 'drivers/net/ethernet/freescale/dpa')
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c207
1 files changed, 106 insertions, 101 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
index 5f772d3..2ed90c8 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_generic.c
@@ -173,31 +173,27 @@ static struct platform_driver dpa_generic_driver = {
.remove = dpa_generic_remove
};
-static 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;
@@ -233,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)
@@ -790,76 +780,106 @@ static struct dpa_fq_cbs_t generic_fq_cbs = {
.egress_ern = { .cb = { .ern = dpa_generic_ern } }
};
+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);
+ }
+
+ INIT_LIST_HEAD(list);
- fqids = of_get_property(dev_node, "fsl,qman-frame-queues-oh", &lenp);
- if (fqids == NULL) {
+ /* 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)
@@ -897,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");
@@ -939,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;
- 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;
+ 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;
}
- bp[i].bpid = (uint8_t)*bpid;
+ bp[i].bpid = (uint8_t)bpid;
bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
&lenp);
@@ -979,6 +989,8 @@ static int dpa_generic_rx_bp_probe(struct platform_device *_of_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");
@@ -1073,46 +1085,39 @@ static int dpa_generic_port_probe(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 *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;
}