summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c22
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.h1
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 58cc3147afe2..73e051d26b9d 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1756,6 +1756,27 @@ static int ibmveth_set_mac_addr(struct net_device *dev, void *p)
return 0;
}
+static netdev_features_t ibmveth_features_check(struct sk_buff *skb,
+ struct net_device *dev,
+ netdev_features_t features)
+{
+ /* Some physical adapters do not support segmentation offload with
+ * MSS < 224. Disable GSO for such packets to avoid adapter freeze.
+ * Note: Single-segment packets (gso_segs == 1) don't need this check
+ * as they bypass the LSO path and are transmitted without segmentation.
+ */
+ if (skb_is_gso(skb)) {
+ if (skb_shinfo(skb)->gso_size < IBMVETH_MIN_LSO_MSS) {
+ netdev_warn_once(dev,
+ "MSS %u too small for LSO, disabling GSO\n",
+ skb_shinfo(skb)->gso_size);
+ features &= ~NETIF_F_GSO_MASK;
+ }
+ }
+
+ return vlan_features_check(skb, features);
+}
+
static const struct net_device_ops ibmveth_netdev_ops = {
.ndo_open = ibmveth_open,
.ndo_stop = ibmveth_close,
@@ -1767,6 +1788,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
.ndo_set_features = ibmveth_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ibmveth_set_mac_addr,
+ .ndo_features_check = ibmveth_features_check,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ibmveth_poll_controller,
#endif
diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h
index 068f99df133e..d87713668ed3 100644
--- a/drivers/net/ethernet/ibm/ibmveth.h
+++ b/drivers/net/ethernet/ibm/ibmveth.h
@@ -37,6 +37,7 @@
#define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002UL
#define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001UL
+#define IBMVETH_MIN_LSO_MSS 224 /* Minimum MSS for LSO */
/* hcall macros */
#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)