summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.c21
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth.h2
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c4
-rw-r--r--drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c7
4 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
index cca3383..d09d6b9 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.c
@@ -345,8 +345,14 @@ priv_rx_error_dqrr(struct qman_portal *portal,
return qman_cb_dqrr_stop;
}
- dpaa_eth_refill_bpools(percpu_priv);
- _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
+ if (unlikely(dpaa_eth_refill_bpools(percpu_priv)))
+ /* Unable to refill the buffer pool due to insufficient
+ * system memory. Just release the frame back into the pool,
+ * otherwise we'll soon end up with an empty buffer pool.
+ */
+ dpa_fd_release(net_dev, &dq->fd);
+ else
+ _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
return qman_cb_dqrr_consume;
}
@@ -376,8 +382,15 @@ priv_rx_default_dqrr(struct qman_portal *portal,
}
/* Vale of plenty: make sure we didn't run out of buffers */
- dpaa_eth_refill_bpools(percpu_priv);
- _dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
+
+ if (unlikely(dpaa_eth_refill_bpools(percpu_priv)))
+ /* Unable to refill the buffer pool due to insufficient
+ * system memory. Just release the frame back into the pool,
+ * otherwise we'll soon end up with an empty buffer pool.
+ */
+ dpa_fd_release(net_dev, &dq->fd);
+ else
+ _dpa_rx(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
return qman_cb_dqrr_consume;
}
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
index e3e5d69..b3f4ec2 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth.h
@@ -451,7 +451,7 @@ struct fm_port_fqs {
/* functions with different implementation for SG and non-SG: */
void dpa_make_private_pool(struct dpa_bp *dpa_bp);
-void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv);
+int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv);
void __hot _dpa_rx(struct net_device *net_dev,
const struct dpa_priv_s *priv,
struct dpa_percpu_priv_s *percpu_priv,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c
index 1d4d323..42a0448 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_non_sg.c
@@ -153,7 +153,7 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp)
/* Add buffers/(skbuffs) for Rx processing whenever bpool count falls below
* REFILL_THRESHOLD.
*/
-void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
+int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
{
int *countptr = percpu_priv->dpa_bp_count;
int count = *countptr;
@@ -169,6 +169,8 @@ void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
for (i = count; i < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; i += 8)
dpa_bp_add_8(dpa_bp, cpu);
}
+
+ return 0;
}
/* Cleanup function for outgoing frame descriptors that were built on Tx path,
diff --git a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
index 32086d4..7f0e870 100644
--- a/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
+++ b/drivers/net/ethernet/freescale/dpa/dpaa_eth_sg.c
@@ -159,7 +159,7 @@ void dpa_make_private_pool(struct dpa_bp *dpa_bp)
* Add buffers/(pages) for Rx processing whenever bpool count falls below
* REFILL_THRESHOLD.
*/
-void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
+int dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
{
int *countptr = percpu_priv->dpa_bp_count;
int count = *countptr;
@@ -179,6 +179,11 @@ void dpaa_eth_refill_bpools(struct dpa_percpu_priv_s *percpu_priv)
count += new_pages;
}
*countptr = count;
+
+ if (unlikely(*countptr < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
+ return -ENOMEM;
+
+ return 0;
}
/* Cleanup function for outgoing frame descriptors that were built on Tx path,