From c75860e48a7634ff8dc050842211f79a0e4e6c46 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Sun, 20 Jan 2019 11:36:38 +0200 Subject: qed: Add infrastructure for error detection and recovery This patch adds the detection and handling of a parity error ("process kill event"), including the update of the protocol drivers, and the prevention of any HW access that will lead to device access towards the host while recovery is in progress. It also provides the means for the protocol drivers to trigger a recovery process on their decision. Signed-off-by: Tomer Tayar Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- include/linux/qed/qed_if.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index 91c536a01b56..c2a1b7dbe4eb 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -764,6 +764,7 @@ struct qed_probe_params { u32 dp_module; u8 dp_level; bool is_vf; + bool recov_in_prog; }; #define QED_DRV_VER_STR_SIZE 12 @@ -810,6 +811,7 @@ struct qed_common_cb_ops { void (*arfs_filter_op)(void *dev, void *fltr, u8 fw_rc); void (*link_update)(void *dev, struct qed_link_output *link); + void (*schedule_recovery_handler)(void *dev); void (*dcbx_aen)(void *dev, struct qed_dcbx_get *get, u32 mib_type); void (*get_generic_tlv_data)(void *dev, struct qed_generic_tlvs *data); void (*get_protocol_tlv_data)(void *dev, void *data); @@ -1057,6 +1059,24 @@ struct qed_common_ops { int (*db_recovery_del)(struct qed_dev *cdev, void __iomem *db_addr, void *db_data); +/** + * @brief recovery_process - Trigger a recovery process + * + * @param cdev + * + * @return 0 on success, error otherwise. + */ + int (*recovery_process)(struct qed_dev *cdev); + +/** + * @brief recovery_prolog - Execute the prolog operations of a recovery process + * + * @param cdev + * + * @return 0 on success, error otherwise. + */ + int (*recovery_prolog)(struct qed_dev *cdev); + /** * @brief update_drv_state - API to inform the change in the driver state. * -- cgit v1.2.3 From 278396de78a9b59a692bc140233bde3a9d8a8a31 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Sun, 20 Jan 2019 11:36:39 +0200 Subject: qede: Error recovery process This patch adds the error recovery process in the qede driver. The process includes a partial/customized driver unload and load, which allows it to look like a short suspend period to the kernel while preserving the net devices' state. Signed-off-by: Tomer Tayar Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- include/linux/qed/qede_rdma.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/qed/qede_rdma.h b/include/linux/qed/qede_rdma.h index 9904617a9730..e29d7199c10e 100644 --- a/include/linux/qed/qede_rdma.h +++ b/include/linux/qed/qede_rdma.h @@ -55,6 +55,16 @@ struct qede_rdma_event_work { enum qede_rdma_event event; }; +enum qede_rdma_probe_mode { + QEDE_RDMA_PROBE_NORMAL, + QEDE_RDMA_PROBE_RECOVERY, +}; + +enum qede_rdma_remove_mode { + QEDE_RDMA_REMOVE_NORMAL, + QEDE_RDMA_REMOVE_RECOVERY, +}; + struct qedr_driver { unsigned char name[32]; @@ -74,21 +84,24 @@ void qede_rdma_unregister_driver(struct qedr_driver *drv); bool qede_rdma_supported(struct qede_dev *dev); #if IS_ENABLED(CONFIG_QED_RDMA) -int qede_rdma_dev_add(struct qede_dev *dev); +int qede_rdma_dev_add(struct qede_dev *dev, enum qede_rdma_probe_mode mode); void qede_rdma_dev_event_open(struct qede_dev *dev); void qede_rdma_dev_event_close(struct qede_dev *dev); -void qede_rdma_dev_remove(struct qede_dev *dev); +void qede_rdma_dev_remove(struct qede_dev *dev, + enum qede_rdma_remove_mode mode); void qede_rdma_event_changeaddr(struct qede_dev *edr); #else -static inline int qede_rdma_dev_add(struct qede_dev *dev) +static inline int qede_rdma_dev_add(struct qede_dev *dev, + enum qede_rdma_probe_mode mode) { return 0; } static inline void qede_rdma_dev_event_open(struct qede_dev *dev) {} static inline void qede_rdma_dev_event_close(struct qede_dev *dev) {} -static inline void qede_rdma_dev_remove(struct qede_dev *dev) {} +static inline void qede_rdma_dev_remove(struct qede_dev *dev, + enum qede_rdma_remove_mode mode) {} static inline void qede_rdma_event_changeaddr(struct qede_dev *edr) {} #endif #endif -- cgit v1.2.3 From 3b707c3008cad04604c1f50e39f456621821c414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Thu, 24 Jan 2019 03:07:02 -0800 Subject: net: dev_is_mac_header_xmit() true for ARPHRD_RAWIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __bpf_redirect() and act_mirred checks this boolean to determine whether to prefix an ethernet header. Signed-off-by: Maciej Żenczykowski Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- include/linux/if_arp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 6756fea18b69..e44746de95cd 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -54,6 +54,7 @@ static inline bool dev_is_mac_header_xmit(const struct net_device *dev) case ARPHRD_IPGRE: case ARPHRD_VOID: case ARPHRD_NONE: + case ARPHRD_RAWIP: return false; default: return true; -- cgit v1.2.3 From abfd04f738c2625f63e04c8fc7cadb3b7a70d580 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 25 Jan 2019 15:32:28 -0800 Subject: qed: Revert error handling changes. This is new code and not bug fixes. This reverts all changes added by merge commit 8fb18be93efd7292d6ee403b9f61af1008239639 Signed-off-by: David S. Miller --- include/linux/qed/qed_if.h | 20 -------------------- include/linux/qed/qede_rdma.h | 21 ++++----------------- 2 files changed, 4 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index c2a1b7dbe4eb..91c536a01b56 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -764,7 +764,6 @@ struct qed_probe_params { u32 dp_module; u8 dp_level; bool is_vf; - bool recov_in_prog; }; #define QED_DRV_VER_STR_SIZE 12 @@ -811,7 +810,6 @@ struct qed_common_cb_ops { void (*arfs_filter_op)(void *dev, void *fltr, u8 fw_rc); void (*link_update)(void *dev, struct qed_link_output *link); - void (*schedule_recovery_handler)(void *dev); void (*dcbx_aen)(void *dev, struct qed_dcbx_get *get, u32 mib_type); void (*get_generic_tlv_data)(void *dev, struct qed_generic_tlvs *data); void (*get_protocol_tlv_data)(void *dev, void *data); @@ -1059,24 +1057,6 @@ struct qed_common_ops { int (*db_recovery_del)(struct qed_dev *cdev, void __iomem *db_addr, void *db_data); -/** - * @brief recovery_process - Trigger a recovery process - * - * @param cdev - * - * @return 0 on success, error otherwise. - */ - int (*recovery_process)(struct qed_dev *cdev); - -/** - * @brief recovery_prolog - Execute the prolog operations of a recovery process - * - * @param cdev - * - * @return 0 on success, error otherwise. - */ - int (*recovery_prolog)(struct qed_dev *cdev); - /** * @brief update_drv_state - API to inform the change in the driver state. * diff --git a/include/linux/qed/qede_rdma.h b/include/linux/qed/qede_rdma.h index e29d7199c10e..9904617a9730 100644 --- a/include/linux/qed/qede_rdma.h +++ b/include/linux/qed/qede_rdma.h @@ -55,16 +55,6 @@ struct qede_rdma_event_work { enum qede_rdma_event event; }; -enum qede_rdma_probe_mode { - QEDE_RDMA_PROBE_NORMAL, - QEDE_RDMA_PROBE_RECOVERY, -}; - -enum qede_rdma_remove_mode { - QEDE_RDMA_REMOVE_NORMAL, - QEDE_RDMA_REMOVE_RECOVERY, -}; - struct qedr_driver { unsigned char name[32]; @@ -84,24 +74,21 @@ void qede_rdma_unregister_driver(struct qedr_driver *drv); bool qede_rdma_supported(struct qede_dev *dev); #if IS_ENABLED(CONFIG_QED_RDMA) -int qede_rdma_dev_add(struct qede_dev *dev, enum qede_rdma_probe_mode mode); +int qede_rdma_dev_add(struct qede_dev *dev); void qede_rdma_dev_event_open(struct qede_dev *dev); void qede_rdma_dev_event_close(struct qede_dev *dev); -void qede_rdma_dev_remove(struct qede_dev *dev, - enum qede_rdma_remove_mode mode); +void qede_rdma_dev_remove(struct qede_dev *dev); void qede_rdma_event_changeaddr(struct qede_dev *edr); #else -static inline int qede_rdma_dev_add(struct qede_dev *dev, - enum qede_rdma_probe_mode mode) +static inline int qede_rdma_dev_add(struct qede_dev *dev) { return 0; } static inline void qede_rdma_dev_event_open(struct qede_dev *dev) {} static inline void qede_rdma_dev_event_close(struct qede_dev *dev) {} -static inline void qede_rdma_dev_remove(struct qede_dev *dev, - enum qede_rdma_remove_mode mode) {} +static inline void qede_rdma_dev_remove(struct qede_dev *dev) {} static inline void qede_rdma_event_changeaddr(struct qede_dev *edr) {} #endif #endif -- cgit v1.2.3