summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-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;
}