diff options
author | Peter Robinson <pbrobinson@gmail.com> | 2018-04-09 18:30:51 +0100 |
---|---|---|
committer | Jeremy Cline <jeremy@jcline.org> | 2018-04-09 14:25:21 -0400 |
commit | 33a8762bdc67af3d65da9821a42c8ae7fb684db5 (patch) | |
tree | 5bc2b15541cb242126c69f431a1e344d31af9913 | |
parent | 197f0bb94153dba8a7aa9d74202607a72d2c57ad (diff) | |
download | kernel-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.patch | 403 | ||||
-rw-r--r-- | bcm2837-lan78xx-fixes.patch | 355 | ||||
-rw-r--r-- | kernel.spec | 7 |
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 |