diff --git a/patches.drivers/fm10k-Fix-configuration-for-macvlan-offload.patch b/patches.drivers/fm10k-Fix-configuration-for-macvlan-offload.patch new file mode 100644 index 0000000..4688603 --- /dev/null +++ b/patches.drivers/fm10k-Fix-configuration-for-macvlan-offload.patch @@ -0,0 +1,85 @@ +From: Alexander Duyck +Date: Wed, 24 Jan 2018 13:39:44 -0800 +Subject: fm10k: Fix configuration for macvlan offload +Patch-mainline: v4.16-rc1 +Git-commit: 85062f856e40c06c8a9c16a70895cec71b967cc4 +References: bsc#1101813 FATE#325148 + +The fm10k driver didn't work correctly when macvlan offload was enabled. +Specifically what would occur is that we would see no unicast packets being +received. This was traced down to us not correctly configuring the default +VLAN ID for the port and defaulting to 0. + +To correct this we either use the default ID provided by the switch or +simply use 1. With that we are able to pass and receive traffic without any +issues. + +In addition we were not repopulating the filter table following a reset. To +correct that I have added a bit of code to fm10k_restore_rx_state that will +repopulate the Rx filter configuration for the macvlan interfaces. + +Signed-off-by: Alexander Duyck +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 25 +++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1182,9 +1182,10 @@ static void fm10k_set_rx_mode(struct net + + void fm10k_restore_rx_state(struct fm10k_intfc *interface) + { ++ struct fm10k_l2_accel *l2_accel = interface->l2_accel; + struct net_device *netdev = interface->netdev; + struct fm10k_hw *hw = &interface->hw; +- int xcast_mode; ++ int xcast_mode, i; + u16 vid, glort; + + /* record glort for this interface */ +@@ -1234,6 +1235,24 @@ void fm10k_restore_rx_state(struct fm10k + __dev_uc_sync(netdev, fm10k_uc_sync, fm10k_uc_unsync); + __dev_mc_sync(netdev, fm10k_mc_sync, fm10k_mc_unsync); + ++ /* synchronize macvlan addresses */ ++ if (l2_accel) { ++ for (i = 0; i < l2_accel->size; i++) { ++ struct net_device *sdev = l2_accel->macvlan[i]; ++ ++ if (!sdev) ++ continue; ++ ++ glort = l2_accel->dglort + 1 + i; ++ ++ hw->mac.ops.update_xcast_mode(hw, glort, ++ FM10K_XCAST_MODE_MULTI); ++ fm10k_queue_mac_request(interface, glort, ++ sdev->dev_addr, ++ hw->mac.default_vid, true); ++ } ++ } ++ + fm10k_mbx_unlock(interface); + + /* record updated xcast mode state */ +@@ -1490,7 +1509,7 @@ static void *fm10k_dfwd_add_station(stru + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_MULTI); + fm10k_queue_mac_request(interface, glort, sdev->dev_addr, +- 0, true); ++ hw->mac.default_vid, true); + } + + fm10k_mbx_unlock(interface); +@@ -1530,7 +1549,7 @@ static void fm10k_dfwd_del_station(struc + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_NONE); + fm10k_queue_mac_request(interface, glort, sdev->dev_addr, +- 0, false); ++ hw->mac.default_vid, false); + } + + fm10k_mbx_unlock(interface); diff --git a/patches.drivers/fm10k-Fix-misuse-of-net_ratelimit.patch b/patches.drivers/fm10k-Fix-misuse-of-net_ratelimit.patch new file mode 100644 index 0000000..1634a40 --- /dev/null +++ b/patches.drivers/fm10k-Fix-misuse-of-net_ratelimit.patch @@ -0,0 +1,35 @@ +From: Joe Perches +Date: Fri, 11 Aug 2017 09:17:15 -0700 +Subject: fm10k: Fix misuse of net_ratelimit() +Patch-mainline: v4.15-rc1 +Git-commit: c0ad8ef3df091ef179d78dccb810024612dcfa44 +References: bsc#1101813 FATE#325148 + +Correct the backward logic using !net_ratelimit() + +Miscellanea: + +o Add a blank line before the error return label + +Signed-off-by: Joe Perches +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c +@@ -806,9 +806,10 @@ static int fm10k_tso(struct fm10k_ring * + tx_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + + return 1; ++ + err_vxlan: + tx_ring->netdev->features &= ~NETIF_F_GSO_UDP_TUNNEL; +- if (!net_ratelimit()) ++ if (net_ratelimit()) + netdev_err(tx_ring->netdev, + "TSO requested for unsupported tunnel, disabling offload\n"); + return -1; diff --git a/patches.drivers/fm10k-Use-seq_putc-in-fm10k_dbg_desc_break.patch b/patches.drivers/fm10k-Use-seq_putc-in-fm10k_dbg_desc_break.patch new file mode 100644 index 0000000..7df95db --- /dev/null +++ b/patches.drivers/fm10k-Use-seq_putc-in-fm10k_dbg_desc_break.patch @@ -0,0 +1,34 @@ +From: Markus Elfring +Date: Mon, 8 May 2017 18:18:09 +0200 +Subject: fm10k: Use seq_putc() in fm10k_dbg_desc_break() +Patch-mainline: v4.15-rc1 +Git-commit: 95f49d4bdee34dd0f68446bb260ab537f62ed9b3 +References: bsc#1101813 FATE#325148 + +Two single characters should be put into a sequence. +Thus use the corresponding function "seq_putc". + +This issue was detected by using the Coccinelle software. + +Signed-off-by: Markus Elfring +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c +@@ -52,9 +52,9 @@ static void fm10k_dbg_desc_seq_stop(stru + static void fm10k_dbg_desc_break(struct seq_file *s, int i) + { + while (i--) +- seq_puts(s, "-"); ++ seq_putc(s, '-'); + +- seq_puts(s, "\n"); ++ seq_putc(s, '\n'); + } + + static int fm10k_dbg_tx_desc_seq_show(struct seq_file *s, void *v) diff --git a/patches.drivers/fm10k-add-missing-fall-through-comment.patch b/patches.drivers/fm10k-add-missing-fall-through-comment.patch new file mode 100644 index 0000000..4132155 --- /dev/null +++ b/patches.drivers/fm10k-add-missing-fall-through-comment.patch @@ -0,0 +1,33 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:07 -0700 +Subject: fm10k: add missing fall through comment +Patch-mainline: v4.15-rc1 +Git-commit: 523a0b558db4ca205522976077911e5efe235781 +References: bsc#1101813 FATE#325148 + +Newer versions of GCC starting with 7 now additionally warn when a case +statement may fall through without an explicit comment mentioning it. +Add such a comment to silence the warning, as this is expected. + +Unfortunately the comment must come directly before the next case +statement, so we put it outside the #ifdef. Otherwise, the compiler +cannot properly detect it and thus the warning is displayed regardless. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c +@@ -876,6 +876,7 @@ static void fm10k_tx_csum(struct fm10k_r + case IPPROTO_GRE: + if (skb->encapsulation) + break; ++ /* fall through */ + default: + if (unlikely(net_ratelimit())) { + dev_warn(tx_ring->dev, diff --git a/patches.drivers/fm10k-avoid-divide-by-zero-in-rare-cases-when-device.patch b/patches.drivers/fm10k-avoid-divide-by-zero-in-rare-cases-when-device.patch new file mode 100644 index 0000000..99cc72a --- /dev/null +++ b/patches.drivers/fm10k-avoid-divide-by-zero-in-rare-cases-when-device.patch @@ -0,0 +1,48 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:11 -0700 +Subject: fm10k: avoid divide by zero in rare cases when device is resetting +Patch-mainline: v4.15-rc1 +Git-commit: dd5eede2b711350f684e8510300cb3762a821ae6 +References: bsc#1101813 FATE#325148 + +It is possible that under rare circumstances the device is undergoing +a reset, such as when a PFLR occurs, and the device may be transmitting +simultaneously. In this case, we might attempt to divide by zero when +finding the proper r_idx. Instead, lets read the num_tx_queues once, +and make sure it's non-zero. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -643,9 +643,13 @@ int fm10k_close(struct net_device *netde + static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev) + { + struct fm10k_intfc *interface = netdev_priv(dev); ++ int num_tx_queues = READ_ONCE(interface->num_tx_queues); + unsigned int r_idx = skb->queue_mapping; + int err; + ++ if (!num_tx_queues) ++ return NETDEV_TX_BUSY; ++ + if ((skb->protocol == htons(ETH_P_8021Q)) && + !skb_vlan_tag_present(skb)) { + /* FM10K only supports hardware tagging, any tags in frame +@@ -698,8 +702,8 @@ static netdev_tx_t fm10k_xmit_frame(stru + __skb_put(skb, pad_len); + } + +- if (r_idx >= interface->num_tx_queues) +- r_idx %= interface->num_tx_queues; ++ if (r_idx >= num_tx_queues) ++ r_idx %= num_tx_queues; + + err = fm10k_xmit_frame_ring(skb, interface->tx_ring[r_idx]); + diff --git a/patches.drivers/fm10k-avoid-needless-delay-when-loading-driver.patch b/patches.drivers/fm10k-avoid-needless-delay-when-loading-driver.patch new file mode 100644 index 0000000..6a24617 --- /dev/null +++ b/patches.drivers/fm10k-avoid-needless-delay-when-loading-driver.patch @@ -0,0 +1,48 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:08 -0700 +Subject: fm10k: avoid needless delay when loading driver +Patch-mainline: v4.15-rc1 +Git-commit: 8bac58be1700dab3cac8cb53ed0651da40777024 +References: bsc#1101813 FATE#325148 + +When we load the driver, we set the last_reset to be in the future, +which delays the initial driver reset. Additionally, the service task +isn't scheduled to run automatically until the timer runs out. This +causes a needless delay of the first reset to begin talking to the +switch manager. + +We can avoid this by simply not setting last_reset and immediately +scheduling the service task while in probe. This allows the device to +wake up faster, and avoids this delay. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -1800,9 +1800,6 @@ static int fm10k_sw_init(struct fm10k_in + netdev->vlan_features |= NETIF_F_HIGHDMA; + } + +- /* delay any future reset requests */ +- interface->last_reset = jiffies + (10 * HZ); +- + /* reset and initialize the hardware so it is in a known state */ + err = hw->mac.ops.reset_hw(hw); + if (err) { +@@ -2079,8 +2076,9 @@ static int fm10k_probe(struct pci_dev *p + /* enable SR-IOV after registering netdev to enforce PF/VF ordering */ + fm10k_iov_configure(pdev, 0); + +- /* clear the service task disable bit to allow service task to start */ ++ /* clear the service task disable bit and kick off service task */ + clear_bit(__FM10K_SERVICE_DISABLE, interface->state); ++ fm10k_service_event_schedule(interface); + + return 0; + diff --git a/patches.drivers/fm10k-avoid-possible-truncation-of-q_vector-name.patch b/patches.drivers/fm10k-avoid-possible-truncation-of-q_vector-name.patch new file mode 100644 index 0000000..a26d19c --- /dev/null +++ b/patches.drivers/fm10k-avoid-possible-truncation-of-q_vector-name.patch @@ -0,0 +1,59 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:06 -0700 +Subject: fm10k: avoid possible truncation of q_vector->name +Patch-mainline: v4.15-rc1 +Git-commit: b94dd008c401fc73a8d843e3219356255f40c1ed +References: bsc#1101813 FATE#325148 + +New versions of GCC since version 7 began warning about possible +truncation of calls to snprintf. We can fix this and avoid false +positives. First, we should pass the full buffer size to snprintf, +because it guarantees a NULL character as part of its passed length, so +passing len-1 is simply wasting a byte of possible storage. + +Second, if we make the ri and ti variables unsigned, the compiler is +able to correctly reason that the value never gets larger than 256, so +it doesn't need to warn about the full space required to print a signed +integer. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -1544,7 +1544,7 @@ int fm10k_qv_request_irq(struct fm10k_in + struct net_device *dev = interface->netdev; + struct fm10k_hw *hw = &interface->hw; + struct msix_entry *entry; +- int ri = 0, ti = 0; ++ unsigned int ri = 0, ti = 0; + int vector, err; + + entry = &interface->msix_entries[NON_Q_VECTORS(hw)]; +@@ -1554,15 +1554,15 @@ int fm10k_qv_request_irq(struct fm10k_in + + /* name the vector */ + if (q_vector->tx.count && q_vector->rx.count) { +- snprintf(q_vector->name, sizeof(q_vector->name) - 1, +- "%s-TxRx-%d", dev->name, ri++); ++ snprintf(q_vector->name, sizeof(q_vector->name), ++ "%s-TxRx-%u", dev->name, ri++); + ti++; + } else if (q_vector->rx.count) { +- snprintf(q_vector->name, sizeof(q_vector->name) - 1, +- "%s-rx-%d", dev->name, ri++); ++ snprintf(q_vector->name, sizeof(q_vector->name), ++ "%s-rx-%u", dev->name, ri++); + } else if (q_vector->tx.count) { +- snprintf(q_vector->name, sizeof(q_vector->name) - 1, +- "%s-tx-%d", dev->name, ti++); ++ snprintf(q_vector->name, sizeof(q_vector->name), ++ "%s-tx-%u", dev->name, ti++); + } else { + /* skip this unused q_vector */ + continue; diff --git a/patches.drivers/fm10k-bump-version-number-e9d328d3.patch b/patches.drivers/fm10k-bump-version-number-e9d328d3.patch new file mode 100644 index 0000000..49f3642 --- /dev/null +++ b/patches.drivers/fm10k-bump-version-number-e9d328d3.patch @@ -0,0 +1,36 @@ +From: Jacob Keller +Date: Thu, 18 Jan 2018 09:18:57 -0800 +Subject: fm10k: bump version number +Patch-mainline: v4.17-rc1 +Git-commit: e9d328d3b753d6f9c75653107fc0689a8e681b16 +References: bsc#1101813 FATE#325148 + +We're aligned with latest version released on SourceForge, so update the +version number to match. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c +@@ -28,13 +28,13 @@ + + #include "fm10k.h" + +-#define DRV_VERSION "0.22.1-k" ++#define DRV_VERSION "0.23.4-k" + #define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver" + const char fm10k_driver_version[] = DRV_VERSION; + char fm10k_driver_name[] = "fm10k"; + static const char fm10k_driver_string[] = DRV_SUMMARY; + static const char fm10k_copyright[] = +- "Copyright(c) 2013 - 2017 Intel Corporation."; ++ "Copyright(c) 2013 - 2018 Intel Corporation."; + + MODULE_AUTHOR("Intel Corporation, "); + MODULE_DESCRIPTION(DRV_SUMMARY); diff --git a/patches.drivers/fm10k-bump-version-number.patch b/patches.drivers/fm10k-bump-version-number.patch new file mode 100644 index 0000000..2105a4c --- /dev/null +++ b/patches.drivers/fm10k-bump-version-number.patch @@ -0,0 +1,26 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:19 -0700 +Subject: fm10k: bump version number +Patch-mainline: v4.15-rc1 +Git-commit: ef57ab791c81b3a83c75a312b15b42f7440bb425 +References: bsc#1101813 FATE#325148 + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c +@@ -28,7 +28,7 @@ + + #include "fm10k.h" + +-#define DRV_VERSION "0.21.7-k" ++#define DRV_VERSION "0.22.1-k" + #define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver" + const char fm10k_driver_version[] = DRV_VERSION; + char fm10k_driver_name[] = "fm10k"; diff --git a/patches.drivers/fm10k-clarify-action-when-updating-the-VLAN-table.patch b/patches.drivers/fm10k-clarify-action-when-updating-the-VLAN-table.patch new file mode 100644 index 0000000..219c85c --- /dev/null +++ b/patches.drivers/fm10k-clarify-action-when-updating-the-VLAN-table.patch @@ -0,0 +1,36 @@ +From: Ngai-Mint Kwan +Date: Wed, 24 Jan 2018 14:23:27 -0800 +Subject: fm10k: clarify action when updating the VLAN table +Patch-mainline: v4.16-rc1 +Git-commit: e0752a68d8de2a6fcb2909d86cab6b23896896de +References: bsc#1101813 FATE#325148 + +Clarify the comment for when entering promiscuous mode that we update +the VLAN table. Add a comment distinguishing the case where we're +exiting promiscuous mode and need to clear the entire VLAN table. + +Signed-off-by: Ngai-Mint Kwan +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1165,10 +1165,12 @@ static void fm10k_set_rx_mode(struct net + + /* update xcast mode first, but only if it changed */ + if (interface->xcast_mode != xcast_mode) { +- /* update VLAN table */ ++ /* update VLAN table when entering promiscuous mode */ + if (xcast_mode == FM10K_XCAST_MODE_PROMISC) + fm10k_queue_vlan_request(interface, FM10K_VLAN_ALL, + 0, true); ++ ++ /* clear VLAN table when exiting promiscuous mode */ + if (interface->xcast_mode == FM10K_XCAST_MODE_PROMISC) + fm10k_clear_unused_vlans(interface); + diff --git a/patches.drivers/fm10k-cleanup-unnecessary-parenthesis-in-fm10k_iov.c.patch b/patches.drivers/fm10k-cleanup-unnecessary-parenthesis-in-fm10k_iov.c.patch new file mode 100644 index 0000000..91c00ab --- /dev/null +++ b/patches.drivers/fm10k-cleanup-unnecessary-parenthesis-in-fm10k_iov.c.patch @@ -0,0 +1,37 @@ +From: Jacob Keller +Date: Wed, 24 Jan 2018 14:17:15 -0800 +Subject: fm10k: cleanup unnecessary parenthesis in fm10k_iov.c +Patch-mainline: v4.16-rc1 +Git-commit: c8eeacb3b02c217150a20a1bea9aef3a6929b205 +References: bsc#1101813 FATE#325148 + +This fixes a few warnings found by checkpatch.pl --strict + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +@@ -353,7 +353,7 @@ int fm10k_iov_resume(struct pci_dev *pde + struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; + + /* allocate all but the last GLORT to the VFs */ +- if (i == ((~hw->mac.dglort_map) >> FM10K_DGLORTMAP_MASK_SHIFT)) ++ if (i == (~hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT)) + break; + + /* assign GLORT to VF, and restrict it to multicast */ +@@ -511,7 +511,7 @@ int fm10k_iov_configure(struct pci_dev * + return err; + + /* allocate VFs if not already allocated */ +- if (num_vfs && (num_vfs != current_vfs)) { ++ if (num_vfs && num_vfs != current_vfs) { + /* Disable completer abort error reporting as + * the VFs can trigger this any time they read a queue + * that they don't own. diff --git a/patches.drivers/fm10k-correct-typo-in-fm10k_pf.c.patch b/patches.drivers/fm10k-correct-typo-in-fm10k_pf.c.patch new file mode 100644 index 0000000..4716a42 --- /dev/null +++ b/patches.drivers/fm10k-correct-typo-in-fm10k_pf.c.patch @@ -0,0 +1,26 @@ +From: Ngai-Mint Kwan +Date: Wed, 24 Jan 2018 14:22:18 -0800 +Subject: fm10k: correct typo in fm10k_pf.c +Patch-mainline: v4.16-rc1 +Git-commit: 6ee98686d1fa6e6e3621802a4cd3ff31bb26dda8 +References: bsc#1101813 FATE#325148 + +Signed-off-by: Ngai-Mint Kwan +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +@@ -866,7 +866,7 @@ static s32 fm10k_iov_assign_default_mac_ + /* Determine correct default VLAN ID. The FM10K_VLAN_OVERRIDE bit is + * used here to indicate to the VF that it will not have privilege to + * write VLAN_TABLE. All policy is enforced on the PF but this allows +- * the VF to correctly report errors to userspace rqeuests. ++ * the VF to correctly report errors to userspace requests. + */ + if (vf_info->pf_vid) + vf_vid = vf_info->pf_vid | FM10K_VLAN_OVERRIDE; diff --git a/patches.drivers/fm10k-don-t-assume-VLAN-1-is-enabled.patch b/patches.drivers/fm10k-don-t-assume-VLAN-1-is-enabled.patch new file mode 100644 index 0000000..689bfed --- /dev/null +++ b/patches.drivers/fm10k-don-t-assume-VLAN-1-is-enabled.patch @@ -0,0 +1,78 @@ +From: Jacob Keller +Date: Wed, 24 Jan 2018 14:20:29 -0800 +Subject: fm10k: don't assume VLAN 1 is enabled +Patch-mainline: v4.16-rc1 +Git-commit: 74d2950c8055a631e196349dd1345ff6deb11c73 +References: bsc#1101813 FATE#325148 + +Since commit 856dfd69e84f ("fm10k: Fix multicast mode synch issues", +2016-03-03) we've incorrectly assumed that VLAN 1 is enabled when the +default VID is not set. + +This occurs because we check the default_vid and if it's zero, start +several loops over the active_vlans bitmask at 1, instead of checking to +ensure that that bit is active. + +This happened because of commit d9ff3ee8efe9 ("fm10k: Add support for +VLAN 0 w/o default VLAN", 2014-08-07) which mistakenly assumed that we +should send requests for MAC and VLAN filters with VLAN 0 when the +default_vid isn't set. + +However, the switch generally considers this an invalid configuration, +so the only time we'd have a default_vid of 0 is when the switch is +down. + +Instead, lets just not request any filters for the default_vid if it's +not yet been assigned. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1050,14 +1050,13 @@ static int __fm10k_uc_sync(struct net_de + const unsigned char *addr, bool sync) + { + struct fm10k_intfc *interface = netdev_priv(dev); +- struct fm10k_hw *hw = &interface->hw; + u16 vid, glort = interface->glort; + s32 err; + + if (!is_valid_ether_addr(addr)) + return -EADDRNOTAVAIL; + +- for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; ++ for (vid = fm10k_find_next_vlan(interface, 0); + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { + err = fm10k_queue_mac_request(interface, glort, +@@ -1116,14 +1115,13 @@ static int __fm10k_mc_sync(struct net_de + const unsigned char *addr, bool sync) + { + struct fm10k_intfc *interface = netdev_priv(dev); +- struct fm10k_hw *hw = &interface->hw; + u16 vid, glort = interface->glort; + s32 err; + + if (!is_multicast_ether_addr(addr)) + return -EADDRNOTAVAIL; + +- for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; ++ for (vid = fm10k_find_next_vlan(interface, 0); + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { + err = fm10k_queue_mac_request(interface, glort, +@@ -1223,7 +1221,7 @@ void fm10k_restore_rx_state(struct fm10k + xcast_mode == FM10K_XCAST_MODE_PROMISC); + + /* update table with current entries */ +- for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; ++ for (vid = fm10k_find_next_vlan(interface, 0); + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { + fm10k_queue_vlan_request(interface, vid, 0, true); diff --git a/patches.drivers/fm10k-don-t-loop-while-resetting-VFs-due-to-VFLR-eve.patch b/patches.drivers/fm10k-don-t-loop-while-resetting-VFs-due-to-VFLR-eve.patch new file mode 100644 index 0000000..21b19a3 --- /dev/null +++ b/patches.drivers/fm10k-don-t-loop-while-resetting-VFs-due-to-VFLR-eve.patch @@ -0,0 +1,77 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:10 -0700 +Subject: fm10k: don't loop while resetting VFs due to VFLR event +Patch-mainline: v4.15-rc1 +Git-commit: d876c1583bb1b7f7264880265b824e88b791aa5d +References: bsc#1101813 FATE#325148 + +We've always had a really weird looping construction for resetting VFs. +We read the VFLRE register and reset the VF if the corresponding bit is +set, which makes sense. However we loop continuously until we no longer +have any bits left unset. At first this makes sense, as a sort of "keep +trying until we succeed" concept. + +Unfortunately this causes a problem if we happen to surprise remove +while this code is executing, because in this case we'll always read all +1s for the VFLRE register. This results in a hard lockup on the CPU +because the loop will never terminate. + +Because our own reset function will clear the VFLR event register +always, (except when we've lost PCIe link obviously) there is no real +reason to loop. In practice, we'll loop over once and find that no VFs +are pending anymore. + +Lets just check once. Since we're clear the notification when we reset +there's no benefit to the loop. Additionally, there shouldn't be a race +as future VLFRE events should trigger an interrupt. Additionally, we +didn't warn or do anything in the looped case anyways. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 32 ++++++++++++--------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +@@ -66,23 +66,21 @@ s32 fm10k_iov_event(struct fm10k_intfc * + goto read_unlock; + + /* read VFLRE to determine if any VFs have been reset */ +- do { +- vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(1)); +- vflre <<= 32; +- vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0)); +- +- i = iov_data->num_vfs; +- +- for (vflre <<= 64 - i; vflre && i--; vflre += vflre) { +- struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; +- +- if (vflre >= 0) +- continue; +- +- hw->iov.ops.reset_resources(hw, vf_info); +- vf_info->mbx.ops.connect(hw, &vf_info->mbx); +- } +- } while (i != iov_data->num_vfs); ++ vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(1)); ++ vflre <<= 32; ++ vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0)); ++ ++ i = iov_data->num_vfs; ++ ++ for (vflre <<= 64 - i; vflre && i--; vflre += vflre) { ++ struct fm10k_vf_info *vf_info = &iov_data->vf_info[i]; ++ ++ if (vflre >= 0) ++ continue; ++ ++ hw->iov.ops.reset_resources(hw, vf_info); ++ vf_info->mbx.ops.connect(hw, &vf_info->mbx); ++ } + + read_unlock: + rcu_read_unlock(); diff --git a/patches.drivers/fm10k-don-t-protect-fm10k_queue_mac_request-by-fm10k.patch b/patches.drivers/fm10k-don-t-protect-fm10k_queue_mac_request-by-fm10k.patch new file mode 100644 index 0000000..7501785 --- /dev/null +++ b/patches.drivers/fm10k-don-t-protect-fm10k_queue_mac_request-by-fm10k.patch @@ -0,0 +1,58 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:59 -0700 +Subject: fm10k: don't protect fm10k_queue_mac_request by fm10k_host_mbx_ready +Patch-mainline: v4.18-rc1 +Git-commit: 0a3e92de1be42b5dbed4b81f835740d3f58c5430 +References: bsc#1101813 FATE#325148 + +We don't actually need to check if the host mbx is ready when queuing +MAC requests, because these are not handled by a special queue which +queues up requests until the mailbox is capable of handling them. + +Pull these requests outside the fm10k_host_mbx_ready() check, as it is +not necessary. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1546,12 +1546,12 @@ static void *fm10k_dfwd_add_station(stru + + glort = l2_accel->dglort + 1 + i; + +- if (fm10k_host_mbx_ready(interface)) { ++ if (fm10k_host_mbx_ready(interface)) + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_MULTI); +- fm10k_queue_mac_request(interface, glort, sdev->dev_addr, +- hw->mac.default_vid, true); +- } ++ ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ hw->mac.default_vid, true); + + for (vid = fm10k_find_next_vlan(interface, 0); + vid < VLAN_N_VID; +@@ -1592,12 +1592,12 @@ static void fm10k_dfwd_del_station(struc + + glort = l2_accel->dglort + 1 + i; + +- if (fm10k_host_mbx_ready(interface)) { ++ if (fm10k_host_mbx_ready(interface)) + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_NONE); +- fm10k_queue_mac_request(interface, glort, sdev->dev_addr, +- hw->mac.default_vid, false); +- } ++ ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ hw->mac.default_vid, false); + + for (vid = fm10k_find_next_vlan(interface, 0); + vid < VLAN_N_VID; diff --git a/patches.drivers/fm10k-fix-failed-to-kill-vid-message-for-VF.patch b/patches.drivers/fm10k-fix-failed-to-kill-vid-message-for-VF.patch new file mode 100644 index 0000000..410be35 --- /dev/null +++ b/patches.drivers/fm10k-fix-failed-to-kill-vid-message-for-VF.patch @@ -0,0 +1,81 @@ +From: Ngai-Mint Kwan +Date: Wed, 24 Jan 2018 14:18:22 -0800 +Subject: fm10k: fix "failed to kill vid" message for VF +Patch-mainline: v4.16-rc1 +Git-commit: cf315ea596ec26d7aa542a9ce354990875a920c0 +References: bsc#1101813 FATE#325148 + +When a VF is under PF VLAN assignment: + +ip link set vf <#> vlan + +This will remove all previous entries in the VLAN table including those +generated by VLAN interfaces created on the VF. The issue arises when +the VF is under PF VLAN assignment and one or more of these VLAN +interfaces of the VF are deleted. When deleting these VLAN interfaces, +the following message will be generated in "dmesg": + +failed to kill vid 0081/ for device + +This is due to the fact that "ndo_vlan_rx_kill_vid" exits with an error. +The handler for this ndo is "fm10k_update_vid". Any calls to this +function while under PF VLAN management will exit prematurely and, thus, +it will generate the failure message. + +Additionally, since "fm10k_update_vid" exits prematurely, none of the +VLAN update is performed. So, even though the actual VLAN interfaces of +the VF will be deleted, the active_vlans bitmask is not cleared. When +the VF is no longer under PF VLAN assignment, the driver mistakenly +restores the previous entries of the VLAN table based on an +unsynchronized list of active VLANs. + +The solution to this issue involves checking the VLAN update action type +before exiting "fm10k_update_vid". If the VLAN update action type is to +"add", this action will not be permitted while the VF is under PF VLAN +assignment and the VLAN update is abandoned like before. + +However, if the VLAN update action type is to "kill", then we need to +also clear the active_vlans bitmask. However, we don't need to actually +queue any messages to the PF, because the MAC and VLAN tables have +already been cleared, and the PF would silently ignore these requests +anyways. + +Signed-off-by: Ngai-Mint Kwan +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -934,8 +934,12 @@ static int fm10k_update_vid(struct net_d + if (vid >= VLAN_N_VID) + return -EINVAL; + +- /* Verify we have permission to add VLANs */ +- if (hw->mac.vlan_override) ++ /* Verify that we have permission to add VLANs. If this is a request ++ * to remove a VLAN, we still want to allow the user to remove the ++ * VLAN device. In that case, we need to clear the bit in the ++ * active_vlans bitmask. ++ */ ++ if (set && hw->mac.vlan_override) + return -EACCES; + + /* update active_vlans bitmask */ +@@ -954,6 +958,12 @@ static int fm10k_update_vid(struct net_d + rx_ring->vid &= ~FM10K_VLAN_CLEAR; + } + ++ /* If our VLAN has been overridden, there is no reason to send VLAN ++ * removal requests as they will be silently ignored. ++ */ ++ if (hw->mac.vlan_override) ++ return 0; ++ + /* Do not remove default VLAN ID related entries from VLAN and MAC + * tables + */ diff --git a/patches.drivers/fm10k-fix-function-doxygen-comments.patch b/patches.drivers/fm10k-fix-function-doxygen-comments.patch new file mode 100644 index 0000000..71b1bb8 --- /dev/null +++ b/patches.drivers/fm10k-fix-function-doxygen-comments.patch @@ -0,0 +1,204 @@ +From: Jacob Keller +Date: Tue, 16 Jan 2018 11:20:51 -0800 +Subject: fm10k: fix function doxygen comments +Patch-mainline: v4.17-rc1 +Git-commit: 363656eb5e574b6dab513a10b7166f08783fa3e3 +References: bsc#1101813 FATE#325148 + +Several function header comments had incorrect function parameter +definitions. Recent versions of the upstream kernel have started to warn +about these issues. Fix up the comments which do not match in order to +resolve these new warnings. + +While fixing these, update the copyright year also. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_common.c | 5 +++-- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 10 +++++----- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 11 ++++++----- + drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 4 ++-- + drivers/net/ethernet/intel/fm10k/fm10k_tlv.c | 7 ++++--- + 5 files changed, 20 insertions(+), 17 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_common.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_common.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2017 Intel Corporation. ++ * Copyright(c) 2013 - 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -262,6 +262,7 @@ s32 fm10k_stop_hw_generic(struct fm10k_h + * fm10k_read_hw_stats_32b - Reads value of 32-bit registers + * @hw: pointer to the hardware structure + * @addr: address of register containing a 32-bit value ++ * @stat: pointer to structure holding hw stat information + * + * Function reads the content of the register and returns the delta + * between the base and the current value. +@@ -281,6 +282,7 @@ u32 fm10k_read_hw_stats_32b(struct fm10k + * fm10k_read_hw_stats_48b - Reads value of 48-bit registers + * @hw: pointer to the hardware structure + * @addr: address of register containing the lower 32-bit value ++ * @stat: pointer to structure holding hw stat information + * + * Function reads the content of 2 registers, combined to represent a 48-bit + * statistical value. Extra processing is required to handle overflowing. +@@ -461,7 +463,6 @@ void fm10k_update_hw_stats_q(struct fm10 + + /** + * fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues +- * @hw: pointer to the hardware structure + * @q: pointer to the ring of hardware statistics queue + * @idx: index pointing to the start of the ring iteration + * @count: number of queues to iterate over +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2017 Intel Corporation. ++ * Copyright(c) 2013 - 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -486,7 +486,7 @@ static void fm10k_insert_tunnel_port(str + + /** + * fm10k_udp_tunnel_add +- * @netdev: network interface device structure ++ * @dev: network interface device structure + * @ti: Tunnel endpoint information + * + * This function is called when a new UDP tunnel port has been added. +@@ -518,8 +518,8 @@ static void fm10k_udp_tunnel_add(struct + + /** + * fm10k_udp_tunnel_del +- * @netdev: network interface device structure +- * @ti: Tunnel endpoint information ++ * @dev: network interface device structure ++ * @ti: Tunnel end point information + * + * This function is called when a new UDP tunnel port is deleted. The freed + * port will be removed from the list, then we reprogram the offloaded port +@@ -803,7 +803,7 @@ int fm10k_queue_vlan_request(struct fm10 + * @glort: the target glort for this update + * @addr: the address to update + * @vid: the vid to update +- * @sync: whether to add or remove ++ * @set: whether to add or remove + * + * This function queues up a MAC request for sending to the switch manager. + * A separate thread monitors the queue and sends updates to the switch +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2017 Intel Corporation. ++ * Copyright(c) 2013 - 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -211,7 +211,7 @@ static void fm10k_start_service_event(st + + /** + * fm10k_service_timer - Timer Call-back +- * @data: pointer to interface cast into an unsigned long ++ * @t: pointer to timer data + **/ + static void fm10k_service_timer(unsigned long data) + { +@@ -648,7 +648,7 @@ void fm10k_update_stats(struct fm10k_int + + /** + * fm10k_watchdog_flush_tx - flush queues on host not ready +- * @interface - pointer to the device interface structure ++ * @interface: pointer to the device interface structure + **/ + static void fm10k_watchdog_flush_tx(struct fm10k_intfc *interface) + { +@@ -678,7 +678,7 @@ static void fm10k_watchdog_flush_tx(stru + + /** + * fm10k_watchdog_subtask - check and bring link up +- * @interface - pointer to the device interface structure ++ * @interface: pointer to the device interface structure + **/ + static void fm10k_watchdog_subtask(struct fm10k_intfc *interface) + { +@@ -702,7 +702,7 @@ static void fm10k_watchdog_subtask(struc + + /** + * fm10k_check_hang_subtask - check for hung queues and dropped interrupts +- * @interface - pointer to the device interface structure ++ * @interface: pointer to the device interface structure + * + * This function serves two purposes. First it strobes the interrupt lines + * in order to make certain interrupts are occurring. Secondly it sets the +@@ -1994,6 +1994,7 @@ skip_tx_dma_drain: + /** + * fm10k_sw_init - Initialize general software structures + * @interface: host interface private structure to initialize ++ * @ent: PCI device ID entry + * + * fm10k_sw_init initializes the interface private data structure. + * Fields are initialized based on PCI device information and +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2017 Intel Corporation. ++ * Copyright(c) 2013 - 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -1180,7 +1180,7 @@ s32 fm10k_iov_msg_msix_pf(struct fm10k_h + + /** + * fm10k_iov_select_vid - Select correct default VLAN ID +- * @hw: Pointer to hardware structure ++ * @vf_info: pointer to VF information structure + * @vid: VLAN ID to correct + * + * Will report an error if the VLAN ID is out of range. For VID = 0, it will +--- a/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_tlv.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -120,6 +120,7 @@ static s32 fm10k_tlv_attr_get_null_strin + * @msg: Pointer to message block + * @attr_id: Attribute ID + * @mac_addr: MAC address to be stored ++ * @vlan: VLAN to be stored + * + * This function will reorder a MAC address to be CPU endian and store it + * in the attribute buffer. It will return success if provided with a +@@ -155,8 +156,8 @@ s32 fm10k_tlv_attr_put_mac_vlan(u32 *msg + /** + * fm10k_tlv_attr_get_mac_vlan - Get MAC/VLAN stored in attribute + * @attr: Pointer to attribute +- * @attr_id: Attribute ID + * @mac_addr: location of buffer to store MAC address ++ * @vlan: location of buffer to store VLAN + * + * This function pulls the MAC address back out of the attribute and will + * place it in the array pointed by by mac_addr. It will return success +@@ -549,7 +550,7 @@ static s32 fm10k_tlv_attr_parse(u32 *att + * @hw: Pointer to hardware structure + * @msg: Pointer to message + * @mbx: Pointer to mailbox information structure +- * @func: Function array containing list of message handling functions ++ * @data: Pointer to message handler data structure + * + * This function should be the first function called upon receiving a + * message. The handler will identify the message type and call the correct diff --git a/patches.drivers/fm10k-fix-incorrect-warning-for-function-prototype.patch b/patches.drivers/fm10k-fix-incorrect-warning-for-function-prototype.patch new file mode 100644 index 0000000..830b023 --- /dev/null +++ b/patches.drivers/fm10k-fix-incorrect-warning-for-function-prototype.patch @@ -0,0 +1,38 @@ +From: Jacob Keller +Date: Tue, 16 Jan 2018 11:20:52 -0800 +Subject: fm10k: fix incorrect warning for function prototype +Patch-mainline: v4.17-rc1 +Git-commit: 7d6707a9daa8f491923406d37e86b55384c6b9fb +References: bsc#1101813 FATE#325148 + +Recent kernels now complain about incorrect function prototype comments, +in order to ensure comments are accurate to the function. However, it +incorrectly associates the comment above the fm10k_pci_tbl[] as +a function header comment. Fix this by removing the extra "*" in the +comment. This normally indicates that the function is a doxygen style +function header comment. + +Once removed, the logic no longer kicks in and the following warning is +fixed: + + warning: cannot understand function prototype: 'const struct pci_device_id fm10k_pci_tbl[] = ' + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -29,7 +29,7 @@ static const struct fm10k_info *fm10k_in + [fm10k_device_vf] = &fm10k_vf_info, + }; + +-/** ++/* + * fm10k_pci_tbl - PCI Device ID Table + * + * Wildcard entries (PCI_ANY_ID) should come last diff --git a/patches.drivers/fm10k-fix-typos-on-fall-through-comments.patch b/patches.drivers/fm10k-fix-typos-on-fall-through-comments.patch new file mode 100644 index 0000000..3d9fd5e --- /dev/null +++ b/patches.drivers/fm10k-fix-typos-on-fall-through-comments.patch @@ -0,0 +1,72 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:05 -0700 +Subject: fm10k: fix typos on fall through comments +Patch-mainline: v4.15-rc1 +Git-commit: 375ce90eab7ee1c87eefa2cd312b0be9ac961082 +References: bsc#1101813 FATE#325148 + +Newer versions of GCC since version 7 now warn when a case statement may +fall through without an explicit comment. "Fallthough" does not count as +it is misspelled. Fix the typos for these comments to appease the new +warnings. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_mbx.c | 4 ++-- + drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 10 +++++----- + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -1586,7 +1586,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw + mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); + break; + } +- /* fallthough */ ++ /* fall through */ + default: + return FM10K_MBX_ERR_NO_MBX; + } +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -1334,19 +1334,19 @@ static u8 fm10k_iov_supported_xcast_mode + case FM10K_XCAST_MODE_PROMISC: + if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE) + return FM10K_XCAST_MODE_PROMISC; +- /* fallthough */ ++ /* fall through */ + case FM10K_XCAST_MODE_ALLMULTI: + if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE) + return FM10K_XCAST_MODE_ALLMULTI; +- /* fallthough */ ++ /* fall through */ + case FM10K_XCAST_MODE_MULTI: + if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE) + return FM10K_XCAST_MODE_MULTI; +- /* fallthough */ ++ /* fall through */ + case FM10K_XCAST_MODE_NONE: + if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE) + return FM10K_XCAST_MODE_NONE; +- /* fallthough */ ++ /* fall through */ + default: + break; + } diff --git a/patches.drivers/fm10k-introduce-a-message-queue-for-MAC-VLAN-message.patch b/patches.drivers/fm10k-introduce-a-message-queue-for-MAC-VLAN-message.patch new file mode 100644 index 0000000..07f4bd2 --- /dev/null +++ b/patches.drivers/fm10k-introduce-a-message-queue-for-MAC-VLAN-message.patch @@ -0,0 +1,724 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:17 -0700 +Subject: fm10k: introduce a message queue for MAC/VLAN messages +Patch-mainline: v4.15-rc1 +Git-commit: fc9173682dcf73cfe3324267424ef17e854bb444 +References: bsc#1101813 FATE#325148 + +Under some circumstances, when dealing with a large number of MAC +address or VLAN updates at once, the fm10k driver, particularly the VFs +can overload the mailbox with too many messages at once. + +This results in a mailbox timeout, which causes the driver to initiate +a reset. During the reset, we re-send all the same messages that +originally caused the timeout. This results in a cycle of resets each +triggering a future reset. + +To fix or avoid this, we introduce a workqueue item which monitors +a queue of MAC and VLAN requests. These requests are queued to the end +of the list, and we process as a FIFO periodically. + +Initially we only handle requests for the netdev, but we do handle +unicast MAC addresses, multicast MAC addresses, and update VLAN +requests. + +A future patch will add support to use this queue for handling MAC +update requests from the VF<->PF mailbox. + +The MAC/VLAN work item will keep checking to make sure that each request +does not overflow the mailbox and cause a timeout. If it might, then the +work item will reschedule itself a short time later. This avoids any +reset cycle, since we never send the message if the mailbox is not +ready. + +As an alternative, we tried increasing the mailbox message FIFO, but +this just delays the problem and results in needless memory waste on the +system. Our new message queue is dynamically allocated so only uses as +much memory as it needs. Additionally, it need not be contiguous like +the Tx and Rx FIFOs. + +Note that this patch chose to only create a queue for MAC and VLAN +messages, since these are the only messages sent in a large enough +volume to cause the reset loop. Other messages are very unlikely to +overflow the mailbox Tx FIFO so easily. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k.h | 39 ++++ + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 199 ++++++++++++++++++----- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 201 ++++++++++++++++++++++++ + 3 files changed, 397 insertions(+), 42 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k.h ++++ b/drivers/net/ethernet/intel/fm10k/fm10k.h +@@ -248,6 +248,29 @@ struct fm10k_udp_port { + __be16 port; + }; + ++enum fm10k_macvlan_request_type { ++ FM10K_UC_MAC_REQUEST, ++ FM10K_MC_MAC_REQUEST, ++ FM10K_VLAN_REQUEST ++}; ++ ++struct fm10k_macvlan_request { ++ enum fm10k_macvlan_request_type type; ++ struct list_head list; ++ union { ++ struct fm10k_mac_request { ++ u8 addr[ETH_ALEN]; ++ u16 glort; ++ u16 vid; ++ } mac; ++ struct fm10k_vlan_request { ++ u32 vid; ++ u8 vsi; ++ } vlan; ++ }; ++ bool set; ++}; ++ + /* one work queue for entire driver */ + extern struct workqueue_struct *fm10k_workqueue; + +@@ -276,6 +299,9 @@ enum fm10k_state_t { + __FM10K_SERVICE_SCHED, + __FM10K_SERVICE_REQUEST, + __FM10K_SERVICE_DISABLE, ++ __FM10K_MACVLAN_SCHED, ++ __FM10K_MACVLAN_REQUEST, ++ __FM10K_MACVLAN_DISABLE, + __FM10K_LINK_DOWN, + __FM10K_UPDATING_STATS, + /* This value must be last and determines the BITMAP size */ +@@ -368,6 +394,12 @@ struct fm10k_intfc { + struct list_head vxlan_port; + struct list_head geneve_port; + ++ /* MAC/VLAN update queue */ ++ struct list_head macvlan_requests; ++ struct delayed_work macvlan_task; ++ /* MAC/VLAN update queue lock */ ++ spinlock_t macvlan_lock; ++ + #ifdef CONFIG_DEBUG_FS + struct dentry *dbg_intfc; + #endif /* CONFIG_DEBUG_FS */ +@@ -487,6 +519,7 @@ void fm10k_up(struct fm10k_intfc *interf + void fm10k_down(struct fm10k_intfc *interface); + void fm10k_update_stats(struct fm10k_intfc *interface); + void fm10k_service_event_schedule(struct fm10k_intfc *interface); ++void fm10k_macvlan_schedule(struct fm10k_intfc *interface); + void fm10k_update_rx_drop_en(struct fm10k_intfc *interface); + #ifdef CONFIG_NET_POLL_CONTROLLER + void fm10k_netpoll(struct net_device *netdev); +@@ -507,6 +540,12 @@ void fm10k_reset_rx_state(struct fm10k_i + int fm10k_setup_tc(struct net_device *dev, u8 tc); + int fm10k_open(struct net_device *netdev); + int fm10k_close(struct net_device *netdev); ++int fm10k_queue_vlan_request(struct fm10k_intfc *interface, u32 vid, ++ u8 vsi, bool set); ++int fm10k_queue_mac_request(struct fm10k_intfc *interface, u16 glort, ++ const unsigned char *addr, u16 vid, bool set); ++void fm10k_clear_macvlan_queue(struct fm10k_intfc *interface, ++ u16 glort, bool vlans); + + /* Ethtool */ + void fm10k_set_ethtool_ops(struct net_device *dev); +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -758,11 +758,132 @@ static bool fm10k_host_mbx_ready(struct + return (hw->mac.type == fm10k_mac_vf || interface->host_ready); + } + ++/** ++ * fm10k_queue_vlan_request - Queue a VLAN update request ++ * @interface: the fm10k interface structure ++ * @vid: the VLAN vid ++ * @vsi: VSI index number ++ * @set: whether to set or clear ++ * ++ * This function queues up a VLAN update. For VFs, this must be sent to the ++ * managing PF over the mailbox. For PFs, we'll use the same handling so that ++ * it's similar to the VF. This avoids storming the PF<->VF mailbox with too ++ * many VLAN updates during reset. ++ */ ++int fm10k_queue_vlan_request(struct fm10k_intfc *interface, ++ u32 vid, u8 vsi, bool set) ++{ ++ struct fm10k_macvlan_request *request; ++ unsigned long flags; ++ ++ /* This must be atomic since we may be called while the netdev ++ * addr_list_lock is held ++ */ ++ request = kzalloc(sizeof(*request), GFP_ATOMIC); ++ if (!request) ++ return -ENOMEM; ++ ++ request->type = FM10K_VLAN_REQUEST; ++ request->vlan.vid = vid; ++ request->vlan.vsi = vsi; ++ request->set = set; ++ ++ spin_lock_irqsave(&interface->macvlan_lock, flags); ++ list_add_tail(&request->list, &interface->macvlan_requests); ++ spin_unlock_irqrestore(&interface->macvlan_lock, flags); ++ ++ fm10k_macvlan_schedule(interface); ++ ++ return 0; ++} ++ ++/** ++ * fm10k_queue_mac_request - Queue a MAC update request ++ * @interface: the fm10k interface structure ++ * @glort: the target glort for this update ++ * @addr: the address to update ++ * @vid: the vid to update ++ * @sync: whether to add or remove ++ * ++ * This function queues up a MAC request for sending to the switch manager. ++ * A separate thread monitors the queue and sends updates to the switch ++ * manager. Return 0 on success, and negative error code on failure. ++ **/ ++int fm10k_queue_mac_request(struct fm10k_intfc *interface, u16 glort, ++ const unsigned char *addr, u16 vid, bool set) ++{ ++ struct fm10k_macvlan_request *request; ++ unsigned long flags; ++ ++ /* This must be atomic since we may be called while the netdev ++ * addr_list_lock is held ++ */ ++ request = kzalloc(sizeof(*request), GFP_ATOMIC); ++ if (!request) ++ return -ENOMEM; ++ ++ if (is_multicast_ether_addr(addr)) ++ request->type = FM10K_MC_MAC_REQUEST; ++ else ++ request->type = FM10K_UC_MAC_REQUEST; ++ ++ ether_addr_copy(request->mac.addr, addr); ++ request->mac.glort = glort; ++ request->mac.vid = vid; ++ request->set = set; ++ ++ spin_lock_irqsave(&interface->macvlan_lock, flags); ++ list_add_tail(&request->list, &interface->macvlan_requests); ++ spin_unlock_irqrestore(&interface->macvlan_lock, flags); ++ ++ fm10k_macvlan_schedule(interface); ++ ++ return 0; ++} ++ ++/** ++ * fm10k_clear_macvlan_queue - Cancel pending updates for a given glort ++ * @interface: the fm10k interface structure ++ * @glort: the target glort to clear ++ * @vlans: true to clear VLAN messages, false to ignore them ++ * ++ * Cancel any outstanding MAC/VLAN requests for a given glort. This is ++ * expected to be called when a logical port goes down. ++ **/ ++void fm10k_clear_macvlan_queue(struct fm10k_intfc *interface, ++ u16 glort, bool vlans) ++ ++{ ++ struct fm10k_macvlan_request *r, *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&interface->macvlan_lock, flags); ++ ++ /* Free any outstanding MAC/VLAN requests for this interface */ ++ list_for_each_entry_safe(r, tmp, &interface->macvlan_requests, list) { ++ switch (r->type) { ++ case FM10K_MC_MAC_REQUEST: ++ case FM10K_UC_MAC_REQUEST: ++ /* Don't free requests for other interfaces */ ++ if (r->mac.glort != glort) ++ break; ++ /* fall through */ ++ case FM10K_VLAN_REQUEST: ++ if (vlans) { ++ list_del(&r->list); ++ kfree(r); ++ } ++ break; ++ } ++ } ++ ++ spin_unlock_irqrestore(&interface->macvlan_lock, flags); ++} ++ + static int fm10k_uc_vlan_unsync(struct net_device *netdev, + const unsigned char *uc_addr) + { + struct fm10k_intfc *interface = netdev_priv(netdev); +- struct fm10k_hw *hw = &interface->hw; + u16 glort = interface->glort; + u16 vid = interface->vid; + bool set = !!(vid / VLAN_N_VID); +@@ -771,10 +892,7 @@ static int fm10k_uc_vlan_unsync(struct n + /* drop any leading bits on the VLAN ID */ + vid &= VLAN_N_VID - 1; + +- if (fm10k_host_mbx_ready(interface)) +- err = hw->mac.ops.update_uc_addr(hw, glort, uc_addr, +- vid, set, 0); +- ++ err = fm10k_queue_mac_request(interface, glort, uc_addr, vid, set); + if (err) + return err; + +@@ -786,7 +904,6 @@ static int fm10k_mc_vlan_unsync(struct n + const unsigned char *mc_addr) + { + struct fm10k_intfc *interface = netdev_priv(netdev); +- struct fm10k_hw *hw = &interface->hw; + u16 glort = interface->glort; + u16 vid = interface->vid; + bool set = !!(vid / VLAN_N_VID); +@@ -795,9 +912,7 @@ static int fm10k_mc_vlan_unsync(struct n + /* drop any leading bits on the VLAN ID */ + vid &= VLAN_N_VID - 1; + +- if (fm10k_host_mbx_ready(interface)) +- err = hw->mac.ops.update_mc_addr(hw, glort, mc_addr, vid, set); +- ++ err = fm10k_queue_mac_request(interface, glort, mc_addr, vid, set); + if (err) + return err; + +@@ -855,18 +970,14 @@ static int fm10k_update_vid(struct net_d + + /* only need to update the VLAN if not in promiscuous mode */ + if (!(netdev->flags & IFF_PROMISC)) { +- err = hw->mac.ops.update_vlan(hw, vid, 0, set); ++ err = fm10k_queue_vlan_request(interface, vid, 0, set); + if (err) + goto err_out; + } + +- /* update our base MAC address if host's mailbox is ready */ +- if (fm10k_host_mbx_ready(interface)) +- err = hw->mac.ops.update_uc_addr(hw, interface->glort, +- hw->mac.addr, vid, set, 0); +- else +- err = -EHOSTDOWN; +- ++ /* Update our base MAC address */ ++ err = fm10k_queue_mac_request(interface, interface->glort, ++ hw->mac.addr, vid, set); + if (err) + goto err_out; + +@@ -910,7 +1021,6 @@ static u16 fm10k_find_next_vlan(struct f + + static void fm10k_clear_unused_vlans(struct fm10k_intfc *interface) + { +- struct fm10k_hw *hw = &interface->hw; + u32 vid, prev_vid; + + /* loop through and find any gaps in the table */ +@@ -922,7 +1032,7 @@ static void fm10k_clear_unused_vlans(str + + /* send request to clear multiple bits at a time */ + prev_vid += (vid - prev_vid - 1) << FM10K_VLAN_LENGTH_SHIFT; +- hw->mac.ops.update_vlan(hw, prev_vid, 0, false); ++ fm10k_queue_vlan_request(interface, prev_vid, 0, false); + } + } + +@@ -937,15 +1047,11 @@ static int __fm10k_uc_sync(struct net_de + if (!is_valid_ether_addr(addr)) + return -EADDRNOTAVAIL; + +- /* update table with current entries if host's mailbox is ready */ +- if (!fm10k_host_mbx_ready(interface)) +- return -EHOSTDOWN; +- + for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { +- err = hw->mac.ops.update_uc_addr(hw, glort, addr, +- vid, sync, 0); ++ err = fm10k_queue_mac_request(interface, glort, ++ addr, vid, sync); + if (err) + return err; + } +@@ -1002,15 +1108,18 @@ static int __fm10k_mc_sync(struct net_de + struct fm10k_intfc *interface = netdev_priv(dev); + struct fm10k_hw *hw = &interface->hw; + u16 vid, glort = interface->glort; ++ s32 err; + +- /* update table with current entries if host's mailbox is ready */ +- if (!fm10k_host_mbx_ready(interface)) +- return 0; ++ if (!is_multicast_ether_addr(addr)) ++ return -EADDRNOTAVAIL; + + for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { +- hw->mac.ops.update_mc_addr(hw, glort, addr, vid, sync); ++ err = fm10k_queue_mac_request(interface, glort, ++ addr, vid, sync); ++ if (err) ++ return err; + } + + return 0; +@@ -1050,7 +1159,8 @@ static void fm10k_set_rx_mode(struct net + if (interface->xcast_mode != xcast_mode) { + /* update VLAN table */ + if (xcast_mode == FM10K_XCAST_MODE_PROMISC) +- hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, true); ++ fm10k_queue_vlan_request(interface, FM10K_VLAN_ALL, ++ 0, true); + if (interface->xcast_mode == FM10K_XCAST_MODE_PROMISC) + fm10k_clear_unused_vlans(interface); + +@@ -1098,22 +1208,20 @@ void fm10k_restore_rx_state(struct fm10k + interface->glort_count, true); + + /* update VLAN table */ +- hw->mac.ops.update_vlan(hw, FM10K_VLAN_ALL, 0, +- xcast_mode == FM10K_XCAST_MODE_PROMISC); ++ fm10k_queue_vlan_request(interface, FM10K_VLAN_ALL, 0, ++ xcast_mode == FM10K_XCAST_MODE_PROMISC); + + /* Add filter for VLAN 0 */ +- hw->mac.ops.update_vlan(hw, 0, 0, true); ++ fm10k_queue_vlan_request(interface, 0, 0, true); + + /* update table with current entries */ + for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; + vid < VLAN_N_VID; + vid = fm10k_find_next_vlan(interface, vid)) { +- hw->mac.ops.update_vlan(hw, vid, 0, true); ++ fm10k_queue_vlan_request(interface, vid, 0, true); + +- /* Update unicast entries if host's mailbox is ready */ +- if (fm10k_host_mbx_ready(interface)) +- hw->mac.ops.update_uc_addr(hw, glort, hw->mac.addr, +- vid, true, 0); ++ fm10k_queue_mac_request(interface, glort, ++ hw->mac.addr, vid, true); + } + + /* update xcast mode before synchronizing addresses if host's mailbox +@@ -1140,6 +1248,13 @@ void fm10k_reset_rx_state(struct fm10k_i + struct net_device *netdev = interface->netdev; + struct fm10k_hw *hw = &interface->hw; + ++ /* Wait for MAC/VLAN work to finish */ ++ while (test_bit(__FM10K_MACVLAN_SCHED, interface->state)) ++ usleep_range(1000, 2000); ++ ++ /* Cancel pending MAC/VLAN requests */ ++ fm10k_clear_macvlan_queue(interface, interface->glort, true); ++ + fm10k_mbx_lock(interface); + + /* clear the logical port state on lower device if host's mailbox is +@@ -1374,8 +1489,8 @@ static void *fm10k_dfwd_add_station(stru + if (fm10k_host_mbx_ready(interface)) { + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_MULTI); +- hw->mac.ops.update_uc_addr(hw, glort, sdev->dev_addr, +- 0, true, 0); ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ 0, true); + } + + fm10k_mbx_unlock(interface); +@@ -1414,8 +1529,8 @@ static void fm10k_dfwd_del_station(struc + if (fm10k_host_mbx_ready(interface)) { + hw->mac.ops.update_xcast_mode(hw, glort, + FM10K_XCAST_MODE_NONE); +- hw->mac.ops.update_uc_addr(hw, glort, sdev->dev_addr, +- 0, false, 0); ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ 0, false); + } + + fm10k_mbx_unlock(interface); +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -91,6 +91,76 @@ static int fm10k_hw_ready(struct fm10k_i + return FM10K_REMOVED(hw->hw_addr) ? -ENODEV : 0; + } + ++/** ++ * fm10k_macvlan_schedule - Schedule MAC/VLAN queue task ++ * @interface: fm10k private interface structure ++ * ++ * Schedule the MAC/VLAN queue monitor task. If the MAC/VLAN task cannot be ++ * started immediately, request that it be restarted when possible. ++ */ ++void fm10k_macvlan_schedule(struct fm10k_intfc *interface) ++{ ++ /* Avoid processing the MAC/VLAN queue when the service task is ++ * disabled, or when we're resetting the device. ++ */ ++ if (!test_bit(__FM10K_MACVLAN_DISABLE, interface->state) && ++ !test_and_set_bit(__FM10K_MACVLAN_SCHED, interface->state)) { ++ clear_bit(__FM10K_MACVLAN_REQUEST, interface->state); ++ /* We delay the actual start of execution in order to allow ++ * multiple MAC/VLAN updates to accumulate before handling ++ * them, and to allow some time to let the mailbox drain ++ * between runs. ++ */ ++ queue_delayed_work(fm10k_workqueue, ++ &interface->macvlan_task, 10); ++ } else { ++ set_bit(__FM10K_MACVLAN_REQUEST, interface->state); ++ } ++} ++ ++/** ++ * fm10k_stop_macvlan_task - Stop the MAC/VLAN queue monitor ++ * @interface: fm10k private interface structure ++ * ++ * Wait until the MAC/VLAN queue task has stopped, and cancel any future ++ * requests. ++ */ ++static void fm10k_stop_macvlan_task(struct fm10k_intfc *interface) ++{ ++ /* Disable the MAC/VLAN work item */ ++ set_bit(__FM10K_MACVLAN_DISABLE, interface->state); ++ ++ /* Make sure we waited until any current invocations have stopped */ ++ cancel_delayed_work_sync(&interface->macvlan_task); ++ ++ /* We set the __FM10K_MACVLAN_SCHED bit when we schedule the task. ++ * However, it may not be unset of the MAC/VLAN task never actually ++ * got a chance to run. Since we've canceled the task here, and it ++ * cannot be rescheuled right now, we need to ensure the scheduled bit ++ * gets unset. ++ */ ++ clear_bit(__FM10K_MACVLAN_SCHED, interface->state); ++} ++ ++/** ++ * fm10k_resume_macvlan_task - Restart the MAC/VLAN queue monitor ++ * @interface: fm10k private interface structure ++ * ++ * Clear the __FM10K_MACVLAN_DISABLE bit and, if a request occurred, schedule ++ * the MAC/VLAN work monitor. ++ */ ++static void fm10k_resume_macvlan_task(struct fm10k_intfc *interface) ++{ ++ /* Re-enable the MAC/VLAN work item */ ++ clear_bit(__FM10K_MACVLAN_DISABLE, interface->state); ++ ++ /* We might have received a MAC/VLAN request while disabled. If so, ++ * kick off the queue now. ++ */ ++ if (test_bit(__FM10K_MACVLAN_REQUEST, interface->state)) ++ fm10k_macvlan_schedule(interface); ++} ++ + void fm10k_service_event_schedule(struct fm10k_intfc *interface) + { + if (!test_bit(__FM10K_SERVICE_DISABLE, interface->state) && +@@ -174,6 +244,12 @@ static bool fm10k_prepare_for_reset(stru + if (test_and_set_bit(__FM10K_RESETTING, interface->state)) + return false; + ++ /* As the MAC/VLAN task will be accessing registers it must not be ++ * running while we reset. Although the task will not be scheduled ++ * once we start resetting it may already be running ++ */ ++ fm10k_stop_macvlan_task(interface); ++ + rtnl_lock(); + + fm10k_iov_suspend(interface->pdev); +@@ -258,6 +334,8 @@ static int fm10k_handle_reset(struct fm1 + + rtnl_unlock(); + ++ fm10k_resume_macvlan_task(interface); ++ + clear_bit(__FM10K_RESETTING, interface->state); + + return err; +@@ -687,6 +765,112 @@ static void fm10k_service_task(struct wo + } + + /** ++ * fm10k_macvlan_task - send queued MAC/VLAN requests to switch manager ++ * @work: pointer to work_struct containing our data ++ * ++ * This work item handles sending MAC/VLAN updates to the switch manager. When ++ * the interface is up, it will attempt to queue mailbox messages to the ++ * switch manager requesting updates for MAC/VLAN pairs. If the Tx fifo of the ++ * mailbox is full, it will reschedule itself to try again in a short while. ++ * This ensures that the driver does not overload the switch mailbox with too ++ * many simultaneous requests, causing an unnecessary reset. ++ **/ ++static void fm10k_macvlan_task(struct work_struct *work) ++{ ++ struct fm10k_macvlan_request *item; ++ struct fm10k_intfc *interface; ++ struct delayed_work *dwork; ++ struct list_head *requests; ++ struct fm10k_hw *hw; ++ unsigned long flags; ++ ++ dwork = to_delayed_work(work); ++ interface = container_of(dwork, struct fm10k_intfc, macvlan_task); ++ hw = &interface->hw; ++ requests = &interface->macvlan_requests; ++ ++ do { ++ /* Pop the first item off the list */ ++ spin_lock_irqsave(&interface->macvlan_lock, flags); ++ item = list_first_entry_or_null(requests, ++ struct fm10k_macvlan_request, ++ list); ++ if (item) ++ list_del_init(&item->list); ++ ++ spin_unlock_irqrestore(&interface->macvlan_lock, flags); ++ ++ /* We have no more items to process */ ++ if (!item) ++ goto done; ++ ++ fm10k_mbx_lock(interface); ++ ++ /* Check that we have plenty of space to send the message. We ++ * want to ensure that the mailbox stays low enough to avoid a ++ * change in the host state, otherwise we may see spurious ++ * link up / link down notifications. ++ */ ++ if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU + 5)) { ++ hw->mbx.ops.process(hw, &hw->mbx); ++ set_bit(__FM10K_MACVLAN_REQUEST, interface->state); ++ fm10k_mbx_unlock(interface); ++ ++ /* Put the request back on the list */ ++ spin_lock_irqsave(&interface->macvlan_lock, flags); ++ list_add(&item->list, requests); ++ spin_unlock_irqrestore(&interface->macvlan_lock, flags); ++ break; ++ } ++ ++ switch (item->type) { ++ case FM10K_MC_MAC_REQUEST: ++ hw->mac.ops.update_mc_addr(hw, ++ item->mac.glort, ++ item->mac.addr, ++ item->mac.vid, ++ item->set); ++ break; ++ case FM10K_UC_MAC_REQUEST: ++ hw->mac.ops.update_uc_addr(hw, ++ item->mac.glort, ++ item->mac.addr, ++ item->mac.vid, ++ item->set, ++ 0); ++ break; ++ case FM10K_VLAN_REQUEST: ++ hw->mac.ops.update_vlan(hw, ++ item->vlan.vid, ++ item->vlan.vsi, ++ item->set); ++ break; ++ default: ++ break; ++ } ++ ++ fm10k_mbx_unlock(interface); ++ ++ /* Free the item now that we've sent the update */ ++ kfree(item); ++ } while (true); ++ ++done: ++ WARN_ON(!test_bit(__FM10K_MACVLAN_SCHED, interface->state)); ++ ++ /* flush memory to make sure state is correct */ ++ smp_mb__before_atomic(); ++ clear_bit(__FM10K_MACVLAN_SCHED, interface->state); ++ ++ /* If a MAC/VLAN request was scheduled since we started, we should ++ * re-schedule. However, there is no reason to re-schedule if there is ++ * no work to do. ++ */ ++ if (test_bit(__FM10K_MACVLAN_REQUEST, interface->state)) ++ fm10k_macvlan_schedule(interface); ++} ++ ++/** + * fm10k_configure_tx_ring - Configure Tx ring after Reset + * @interface: board private structure + * @ring: structure containing ring specific data +@@ -1918,11 +2102,15 @@ static int fm10k_sw_init(struct fm10k_in + INIT_LIST_HEAD(&interface->vxlan_port); + INIT_LIST_HEAD(&interface->geneve_port); + ++ /* Initialize the MAC/VLAN queue */ ++ INIT_LIST_HEAD(&interface->macvlan_requests); ++ + netdev_rss_key_fill(rss_key, sizeof(rss_key)); + memcpy(interface->rssrk, rss_key, sizeof(rss_key)); + + /* Initialize the mailbox lock */ + spin_lock_init(&interface->mbx_lock); ++ spin_lock_init(&interface->macvlan_lock); + + /* Start off interface as being down */ + set_bit(__FM10K_DOWN, interface->state); +@@ -2131,6 +2319,9 @@ static int fm10k_probe(struct pci_dev *p + (unsigned long)interface); + INIT_WORK(&interface->service_task, fm10k_service_task); + ++ /* Setup the MAC/VLAN queue */ ++ INIT_DELAYED_WORK(&interface->macvlan_task, fm10k_macvlan_task); ++ + /* kick off service timer now, even when interface is down */ + mod_timer(&interface->service_timer, (HZ * 2) + jiffies); + +@@ -2184,6 +2375,10 @@ static void fm10k_remove(struct pci_dev + del_timer_sync(&interface->service_timer); + + fm10k_stop_service_event(interface); ++ fm10k_stop_macvlan_task(interface); ++ ++ /* Remove all pending MAC/VLAN requests */ ++ fm10k_clear_macvlan_queue(interface, interface->glort, true); + + /* free netdev, this may bounce the interrupts due to setup_tc */ + if (netdev->reg_state == NETREG_REGISTERED) +@@ -2220,6 +2415,9 @@ static void fm10k_prepare_suspend(struct + * a surprise remove if the PCIe device is disabled while we're + * stopped. We stop the watchdog task until after we resume software + * activity. ++ * ++ * Note that the MAC/VLAN task will be stopped as part of preparing ++ * for reset so we don't need to handle it here. + */ + fm10k_stop_service_event(interface); + +@@ -2259,6 +2457,9 @@ static int fm10k_handle_resume(struct fm + /* restart the service task */ + fm10k_start_service_event(interface); + ++ /* Restart the MAC/VLAN request queue in-case of outstanding events */ ++ fm10k_macvlan_schedule(interface); ++ + return err; + } + diff --git a/patches.drivers/fm10k-mark-PM-functions-as-__maybe_unused.patch b/patches.drivers/fm10k-mark-PM-functions-as-__maybe_unused.patch new file mode 100644 index 0000000..c991194 --- /dev/null +++ b/patches.drivers/fm10k-mark-PM-functions-as-__maybe_unused.patch @@ -0,0 +1,76 @@ +From: Arnd Bergmann +Date: Wed, 17 Jan 2018 07:57:32 -0800 +Subject: fm10k: mark PM functions as __maybe_unused +Patch-mainline: v4.15-rc9 +Git-commit: b200bfd6112a87283e58bcfcc4cb57a5517ae82f +References: bsc#1101813 FATE#325148 + +A cleanup of the PM code left an incorrect #ifdef in place, leading +to a harmless build warning: + +drivers/net/ethernet/intel/fm10k/fm10k_pci.c:2502:12: error: 'fm10k_suspend' defined but not used [-Werror=unused-function] +drivers/net/ethernet/intel/fm10k/fm10k_pci.c:2475:12: error: 'fm10k_resume' defined but not used [-Werror=unused-function] + +It's easier to use __maybe_unused attributes here, since you +can't pick the wrong one. + +Fixes: 8249c47c6ba4 ("fm10k: use generic PM hooks instead of legacy PCIe power hooks") +Signed-off-by: Arnd Bergmann +Acked-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -2463,7 +2463,6 @@ static int fm10k_handle_resume(struct fm + return err; + } + +-#ifdef CONFIG_PM + /** + * fm10k_resume - Generic PM resume hook + * @dev: generic device structure +@@ -2472,7 +2471,7 @@ static int fm10k_handle_resume(struct fm + * suspend or hibernation. This function does not need to handle lower PCIe + * device state as the stack takes care of that for us. + **/ +-static int fm10k_resume(struct device *dev) ++static int __maybe_unused fm10k_resume(struct device *dev) + { + struct fm10k_intfc *interface = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = interface->netdev; +@@ -2499,7 +2498,7 @@ static int fm10k_resume(struct device *d + * system suspend or hibernation. This function does not need to handle lower + * PCIe device state as the stack takes care of that for us. + **/ +-static int fm10k_suspend(struct device *dev) ++static int __maybe_unused fm10k_suspend(struct device *dev) + { + struct fm10k_intfc *interface = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = interface->netdev; +@@ -2511,8 +2510,6 @@ static int fm10k_suspend(struct device * + return 0; + } + +-#endif /* CONFIG_PM */ +- + /** + * fm10k_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device +@@ -2643,11 +2640,9 @@ static struct pci_driver fm10k_driver = + .id_table = fm10k_pci_tbl, + .probe = fm10k_probe, + .remove = fm10k_remove, +-#ifdef CONFIG_PM + .driver = { + .pm = &fm10k_pm_ops, + }, +-#endif /* CONFIG_PM */ + .sriov_configure = fm10k_iov_configure, + .err_handler = &fm10k_err_handler + }; diff --git a/patches.drivers/fm10k-move-fm10k_prepare_for_reset-and-fm10k_handle_.patch b/patches.drivers/fm10k-move-fm10k_prepare_for_reset-and-fm10k_handle_.patch new file mode 100644 index 0000000..31f975d --- /dev/null +++ b/patches.drivers/fm10k-move-fm10k_prepare_for_reset-and-fm10k_handle_.patch @@ -0,0 +1,92 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:12 -0700 +Subject: fm10k: move fm10k_prepare_for_reset and fm10k_handle_reset +Patch-mainline: v4.15-rc1 +Git-commit: 65b0a469e9e6d025ce9cc46f6cc94d28abf5561c +References: bsc#1101813 FATE#325148 + +A future patch needs these functions defined earlier in the file. Move +them closer to above where they will be called. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 58 +++++++++++++-------------- + 1 file changed, 29 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -132,35 +132,6 @@ static void fm10k_service_timer(unsigned + fm10k_service_event_schedule(interface); + } + +-static void fm10k_detach_subtask(struct fm10k_intfc *interface) +-{ +- struct net_device *netdev = interface->netdev; +- u32 __iomem *hw_addr; +- u32 value; +- +- /* do nothing if device is still present or hw_addr is set */ +- if (netif_device_present(netdev) || interface->hw.hw_addr) +- return; +- +- /* check the real address space to see if we've recovered */ +- hw_addr = READ_ONCE(interface->uc_addr); +- value = readl(hw_addr); +- if (~value) { +- interface->hw.hw_addr = interface->uc_addr; +- netif_device_attach(netdev); +- set_bit(FM10K_FLAG_RESET_REQUESTED, interface->flags); +- netdev_warn(netdev, "PCIe link restored, device now attached\n"); +- return; +- } +- +- rtnl_lock(); +- +- if (netif_running(netdev)) +- dev_close(netdev); +- +- rtnl_unlock(); +-} +- + static void fm10k_prepare_for_reset(struct fm10k_intfc *interface) + { + struct net_device *netdev = interface->netdev; +@@ -270,6 +241,35 @@ reinit_err: + return err; + } + ++static void fm10k_detach_subtask(struct fm10k_intfc *interface) ++{ ++ struct net_device *netdev = interface->netdev; ++ u32 __iomem *hw_addr; ++ u32 value; ++ ++ /* do nothing if device is still present or hw_addr is set */ ++ if (netif_device_present(netdev) || interface->hw.hw_addr) ++ return; ++ ++ /* check the real address space to see if we've recovered */ ++ hw_addr = READ_ONCE(interface->uc_addr); ++ value = readl(hw_addr); ++ if (~value) { ++ interface->hw.hw_addr = interface->uc_addr; ++ netif_device_attach(netdev); ++ set_bit(FM10K_FLAG_RESET_REQUESTED, interface->flags); ++ netdev_warn(netdev, "PCIe link restored, device now attached\n"); ++ return; ++ } ++ ++ rtnl_lock(); ++ ++ if (netif_running(netdev)) ++ dev_close(netdev); ++ ++ rtnl_unlock(); ++} ++ + static void fm10k_reinit(struct fm10k_intfc *interface) + { + int err; diff --git a/patches.drivers/fm10k-prefer-s-and-__func__-for-diagnostic-prints.patch b/patches.drivers/fm10k-prefer-s-and-__func__-for-diagnostic-prints.patch new file mode 100644 index 0000000..da62fd4 --- /dev/null +++ b/patches.drivers/fm10k-prefer-s-and-__func__-for-diagnostic-prints.patch @@ -0,0 +1,67 @@ +From: Jacob Keller +Date: Fri, 11 Aug 2017 11:14:37 -0700 +Subject: fm10k: prefer %s and __func__ for diagnostic prints +Patch-mainline: v4.15-rc1 +Git-commit: 87be98927eb0bfa5484dfbe5ba2f6b7f91dd9187 +References: bsc#1101813 FATE#325148 + +Don't hard code the function names in the diagnostic output when these +reset related routines fail. Instead, use %s and __func__ so that future +refactors don't need to change the print outs. + +Additionally, while we are here, add missing function header comments +for the new reset_prepare and reset_done function handlers. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -2588,11 +2588,18 @@ static void fm10k_io_resume(struct pci_d + + if (err) + dev_warn(&pdev->dev, +- "fm10k_io_resume failed: %d\n", err); ++ "%s failed: %d\n", __func__, err); + else + netif_device_attach(netdev); + } + ++/** ++ * fm10k_io_reset_prepare - called when PCI function is about to be reset ++ * @pdev: Pointer to PCI device ++ * ++ * This callback is called when the PCI function is about to be reset, ++ * allowing the device driver to prepare for it. ++ */ + static void fm10k_io_reset_prepare(struct pci_dev *pdev) + { + /* warn incase we have any active VF devices */ +@@ -2602,6 +2609,13 @@ static void fm10k_io_reset_prepare(struc + fm10k_prepare_suspend(pci_get_drvdata(pdev)); + } + ++/** ++ * fm10k_io_reset_done - called when PCI function has finished resetting ++ * @pdev: Pointer to PCI device ++ * ++ * This callback is called just after the PCI function is reset, such as via ++ * /sys/class/net//device/reset or similar. ++ */ + static void fm10k_io_reset_done(struct pci_dev *pdev) + { + struct fm10k_intfc *interface = pci_get_drvdata(pdev); +@@ -2609,7 +2623,7 @@ static void fm10k_io_reset_done(struct p + + if (err) { + dev_warn(&pdev->dev, +- "fm10k_io_reset_notify failed: %d\n", err); ++ "%s failed: %d\n", __func__, err); + netif_device_detach(interface->netdev); + } + } diff --git a/patches.drivers/fm10k-prepare_for_reset-when-we-lose-PCIe-Link.patch b/patches.drivers/fm10k-prepare_for_reset-when-we-lose-PCIe-Link.patch new file mode 100644 index 0000000..c41e50d --- /dev/null +++ b/patches.drivers/fm10k-prepare_for_reset-when-we-lose-PCIe-Link.patch @@ -0,0 +1,256 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:14 -0700 +Subject: fm10k: prepare_for_reset() when we lose PCIe Link +Patch-mainline: v4.15-rc1 +Git-commit: 0b40f457488d966878eec413a91f27d9b21e6ce5 +References: bsc#1101813 FATE#325148 + +If we lose PCIe link, such as when an unannounced PFLR event occurs, or +when a device is surprise removed, we currently detach the device and +close the netdev. This unfortunately leaves a lot of things still +active, such as the msix_mbx_pf IRQ, and Tx/Rx resources. + +This can cause problems because the register reads will return +potentially invalid values which may result in unknown driver behavior. + +Begin the process of resetting using fm10k_prepare_for_reset(), much in +the same way as the suspend and resume cycle does. This will attempt to +shutdown as much as possible, in order to prevent possible issues. + +A naive implementation for this has issues, because there are now +multiple flows calling the reset logic and setting a reset bit. This +would cause problems, because the "re-attach" routine might call +fm10k_handle_reset() prior to the reset actually finishing. Instead, +we'll add state bits to indicate which flow actually initiated the +reset. + +For the general reset flow, we'll assume that if someone else is +resetting that we do not need to handle it at all, so it does not need +its own state bit. For the suspend case, we will simply issue a warning +indicating that we are attempting to recover from this case when +resuming. + +For the detached subtask, we'll simply refuse to re-attach until we've +actually initiated a reset as part of that flow. + +Finally, we'll stop attempting to manage the mailbox subtask when we're +detached, since there's nothing we can do if we don't have a PCIe +address. + +Overall this produces a much cleaner shutdown and recovery cycle for +a PCIe surprise remove event. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k.h | 2 + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 103 ++++++++++++++++++++------- + 2 files changed, 79 insertions(+), 26 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k.h ++++ b/drivers/net/ethernet/intel/fm10k/fm10k.h +@@ -270,6 +270,8 @@ enum fm10k_flags_t { + + enum fm10k_state_t { + __FM10K_RESETTING, ++ __FM10K_RESET_DETACHED, ++ __FM10K_RESET_SUSPENDED, + __FM10K_DOWN, + __FM10K_SERVICE_SCHED, + __FM10K_SERVICE_REQUEST, +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -153,7 +153,15 @@ static void fm10k_service_timer(unsigned + fm10k_service_event_schedule(interface); + } + +-static void fm10k_prepare_for_reset(struct fm10k_intfc *interface) ++/** ++ * fm10k_prepare_for_reset - Prepare the driver and device for a pending reset ++ * @interface: fm10k private data structure ++ * ++ * This function prepares for a device reset by shutting as much down as we ++ * can. It does nothing and returns false if __FM10K_RESETTING was already set ++ * prior to calling this function. It returns true if it actually did work. ++ */ ++static bool fm10k_prepare_for_reset(struct fm10k_intfc *interface) + { + struct net_device *netdev = interface->netdev; + +@@ -162,8 +170,9 @@ static void fm10k_prepare_for_reset(stru + /* put off any impending NetWatchDogTimeout */ + netif_trans_update(netdev); + +- while (test_and_set_bit(__FM10K_RESETTING, interface->state)) +- usleep_range(1000, 2000); ++ /* Nothing to do if a reset is already in progress */ ++ if (test_and_set_bit(__FM10K_RESETTING, interface->state)) ++ return false; + + rtnl_lock(); + +@@ -181,6 +190,8 @@ static void fm10k_prepare_for_reset(stru + interface->last_reset = jiffies + (10 * HZ); + + rtnl_unlock(); ++ ++ return true; + } + + static int fm10k_handle_reset(struct fm10k_intfc *interface) +@@ -189,6 +200,8 @@ static int fm10k_handle_reset(struct fm1 + struct fm10k_hw *hw = &interface->hw; + int err; + ++ WARN_ON(!test_bit(__FM10K_RESETTING, interface->state)); ++ + rtnl_lock(); + + pci_set_master(interface->pdev); +@@ -267,51 +280,75 @@ static void fm10k_detach_subtask(struct + struct net_device *netdev = interface->netdev; + u32 __iomem *hw_addr; + u32 value; ++ int err; + +- /* do nothing if device is still present or hw_addr is set */ ++ /* do nothing if netdev is still present or hw_addr is set */ + if (netif_device_present(netdev) || interface->hw.hw_addr) + return; + ++ /* We've lost the PCIe register space, and can no longer access the ++ * device. Shut everything except the detach subtask down and prepare ++ * to reset the device in case we recover. If we actually prepare for ++ * reset, indicate that we're detached. ++ */ ++ if (fm10k_prepare_for_reset(interface)) ++ set_bit(__FM10K_RESET_DETACHED, interface->state); ++ + /* check the real address space to see if we've recovered */ + hw_addr = READ_ONCE(interface->uc_addr); + value = readl(hw_addr); + if (~value) { ++ /* Make sure the reset was initiated because we detached, ++ * otherwise we might race with a different reset flow. ++ */ ++ if (!test_and_clear_bit(__FM10K_RESET_DETACHED, ++ interface->state)) ++ return; ++ ++ /* Restore the hardware address */ + interface->hw.hw_addr = interface->uc_addr; ++ ++ /* PCIe link has been restored, and the device is active ++ * again. Restore everything and reset the device. ++ */ ++ err = fm10k_handle_reset(interface); ++ if (err) { ++ netdev_err(netdev, "Unable to reset device: %d\n", err); ++ interface->hw.hw_addr = NULL; ++ return; ++ } ++ ++ /* Re-attach the netdev */ + netif_device_attach(netdev); +- set_bit(FM10K_FLAG_RESET_REQUESTED, interface->flags); + netdev_warn(netdev, "PCIe link restored, device now attached\n"); + return; + } +- +- rtnl_lock(); +- +- if (netif_running(netdev)) +- dev_close(netdev); +- +- rtnl_unlock(); + } + +-static void fm10k_reinit(struct fm10k_intfc *interface) ++static void fm10k_reset_subtask(struct fm10k_intfc *interface) + { + int err; + +- fm10k_prepare_for_reset(interface); +- +- err = fm10k_handle_reset(interface); +- if (err) +- dev_err(&interface->pdev->dev, +- "fm10k_handle_reset failed: %d\n", err); +-} +- +-static void fm10k_reset_subtask(struct fm10k_intfc *interface) +-{ + if (!test_and_clear_bit(FM10K_FLAG_RESET_REQUESTED, + interface->flags)) + return; + ++ /* If another thread has already prepared to reset the device, we ++ * should not attempt to handle a reset here, since we'd race with ++ * that thread. This may happen if we suspend the device or if the ++ * PCIe link is lost. In this case, we'll just ignore the RESET ++ * request, as it will (eventually) be taken care of when the thread ++ * which actually started the reset is finished. ++ */ ++ if (!fm10k_prepare_for_reset(interface)) ++ return; ++ + netdev_err(interface->netdev, "Reset interface\n"); + +- fm10k_reinit(interface); ++ err = fm10k_handle_reset(interface); ++ if (err) ++ dev_err(&interface->pdev->dev, ++ "fm10k_handle_reset failed: %d\n", err); + } + + /** +@@ -381,6 +418,10 @@ static void fm10k_watchdog_update_host_s + **/ + static void fm10k_mbx_subtask(struct fm10k_intfc *interface) + { ++ /* If we're resetting, bail out */ ++ if (test_bit(__FM10K_RESETTING, interface->state)) ++ return; ++ + /* process upstream mailbox and update device state */ + fm10k_watchdog_update_host_state(interface); + +@@ -630,9 +671,11 @@ static void fm10k_service_task(struct wo + + interface = container_of(work, struct fm10k_intfc, service_task); + ++ /* Check whether we're detached first */ ++ fm10k_detach_subtask(interface); ++ + /* tasks run even when interface is down */ + fm10k_mbx_subtask(interface); +- fm10k_detach_subtask(interface); + fm10k_reset_subtask(interface); + + /* tasks only run when interface is up */ +@@ -2177,7 +2220,8 @@ static void fm10k_prepare_suspend(struct + */ + fm10k_stop_service_event(interface); + +- fm10k_prepare_for_reset(interface); ++ if (fm10k_prepare_for_reset(interface)) ++ set_bit(__FM10K_RESET_SUSPENDED, interface->state); + } + + static int fm10k_handle_resume(struct fm10k_intfc *interface) +@@ -2185,6 +2229,13 @@ static int fm10k_handle_resume(struct fm + struct fm10k_hw *hw = &interface->hw; + int err; + ++ /* Even if we didn't properly prepare for reset in ++ * fm10k_prepare_suspend, we'll attempt to resume anyways. ++ */ ++ if (!test_and_clear_bit(__FM10K_RESET_SUSPENDED, interface->state)) ++ dev_warn(&interface->pdev->dev, ++ "Device was shut down as part of suspend... Attempting to recover\n"); ++ + /* reset statistics starting values */ + hw->mac.ops.rebind_hw_stats(hw, &interface->stats); + diff --git a/patches.drivers/fm10k-prevent-race-condition-of-__FM10K_SERVICE_SCHE.patch b/patches.drivers/fm10k-prevent-race-condition-of-__FM10K_SERVICE_SCHE.patch new file mode 100644 index 0000000..ea7b0d9 --- /dev/null +++ b/patches.drivers/fm10k-prevent-race-condition-of-__FM10K_SERVICE_SCHE.patch @@ -0,0 +1,97 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:13 -0700 +Subject: fm10k: prevent race condition of __FM10K_SERVICE_SCHED +Patch-mainline: v4.15-rc1 +Git-commit: 04914390f5a197da1e042f585e1263ad8ebff632 +References: bsc#1101813 FATE#325148 + +Although very unlikely, it is possible that cancel_work_sync() may stop +the service_task before it actually started. In this case, the +__FM10K_SERVICE_SCHED bit will never be cleared. This results in the +service task being unable to reschedule in the future. Add a helper +function which sets the service disable bit, waits for the service task +to stop and clears the schedule bit, thus avoiding the race condition. +We know the schedule bit is safe to clear because the cancel_work_sync() +guarantees the service task is not running. + +Add a helper function also to restart the service task, for symmetry. +This is not strictly needed but helps the mental model of how to stop +and start the service task. + +This race could only happen in fm10k_suspend/fm10k_resume as this is the +only place where the service task is actually restarted. Thus, +suspend/resume testing would be ideal. However, note that the chance of +this happening is very slim as the service event is scheduled for +immediate execution, and you would have to trigger a suspend at almost +the exact same time as the service task was scheduled. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 32 +++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -118,6 +118,27 @@ static void fm10k_service_event_complete + fm10k_service_event_schedule(interface); + } + ++static void fm10k_stop_service_event(struct fm10k_intfc *interface) ++{ ++ set_bit(__FM10K_SERVICE_DISABLE, interface->state); ++ cancel_work_sync(&interface->service_task); ++ ++ /* It's possible that cancel_work_sync stopped the service task from ++ * running before it could actually start. In this case the ++ * __FM10K_SERVICE_SCHED bit will never be cleared. Since we know that ++ * the service task cannot be running at this point, we need to clear ++ * the scheduled bit, as otherwise the service task may never be ++ * restarted. ++ */ ++ clear_bit(__FM10K_SERVICE_SCHED, interface->state); ++} ++ ++static void fm10k_start_service_event(struct fm10k_intfc *interface) ++{ ++ clear_bit(__FM10K_SERVICE_DISABLE, interface->state); ++ fm10k_service_event_schedule(interface); ++} ++ + /** + * fm10k_service_timer - Timer Call-back + * @data: pointer to interface cast into an unsigned long +@@ -2116,8 +2137,7 @@ static void fm10k_remove(struct pci_dev + + del_timer_sync(&interface->service_timer); + +- set_bit(__FM10K_SERVICE_DISABLE, interface->state); +- cancel_work_sync(&interface->service_task); ++ fm10k_stop_service_event(interface); + + /* free netdev, this may bounce the interrupts due to setup_tc */ + if (netdev->reg_state == NETREG_REGISTERED) +@@ -2155,8 +2175,7 @@ static void fm10k_prepare_suspend(struct + * stopped. We stop the watchdog task until after we resume software + * activity. + */ +- set_bit(__FM10K_SERVICE_DISABLE, interface->state); +- cancel_work_sync(&interface->service_task); ++ fm10k_stop_service_event(interface); + + fm10k_prepare_for_reset(interface); + } +@@ -2183,9 +2202,8 @@ static int fm10k_handle_resume(struct fm + interface->link_down_event = jiffies + (HZ); + set_bit(__FM10K_LINK_DOWN, interface->state); + +- /* clear the service task disable bit to allow service task to start */ +- clear_bit(__FM10K_SERVICE_DISABLE, interface->state); +- fm10k_service_event_schedule(interface); ++ /* restart the service task */ ++ fm10k_start_service_event(interface); + + return err; + } diff --git a/patches.drivers/fm10k-reduce-duplicate-fm10k_stat-macro-code.patch b/patches.drivers/fm10k-reduce-duplicate-fm10k_stat-macro-code.patch new file mode 100644 index 0000000..14c8560 --- /dev/null +++ b/patches.drivers/fm10k-reduce-duplicate-fm10k_stat-macro-code.patch @@ -0,0 +1,73 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:55 -0700 +Subject: fm10k: reduce duplicate fm10k_stat macro code +Patch-mainline: v4.18-rc1 +Git-commit: 2ead8ae110c6b62fe4d1d1bf04855e86582b96f5 +References: bsc#1101813 FATE#325148 + +Share some of the code for setting up fm10k_stat macros by implementing +an FM10K_STAT_FIELDS macro which we can use when setting up the type +specific macros. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 29 +++++++++++------------ + 1 file changed, 15 insertions(+), 14 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +@@ -28,12 +28,17 @@ struct fm10k_stats { + int stat_offset; + }; + +-#define FM10K_NETDEV_STAT(_net_stat) { \ +- .stat_string = #_net_stat, \ +- .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ +- .stat_offset = offsetof(struct net_device_stats, _net_stat) \ ++#define FM10K_STAT_FIELDS(_type, _name, _stat) { \ ++ .stat_string = _name, \ ++ .sizeof_stat = FIELD_SIZEOF(_type, _stat), \ ++ .stat_offset = offsetof(_type, _stat) \ + } + ++/* netdevice statistics */ ++#define FM10K_NETDEV_STAT(_net_stat) \ ++ FM10K_STAT_FIELDS(struct net_device_stats, __stringify(_net_stat), \ ++ _net_stat) ++ + static const struct fm10k_stats fm10k_gstrings_net_stats[] = { + FM10K_NETDEV_STAT(tx_packets), + FM10K_NETDEV_STAT(tx_bytes), +@@ -51,11 +56,9 @@ static const struct fm10k_stats fm10k_gs + + #define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats) + +-#define FM10K_STAT(_name, _stat) { \ +- .stat_string = _name, \ +- .sizeof_stat = FIELD_SIZEOF(struct fm10k_intfc, _stat), \ +- .stat_offset = offsetof(struct fm10k_intfc, _stat) \ +-} ++/* General interface statistics */ ++#define FM10K_STAT(_name, _stat) \ ++ FM10K_STAT_FIELDS(struct fm10k_intfc, _name, _stat) + + static const struct fm10k_stats fm10k_gstrings_global_stats[] = { + FM10K_STAT("tx_restart_queue", restart_queue), +@@ -92,11 +95,9 @@ static const struct fm10k_stats fm10k_gs + FM10K_STAT("nodesc_drop", stats.nodesc_drop.count), + }; + +-#define FM10K_MBX_STAT(_name, _stat) { \ +- .stat_string = _name, \ +- .sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \ +- .stat_offset = offsetof(struct fm10k_mbx_info, _stat) \ +-} ++/* mailbox statistics */ ++#define FM10K_MBX_STAT(_name, _stat) \ ++ FM10K_STAT_FIELDS(struct fm10k_mbx_info, _name, _stat) + + static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = { + FM10K_MBX_STAT("mbx_tx_busy", tx_busy), diff --git a/patches.drivers/fm10k-reschedule-service-event-if-we-stall-the-PF-SM.patch b/patches.drivers/fm10k-reschedule-service-event-if-we-stall-the-PF-SM.patch new file mode 100644 index 0000000..7724d3d --- /dev/null +++ b/patches.drivers/fm10k-reschedule-service-event-if-we-stall-the-PF-SM.patch @@ -0,0 +1,42 @@ +From: Jacob Keller +Date: Wed, 8 Mar 2017 15:55:43 -0800 +Subject: fm10k: reschedule service event if we stall the PF<->SM mailbox +Patch-mainline: v4.15-rc1 +Git-commit: b52b7f7059f2df8eb3258a25bc69e12dc21ebcd7 +References: bsc#1101813 FATE#325148 + +When we are handling PF<->VF mailbox messages, it is possible that the +VF will send us so many messages that the PF<->SM FIFO will fill up. In +this case, we stop the loop and wait until the service event is +rescheduled. + +Normally this should happen due to an interrupt. But it is possible that +we don't get another interrupt for a while and it isn't until the +service timer actually reschedules us. Instead, simply reschedule +immediately which will cause the service event to be run again as soon +as we exit. + +This ensures that we promptly handle all of the PF<->VF messages with +minimal delay, while still giving time for the SM mailbox to drain. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +@@ -143,6 +143,10 @@ process_mbx: + if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) { + /* keep track of how many times this occurs */ + interface->hw_sm_mbx_full++; ++ ++ /* make sure we try again momentarily */ ++ fm10k_service_event_schedule(interface); ++ + break; + } + diff --git a/patches.drivers/fm10k-setup-VLANs-for-l2-accelerated-macvlan-interfa.patch b/patches.drivers/fm10k-setup-VLANs-for-l2-accelerated-macvlan-interfa.patch new file mode 100644 index 0000000..0b610a8 --- /dev/null +++ b/patches.drivers/fm10k-setup-VLANs-for-l2-accelerated-macvlan-interfa.patch @@ -0,0 +1,141 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:54 -0700 +Subject: fm10k: setup VLANs for l2 accelerated macvlan interfaces +Patch-mainline: v4.18-rc1 +Git-commit: 3c6a67dd6697e25bfec0b85a008ec4a3c482d993 +References: bsc#1101813 FATE#325148 + +We have support for accelerating macvlan devices via the +.ndo_dfwd_add_station() netdev op. These accelerated macvlan MAC +addresses are stored in the l2_accel structure, separate from the +unicast or multicast address lists. + +If a VLAN is added on top of the macvlan device by the stack, traffic +will not properly flow to the macvlan. This occurs because we fail to +setup the VLANs for l2_accel MAC addresses. + +In the non-offloaded case the MAC address is added to the unicast +address list, and thus the normal setup for enabling VLANs works as +expected. + +We also need to add VLANs marked from .ndo_vlan_rx_add_vid() into the +l2_accel MAC addresses. Otherwise, VLAN traffic will not properly be +received by the VLAN devices attached to the offloaded macvlan devices. + +Fix this by adding necessary logic to setup VLANs not only for the +unicast and multicast addresses, but also the l2_accel list. We need +similar logic in dfwd_add_station, dfwd_del_station, fm10k_update_vid, +and fm10k_restore_rx_state. + +Signed-off-by: Jacob Keller +Reviewed-by: Alexander Duyck +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 50 +++++++++++++++++++++++- + 1 file changed, 48 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -923,7 +923,9 @@ static int fm10k_mc_vlan_unsync(struct n + static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set) + { + struct fm10k_intfc *interface = netdev_priv(netdev); ++ struct fm10k_l2_accel *l2_accel = interface->l2_accel; + struct fm10k_hw *hw = &interface->hw; ++ u16 glort; + s32 err; + int i; + +@@ -991,6 +993,22 @@ static int fm10k_update_vid(struct net_d + if (err) + goto err_out; + ++ /* Update L2 accelerated macvlan addresses */ ++ if (l2_accel) { ++ for (i = 0; i < l2_accel->size; i++) { ++ struct net_device *sdev = l2_accel->macvlan[i]; ++ ++ if (!sdev) ++ continue; ++ ++ glort = l2_accel->dglort + 1 + i; ++ ++ fm10k_queue_mac_request(interface, glort, ++ sdev->dev_addr, ++ vid, set); ++ } ++ } ++ + /* set VLAN ID prior to syncing/unsyncing the VLAN */ + interface->vid = vid + (set ? VLAN_N_VID : 0); + +@@ -1230,6 +1248,22 @@ void fm10k_restore_rx_state(struct fm10k + + fm10k_queue_mac_request(interface, glort, + hw->mac.addr, vid, true); ++ ++ /* synchronize macvlan addresses */ ++ if (l2_accel) { ++ for (i = 0; i < l2_accel->size; i++) { ++ struct net_device *sdev = l2_accel->macvlan[i]; ++ ++ if (!sdev) ++ continue; ++ ++ glort = l2_accel->dglort + 1 + i; ++ ++ fm10k_queue_mac_request(interface, glort, ++ sdev->dev_addr, ++ vid, true); ++ } ++ } + } + + /* update xcast mode before synchronizing addresses if host's mailbox +@@ -1446,7 +1480,7 @@ static void *fm10k_dfwd_add_station(stru + struct fm10k_dglort_cfg dglort = { 0 }; + struct fm10k_hw *hw = &interface->hw; + int size = 0, i; +- u16 glort; ++ u16 vid, glort; + + /* allocate l2 accel structure if it is not available */ + if (!l2_accel) { +@@ -1519,6 +1553,12 @@ static void *fm10k_dfwd_add_station(stru + hw->mac.default_vid, true); + } + ++ for (vid = fm10k_find_next_vlan(interface, 0); ++ vid < VLAN_N_VID; ++ vid = fm10k_find_next_vlan(interface, vid)) ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ vid, true); ++ + fm10k_mbx_unlock(interface); + + return sdev; +@@ -1531,8 +1571,8 @@ static void fm10k_dfwd_del_station(struc + struct fm10k_dglort_cfg dglort = { 0 }; + struct fm10k_hw *hw = &interface->hw; + struct net_device *sdev = priv; ++ u16 vid, glort; + int i; +- u16 glort; + + if (!l2_accel) + return; +@@ -1559,6 +1599,12 @@ static void fm10k_dfwd_del_station(struc + hw->mac.default_vid, false); + } + ++ for (vid = fm10k_find_next_vlan(interface, 0); ++ vid < VLAN_N_VID; ++ vid = fm10k_find_next_vlan(interface, vid)) ++ fm10k_queue_mac_request(interface, glort, sdev->dev_addr, ++ vid, false); ++ + fm10k_mbx_unlock(interface); + + /* record removal */ diff --git a/patches.drivers/fm10k-simplify-reading-PFVFLRE-register.patch b/patches.drivers/fm10k-simplify-reading-PFVFLRE-register.patch new file mode 100644 index 0000000..17ea6b6 --- /dev/null +++ b/patches.drivers/fm10k-simplify-reading-PFVFLRE-register.patch @@ -0,0 +1,40 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:09 -0700 +Subject: fm10k: simplify reading PFVFLRE register +Patch-mainline: v4.15-rc1 +Git-commit: 4abf01b43b62525e4f1a20dd1a2bc4a1967d8928 +References: bsc#1101813 FATE#325148 + +We're doing a really convoluted bitshift and read for the PFVFLRE +register. Just reading the PFVFLRE(1), shifting it by 32, then reading +PFVFLRE(0) should be sufficient. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -67,10 +67,8 @@ s32 fm10k_iov_event(struct fm10k_intfc * + + /* read VFLRE to determine if any VFs have been reset */ + do { +- vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(0)); ++ vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(1)); + vflre <<= 32; +- vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(1)); +- vflre = (vflre << 32) | (vflre >> 32); + vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0)); + + i = iov_data->num_vfs; diff --git a/patches.drivers/fm10k-stop-adding-VLAN-0-to-the-VLAN-table.patch b/patches.drivers/fm10k-stop-adding-VLAN-0-to-the-VLAN-table.patch new file mode 100644 index 0000000..1df1577 --- /dev/null +++ b/patches.drivers/fm10k-stop-adding-VLAN-0-to-the-VLAN-table.patch @@ -0,0 +1,48 @@ +From: Jacob Keller +Date: Wed, 24 Jan 2018 14:19:30 -0800 +Subject: fm10k: stop adding VLAN 0 to the VLAN table +Patch-mainline: v4.16-rc1 +Git-commit: 8c2c5039073849d5b6f9cedaea604ebab1a50dc8 +References: bsc#1101813 FATE#325148 + +Currently, when the driver loads, it sends a request to add VLAN 0 to the +VLAN table. For the PF, this is honored, and VLAN 0 is indeed set. For +the VF, this request is silently converted into a request for the +default VLAN as defined by either the switch vid or the PF vid. + +This results in the odd behavior that the VLAN table doesn't appear +consistent between the PF and the VF. + +Furthermore, setting a MAC filter with VLAN 0 is generally considered an +invalid configuration by the switch, and since commit 856dfd69e84f +("fm10k: Fix multicast mode synch issues", 2016-03-03) we've had code +which prevents us from ever sending such a request. + +Since there's not really a good reason to keep VLAN 0 in the VLAN table, +stop requesting it in fm10k_restore_rx_state(). + +This might seem to indicate that we would no longer properly configure +the MAC and VLAN tables for the default vid. However, due to the way +that fm10k_find_next_vlan() behaves, it will always return the +default_vid as enabled. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +@@ -1222,9 +1222,6 @@ void fm10k_restore_rx_state(struct fm10k + fm10k_queue_vlan_request(interface, FM10K_VLAN_ALL, 0, + xcast_mode == FM10K_XCAST_MODE_PROMISC); + +- /* Add filter for VLAN 0 */ +- fm10k_queue_vlan_request(interface, 0, 0, true); +- + /* update table with current entries */ + for (vid = hw->mac.default_vid ? fm10k_find_next_vlan(interface, 0) : 1; + vid < VLAN_N_VID; diff --git a/patches.drivers/fm10k-stop-spurious-link-down-messages-when-Tx-FIFO-.patch b/patches.drivers/fm10k-stop-spurious-link-down-messages-when-Tx-FIFO-.patch new file mode 100644 index 0000000..6b56768 --- /dev/null +++ b/patches.drivers/fm10k-stop-spurious-link-down-messages-when-Tx-FIFO-.patch @@ -0,0 +1,53 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:04 -0700 +Subject: fm10k: stop spurious link down messages when Tx FIFO is full +Patch-mainline: v4.15-rc1 +Git-commit: 5c66d1251d67714e9f6e6b0af18ca989109b876f +References: bsc#1101813 FATE#325148 + +In fm10k_get_host_state_generic, we check the mailbox tx_read() function +to ensure that the mailbox is still open. This function also checks to +make sure we have space to transmit another message. Unfortunately, if +we just recently sent a bunch of messages (such as enabling hundreds of +VLANs on a VF) this can result in a race where the watchdog task thinks +the link went down just because we haven't had time to process all these +messages yet. + +Instead, lets just check whether the mailbox is still open. This ensures +that we don't race with the Tx FIFO, and we only link down once the +mailbox is not open. + +This is safe, because if the FIFO fills up and we're unable to send +a message for too long, we'll end up triggering the timeout detection +which results in a reset. Additionally, since we still check to ensure +the mailbox state is OPEN, we'll transition to link down whenever the +mailbox closes as well. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_common.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_common.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_common.c +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -517,8 +517,8 @@ s32 fm10k_get_host_state_generic(struct + goto out; + } + +- /* verify Mailbox is still valid */ +- if (!mbx->ops.tx_ready(mbx, FM10K_VFMBX_MSG_MTU)) ++ /* verify Mailbox is still open */ ++ if (mbx->state != FM10K_STATE_OPEN) + goto out; + + /* interface cannot receive traffic without logical ports */ diff --git a/patches.drivers/fm10k-use-generic-PM-hooks-instead-of-legacy-PCIe-po.patch b/patches.drivers/fm10k-use-generic-PM-hooks-instead-of-legacy-PCIe-po.patch new file mode 100644 index 0000000..6a28668 --- /dev/null +++ b/patches.drivers/fm10k-use-generic-PM-hooks-instead-of-legacy-PCIe-po.patch @@ -0,0 +1,135 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:16 -0700 +Subject: fm10k: use generic PM hooks instead of legacy PCIe power hooks +Patch-mainline: v4.15-rc1 +Git-commit: 8249c47c6ba48cd3eba7c3ca7f8e733ee815c39b +References: bsc#1101813 FATE#325148 + +Replace the PCI specific legacy power management hooks with the new +generic power management hooks which work properly for both suspend and +hibernate. The new generic system is better and properly handles the +lower level PCIe power management rather than forcing the driver to +handle it. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 67 ++++++++------------------- + 1 file changed, 22 insertions(+), 45 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -2264,36 +2264,19 @@ static int fm10k_handle_resume(struct fm + + #ifdef CONFIG_PM + /** +- * fm10k_resume - Restore device to pre-sleep state +- * @pdev: PCI device information struct ++ * fm10k_resume - Generic PM resume hook ++ * @dev: generic device structure + * +- * fm10k_resume is called after the system has powered back up from a sleep +- * state and is ready to resume operation. This function is meant to restore +- * the device back to its pre-sleep state. ++ * Generic PM hook used when waking the device from a low power state after ++ * suspend or hibernation. This function does not need to handle lower PCIe ++ * device state as the stack takes care of that for us. + **/ +-static int fm10k_resume(struct pci_dev *pdev) ++static int fm10k_resume(struct device *dev) + { +- struct fm10k_intfc *interface = pci_get_drvdata(pdev); ++ struct fm10k_intfc *interface = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = interface->netdev; + struct fm10k_hw *hw = &interface->hw; +- u32 err; +- +- pci_set_power_state(pdev, PCI_D0); +- pci_restore_state(pdev); +- +- /* pci_restore_state clears dev->state_saved so call +- * pci_save_state to restore it. +- */ +- pci_save_state(pdev); +- +- err = pci_enable_device_mem(pdev); +- if (err) { +- dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); +- return err; +- } +- pci_set_master(pdev); +- +- pci_wake_from_d3(pdev, false); ++ int err; + + /* refresh hw_addr in case it was dropped */ + hw->hw_addr = interface->uc_addr; +@@ -2308,36 +2291,27 @@ static int fm10k_resume(struct pci_dev * + } + + /** +- * fm10k_suspend - Prepare the device for a system sleep state +- * @pdev: PCI device information struct ++ * fm10k_suspend - Generic PM suspend hook ++ * @dev: generic device structure + * +- * fm10k_suspend is meant to shutdown the device prior to the system entering +- * a sleep state. The fm10k hardware does not support wake on lan so the +- * driver simply needs to shut down the device so it is in a low power state. ++ * Generic PM hook used when setting the device into a low power state for ++ * system suspend or hibernation. This function does not need to handle lower ++ * PCIe device state as the stack takes care of that for us. + **/ +-static int fm10k_suspend(struct pci_dev *pdev, +- pm_message_t __always_unused state) ++static int fm10k_suspend(struct device *dev) + { +- struct fm10k_intfc *interface = pci_get_drvdata(pdev); ++ struct fm10k_intfc *interface = pci_get_drvdata(to_pci_dev(dev)); + struct net_device *netdev = interface->netdev; +- int err = 0; + + netif_device_detach(netdev); + + fm10k_prepare_suspend(interface); + +- err = pci_save_state(pdev); +- if (err) +- return err; +- +- pci_disable_device(pdev); +- pci_wake_from_d3(pdev, false); +- pci_set_power_state(pdev, PCI_D3hot); +- + return 0; + } + + #endif /* CONFIG_PM */ ++ + /** + * fm10k_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device +@@ -2447,15 +2421,18 @@ static const struct pci_error_handlers f + .reset_done = fm10k_io_reset_done, + }; + ++static SIMPLE_DEV_PM_OPS(fm10k_pm_ops, fm10k_suspend, fm10k_resume); ++ + static struct pci_driver fm10k_driver = { + .name = fm10k_driver_name, + .id_table = fm10k_pci_tbl, + .probe = fm10k_probe, + .remove = fm10k_remove, + #ifdef CONFIG_PM +- .suspend = fm10k_suspend, +- .resume = fm10k_resume, +-#endif ++ .driver = { ++ .pm = &fm10k_pm_ops, ++ }, ++#endif /* CONFIG_PM */ + .sriov_configure = fm10k_iov_configure, + .err_handler = &fm10k_err_handler + }; diff --git a/patches.drivers/fm10k-use-macro-to-avoid-passing-the-array-and-size-.patch b/patches.drivers/fm10k-use-macro-to-avoid-passing-the-array-and-size-.patch new file mode 100644 index 0000000..6b3f3dd --- /dev/null +++ b/patches.drivers/fm10k-use-macro-to-avoid-passing-the-array-and-size-.patch @@ -0,0 +1,138 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:57 -0700 +Subject: fm10k: use macro to avoid passing the array and size separately +Patch-mainline: v4.18-rc1 +Git-commit: 36592d6ce8d38590894fb34329b0786386ee75bc +References: bsc#1101813 FATE#325148 + +Avoid potential bugs with fm10k_add_stat_strings and +fm10k_add_ethtool_stats by using a macro to calculate the ARRAY_SIZE +when passing. This helps ensure that the size is always correct. + +Note that it assumes we only pass static const fm10k_stat arrays, and +that evaluation of the argument won't have side effects. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 48 ++++++++++------------- + 1 file changed, 21 insertions(+), 27 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +@@ -152,8 +152,8 @@ enum { + static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = { + }; + +-static void fm10k_add_stat_strings(u8 **p, const struct fm10k_stats stats[], +- const unsigned int size, ...) ++static void __fm10k_add_stat_strings(u8 **p, const struct fm10k_stats stats[], ++ const unsigned int size, ...) + { + unsigned int i; + +@@ -167,31 +167,28 @@ static void fm10k_add_stat_strings(u8 ** + } + } + ++#define fm10k_add_stat_strings(p, stats, ...) \ ++ __fm10k_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__) ++ + static void fm10k_get_stat_strings(struct net_device *dev, u8 *data) + { + struct fm10k_intfc *interface = netdev_priv(dev); + unsigned int i; + +- fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats, +- FM10K_NETDEV_STATS_LEN); ++ fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats); + +- fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats, +- FM10K_GLOBAL_STATS_LEN); ++ fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats); + +- fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats, +- FM10K_MBX_STATS_LEN); ++ fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats); + + if (interface->hw.mac.type != fm10k_mac_vf) +- fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats, +- FM10K_PF_STATS_LEN); ++ fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats); + + for (i = 0; i < interface->hw.mac.max_queues; i++) { + fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN, + "tx", i); + + fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN, + "rx", i); + } + } +@@ -237,9 +234,9 @@ static int fm10k_get_sset_count(struct n + } + } + +-static void fm10k_add_ethtool_stats(u64 **data, void *pointer, +- const struct fm10k_stats stats[], +- const unsigned int size) ++static void __fm10k_add_ethtool_stats(u64 **data, void *pointer, ++ const struct fm10k_stats stats[], ++ const unsigned int size) + { + unsigned int i; + char *p; +@@ -273,6 +270,9 @@ static void fm10k_add_ethtool_stats(u64 + } + } + ++#define fm10k_add_ethtool_stats(data, pointer, stats) \ ++ __fm10k_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats)) ++ + static void fm10k_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats __always_unused *stats, + u64 *data) +@@ -283,20 +283,16 @@ static void fm10k_get_ethtool_stats(stru + + fm10k_update_stats(interface); + +- fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats, +- FM10K_NETDEV_STATS_LEN); ++ fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats); + +- fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats, +- FM10K_GLOBAL_STATS_LEN); ++ fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats); + + fm10k_add_ethtool_stats(&data, &interface->hw.mbx, +- fm10k_gstrings_mbx_stats, +- FM10K_MBX_STATS_LEN); ++ fm10k_gstrings_mbx_stats); + + if (interface->hw.mac.type != fm10k_mac_vf) { + fm10k_add_ethtool_stats(&data, interface, +- fm10k_gstrings_pf_stats, +- FM10K_PF_STATS_LEN); ++ fm10k_gstrings_pf_stats); + } + + for (i = 0; i < interface->hw.mac.max_queues; i++) { +@@ -304,13 +300,11 @@ static void fm10k_get_ethtool_stats(stru + + ring = interface->tx_ring[i]; + fm10k_add_ethtool_stats(&data, ring, +- fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN); ++ fm10k_gstrings_queue_stats); + + ring = interface->rx_ring[i]; + fm10k_add_ethtool_stats(&data, ring, +- fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN); ++ fm10k_gstrings_queue_stats); + } + } + diff --git a/patches.drivers/fm10k-use-spinlock-to-implement-mailbox-lock.patch b/patches.drivers/fm10k-use-spinlock-to-implement-mailbox-lock.patch new file mode 100644 index 0000000..9455390 --- /dev/null +++ b/patches.drivers/fm10k-use-spinlock-to-implement-mailbox-lock.patch @@ -0,0 +1,77 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:15 -0700 +Subject: fm10k: use spinlock to implement mailbox lock +Patch-mainline: v4.15-rc1 +Git-commit: b4fcd43661df0d84cc4e030ab7a26533114889b9 +References: bsc#1101813 FATE#325148 + +Lets not re-invent the locking wheel. Remove our bitlock and use +a proper spinlock instead. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k.h | 15 +++++---------- + drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 3 +++ + 2 files changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k.h ++++ b/drivers/net/ethernet/intel/fm10k/fm10k.h +@@ -276,7 +276,6 @@ enum fm10k_state_t { + __FM10K_SERVICE_SCHED, + __FM10K_SERVICE_REQUEST, + __FM10K_SERVICE_DISABLE, +- __FM10K_MBX_LOCK, + __FM10K_LINK_DOWN, + __FM10K_UPDATING_STATS, + /* This value must be last and determines the BITMAP size */ +@@ -346,6 +345,8 @@ struct fm10k_intfc { + + struct fm10k_hw_stats stats; + struct fm10k_hw hw; ++ /* Mailbox lock */ ++ spinlock_t mbx_lock; + u32 __iomem *uc_addr; + u32 __iomem *sw_addr; + u16 msg_enable; +@@ -386,23 +387,17 @@ struct fm10k_intfc { + + static inline void fm10k_mbx_lock(struct fm10k_intfc *interface) + { +- /* busy loop if we cannot obtain the lock as some calls +- * such as ndo_set_rx_mode may be made in atomic context +- */ +- while (test_and_set_bit(__FM10K_MBX_LOCK, interface->state)) +- udelay(20); ++ spin_lock(&interface->mbx_lock); + } + + static inline void fm10k_mbx_unlock(struct fm10k_intfc *interface) + { +- /* flush memory to make sure state is correct */ +- smp_mb__before_atomic(); +- clear_bit(__FM10K_MBX_LOCK, interface->state); ++ spin_unlock(&interface->mbx_lock); + } + + static inline int fm10k_mbx_trylock(struct fm10k_intfc *interface) + { +- return !test_and_set_bit(__FM10K_MBX_LOCK, interface->state); ++ return spin_trylock(&interface->mbx_lock); + } + + /* fm10k_test_staterr - test bits in Rx descriptor status and error fields */ +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +@@ -1921,6 +1921,9 @@ static int fm10k_sw_init(struct fm10k_in + netdev_rss_key_fill(rss_key, sizeof(rss_key)); + memcpy(interface->rssrk, rss_key, sizeof(rss_key)); + ++ /* Initialize the mailbox lock */ ++ spin_lock_init(&interface->mbx_lock); ++ + /* Start off interface as being down */ + set_bit(__FM10K_DOWN, interface->state); + set_bit(__FM10K_UPDATING_STATS, interface->state); diff --git a/patches.drivers/fm10k-use-the-MAC-VLAN-queue-for-VF-PF-MAC-VLAN-requ.patch b/patches.drivers/fm10k-use-the-MAC-VLAN-queue-for-VF-PF-MAC-VLAN-requ.patch new file mode 100644 index 0000000..2148bae --- /dev/null +++ b/patches.drivers/fm10k-use-the-MAC-VLAN-queue-for-VF-PF-MAC-VLAN-requ.patch @@ -0,0 +1,223 @@ +From: Jacob Keller +Date: Mon, 10 Jul 2017 13:23:18 -0700 +Subject: fm10k: use the MAC/VLAN queue for VF<->PF MAC/VLAN requests +Patch-mainline: v4.15-rc1 +Git-commit: 1f5c27e52857c9ba8f1ee4ed5093bee1a341f330 +References: bsc#1101813 FATE#325148 + +Now that we have a working MAC/VLAN queue for handling MAC/VLAN messages +from the netdev, replace the default handler for the VF<->PF messages. +This new handler is very similar to the default code, but uses the +MAC/VLAN queue instead of sending the message directly. Unfortunately we +can't easily re-use the default code, so we'll just replace the entire +function. + +This ensures that a VF requesting a large number of VLANs or MAC +addresses does not start a reset cycle, as explained in the commit which +introduced the message queue. + +Signed-off-by: Jacob Keller +Reviewed-by: Ngai-mint Kwan +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 132 ++++++++++++++++++++++++++- + drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 2 + drivers/net/ethernet/intel/fm10k/fm10k_pf.h | 3 + 3 files changed, 133 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c +@@ -35,10 +35,133 @@ static s32 fm10k_iov_msg_error(struct fm + return fm10k_tlv_msg_error(hw, results, mbx); + } + ++/** ++ * fm10k_iov_msg_queue_mac_vlan - Message handler for MAC/VLAN request from VF ++ * @hw: Pointer to hardware structure ++ * @results: Pointer array to message, results[0] is pointer to message ++ * @mbx: Pointer to mailbox information structure ++ * ++ * This function is a custom handler for MAC/VLAN requests from the VF. The ++ * assumption is that it is acceptable to directly hand off the message from ++ * the VF to the PF's switch manager. However, we use a MAC/VLAN message ++ * queue to avoid overloading the mailbox when a large number of requests ++ * come in. ++ **/ ++static s32 fm10k_iov_msg_queue_mac_vlan(struct fm10k_hw *hw, u32 **results, ++ struct fm10k_mbx_info *mbx) ++{ ++ struct fm10k_vf_info *vf_info = (struct fm10k_vf_info *)mbx; ++ struct fm10k_intfc *interface = hw->back; ++ u8 mac[ETH_ALEN]; ++ u32 *result; ++ int err = 0; ++ bool set; ++ u16 vlan; ++ u32 vid; ++ ++ /* we shouldn't be updating rules on a disabled interface */ ++ if (!FM10K_VF_FLAG_ENABLED(vf_info)) ++ err = FM10K_ERR_PARAM; ++ ++ if (!err && !!results[FM10K_MAC_VLAN_MSG_VLAN]) { ++ result = results[FM10K_MAC_VLAN_MSG_VLAN]; ++ ++ /* record VLAN id requested */ ++ err = fm10k_tlv_attr_get_u32(result, &vid); ++ if (err) ++ return err; ++ ++ set = !(vid & FM10K_VLAN_CLEAR); ++ vid &= ~FM10K_VLAN_CLEAR; ++ ++ /* if the length field has been set, this is a multi-bit ++ * update request. For multi-bit requests, simply disallow ++ * them when the pf_vid has been set. In this case, the PF ++ * should have already cleared the VLAN_TABLE, and if we ++ * allowed them, it could allow a rogue VF to receive traffic ++ * on a VLAN it was not assigned. In the single-bit case, we ++ * need to modify requests for VLAN 0 to use the default PF or ++ * SW vid when assigned. ++ */ ++ ++ if (vid >> 16) { ++ /* prevent multi-bit requests when PF has ++ * administratively set the VLAN for this VF ++ */ ++ if (vf_info->pf_vid) ++ return FM10K_ERR_PARAM; ++ } else { ++ err = fm10k_iov_select_vid(vf_info, (u16)vid); ++ if (err < 0) ++ return err; ++ ++ vid = err; ++ } ++ ++ /* update VSI info for VF in regards to VLAN table */ ++ err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set); ++ } ++ ++ if (!err && !!results[FM10K_MAC_VLAN_MSG_MAC]) { ++ result = results[FM10K_MAC_VLAN_MSG_MAC]; ++ ++ /* record unicast MAC address requested */ ++ err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan); ++ if (err) ++ return err; ++ ++ /* block attempts to set MAC for a locked device */ ++ if (is_valid_ether_addr(vf_info->mac) && ++ !ether_addr_equal(mac, vf_info->mac)) ++ return FM10K_ERR_PARAM; ++ ++ set = !(vlan & FM10K_VLAN_CLEAR); ++ vlan &= ~FM10K_VLAN_CLEAR; ++ ++ err = fm10k_iov_select_vid(vf_info, vlan); ++ if (err < 0) ++ return err; ++ ++ vlan = (u16)err; ++ ++ /* Add this request to the MAC/VLAN queue */ ++ err = fm10k_queue_mac_request(interface, vf_info->glort, ++ mac, vlan, set); ++ } ++ ++ if (!err && !!results[FM10K_MAC_VLAN_MSG_MULTICAST]) { ++ result = results[FM10K_MAC_VLAN_MSG_MULTICAST]; ++ ++ /* record multicast MAC address requested */ ++ err = fm10k_tlv_attr_get_mac_vlan(result, mac, &vlan); ++ if (err) ++ return err; ++ ++ /* verify that the VF is allowed to request multicast */ ++ if (!(vf_info->vf_flags & FM10K_VF_FLAG_MULTI_ENABLED)) ++ return FM10K_ERR_PARAM; ++ ++ set = !(vlan & FM10K_VLAN_CLEAR); ++ vlan &= ~FM10K_VLAN_CLEAR; ++ ++ err = fm10k_iov_select_vid(vf_info, vlan); ++ if (err < 0) ++ return err; ++ ++ vlan = (u16)err; ++ ++ /* Add this request to the MAC/VLAN queue */ ++ err = fm10k_queue_mac_request(interface, vf_info->glort, ++ mac, vlan, set); ++ } ++ ++ return err; ++} ++ + static const struct fm10k_msg_data iov_mbx_data[] = { + FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test), + FM10K_VF_MSG_MSIX_HANDLER(fm10k_iov_msg_msix_pf), +- FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_mac_vlan_pf), ++ FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_iov_msg_queue_mac_vlan), + FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_iov_msg_lport_state_pf), + FM10K_TLV_MSG_ERROR_HANDLER(fm10k_iov_msg_error), + }; +@@ -126,8 +249,10 @@ process_mbx: + hw->mbx.ops.process(hw, &hw->mbx); + + /* verify port mapping is valid, if not reset port */ +- if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort)) ++ if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort)) { + hw->iov.ops.reset_lport(hw, vf_info); ++ fm10k_clear_macvlan_queue(interface, glort, false); ++ } + + /* reset VFs that have mailbox timed out */ + if (!mbx->timeout) { +@@ -190,6 +315,7 @@ void fm10k_iov_suspend(struct pci_dev *p + + hw->iov.ops.reset_resources(hw, vf_info); + hw->iov.ops.reset_lport(hw, vf_info); ++ fm10k_clear_macvlan_queue(interface, vf_info->glort, false); + } + } + +@@ -414,6 +540,8 @@ static inline void fm10k_reset_vf_info(s + /* disable LPORT for this VF which clears switch rules */ + hw->iov.ops.reset_lport(hw, vf_info); + ++ fm10k_clear_macvlan_queue(interface, vf_info->glort, false); ++ + /* assign new MAC+VLAN for this VF */ + hw->iov.ops.assign_default_mac_vlan(hw, vf_info); + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +@@ -1186,7 +1186,7 @@ s32 fm10k_iov_msg_msix_pf(struct fm10k_h + * Will report an error if the VLAN ID is out of range. For VID = 0, it will + * return either the pf_vid or sw_vid depending on which one is set. + */ +-static s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid) ++s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid) + { + if (!vid) + return vf_info->pf_vid ? vf_info->pf_vid : vf_info->sw_vid; +--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.h ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.h +@@ -1,5 +1,5 @@ + /* Intel(R) Ethernet Switch Host Interface Driver +- * Copyright(c) 2013 - 2016 Intel Corporation. ++ * Copyright(c) 2013 - 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -114,6 +114,7 @@ extern const struct fm10k_tlv_attr fm10k + #define FM10K_PF_MSG_ERR_HANDLER(msg, func) \ + FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_##msg, fm10k_err_msg_attr, func) + ++s32 fm10k_iov_select_vid(struct fm10k_vf_info *vf_info, u16 vid); + s32 fm10k_iov_msg_msix_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *); + s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *, u32 **, + struct fm10k_mbx_info *); diff --git a/patches.drivers/fm10k-use-variadic-arguments-to-fm10k_add_stat_strin.patch b/patches.drivers/fm10k-use-variadic-arguments-to-fm10k_add_stat_strin.patch new file mode 100644 index 0000000..97c45e3 --- /dev/null +++ b/patches.drivers/fm10k-use-variadic-arguments-to-fm10k_add_stat_strin.patch @@ -0,0 +1,123 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:56 -0700 +Subject: fm10k: use variadic arguments to fm10k_add_stat_strings +Patch-mainline: v4.18-rc1 +Git-commit: d63bb21a7e722fcaa6cc6a217f21fe25a9e2c89e +References: bsc#1101813 FATE#325148 + +Instead of using a fixed prefix string we setup before each call to +fm10k_add_stat_strings, modify the helper to take variadic arguments and +pass them to vsnprintf. This requires changing the fm10k_stat strings to +take % format specifiers where necessary, but the resulting code is much +simpler. + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 55 +++++++++++------------ + 1 file changed, 28 insertions(+), 27 deletions(-) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +@@ -23,6 +23,11 @@ + #include "fm10k.h" + + struct fm10k_stats { ++ /* The stat_string is expected to be a format string formatted using ++ * vsnprintf by fm10k_add_stat_strings. Every member of a stats array ++ * should use the same format specifiers as they will be formatted ++ * using the same variadic arguments. ++ */ + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; +@@ -111,15 +116,13 @@ static const struct fm10k_stats fm10k_gs + FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed), + }; + +-#define FM10K_QUEUE_STAT(_name, _stat) { \ +- .stat_string = _name, \ +- .sizeof_stat = FIELD_SIZEOF(struct fm10k_ring, _stat), \ +- .stat_offset = offsetof(struct fm10k_ring, _stat) \ +-} ++/* per-queue ring statistics */ ++#define FM10K_QUEUE_STAT(_name, _stat) \ ++ FM10K_STAT_FIELDS(struct fm10k_ring, _name, _stat) + + static const struct fm10k_stats fm10k_gstrings_queue_stats[] = { +- FM10K_QUEUE_STAT("packets", stats.packets), +- FM10K_QUEUE_STAT("bytes", stats.bytes), ++ FM10K_QUEUE_STAT("%s_queue_%u_packets", stats.packets), ++ FM10K_QUEUE_STAT("%s_queue_%u_bytes", stats.bytes), + }; + + #define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats) +@@ -149,16 +152,18 @@ enum { + static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = { + }; + +-static void fm10k_add_stat_strings(u8 **p, const char *prefix, +- const struct fm10k_stats stats[], +- const unsigned int size) ++static void fm10k_add_stat_strings(u8 **p, const struct fm10k_stats stats[], ++ const unsigned int size, ...) + { + unsigned int i; + + for (i = 0; i < size; i++) { +- snprintf(*p, ETH_GSTRING_LEN, "%s%s", +- prefix, stats[i].stat_string); ++ va_list args; ++ ++ va_start(args, size); ++ vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args); + *p += ETH_GSTRING_LEN; ++ va_end(args); + } + } + +@@ -167,31 +172,27 @@ static void fm10k_get_stat_strings(struc + struct fm10k_intfc *interface = netdev_priv(dev); + unsigned int i; + +- fm10k_add_stat_strings(&data, "", fm10k_gstrings_net_stats, ++ fm10k_add_stat_strings(&data, fm10k_gstrings_net_stats, + FM10K_NETDEV_STATS_LEN); + +- fm10k_add_stat_strings(&data, "", fm10k_gstrings_global_stats, ++ fm10k_add_stat_strings(&data, fm10k_gstrings_global_stats, + FM10K_GLOBAL_STATS_LEN); + +- fm10k_add_stat_strings(&data, "", fm10k_gstrings_mbx_stats, ++ fm10k_add_stat_strings(&data, fm10k_gstrings_mbx_stats, + FM10K_MBX_STATS_LEN); + + if (interface->hw.mac.type != fm10k_mac_vf) +- fm10k_add_stat_strings(&data, "", fm10k_gstrings_pf_stats, ++ fm10k_add_stat_strings(&data, fm10k_gstrings_pf_stats, + FM10K_PF_STATS_LEN); + + for (i = 0; i < interface->hw.mac.max_queues; i++) { +- char prefix[ETH_GSTRING_LEN]; +- +- snprintf(prefix, ETH_GSTRING_LEN, "tx_queue_%u_", i); +- fm10k_add_stat_strings(&data, prefix, +- fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN); +- +- snprintf(prefix, ETH_GSTRING_LEN, "rx_queue_%u_", i); +- fm10k_add_stat_strings(&data, prefix, +- fm10k_gstrings_queue_stats, +- FM10K_QUEUE_STATS_LEN); ++ fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats, ++ FM10K_QUEUE_STATS_LEN, ++ "tx", i); ++ ++ fm10k_add_stat_strings(&data, fm10k_gstrings_queue_stats, ++ FM10K_QUEUE_STATS_LEN, ++ "rx", i); + } + } + diff --git a/patches.drivers/fm10k-warn-if-the-stat-size-is-unknown.patch b/patches.drivers/fm10k-warn-if-the-stat-size-is-unknown.patch new file mode 100644 index 0000000..3d09406 --- /dev/null +++ b/patches.drivers/fm10k-warn-if-the-stat-size-is-unknown.patch @@ -0,0 +1,26 @@ +From: Jacob Keller +Date: Thu, 12 Apr 2018 11:15:58 -0700 +Subject: fm10k: warn if the stat size is unknown +Patch-mainline: v4.18-rc1 +Git-commit: 454ca380ce3cac79bfd295f5a7ae15ec26ff1b67 +References: bsc#1101813 FATE#325148 + +Signed-off-by: Jacob Keller +Tested-by: Krishneil Singh +Signed-off-by: Jeff Kirsher +Acked-by: Thomas Bogendoerfer +--- + drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c ++++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c +@@ -265,6 +265,8 @@ static void __fm10k_add_ethtool_stats(u6 + *((*data)++) = *(u8 *)p; + break; + default: ++ WARN_ONCE(1, "unexpected stat size for %s", ++ stats[i].stat_string); + *((*data)++) = 0; + } + } diff --git a/series.conf b/series.conf index aa5dfb0..35d9312 100644 --- a/series.conf +++ b/series.conf @@ -8160,8 +8160,28 @@ patches.drivers/0001-thunderbolt-Add-polling-mode-for-rings.patch patches.drivers/0001-thunderbolt-Allocate-ring-HopID-automatically-if-req.patch patches.drivers/fm10k-ensure-we-process-SM-mbx-when-processing-VF-mb.patch + patches.drivers/fm10k-reschedule-service-event-if-we-stall-the-PF-SM.patch + patches.drivers/fm10k-Use-seq_putc-in-fm10k_dbg_desc_break.patch + patches.drivers/fm10k-stop-spurious-link-down-messages-when-Tx-FIFO-.patch + patches.drivers/fm10k-fix-typos-on-fall-through-comments.patch + patches.drivers/fm10k-avoid-possible-truncation-of-q_vector-name.patch + patches.drivers/fm10k-add-missing-fall-through-comment.patch + patches.drivers/fm10k-avoid-needless-delay-when-loading-driver.patch + patches.drivers/fm10k-simplify-reading-PFVFLRE-register.patch + patches.drivers/fm10k-don-t-loop-while-resetting-VFs-due-to-VFLR-eve.patch + patches.drivers/fm10k-avoid-divide-by-zero-in-rare-cases-when-device.patch + patches.drivers/fm10k-move-fm10k_prepare_for_reset-and-fm10k_handle_.patch + patches.drivers/fm10k-prevent-race-condition-of-__FM10K_SERVICE_SCHE.patch patches.drivers/i40e-fix-client-notify-of-VF-reset.patch patches.drivers/cxgb4-Update-comment-for-min_mtu.patch + patches.drivers/fm10k-prepare_for_reset-when-we-lose-PCIe-Link.patch + patches.drivers/fm10k-use-spinlock-to-implement-mailbox-lock.patch + patches.drivers/fm10k-use-generic-PM-hooks-instead-of-legacy-PCIe-po.patch + patches.drivers/fm10k-introduce-a-message-queue-for-MAC-VLAN-message.patch + patches.drivers/fm10k-use-the-MAC-VLAN-queue-for-VF-PF-MAC-VLAN-requ.patch + patches.drivers/fm10k-bump-version-number.patch + patches.drivers/fm10k-Fix-misuse-of-net_ratelimit.patch + patches.drivers/fm10k-prefer-s-and-__func__-for-diagnostic-prints.patch patches.drivers/fm10k-fix-mis-ordered-parameters-in-declaration-for-.patch patches.drivers/cxgb4-add-new-T6-pci-device-id-s-acd669a8.patch patches.drivers/cxgb4vf-make-a-couple-of-functions-static.patch @@ -10350,6 +10370,7 @@ patches.fixes/bpf-mark-dst-unknown-on-inconsistent-s-u-bounds-adju.patch patches.suse/netlink-reset-extack-earlier-in-netlink_rcv_skb.patch patches.drivers/cfg80211-fix-station-info-handling-bugs + patches.drivers/fm10k-mark-PM-functions-as-__maybe_unused.patch patches.suse/flow_dissector-properly-cap-thoff-field.patch patches.suse/ip6_gre-init-dev-mtu-and-dev-hard_header_len-correct.patch patches.drivers/can-af_can-can_rcv-replace-WARN_ONCE-by-pr_warn_once @@ -11144,6 +11165,13 @@ patches.drivers/igb-Free-IRQs-when-device-is-hotplugged.patch patches.drivers/igb-Clear-TXSTMP-when-ptp_tx_work-is-timeout.patch patches.drivers/cxgb4-make-symbol-pedits-static.patch + patches.drivers/fm10k-Fix-configuration-for-macvlan-offload.patch + patches.drivers/fm10k-cleanup-unnecessary-parenthesis-in-fm10k_iov.c.patch + patches.drivers/fm10k-fix-failed-to-kill-vid-message-for-VF.patch + patches.drivers/fm10k-stop-adding-VLAN-0-to-the-VLAN-table.patch + patches.drivers/fm10k-don-t-assume-VLAN-1-is-enabled.patch + patches.drivers/fm10k-correct-typo-in-fm10k_pf.c.patch + patches.drivers/fm10k-clarify-action-when-updating-the-VLAN-table.patch patches.drivers/net-smc-cancel-tx-worker-in-case-of-socket-aborts.patch patches.drivers/net-smc-handle-state-smc_peerfinclosewait-correctly.patch patches.drivers/net-smc-terminate-link-group-for-ib_post_send-problems.patch @@ -12903,6 +12931,9 @@ patches.drivers/ibmvnic-Do-not-attempt-to-login-if-RX-or-TX-queues-a.patch patches.drivers/qlogic-qed-Constify-pkt_type_str.patch patches.drivers/emulex-benet-Constify-be_misconfig_evt_port_state.patch + patches.drivers/fm10k-fix-function-doxygen-comments.patch + patches.drivers/fm10k-fix-incorrect-warning-for-function-prototype.patch + patches.drivers/fm10k-bump-version-number-e9d328d3.patch patches.drivers/net-smc-cleanup-smc_llc-h-and-smc_clc-h-headers.patch patches.drivers/net-smc-move-netinfo-function-to-file-smc_clc-c.patch patches.drivers/net-smc-remove-unused-fields-from-smc-structures.patch @@ -14030,6 +14061,12 @@ patches.drivers/bnxt_en-Check-unsupported-speeds-in-bnxt_update_link.patch patches.drivers/bnxt_en-Read-phy-eeprom-A2h-address-only-when-optica.patch patches.drivers/bnxt_en-Always-forward-VF-MAC-address-to-the-PF.patch + patches.drivers/fm10k-setup-VLANs-for-l2-accelerated-macvlan-interfa.patch + patches.drivers/fm10k-reduce-duplicate-fm10k_stat-macro-code.patch + patches.drivers/fm10k-use-variadic-arguments-to-fm10k_add_stat_strin.patch + patches.drivers/fm10k-use-macro-to-avoid-passing-the-array-and-size-.patch + patches.drivers/fm10k-warn-if-the-stat-size-is-unknown.patch + patches.drivers/fm10k-don-t-protect-fm10k_queue_mac_request-by-fm10k.patch patches.drivers/net-smc-no-tx-work-trigger-for-fallback-sockets.patch patches.drivers/net-smc-register-new-rmbs-with-the-peer.patch patches.drivers/net-smc-remove-unnecessary-cast.patch