summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/sdk_dpaa
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale/sdk_dpaa')
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/Kconfig23
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c13
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h11
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c2
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c65
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h1
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c47
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h2
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c11
-rw-r--r--drivers/net/ethernet/freescale/sdk_dpaa/mac.c4
10 files changed, 97 insertions, 82 deletions
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
index 92118b7..b21d236 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
@@ -20,6 +20,29 @@ config FSL_DPAA_CEETM
help
Enable QoS offloading support through the CEETM hardware block.
+config FSL_DPAA_CEETM_CCS_THRESHOLD_1G
+ hex "CEETM egress congestion threshold on 1G ports"
+ depends on FSL_DPAA_CEETM
+ range 0x1000 0x10000000
+ default "0x000a0000"
+ help
+ The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports.
+ The threshold needs to be configured keeping in mind the following factors:
+ - A threshold too large will buffer frames for a long time in the TX queues,
+ when a small shaping rate is configured. This will cause buffer pool depletion
+ or out of memory errors. This in turn will cause frame loss on RX;
+ - A threshold too small will cause unnecessary frame loss by entering
+ congestion too often.
+
+config FSL_DPAA_CEETM_CCS_THRESHOLD_10G
+ hex "CEETM egress congestion threshold on 10G ports"
+ depends on FSL_DPAA_CEETM
+ range 0x1000 0x20000000
+ default "0x00640000"
+ help
+ The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports.
+ See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details.
+
config FSL_DPAA_OFFLINE_PORTS
bool "Offline Ports support"
depends on FSL_SDK_DPAA_ETH
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
index 7026f91..1f76aa3 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
@@ -775,6 +775,17 @@ static int dpa_private_netdev_init(struct net_device *net_dev)
/* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
net_dev->features |= NETIF_F_HW_ACCEL_MQ;
+#ifndef CONFIG_PPC
+ /* Due to the A010022 FMan errata, we can not use contig frames larger
+ * than 4K, nor S/G frames. We need to stop advertising S/G and GSO
+ * support.
+ */
+ if (unlikely(dpaa_errata_a010022)) {
+ net_dev->hw_features &= ~NETIF_F_SG;
+ net_dev->features &= ~NETIF_F_GSO;
+ }
+#endif
+
return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
}
@@ -863,7 +874,7 @@ static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
for (i = 0; i < count; i++) {
int err;
- err = dpa_bp_alloc(&dpa_bp[i]);
+ err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
if (err < 0) {
dpa_bp_free(priv);
priv->dpa_bp = NULL;
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
index b1703bc..57c9bef 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
@@ -514,17 +514,6 @@ dpa_fd_offset(const struct qm_fd *fd)
return fd->offset;
}
-/* Verifies if the skb length is below the interface MTU */
-static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu)
-{
- if (unlikely(skb->len > mtu))
- if ((skb->protocol != htons(ETH_P_8021Q))
- || (skb->len > mtu + 4))
- return -1;
-
- return 0;
-}
-
static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
{
uint16_t headroom;
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
index 507e77c..be6e4f8 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
@@ -176,7 +176,7 @@ int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
for (i = 0; i < count; i++) {
int err;
- err = dpa_bp_alloc(&dpa_bp[i]);
+ err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
if (err < 0) {
dpa_bp_free(priv);
priv->dpa_bp = NULL;
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
index cac613b..b090db1 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
@@ -69,24 +69,27 @@ static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
const struct qm_mr_entry *msg)
{
- struct net_device *net_dev;
- struct ceetm_class *cls;
+ struct dpa_percpu_priv_s *dpa_percpu_priv;
struct ceetm_class_stats *cstats = NULL;
const struct dpa_priv_s *dpa_priv;
- struct dpa_percpu_priv_s *dpa_percpu_priv;
- struct sk_buff *skb;
struct qm_fd fd = msg->ern.fd;
+ struct net_device *net_dev;
+ struct ceetm_fq *ceetm_fq;
+ struct ceetm_class *cls;
+ struct sk_buff *skb;
- net_dev = ((struct ceetm_fq *)fq)->net_dev;
+ ceetm_fq = container_of(fq, struct ceetm_fq, fq);
+ net_dev = ceetm_fq->net_dev;
dpa_priv = netdev_priv(net_dev);
dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
/* Increment DPA counters */
dpa_percpu_priv->stats.tx_dropped++;
dpa_percpu_priv->stats.tx_fifo_errors++;
+ count_ern(dpa_percpu_priv, msg);
/* Increment CEETM counters */
- cls = ((struct ceetm_fq *)fq)->ceetm_cls;
+ cls = ceetm_fq->ceetm_cls;
switch (cls->type) {
case CEETM_PRIO:
cstats = this_cpu_ptr(cls->prio.cstats);
@@ -99,11 +102,15 @@ static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
if (cstats)
cstats->ern_drop_count++;
+ /* Release the buffers that were supposed to be recycled. */
if (fd.bpid != 0xff) {
dpa_fd_release(net_dev, &fd);
return;
}
+ /* Release the frames that were supposed to return on the
+ * confirmation path.
+ */
skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
dev_kfree_skb_any(skb);
}
@@ -125,16 +132,16 @@ static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
break;
}
+ ceetm_fq->congested = congested;
+
if (congested) {
dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
- netif_tx_stop_all_queues(dpa_priv->net_dev);
dpa_priv->cgr_data.cgr_congested_count++;
if (cstats)
cstats->congested_count++;
} else {
dpa_priv->cgr_data.congested_jiffies +=
(jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
- netif_tx_wake_all_queues(dpa_priv->net_dev);
}
}
@@ -148,6 +155,7 @@ static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
(*fq)->net_dev = dev;
(*fq)->ceetm_cls = cls;
+ (*fq)->congested = 0;
return 0;
}
@@ -185,9 +193,9 @@ static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
/* Set the congestion state thresholds according to the link speed */
if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
- cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
+ cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G;
else
- cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
+ cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G;
qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
@@ -1908,17 +1916,22 @@ static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
{
- int ret;
- bool act_drop = false;
+ const int queue_mapping = dpa_get_queue_mapping(skb);
struct Qdisc *sch = net_dev->qdisc;
- struct ceetm_class *cl;
- struct dpa_priv_s *priv_dpa;
- struct qman_fq *egress_fq, *conf_fq;
- struct ceetm_qdisc *priv = qdisc_priv(sch);
- struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats);
struct ceetm_class_stats *cstats;
- const int queue_mapping = dpa_get_queue_mapping(skb);
- spinlock_t *root_lock = qdisc_lock(sch);
+ struct ceetm_qdisc_stats *qstats;
+ struct dpa_priv_s *priv_dpa;
+ struct ceetm_fq *ceetm_fq;
+ struct ceetm_qdisc *priv;
+ struct qman_fq *conf_fq;
+ struct ceetm_class *cl;
+ spinlock_t *root_lock;
+ bool act_drop = false;
+ int ret;
+
+ root_lock = qdisc_lock(sch);
+ priv = qdisc_priv(sch);
+ qstats = this_cpu_ptr(priv->root.qstats);
spin_lock(root_lock);
cl = ceetm_classify(skb, sch, &ret, &act_drop);
@@ -1945,11 +1958,11 @@ int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
*/
switch (cl->type) {
case CEETM_PRIO:
- egress_fq = &cl->prio.fq->fq;
+ ceetm_fq = cl->prio.fq;
cstats = this_cpu_ptr(cl->prio.cstats);
break;
case CEETM_WBFS:
- egress_fq = &cl->wbfs.fq->fq;
+ ceetm_fq = cl->wbfs.fq;
cstats = this_cpu_ptr(cl->wbfs.cstats);
break;
default:
@@ -1957,8 +1970,16 @@ int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
goto drop;
}
+ /* If the FQ is congested, avoid enqueuing the frame and dropping it
+ * when it returns on the ERN path. Drop it here directly instead.
+ */
+ if (unlikely(ceetm_fq->congested)) {
+ qstats->drops++;
+ goto drop;
+ }
+
bstats_update(&cstats->bstats, skb);
- return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
+ return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq);
drop:
dev_kfree_skb_any(skb);
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
index 63cc3475..0ff3b9d 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
@@ -105,6 +105,7 @@ struct ceetm_fq {
struct qman_fq fq;
struct net_device *net_dev;
struct ceetm_class *ceetm_cls;
+ int congested; /* Congestion status */
};
struct root_q {
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
index 19a8a3c..bbaf29c 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
@@ -469,14 +469,18 @@ int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
#ifdef CONFIG_FSL_DPAA_1588
struct dpa_priv_s *priv = netdev_priv(dev);
#endif
- int ret = 0;
+ int ret = -EINVAL;
- /* at least one timestamping feature must be enabled */
-#ifdef CONFIG_FSL_DPAA_TS
if (!netif_running(dev))
-#endif
return -EINVAL;
+ if (cmd == SIOCGMIIREG) {
+ if (!dev->phydev)
+ ret = -EINVAL;
+ else
+ ret = phy_mii_ioctl(dev->phydev, rq, cmd);
+ }
+
#ifdef CONFIG_FSL_DPAA_TS
if (cmd == SIOCSHWTSTAMP)
return dpa_ts_ioctl(dev, rq, cmd);
@@ -711,11 +715,10 @@ void dpa_set_buffers_layout(struct mac_device *mac_dev,
EXPORT_SYMBOL(dpa_set_buffers_layout);
int __attribute__((nonnull))
-dpa_bp_alloc(struct dpa_bp *dpa_bp)
+dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev)
{
int err;
struct bman_pool_params bp_params;
- struct platform_device *pdev;
if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
@@ -748,44 +751,25 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp)
dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
- pdev = platform_device_register_simple("dpaa_eth_bpool",
- dpa_bp->bpid, NULL, 0);
- if (IS_ERR(pdev)) {
- pr_err("platform_device_register_simple() failed\n");
- err = PTR_ERR(pdev);
- goto pdev_register_failed;
- }
- {
- struct dma_map_ops *ops = get_dma_ops(&pdev->dev);
- ops->dma_supported = NULL;
- }
- err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
+ err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
if (err) {
pr_err("dma_coerce_mask_and_coherent() failed\n");
- goto pdev_mask_failed;
+ goto bman_free_pool;
}
-#ifdef CONFIG_FMAN_ARM
- /* force coherency */
- pdev->dev.archdata.dma_coherent = true;
- arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
-#endif
- dpa_bp->dev = &pdev->dev;
+ dpa_bp->dev = dev;
if (dpa_bp->seed_cb) {
err = dpa_bp->seed_cb(dpa_bp);
if (err)
- goto pool_seed_failed;
+ goto bman_free_pool;
}
dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
return 0;
-pool_seed_failed:
-pdev_mask_failed:
- platform_device_unregister(pdev);
-pdev_register_failed:
+bman_free_pool:
bman_free_pool(dpa_bp->pool);
return err;
@@ -847,9 +831,6 @@ _dpa_bp_free(struct dpa_bp *dpa_bp)
dpa_bp_array[bp->bpid] = NULL;
bman_free_pool(bp->pool);
-
- if (bp->dev)
- platform_device_unregister(to_platform_device(bp->dev));
}
void __cold __attribute__((nonnull))
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
index 41db430..b039328 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
@@ -164,7 +164,7 @@ void dpa_set_rx_mode(struct net_device *net_dev);
void dpa_set_buffers_layout(struct mac_device *mac_dev,
struct dpa_buffer_layout_s *layout);
int __attribute__((nonnull))
-dpa_bp_alloc(struct dpa_bp *dpa_bp);
+dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev);
void __cold __attribute__((nonnull))
dpa_bp_free(struct dpa_priv_s *priv);
struct dpa_bp *dpa_bpid2pool(int bpid);
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
index 11b47e8..32e62e6 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
@@ -616,13 +616,6 @@ void __hot _dpa_rx(struct net_device *net_dev,
(*count_ptr)--;
skb->protocol = eth_type_trans(skb, net_dev);
- /* IP Reassembled frames are allowed to be larger than MTU */
- if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) &&
- !(fd_status & FM_FD_IPR))) {
- percpu_stats->rx_dropped++;
- goto drop_bad_frame;
- }
-
skb_len = skb->len;
#ifdef CONFIG_FSL_DPAA_DBG_LOOP
@@ -655,10 +648,6 @@ void __hot _dpa_rx(struct net_device *net_dev,
packet_dropped:
return;
-drop_bad_frame:
- dev_kfree_skb(skb);
- return;
-
_release_frame:
dpa_fd_release(net_dev, fd);
}
diff --git a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
index 60133b0..a6bfcea 100644
--- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
@@ -76,7 +76,7 @@ static const char phy_str[][11] = {
[PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
[PHY_INTERFACE_MODE_RTBI] = "rtbi",
[PHY_INTERFACE_MODE_XGMII] = "xgmii",
- [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500",
+ [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500",
};
static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
@@ -103,7 +103,7 @@ static const uint16_t phy2speed[] = {
[PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
[PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
[PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
- [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500,
+ [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500,
};
static struct mac_device * __cold