summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Robinson <pbrobinson@gmail.com>2018-04-09 18:30:51 +0100
committerJeremy Cline <jeremy@jcline.org>2018-04-09 14:25:21 -0400
commit33a8762bdc67af3d65da9821a42c8ae7fb684db5 (patch)
tree5bc2b15541cb242126c69f431a1e344d31af9913
parent197f0bb94153dba8a7aa9d74202607a72d2c57ad (diff)
downloadkernel-33a8762bdc67af3d65da9821a42c8ae7fb684db5.tar.gz
kernel-33a8762bdc67af3d65da9821a42c8ae7fb684db5.tar.xz
kernel-33a8762bdc67af3d65da9821a42c8ae7fb684db5.zip
More fixes for Raspberry Pi 3+ lan78xx ethernet interface, Fixes for Cavium ThunderX ZIP driver stability
-rw-r--r--arm64-thunderx-crypto-zip-fixes.patch403
-rw-r--r--bcm2837-lan78xx-fixes.patch355
-rw-r--r--kernel.spec7
3 files changed, 765 insertions, 0 deletions
diff --git a/arm64-thunderx-crypto-zip-fixes.patch b/arm64-thunderx-crypto-zip-fixes.patch
new file mode 100644
index 000000000..7f970ee30
--- /dev/null
+++ b/arm64-thunderx-crypto-zip-fixes.patch
@@ -0,0 +1,403 @@
+From patchwork Mon Apr 9 15:45:50 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,1/5] crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
+From: Jan Glauber <jglauber@cavium.com>
+X-Patchwork-Id: 10331719
+Message-Id: <20180409154554.7578-2-jglauber@cavium.com>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S . Miller" <davem@davemloft.net>,
+ linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Mahipal Challa <Mahipal.Challa@cavium.com>,
+ Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>,
+ stable <stable@vger.kernel.org>
+Date: Mon, 9 Apr 2018 17:45:50 +0200
+
+Enabling virtual mapped kernel stacks breaks the thunderx_zip
+driver. On compression or decompression the executing CPU hangs
+in an endless loop. The reason for this is the usage of __pa
+by the driver which does no longer work for an address that is
+not part of the 1:1 mapping.
+
+The zip driver allocates a result struct on the stack and needs
+to tell the hardware the physical address within this struct
+that is used to signal the completion of the request.
+
+As the hardware gets the wrong address after the broken __pa
+conversion it writes to an arbitrary address. The zip driver then
+waits forever for the completion byte to contain a non-zero value.
+
+Allocating the result struct from 1:1 mapped memory resolves this
+bug.
+
+Signed-off-by: Jan Glauber <jglauber@cavium.com>
+Reviewed-by: Robert Richter <rrichter@cavium.com>
+Cc: stable <stable@vger.kernel.org> # 4.14
+---
+ drivers/crypto/cavium/zip/zip_crypto.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/crypto/cavium/zip/zip_crypto.c b/drivers/crypto/cavium/zip/zip_crypto.c
+index 8df4d26cf9d4..b92b6e7e100f 100644
+--- a/drivers/crypto/cavium/zip/zip_crypto.c
++++ b/drivers/crypto/cavium/zip/zip_crypto.c
+@@ -124,7 +124,7 @@ int zip_compress(const u8 *src, unsigned int slen,
+ struct zip_kernel_ctx *zip_ctx)
+ {
+ struct zip_operation *zip_ops = NULL;
+- struct zip_state zip_state;
++ struct zip_state *zip_state;
+ struct zip_device *zip = NULL;
+ int ret;
+
+@@ -135,20 +135,23 @@ int zip_compress(const u8 *src, unsigned int slen,
+ if (!zip)
+ return -ENODEV;
+
+- memset(&zip_state, 0, sizeof(struct zip_state));
++ zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
++ if (!zip_state)
++ return -ENOMEM;
++
+ zip_ops = &zip_ctx->zip_comp;
+
+ zip_ops->input_len = slen;
+ zip_ops->output_len = *dlen;
+ memcpy(zip_ops->input, src, slen);
+
+- ret = zip_deflate(zip_ops, &zip_state, zip);
++ ret = zip_deflate(zip_ops, zip_state, zip);
+
+ if (!ret) {
+ *dlen = zip_ops->output_len;
+ memcpy(dst, zip_ops->output, *dlen);
+ }
+-
++ kfree(zip_state);
+ return ret;
+ }
+
+@@ -157,7 +160,7 @@ int zip_decompress(const u8 *src, unsigned int slen,
+ struct zip_kernel_ctx *zip_ctx)
+ {
+ struct zip_operation *zip_ops = NULL;
+- struct zip_state zip_state;
++ struct zip_state *zip_state;
+ struct zip_device *zip = NULL;
+ int ret;
+
+@@ -168,7 +171,10 @@ int zip_decompress(const u8 *src, unsigned int slen,
+ if (!zip)
+ return -ENODEV;
+
+- memset(&zip_state, 0, sizeof(struct zip_state));
++ zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
++ if (!zip_state)
++ return -ENOMEM;
++
+ zip_ops = &zip_ctx->zip_decomp;
+ memcpy(zip_ops->input, src, slen);
+
+@@ -179,13 +185,13 @@ int zip_decompress(const u8 *src, unsigned int slen,
+ zip_ops->input_len = slen;
+ zip_ops->output_len = *dlen;
+
+- ret = zip_inflate(zip_ops, &zip_state, zip);
++ ret = zip_inflate(zip_ops, zip_state, zip);
+
+ if (!ret) {
+ *dlen = zip_ops->output_len;
+ memcpy(dst, zip_ops->output, *dlen);
+ }
+-
++ kfree(zip_state);
+ return ret;
+ }
+
+From patchwork Mon Apr 9 15:45:51 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,2/5] crypto: thunderx_zip: Limit result reading attempts
+From: Jan Glauber <jglauber@cavium.com>
+X-Patchwork-Id: 10331705
+Message-Id: <20180409154554.7578-3-jglauber@cavium.com>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S . Miller" <davem@davemloft.net>,
+ linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Mahipal Challa <Mahipal.Challa@cavium.com>,
+ Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>,
+ stable <stable@vger.kernel.org>
+Date: Mon, 9 Apr 2018 17:45:51 +0200
+
+After issuing a request an endless loop was used to read the
+completion state from memory which is asynchronously updated
+by the ZIP coprocessor.
+
+Add an upper bound to the retry attempts to prevent a CPU getting stuck
+forever in case of an error. Additionally, add a read memory barrier
+and a small delay between the reading attempts.
+
+Signed-off-by: Jan Glauber <jglauber@cavium.com>
+Reviewed-by: Robert Richter <rrichter@cavium.com>
+Cc: stable <stable@vger.kernel.org> # 4.14
+---
+ drivers/crypto/cavium/zip/common.h | 21 +++++++++++++++++++++
+ drivers/crypto/cavium/zip/zip_deflate.c | 4 ++--
+ drivers/crypto/cavium/zip/zip_inflate.c | 4 ++--
+ 3 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/cavium/zip/common.h b/drivers/crypto/cavium/zip/common.h
+index dc451e0a43c5..58fb3ed6e644 100644
+--- a/drivers/crypto/cavium/zip/common.h
++++ b/drivers/crypto/cavium/zip/common.h
+@@ -46,8 +46,10 @@
+ #ifndef __COMMON_H__
+ #define __COMMON_H__
+
++#include <linux/delay.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
++#include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+@@ -149,6 +151,25 @@ struct zip_operation {
+ u32 sizeofzops;
+ };
+
++static inline int zip_poll_result(union zip_zres_s *result)
++{
++ int retries = 1000;
++
++ while (!result->s.compcode) {
++ if (!--retries) {
++ pr_err("ZIP ERR: request timed out");
++ return -ETIMEDOUT;
++ }
++ udelay(10);
++ /*
++ * Force re-reading of compcode which is updated
++ * by the ZIP coprocessor.
++ */
++ rmb();
++ }
++ return 0;
++}
++
+ /* error messages */
+ #define zip_err(fmt, args...) pr_err("ZIP ERR:%s():%d: " \
+ fmt "\n", __func__, __LINE__, ## args)
+diff --git a/drivers/crypto/cavium/zip/zip_deflate.c b/drivers/crypto/cavium/zip/zip_deflate.c
+index 9a944b8c1e29..d7133f857d67 100644
+--- a/drivers/crypto/cavium/zip/zip_deflate.c
++++ b/drivers/crypto/cavium/zip/zip_deflate.c
+@@ -129,8 +129,8 @@ int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s,
+ /* Stats update for compression requests submitted */
+ atomic64_inc(&zip_dev->stats.comp_req_submit);
+
+- while (!result_ptr->s.compcode)
+- continue;
++ /* Wait for completion or error */
++ zip_poll_result(result_ptr);
+
+ /* Stats update for compression requests completed */
+ atomic64_inc(&zip_dev->stats.comp_req_complete);
+diff --git a/drivers/crypto/cavium/zip/zip_inflate.c b/drivers/crypto/cavium/zip/zip_inflate.c
+index 50cbdd83dbf2..7e0d73e2f89e 100644
+--- a/drivers/crypto/cavium/zip/zip_inflate.c
++++ b/drivers/crypto/cavium/zip/zip_inflate.c
+@@ -143,8 +143,8 @@ int zip_inflate(struct zip_operation *zip_ops, struct zip_state *s,
+ /* Decompression requests submitted stats update */
+ atomic64_inc(&zip_dev->stats.decomp_req_submit);
+
+- while (!result_ptr->s.compcode)
+- continue;
++ /* Wait for completion or error */
++ zip_poll_result(result_ptr);
+
+ /* Decompression requests completed stats update */
+ atomic64_inc(&zip_dev->stats.decomp_req_complete);
+From patchwork Mon Apr 9 15:45:52 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,3/5] crypto: thunderx_zip: Prevent division by zero
+From: Jan Glauber <jglauber@cavium.com>
+X-Patchwork-Id: 10331709
+Message-Id: <20180409154554.7578-4-jglauber@cavium.com>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S . Miller" <davem@davemloft.net>,
+ linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Mahipal Challa <Mahipal.Challa@cavium.com>,
+ Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
+Date: Mon, 9 Apr 2018 17:45:52 +0200
+
+Avoid two potential divisions by zero when calculating average
+values for the zip statistics.
+
+Signed-off-by: Jan Glauber <jglauber@cavium.com>
+Reviewed-by: Robert Richter <rrichter@cavium.com>
+---
+ drivers/crypto/cavium/zip/zip_main.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
+index 1cd8aa488185..79b449e0f955 100644
+--- a/drivers/crypto/cavium/zip/zip_main.c
++++ b/drivers/crypto/cavium/zip/zip_main.c
+@@ -482,10 +482,11 @@ static int zip_show_stats(struct seq_file *s, void *unused)
+ atomic64_add(val, &st->pending_req);
+ }
+
+- avg_chunk = (atomic64_read(&st->comp_in_bytes) /
+- atomic64_read(&st->comp_req_complete));
+- avg_cr = (atomic64_read(&st->comp_in_bytes) /
+- atomic64_read(&st->comp_out_bytes));
++ val = atomic64_read(&st->comp_req_complete);
++ avg_chunk = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
++
++ val = atomic64_read(&st->comp_out_bytes);
++ avg_cr = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
+ seq_printf(s, " ZIP Device %d Stats\n"
+ "-----------------------------------\n"
+ "Comp Req Submitted : \t%lld\n"
+From patchwork Mon Apr 9 15:45:53 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,4/5] crypto: thunderx_zip: Fix statistics pending request value
+From: Jan Glauber <jglauber@cavium.com>
+X-Patchwork-Id: 10331711
+Message-Id: <20180409154554.7578-5-jglauber@cavium.com>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S . Miller" <davem@davemloft.net>,
+ linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Mahipal Challa <Mahipal.Challa@cavium.com>,
+ Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
+Date: Mon, 9 Apr 2018 17:45:53 +0200
+
+The pending request counter was read from the wrong register. While
+at it, there is no need to use an atomic for it as it is only read
+localy in a loop.
+
+Signed-off-by: Jan Glauber <jglauber@cavium.com>
+Reviewed-by: Robert Richter <rrichter@cavium.com>
+---
+ drivers/crypto/cavium/zip/zip_main.c | 13 +++++--------
+ drivers/crypto/cavium/zip/zip_main.h | 1 -
+ 2 files changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
+index 79b449e0f955..ae5b20c695ca 100644
+--- a/drivers/crypto/cavium/zip/zip_main.c
++++ b/drivers/crypto/cavium/zip/zip_main.c
+@@ -469,6 +469,8 @@ static int zip_show_stats(struct seq_file *s, void *unused)
+ struct zip_stats *st;
+
+ for (index = 0; index < MAX_ZIP_DEVICES; index++) {
++ u64 pending = 0;
++
+ if (zip_dev[index]) {
+ zip = zip_dev[index];
+ st = &zip->stats;
+@@ -476,10 +478,8 @@ static int zip_show_stats(struct seq_file *s, void *unused)
+ /* Get all the pending requests */
+ for (q = 0; q < ZIP_NUM_QUEUES; q++) {
+ val = zip_reg_read((zip->reg_base +
+- ZIP_DBG_COREX_STA(q)));
+- val = (val >> 32);
+- val = val & 0xffffff;
+- atomic64_add(val, &st->pending_req);
++ ZIP_DBG_QUEX_STA(q)));
++ pending += val >> 32 & 0xffffff;
+ }
+
+ val = atomic64_read(&st->comp_req_complete);
+@@ -514,10 +514,7 @@ static int zip_show_stats(struct seq_file *s, void *unused)
+ (u64)atomic64_read(&st->decomp_in_bytes),
+ (u64)atomic64_read(&st->decomp_out_bytes),
+ (u64)atomic64_read(&st->decomp_bad_reqs),
+- (u64)atomic64_read(&st->pending_req));
+-
+- /* Reset pending requests count */
+- atomic64_set(&st->pending_req, 0);
++ pending);
+ }
+ }
+ return 0;
+diff --git a/drivers/crypto/cavium/zip/zip_main.h b/drivers/crypto/cavium/zip/zip_main.h
+index 64e051f60784..e1e4fa92ce80 100644
+--- a/drivers/crypto/cavium/zip/zip_main.h
++++ b/drivers/crypto/cavium/zip/zip_main.h
+@@ -74,7 +74,6 @@ struct zip_stats {
+ atomic64_t comp_req_complete;
+ atomic64_t decomp_req_submit;
+ atomic64_t decomp_req_complete;
+- atomic64_t pending_req;
+ atomic64_t comp_in_bytes;
+ atomic64_t comp_out_bytes;
+ atomic64_t decomp_in_bytes;
+From patchwork Mon Apr 9 15:45:54 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v2,5/5] crypto: thunderx_zip: Fix smp_processor_id() warnings
+From: Jan Glauber <jglauber@cavium.com>
+X-Patchwork-Id: 10331715
+Message-Id: <20180409154554.7578-6-jglauber@cavium.com>
+To: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S . Miller" <davem@davemloft.net>,
+ linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Mahipal Challa <Mahipal.Challa@cavium.com>,
+ Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
+Date: Mon, 9 Apr 2018 17:45:54 +0200
+
+Switch to raw_smp_processor_id() to prevent a number of
+warnings from kernel debugging. We do not care about
+preemption here, as the CPU number is only used as a
+poor mans load balancing or device selection. If preemption
+happens during a compress/decompress operation a small performance
+hit will occur but everything will continue to work, so just
+ignore it.
+
+Signed-off-by: Jan Glauber <jglauber@cavium.com>
+Reviewed-by: Robert Richter <rrichter@cavium.com>
+---
+ drivers/crypto/cavium/zip/zip_device.c | 4 ++--
+ drivers/crypto/cavium/zip/zip_main.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/cavium/zip/zip_device.c b/drivers/crypto/cavium/zip/zip_device.c
+index ccf21fb91513..f174ec29ed69 100644
+--- a/drivers/crypto/cavium/zip/zip_device.c
++++ b/drivers/crypto/cavium/zip/zip_device.c
+@@ -87,12 +87,12 @@ u32 zip_load_instr(union zip_inst_s *instr,
+ * Distribute the instructions between the enabled queues based on
+ * the CPU id.
+ */
+- if (smp_processor_id() % 2 == 0)
++ if (raw_smp_processor_id() % 2 == 0)
+ queue = 0;
+ else
+ queue = 1;
+
+- zip_dbg("CPU Core: %d Queue number:%d", smp_processor_id(), queue);
++ zip_dbg("CPU Core: %d Queue number:%d", raw_smp_processor_id(), queue);
+
+ /* Take cmd buffer lock */
+ spin_lock(&zip_dev->iq[queue].lock);
+diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
+index ae5b20c695ca..be055b9547f6 100644
+--- a/drivers/crypto/cavium/zip/zip_main.c
++++ b/drivers/crypto/cavium/zip/zip_main.c
+@@ -113,7 +113,7 @@ struct zip_device *zip_get_device(int node)
+ */
+ int zip_get_node_id(void)
+ {
+- return cpu_to_node(smp_processor_id());
++ return cpu_to_node(raw_smp_processor_id());
+ }
+
+ /* Initializes the ZIP h/w sub-system */
diff --git a/bcm2837-lan78xx-fixes.patch b/bcm2837-lan78xx-fixes.patch
index f877ac15b..1cb1dea08 100644
--- a/bcm2837-lan78xx-fixes.patch
+++ b/bcm2837-lan78xx-fixes.patch
@@ -106,3 +106,358 @@ index 60a604cc7647..a21039852f8d 100644
addr_lo = addr[0] | (addr[1] << 8) |
(addr[2] << 16) | (addr[3] << 24);
addr_hi = addr[4] | (addr[5] << 8);
+From b5284e5d2d3562dac311443969a538b7fecb9848 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 28 Mar 2018 12:18:13 +0100
+Subject: [PATCH 1/5] lan78xx: Ignore DT MAC address if already valid
+
+The patch to set the lan78xx MAC address from DT does so regardless of
+whether or not the interface already has a valid address. As the
+initialisation function is called from the reset handler when the
+interface is brought up, it is impossible to change the MAC address
+in a way that persists across the interface being brought up.
+
+Fix the problem by moving the DT reading code after the check for a
+valid address.
+
+See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=209309
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/net/usb/lan78xx.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index b43b16b6e7ee..97ee7d3f749d 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -1641,14 +1641,6 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev)
+ u32 addr_lo, addr_hi;
+ int ret;
+ u8 addr[6];
+- const u8 *mac_addr;
+-
+- /* maybe the boot loader passed the MAC address in devicetree */
+- mac_addr = of_get_mac_address(dev->udev->dev.of_node);
+- if (mac_addr) {
+- ether_addr_copy(addr, mac_addr);
+- goto set_mac_addr;
+- }
+
+ ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo);
+ ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi);
+@@ -1661,6 +1653,15 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev)
+ addr[5] = (addr_hi >> 8) & 0xFF;
+
+ if (!is_valid_ether_addr(addr)) {
++ const u8 *mac_addr;
++
++ /* maybe the boot loader passed the MAC address in devicetree */
++ mac_addr = of_get_mac_address(dev->udev->dev.of_node);
++ if (mac_addr) {
++ ether_addr_copy(addr, mac_addr);
++ goto set_mac_addr;
++ }
++
+ /* reading mac address from EEPROM or OTP */
+ if ((lan78xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+ addr) == 0) ||
+--
+2.17.0
+
+From 2c5d6ac9133cbfed05b97b34246121bddaf2aea4 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Wed, 4 Apr 2018 16:34:24 +0100
+Subject: [PATCH 2/5] net: lan78xx: Allow for VLAN headers in timeout.
+
+The frame abort timeout being set by lan78xx_set_rx_max_frame_length
+didn't account for any VLAN headers, resulting in very low
+throughput if used with tagged VLANs.
+Use VLAN_ETH_HLEN instead of ETH_HLEN to correct for this.
+
+See https://github.com/raspberrypi/linux/issues/2458
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/net/usb/lan78xx.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 97ee7d3f749d..5fd7b8569cba 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2193,7 +2193,7 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu)
+ if ((ll_mtu % dev->maxpacket) == 0)
+ return -EDOM;
+
+- ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN);
++ ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN);
+
+ netdev->mtu = new_mtu;
+
+@@ -2488,7 +2488,8 @@ static int lan78xx_reset(struct lan78xx_net *dev)
+ buf |= FCT_TX_CTL_EN_;
+ ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf);
+
+- ret = lan78xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN);
++ ret = lan78xx_set_rx_max_frame_length(dev,
++ dev->net->mtu + VLAN_ETH_HLEN);
+
+ ret = lan78xx_read_reg(dev, MAC_RX, &buf);
+ buf |= MAC_RX_RXEN_;
+--
+2.17.0
+
+From 833315351413d94d7db407847448dfeddfafe127 Mon Sep 17 00:00:00 2001
+From: Peter Robinson <pbrobinson@gmail.com>
+Date: Mon, 9 Apr 2018 17:51:35 +0100
+Subject: [PATCH 3/5] lan78xx: Connect phy early
+
+When using wicked with a lan78xx device attached to the system, we
+end up with ethtool commands issued on the device before an ifup
+got issued. That lead to the following crash:
+
+ Unable to handle kernel NULL pointer dereference at virtual address 0000039c
+ pgd = ffff800035b30000
+ [0000039c] *pgd=0000000000000000
+ Internal error: Oops: 96000004 [#1] SMP
+ Modules linked in: [...]
+ Supported: Yes
+ CPU: 3 PID: 638 Comm: wickedd Tainted: G E 4.12.14-0-default #1
+ Hardware name: raspberrypi rpi/rpi, BIOS 2018.03-rc2 02/21/2018
+ task: ffff800035e74180 task.stack: ffff800036718000
+ PC is at phy_ethtool_ksettings_get+0x20/0x98
+ LR is at lan78xx_get_link_ksettings+0x44/0x60 [lan78xx]
+ pc : [<ffff0000086f7f30>] lr : [<ffff000000dcca84>] pstate: 20000005
+ sp : ffff80003671bb20
+ x29: ffff80003671bb20 x28: ffff800035e74180
+ x27: ffff000008912000 x26: 000000000000001d
+ x25: 0000000000000124 x24: ffff000008f74d00
+ x23: 0000004000114809 x22: 0000000000000000
+ x21: ffff80003671bbd0 x20: 0000000000000000
+ x19: ffff80003671bbd0 x18: 000000000000040d
+ x17: 0000000000000001 x16: 0000000000000000
+ x15: 0000000000000000 x14: ffffffffffffffff
+ x13: 0000000000000000 x12: 0000000000000020
+ x11: 0101010101010101 x10: fefefefefefefeff
+ x9 : 7f7f7f7f7f7f7f7f x8 : fefefeff31677364
+ x7 : 0000000080808080 x6 : ffff80003671bc9c
+ x5 : ffff80003671b9f8 x4 : ffff80002c296190
+ x3 : 0000000000000000 x2 : 0000000000000000
+ x1 : ffff80003671bbd0 x0 : ffff80003671bc00
+ Process wickedd (pid: 638, stack limit = 0xffff800036718000)
+ Call trace:
+ Exception stack(0xffff80003671b9e0 to 0xffff80003671bb20)
+ b9e0: ffff80003671bc00 ffff80003671bbd0 0000000000000000 0000000000000000
+ ba00: ffff80002c296190 ffff80003671b9f8 ffff80003671bc9c 0000000080808080
+ ba20: fefefeff31677364 7f7f7f7f7f7f7f7f fefefefefefefeff 0101010101010101
+ ba40: 0000000000000020 0000000000000000 ffffffffffffffff 0000000000000000
+ ba60: 0000000000000000 0000000000000001 000000000000040d ffff80003671bbd0
+ ba80: 0000000000000000 ffff80003671bbd0 0000000000000000 0000004000114809
+ baa0: ffff000008f74d00 0000000000000124 000000000000001d ffff000008912000
+ bac0: ffff800035e74180 ffff80003671bb20 ffff000000dcca84 ffff80003671bb20
+ bae0: ffff0000086f7f30 0000000020000005 ffff80002c296000 ffff800035223900
+ bb00: 0000ffffffffffff 0000000000000000 ffff80003671bb20 ffff0000086f7f30
+ [<ffff0000086f7f30>] phy_ethtool_ksettings_get+0x20/0x98
+ [<ffff000000dcca84>] lan78xx_get_link_ksettings+0x44/0x60 [lan78xx]
+ [<ffff0000087cbc40>] ethtool_get_settings+0x68/0x210
+ [<ffff0000087cc0d4>] dev_ethtool+0x214/0x2180
+ [<ffff0000087e5008>] dev_ioctl+0x400/0x630
+ [<ffff00000879dd00>] sock_do_ioctl+0x70/0x88
+ [<ffff00000879f5f8>] sock_ioctl+0x208/0x368
+ [<ffff0000082cde10>] do_vfs_ioctl+0xb0/0x848
+ [<ffff0000082ce634>] SyS_ioctl+0x8c/0xa8
+ Exception stack(0xffff80003671bec0 to 0xffff80003671c000)
+ bec0: 0000000000000009 0000000000008946 0000fffff4e841d0 0000aa0032687465
+ bee0: 0000aaaafa2319d4 0000fffff4e841d4 0000000032687465 0000000032687465
+ bf00: 000000000000001d 7f7fff7f7f7f7f7f 72606b622e71ff4c 7f7f7f7f7f7f7f7f
+ bf20: 0101010101010101 0000000000000020 ffffffffffffffff 0000ffff7f510c68
+ bf40: 0000ffff7f6a9d18 0000ffff7f44ce30 000000000000040d 0000ffff7f6f98f0
+ bf60: 0000fffff4e842c0 0000000000000001 0000aaaafa2c2e00 0000ffff7f6ab000
+ bf80: 0000fffff4e842c0 0000ffff7f62a000 0000aaaafa2b9f20 0000aaaafa2c2e00
+ bfa0: 0000fffff4e84818 0000fffff4e841a0 0000ffff7f5ad0cc 0000fffff4e841a0
+ bfc0: 0000ffff7f44ce3c 0000000080000000 0000000000000009 000000000000001d
+ bfe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+
+The culprit is quite simple: The driver tries to access the phy left and right,
+but only actually has a working reference to it when the device is up.
+
+The fix thus is quite simple too: Get a reference to the phy on probe already
+and keep it even when the device is going down.
+
+With this patch applied, I can successfully run wicked on my system and bring
+the interface up and down as many times as I want, without getting NULL pointer
+dereferences in between.
+
+Signed-off-by: Alexander Graf <agraf@suse.de>
+---
+ drivers/net/usb/lan78xx.c | 34 ++++++++++++++++++----------------
+ 1 file changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 5fd7b8569cba..60fa1257721c 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2094,10 +2094,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
+
+ dev->fc_autoneg = phydev->autoneg;
+
+- phy_start(phydev);
+-
+- netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+-
+ return 0;
+
+ error:
+@@ -2541,9 +2537,9 @@ static int lan78xx_open(struct net_device *net)
+ if (ret < 0)
+ goto done;
+
+- ret = lan78xx_phy_init(dev);
+- if (ret < 0)
+- goto done;
++ phy_start(net->phydev);
++
++ netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+
+ /* for Link Check */
+ if (dev->urb_intr) {
+@@ -2604,13 +2600,8 @@ static int lan78xx_stop(struct net_device *net)
+ if (timer_pending(&dev->stat_monitor))
+ del_timer_sync(&dev->stat_monitor);
+
+- phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0);
+- phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0);
+-
+- phy_stop(net->phydev);
+- phy_disconnect(net->phydev);
+-
+- net->phydev = NULL;
++ if (net->phydev)
++ phy_stop(net->phydev);
+
+ clear_bit(EVENT_DEV_OPEN, &dev->flags);
+ netif_stop_queue(net);
+@@ -3525,8 +3516,13 @@ static void lan78xx_disconnect(struct usb_interface *intf)
+ return;
+
+ udev = interface_to_usbdev(intf);
+-
+ net = dev->net;
++
++ phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0);
++ phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0);
++
++ phy_disconnect(net->phydev);
++
+ unregister_netdev(net);
+
+ cancel_delayed_work_sync(&dev->wq);
+@@ -3682,8 +3678,14 @@ static int lan78xx_probe(struct usb_interface *intf,
+ pm_runtime_set_autosuspend_delay(&udev->dev,
+ DEFAULT_AUTOSUSPEND_DELAY);
+
++ ret = lan78xx_phy_init(dev);
++ if (ret < 0)
++ goto out4;
++
+ return 0;
+
++out4:
++ unregister_netdev(netdev);
+ out3:
+ lan78xx_unbind(dev, intf);
+ out2:
+@@ -4031,7 +4033,7 @@ static int lan78xx_reset_resume(struct usb_interface *intf)
+
+ lan78xx_reset(dev);
+
+- lan78xx_phy_init(dev);
++ phy_start(dev->net->phydev);
+
+ return lan78xx_resume(intf);
+ }
+--
+2.17.0
+
+From 7b4cc4a0af02c0d798007a143efa7509711d52d7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 4 Apr 2018 16:39:44 +0100
+Subject: [PATCH 4/5] lan78xx: Don't reset the interface on open
+
+With Alexander Graf's patch ("lan78xx: Connect phy early") applied,
+the call to lan78xx_reset within lan78xx_open prevents the phy
+interrupt from being generated (even though the link is up).
+
+Avoid this issue by removing the lan78xx_reset call.
+
+See: https://github.com/raspberrypi/linux/issues/2437
+ https://github.com/raspberrypi/linux/issues/2442
+ https://github.com/raspberrypi/linux/issues/2457
+---
+ drivers/net/usb/lan78xx.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 60fa1257721c..293ed1847932 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2533,10 +2533,6 @@ static int lan78xx_open(struct net_device *net)
+ if (ret < 0)
+ goto out;
+
+- ret = lan78xx_reset(dev);
+- if (ret < 0)
+- goto done;
+-
+ phy_start(net->phydev);
+
+ netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+--
+2.17.0
+
+From ddbd11509f01c388b968872aeabf630654275b0a Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Mon, 9 Apr 2018 14:31:54 +0100
+Subject: [PATCH 5/5] net: lan78xx: Request s/w csum check on VLAN tagged
+ packets.
+
+There appears to be some issue in the LAN78xx where the checksum
+computed on a VLAN tagged packet is incorrect, or at least not
+in the form that the kernel is after. This is most easily shown
+by pinging a device via a VLAN tagged interface and it will dump
+out the error message and stack trace from netdev_rx_csum_fault.
+It has also been seen with standard TCP and UDP packets.
+
+Until this is fully understood, request that the network stack
+computes the checksum on packets signalled as having a VLAN tag
+applied.
+
+See https://github.com/raspberrypi/linux/issues/2458
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/net/usb/lan78xx.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 293ed1847932..44cabda17bb6 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2937,8 +2937,12 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
+ struct sk_buff *skb,
+ u32 rx_cmd_a, u32 rx_cmd_b)
+ {
++ /* Checksum offload appears to be flawed if used with VLANs.
++ * Elect for sw checksum check instead.
++ */
+ if (!(dev->net->features & NETIF_F_RXCSUM) ||
+- unlikely(rx_cmd_a & RX_CMD_A_ICSM_)) {
++ unlikely(rx_cmd_a & RX_CMD_A_ICSM_) ||
++ (rx_cmd_a & RX_CMD_A_FVTG_)) {
+ skb->ip_summed = CHECKSUM_NONE;
+ } else {
+ skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT_));
+--
+2.17.0
+
diff --git a/kernel.spec b/kernel.spec
index 2cc38fd9b..2569967db 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -605,6 +605,9 @@ Patch311: bcm2835-hwrng-Handle-deferred-clock-properly.patch
Patch312: bcm283x-clk-audio-fixes.patch
+# https://marc.info/?l=linux-kernel&m=152328880417846&w=2
+Patch313: arm64-thunderx-crypto-zip-fixes.patch
+
# Enabling Patches for the RPi3+
Patch320: bcm2837-rpi-initial-support-for-the-3.patch
Patch321: bcm2837-gpio-expander.patch
@@ -1879,6 +1882,10 @@ fi
#
#
%changelog
+* Mon Apr 9 2018 Peter Robinson <pbrobinson@fedoraproject.org>
+- More fixes for Raspberry Pi 3+ lan78xx ethernet interface
+- Fixes for Cavium ThunderX ZIP driver stability
+
* Mon Apr 09 2018 Jeremy Cline <jeremy@jcline.org> - 4.16.1-200
- Linux v4.16.1