This commit is contained in:
Vincent Wiemann 2018-07-09 00:14:34 +00:00 committed by GitHub
commit db14444cfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 717 additions and 0 deletions

View File

@ -0,0 +1,29 @@
From: Alexander Couzens <lynxis@fe80.eu>
Date: Sun, 11 Jun 2017 12:43:24 +0200
Subject: ar71xx/ag71xx_ar7240_get_port_link: fix off-by-one check on argument `port`
Found-by: Coverity Scan #1329901
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
index c5aed0d2dbfcc726f54ca7eaf7dde2f7aba03ca7..e457acb50cf03e2ece5584843d6ce437da8bb8cb 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
@@ -963,7 +963,7 @@ ar7240_get_port_link(struct switch_dev *dev, int port,
struct mii_bus *mii = as->mii_bus;
u32 status;
- if (port > AR7240_NUM_PORTS)
+ if (port >= AR7240_NUM_PORTS)
return -EINVAL;
status = ar7240sw_reg_read(mii, AR7240_REG_PORT_STATUS(port));
@@ -1000,7 +1000,7 @@ ar7240_get_port_stats(struct switch_dev *dev, int port,
{
struct ar7240sw *as = sw_to_ar7240(dev);
- if (port > AR7240_NUM_PORTS)
+ if (port >= AR7240_NUM_PORTS)
return -EINVAL;
ar7240sw_capture_stats(as);

View File

@ -0,0 +1,20 @@
From: Alexander Couzens <lynxis@fe80.eu>
Date: Sun, 11 Jun 2017 12:49:19 +0200
Subject: ar71xx/ag71xx_mdio_probe: fix a memory leak when probe fails
Found-by: Coverity Scan #1330233
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c
index 71ae8258b2ef20f7d20ceacec59011ab3babfe23..b63a4b7f9d9f4b997843aa4a91c385ea186d67e2 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c
@@ -234,7 +234,7 @@ static int ag71xx_mdio_probe(struct platform_device *pdev)
if (!res) {
dev_err(&pdev->dev, "no iomem resource found\n");
err = -ENXIO;
- goto err_out;
+ goto err_free_mdio;
}
am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1);

View File

@ -0,0 +1,23 @@
From: Alexander Couzens <lynxis@fe80.eu>
Date: Sun, 11 Jun 2017 12:51:58 +0200
Subject: ar71xx/ag71xx_ethtool: don't return uninitialized return value on success
ag71xx_ethtool_set_ringparam() will return an uninitialized value on
success.
Found-by: Coverity Scan #1330877
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c
index dfcbb54e93a298eee7858d6b26e533e0aeefb00b..f0e102152f269c6604925421de6ca27ccc6bb6ad 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c
@@ -86,7 +86,7 @@ static int ag71xx_ethtool_set_ringparam(struct net_device *dev,
struct ag71xx *ag = netdev_priv(dev);
unsigned tx_size;
unsigned rx_size;
- int err;
+ int err = 0;
if (er->rx_mini_pending != 0||
er->rx_jumbo_pending != 0 ||

View File

@ -0,0 +1,75 @@
From: Rosen Penev <rosenp@gmail.com>
Date: Tue, 17 Oct 2017 09:25:56 -0700
Subject: ag71xx: Switch from driver to kernel macro for NAPI_WEIGHT.
NAPI_POLL_WEIGHT was introduced in the kernel for exactly this purpose 5 years ago.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index 898bde1d257bb70801f4f585c1aa278ebb9d0030..7b1cc1e1032f7b87430a9be1507ddb3e3faa26bc 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -40,7 +40,6 @@
#define AG71XX_DRV_NAME "ag71xx"
#define AG71XX_DRV_VERSION "0.5.35"
-#define AG71XX_NAPI_WEIGHT 64
#define AG71XX_OOM_REFILL (1 + HZ/10)
#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
@@ -136,8 +135,8 @@ struct ag71xx_napi_stats {
unsigned long tx_packets;
unsigned long tx_packets_max;
- unsigned long rx[AG71XX_NAPI_WEIGHT + 1];
- unsigned long tx[AG71XX_NAPI_WEIGHT + 1];
+ unsigned long rx[NAPI_POLL_WEIGHT + 1];
+ unsigned long tx[NAPI_POLL_WEIGHT + 1];
};
struct ag71xx_debug {
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
index c86803c9ceda7c57f643df29acc8254768b3d264..89cea0c0f5ae97c9917cd13e1ee89bd31fe45e58 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
@@ -78,7 +78,7 @@ void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
if (rx) {
stats->rx_count++;
stats->rx_packets += rx;
- if (rx <= AG71XX_NAPI_WEIGHT)
+ if (rx <= NAPI_POLL_WEIGHT)
stats->rx[rx]++;
if (rx > stats->rx_packets_max)
stats->rx_packets_max = rx;
@@ -87,7 +87,7 @@ void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx)
if (tx) {
stats->tx_count++;
stats->tx_packets += tx;
- if (tx <= AG71XX_NAPI_WEIGHT)
+ if (tx <= NAPI_POLL_WEIGHT)
stats->tx[tx]++;
if (tx > stats->tx_packets_max)
stats->tx_packets_max = tx;
@@ -121,7 +121,7 @@ static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf,
len += snprintf(buf + len, buflen - len, "%3s %10s %10s\n",
"len", "rx", "tx");
- for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++)
+ for (i = 1; i <= NAPI_POLL_WEIGHT; i++)
len += snprintf(buf + len, buflen - len,
"%3d: %10lu %10lu\n",
i, stats->rx[i], stats->tx[i]);
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 72dd654a691355c881b15d796fad0d640e05fc15..b675c99f168bd5a6ea238c8321534bb0b8925521 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -1376,7 +1376,7 @@ static int ag71xx_probe(struct platform_device *pdev)
memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN);
- netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT);
+ netif_napi_add(dev, &ag->napi, ag71xx_poll, NAPI_POLL_WEIGHT);
ag71xx_dump_regs(ag);

View File

@ -0,0 +1,33 @@
From: Rosen Penev <rosenp@gmail.com>
Date: Mon, 4 Dec 2017 11:40:22 -0800
Subject: ag71xx: Reduce NAPI weight to 32.
Qualcomm claims this reduces cache misses. Original commit message below:
From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
Date: Tue, 11 Jun 2013 12:18:46 -0500
Subject: [ag71xx] reduce NAPI weight
In an attempt to increase our cache warmth, we are decreasing NAPI.
This increases the warmth of the reused SKBs.
Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
Signed-off-by: Rosen Penev <rosenp@gmail.com>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index 7b1cc1e1032f7b87430a9be1507ddb3e3faa26bc..71fbe8975b22c291ed13bb549f6b4d2951ff67c0 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -40,6 +40,12 @@
#define AG71XX_DRV_NAME "ag71xx"
#define AG71XX_DRV_VERSION "0.5.35"
+/*
+ * For our NAPI weight bigger does *NOT* mean better - it means more
+ * D-cache misses and lots more wasted cycles than we'll ever
+ * possibly gain from saving instructions.
+ */
+#define AG71XX_NAPI_WEIGHT 32
#define AG71XX_OOM_REFILL (1 + HZ/10)
#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)

View File

@ -0,0 +1,70 @@
From: Rosen Penev <rosenp@gmail.com>
Date: Mon, 4 Dec 2017 11:40:23 -0800
Subject: ag71xx: Reorder ag71xx struct members for better cache performance
Qualcomm claims this improves the D-cache footprint. Origina commit message below:
From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
Date: Fri, 7 Jun 2013 10:57:28 -0500
Subject: [ag71xx] cluster/align structs for cache perf
Cluster the frequently used, per-packet structures in ag71xx near
to each other, and cacheline-align them. Some other re-ordering
occurred to move "warmer" structures near the per-packet structures.
Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
Signed-off-by: Rosen Penev <rosenp@gmail.com>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index 71fbe8975b22c291ed13bb549f6b4d2951ff67c0..d50ea81263744b5dd7e2ffa0c1d9c1061ef0ba8d 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -153,20 +153,31 @@ struct ag71xx_debug {
};
struct ag71xx {
- void __iomem *mac_base;
+ /*
+ * Critical data related to the per-packet data path are clustered
+ * early in this structure to help improve the D-cache footprint.
+ */
+ struct ag71xx_ring rx_ring ____cacheline_aligned;
+ struct ag71xx_ring tx_ring ____cacheline_aligned;
+
+ unsigned int max_frame_len;
+ unsigned int desc_pktlen_mask;
+ unsigned int rx_buf_size;
- spinlock_t lock;
- struct platform_device *pdev;
struct net_device *dev;
+ struct platform_device *pdev;
+ spinlock_t lock;
struct napi_struct napi;
u32 msg_enable;
+ /*
+ * From this point onwards we're not looking at per-packet fields.
+ */
+ void __iomem *mac_base;
+
struct ag71xx_desc *stop_desc;
dma_addr_t stop_desc_dma;
- struct ag71xx_ring rx_ring;
- struct ag71xx_ring tx_ring;
-
struct mii_bus *mii_bus;
struct phy_device *phy_dev;
void *phy_priv;
@@ -175,10 +186,6 @@ struct ag71xx {
unsigned int speed;
int duplex;
- unsigned int max_frame_len;
- unsigned int desc_pktlen_mask;
- unsigned int rx_buf_size;
-
struct delayed_work restart_work;
struct delayed_work link_work;
struct timer_list oom_timer;

View File

@ -0,0 +1,123 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 5 Dec 2017 14:17:24 +0100
Subject: ar71xx: allocate rx/tx descriptor/buffers in one chunk
Reduces false sharing due to cache aliases
Signed-off-by: Felix Fietkau <nbd@nbd.name>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index b675c99f168bd5a6ea238c8321534bb0b8925521..1cb590fad044d54fe1cfd0e765aa43ee981ae9c1 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -97,41 +97,6 @@ static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr)
(intr & AG71XX_INT_RX_BE) ? "RXBE " : "");
}
-static void ag71xx_ring_free(struct ag71xx_ring *ring)
-{
- int ring_size = BIT(ring->order);
- kfree(ring->buf);
-
- if (ring->descs_cpu)
- dma_free_coherent(NULL, ring_size * AG71XX_DESC_SIZE,
- ring->descs_cpu, ring->descs_dma);
-}
-
-static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
-{
- int ring_size = BIT(ring->order);
- int err;
-
- ring->descs_cpu = dma_alloc_coherent(NULL, ring_size * AG71XX_DESC_SIZE,
- &ring->descs_dma, GFP_ATOMIC);
- if (!ring->descs_cpu) {
- err = -ENOMEM;
- goto err;
- }
-
-
- ring->buf = kzalloc(ring_size * sizeof(*ring->buf), GFP_KERNEL);
- if (!ring->buf) {
- err = -ENOMEM;
- goto err;
- }
-
- return 0;
-
-err:
- return err;
-}
-
static void ag71xx_ring_tx_clean(struct ag71xx *ag)
{
struct ag71xx_ring *ring = &ag->tx_ring;
@@ -322,30 +287,56 @@ static int ag71xx_ring_rx_refill(struct ag71xx *ag)
static int ag71xx_rings_init(struct ag71xx *ag)
{
- int ret;
+ struct ag71xx_ring *tx = &ag->tx_ring;
+ struct ag71xx_ring *rx = &ag->rx_ring;
+ int ring_size = BIT(tx->order) + BIT(rx->order);
+ int tx_size = BIT(tx->order);
+
+ tx->buf = kzalloc(ring_size * sizeof(*tx->buf), GFP_KERNEL);
+ if (!tx->buf)
+ return -ENOMEM;
+
+ tx->descs_cpu = dma_alloc_coherent(NULL, ring_size * AG71XX_DESC_SIZE,
+ &tx->descs_dma, GFP_ATOMIC);
+ if (!tx->descs_cpu) {
+ kfree(tx->buf);
+ tx->buf = NULL;
+ return -ENOMEM;
+ }
- ret = ag71xx_ring_alloc(&ag->tx_ring);
- if (ret)
- return ret;
+ rx->buf = &tx->buf[BIT(tx->order)];
+ rx->descs_cpu = ((void *)tx->descs_cpu) + tx_size * AG71XX_DESC_SIZE;
+ rx->descs_dma = tx->descs_dma + tx_size * AG71XX_DESC_SIZE;
ag71xx_ring_tx_init(ag);
+ return ag71xx_ring_rx_init(ag);
+}
- ret = ag71xx_ring_alloc(&ag->rx_ring);
- if (ret)
- return ret;
+static void ag71xx_rings_free(struct ag71xx *ag)
+{
+ struct ag71xx_ring *tx = &ag->tx_ring;
+ struct ag71xx_ring *rx = &ag->rx_ring;
+ int ring_size = BIT(tx->order) + BIT(rx->order);
- ret = ag71xx_ring_rx_init(ag);
- return ret;
+ if (tx->descs_cpu)
+ dma_free_coherent(NULL, ring_size * AG71XX_DESC_SIZE,
+ tx->descs_cpu, tx->descs_dma);
+
+ kfree(tx->buf);
+
+ tx->descs_cpu = NULL;
+ rx->descs_cpu = NULL;
+ tx->buf = NULL;
+ rx->buf = NULL;
}
static void ag71xx_rings_cleanup(struct ag71xx *ag)
{
ag71xx_ring_rx_clean(ag);
- ag71xx_ring_free(&ag->rx_ring);
-
ag71xx_ring_tx_clean(ag);
+ ag71xx_rings_free(ag);
+
netdev_reset_queue(ag->dev);
- ag71xx_ring_free(&ag->tx_ring);
}
static unsigned char *ag71xx_speed_str(struct ag71xx *ag)

View File

@ -0,0 +1,26 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 5 Dec 2017 14:23:59 +0100
Subject: ar71xx: only access device stats in tx handler if packets were processed
Signed-off-by: Felix Fietkau <nbd@nbd.name>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 1cb590fad044d54fe1cfd0e765aa43ee981ae9c1..6a8558284ed6a1feb1fddfe2875ba182c78a95d4 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -1006,12 +1006,12 @@ static int ag71xx_tx_packets(struct ag71xx *ag, bool flush)
DBG("%s: %d packets sent out\n", ag->dev->name, sent);
- ag->dev->stats.tx_bytes += bytes_compl;
- ag->dev->stats.tx_packets += sent;
-
if (!sent)
return 0;
+ ag->dev->stats.tx_bytes += bytes_compl;
+ ag->dev->stats.tx_packets += sent;
+
netdev_completed_queue(ag->dev, sent, bytes_compl);
if ((ring->curr - ring->dirty) < (ring_size * 3) / 4)
netif_wake_queue(ag->dev);

View File

@ -0,0 +1,69 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 5 Dec 2017 14:40:32 +0100
Subject: ar71xx: use global timestamp for hang check
Shrink the size of struct ag71xx_buf to 8 bytes, which improves cache
footprint
Signed-off-by: Felix Fietkau <nbd@nbd.name>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index d50ea81263744b5dd7e2ffa0c1d9c1061ef0ba8d..24ed2f56e41cf5fe1974c24786194620627a192b 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -100,9 +100,8 @@ struct ag71xx_buf {
};
union {
dma_addr_t dma_addr;
- unsigned long timestamp;
+ unsigned int len;
};
- unsigned int len;
};
struct ag71xx_ring {
@@ -170,6 +169,8 @@ struct ag71xx {
struct napi_struct napi;
u32 msg_enable;
+ unsigned long timestamp;
+
/*
* From this point onwards we're not looking at per-packet fields.
*/
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 6a8558284ed6a1feb1fddfe2875ba182c78a95d4..bc876e9d73e3e26143cfac0d5484e7900dd9db01 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -823,7 +823,7 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
i = (ring->curr + n - 1) & ring_mask;
ring->buf[i].len = skb->len;
ring->buf[i].skb = skb;
- ring->buf[i].timestamp = jiffies;
+ ag->timestamp = jiffies;
netdev_sent_queue(dev, skb->len);
@@ -933,11 +933,11 @@ static void ag71xx_restart_work_func(struct work_struct *work)
rtnl_unlock();
}
-static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp)
+static bool ag71xx_check_dma_stuck(struct ag71xx *ag)
{
u32 rx_sm, tx_sm, rx_fd;
- if (likely(time_before(jiffies, timestamp + HZ/10)))
+ if (likely(time_before(jiffies, ag->timestamp + HZ/10)))
return false;
if (!netif_carrier_ok(ag->dev))
@@ -976,7 +976,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag, bool flush)
if (!flush && !ag71xx_desc_empty(desc)) {
if (pdata->is_ar724x &&
- ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) {
+ ag71xx_check_dma_stuck(ag)) {
schedule_delayed_work(&ag->restart_work, HZ / 2);
dma_stuck = true;
}

View File

@ -0,0 +1,55 @@
From: Rosen Penev <rosenp@gmail.com>
Date: Wed, 7 Feb 2018 13:57:30 -0800
Subject: ag71xx: Move timestamp struct member outside of struct.
With this change, the timestamp variable is only used in ag71xx_check_dma_stuck. Small tx speedup.
Based on a Qualcomm commit. ag->timestamp = jiffies was not replaced with netif_trans_update(dev) because of this quote:
It should be noted that after this series several instances
of netif_trans_update() are useless (if they occur in
.ndo_start_xmit and driver doesn't set LLTX flag -- stack already
did an update).
From: http://lists.openwall.net/netdev/2016/05/03/87
Signed-off-by: Rosen Penev <rosenp@gmail.com>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index 24ed2f56e41cf5fe1974c24786194620627a192b..0927b1871ee6dbf76b7775c7882e67a0cf5b2503 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -169,8 +169,6 @@ struct ag71xx {
struct napi_struct napi;
u32 msg_enable;
- unsigned long timestamp;
-
/*
* From this point onwards we're not looking at per-packet fields.
*/
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index bc876e9d73e3e26143cfac0d5484e7900dd9db01..2f4218e08a9749ffc45c8265e7931f205e8e7935 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -823,7 +823,6 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
i = (ring->curr + n - 1) & ring_mask;
ring->buf[i].len = skb->len;
ring->buf[i].skb = skb;
- ag->timestamp = jiffies;
netdev_sent_queue(dev, skb->len);
@@ -935,9 +934,11 @@ static void ag71xx_restart_work_func(struct work_struct *work)
static bool ag71xx_check_dma_stuck(struct ag71xx *ag)
{
+ unsigned long timestamp;
u32 rx_sm, tx_sm, rx_fd;
- if (likely(time_before(jiffies, ag->timestamp + HZ/10)))
+ timestamp = netdev_get_tx_queue(ag->dev, 0)->trans_start;
+ if (likely(time_before(jiffies, timestamp + HZ/10)))
return false;
if (!netif_carrier_ok(ag->dev))

View File

@ -0,0 +1,45 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 28 Feb 2018 13:57:58 +0100
Subject: ar71xx: fix build with ag71xx debugfs support enabled
Signed-off-by: Felix Fietkau <nbd@nbd.name>
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
index 89cea0c0f5ae97c9917cd13e1ee89bd31fe45e58..20910b9681a54e53f3e089d0a589e1b2b45c1833 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
@@ -175,8 +175,8 @@ static ssize_t read_file_ring(struct file *file, char __user *user_buf,
return -ENOMEM;
len += snprintf(buf + len, buflen - len,
- "Idx ... %-8s %-8s %-8s %-8s . %-10s\n",
- "desc", "next", "data", "ctrl", "timestamp");
+ "Idx ... %-8s %-8s %-8s %-8s .\n",
+ "desc", "next", "data", "ctrl");
spin_lock_irqsave(&ag->lock, flags);
@@ -184,12 +184,11 @@ static ssize_t read_file_ring(struct file *file, char __user *user_buf,
dirty = (ring->dirty & ring_mask);
desc_hw = ag71xx_rr(ag, desc_reg);
for (i = 0; i < ring_size; i++) {
- struct ag71xx_buf *ab = &ring->buf[i];
struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
u32 desc_dma = ((u32) ring->descs_dma) + i * AG71XX_DESC_SIZE;
len += snprintf(buf + len, buflen - len,
- "%3d %c%c%c %08x %08x %08x %08x %c %10lu\n",
+ "%3d %c%c%c %08x %08x %08x %08x %c\n",
i,
(i == curr) ? 'C' : ' ',
(i == dirty) ? 'D' : ' ',
@@ -198,8 +197,7 @@ static ssize_t read_file_ring(struct file *file, char __user *user_buf,
desc->next,
desc->data,
desc->ctrl,
- (desc->ctrl & DESC_EMPTY) ? 'E' : '*',
- ab->timestamp);
+ (desc->ctrl & DESC_EMPTY) ? 'E' : '*');
}
spin_unlock_irqrestore(&ag->lock, flags);

View File

@ -0,0 +1,149 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Fri, 2 Mar 2018 21:30:10 +0100
Subject: ar71xx: remove pdata->fifo_cfg*
The values are the same for all chipsets that use it
Signed-off-by: Felix Fietkau <nbd@nbd.name>
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
index 5f971ea32d35035617229076b7a7fc30ed4d2dcc..b46bab7886c363a1559da6f4d7ad0c8e27b7ae10 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
@@ -900,13 +900,6 @@ void __init ath79_register_eth(unsigned int id)
}
pdata->has_gbit = 1;
pdata->is_ar724x = 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_AR7241:
@@ -936,13 +929,6 @@ void __init ath79_register_eth(unsigned int id)
pdata->is_ar724x = 1;
if (ath79_soc == ATH79_SOC_AR7240)
pdata->is_ar7240 = 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_AR9132:
@@ -979,13 +965,6 @@ void __init ath79_register_eth(unsigned int id)
}
pdata->is_ar724x = 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_AR9341:
@@ -1016,13 +995,6 @@ void __init ath79_register_eth(unsigned int id)
pdata->max_frame_len = SZ_16K - 1;
pdata->desc_pktlen_mask = SZ_16K - 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_TP9343:
@@ -1048,13 +1020,6 @@ void __init ath79_register_eth(unsigned int id)
pdata->has_gbit = 1;
pdata->is_ar724x = 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_QCA9556:
@@ -1082,13 +1047,6 @@ void __init ath79_register_eth(unsigned int id)
*/
pdata->max_frame_len = SZ_4K - 1;
pdata->desc_pktlen_mask = SZ_16K - 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
case ATH79_SOC_QCA956X:
@@ -1121,13 +1079,6 @@ void __init ath79_register_eth(unsigned int id)
pdata->has_gbit = 1;
pdata->is_ar724x = 1;
-
- if (!pdata->fifo_cfg1)
- pdata->fifo_cfg1 = 0x0010ffff;
- if (!pdata->fifo_cfg2)
- pdata->fifo_cfg2 = 0x015500aa;
- if (!pdata->fifo_cfg3)
- pdata->fifo_cfg3 = 0x01f00140;
break;
default:
diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h
index 5fdc59c7b78b84670daefa9fd831b154ded84ddc..c4c3a6d44c935b84b5d6dae58a4f441e5492463c 100644
--- a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h
+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h
@@ -45,10 +45,6 @@ struct ag71xx_platform_data {
void (*set_speed)(int speed);
void (*update_pll)(u32 pll_10, u32 pll_100, u32 pll_1000);
- u32 fifo_cfg1;
- u32 fifo_cfg2;
- u32 fifo_cfg3;
-
unsigned int max_frame_len;
unsigned int desc_pktlen_mask;
};
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 2f4218e08a9749ffc45c8265e7931f205e8e7935..33237e01e6b191ff30449458f1a22ee44ba6d9e2 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -460,8 +460,8 @@ static void ag71xx_hw_setup(struct ag71xx *ag)
/* setup FIFO configuration registers */
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
if (pdata->is_ar724x) {
- ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1);
- ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0010ffff);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x015500aa);
} else {
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
@@ -603,7 +603,7 @@ __ag71xx_link_adjust(struct ag71xx *ag, bool update)
if (pdata->is_ar91xx)
fifo3 = 0x00780fff;
else if (pdata->is_ar724x)
- fifo3 = pdata->fifo_cfg3;
+ fifo3 = 0x01f00140;
else
fifo3 = 0x008001ff;