Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -22,7 +22,7 @@ $(eval $(call KernelPackage,pse-pd))
|
||||
|
||||
define AddDepends/pse-pd
|
||||
SUBMENU:=$(PSE_MENU)
|
||||
DEPENDS+=kmod-pse-pd $(1)
|
||||
DEPENDS+=+kmod-pse-pd $(1)
|
||||
endef
|
||||
|
||||
define KernelPackage/pse-regulator
|
||||
|
||||
@@ -9,9 +9,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uhttpd.git
|
||||
PKG_SOURCE_DATE:=2026-05-15
|
||||
PKG_SOURCE_VERSION:=6fadf0da50509a510ac4f85d2adb70a83de2e1fc
|
||||
PKG_MIRROR_HASH:=66775a84eec4dbfdea35d460f7978a0cedd1a58ac84d90bd1ff388020f8eddcc
|
||||
PKG_SOURCE_DATE:=2026-05-20
|
||||
PKG_SOURCE_VERSION:=6ab9abb56bcb28684f382f7a94c170fad02348ea
|
||||
PKG_MIRROR_HASH:=5edf4161ae48fd38db530f12091821d445d7346e72c69b76097f2f3e07e53a65
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=ISC
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ proto_qmi_setup() {
|
||||
local connstat dataformat mcc mnc plmn_mode
|
||||
local cid_4 cid_6 pdh_4 pdh_6
|
||||
local dns1_6 dns2_6 gateway_6 ip_6 ip_prefix_length
|
||||
local profile_pdptype
|
||||
local profile_pdptype profile_id
|
||||
|
||||
local delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS
|
||||
json_get_vars delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS
|
||||
@@ -331,12 +331,13 @@ proto_qmi_setup() {
|
||||
|
||||
[ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
|
||||
|
||||
# Configure PDP type and APN for profile 1.
|
||||
# Configure PDP type and APN.
|
||||
# In case GGSN rejects IPv4v6 PDP, modem might not be able to
|
||||
# establish a non-LTE data session.
|
||||
profile_pdptype="$pdptype"
|
||||
profile_id="${profile:-1}"
|
||||
[ "$profile_pdptype" = "ip" ] && profile_pdptype="ipv4"
|
||||
uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,1" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
|
||||
uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,$profile_id" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
|
||||
|
||||
if [ "$pdptype" = "ip" ]; then
|
||||
[ -z "$autoconnect" ] && autoconnect=1
|
||||
|
||||
@@ -21,7 +21,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
#include <uapi/linux/ppp_defs.h>
|
||||
|
||||
#include "airoha_regs.h"
|
||||
@@ -439,6 +440,41 @@ static void airoha_fe_crsn_qsel_init(str
|
||||
@@ -439,6 +440,47 @@ static void airoha_fe_crsn_qsel_init(str
|
||||
CDM_CRSN_QSEL_Q1));
|
||||
}
|
||||
|
||||
@@ -59,11 +59,17 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+ for (i = 0; i < AIROHA_MAX_NUM_LRO_QUEUES; i++)
|
||||
+ airoha_fe_clear(eth, REG_CDM_LRO_RXQ(id, i), LRO_RXQ_MASK(i));
|
||||
+}
|
||||
+
|
||||
+static bool airoha_fe_lro_is_enabled(struct airoha_eth *eth, int qdma_id)
|
||||
+{
|
||||
+ return airoha_fe_get(eth, REG_CDM_LRO_EN(qdma_id + 1),
|
||||
+ LRO_RXQ_EN_MASK);
|
||||
+}
|
||||
+
|
||||
static int airoha_fe_init(struct airoha_eth *eth)
|
||||
{
|
||||
airoha_fe_maccr_init(eth);
|
||||
@@ -603,9 +639,78 @@ static int airoha_qdma_get_gdm_port(stru
|
||||
@@ -603,9 +645,78 @@ static int airoha_qdma_get_gdm_port(stru
|
||||
return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
|
||||
}
|
||||
|
||||
@@ -142,7 +148,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_qdma *qdma = q->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int qid = q - &qdma->q_rx[0];
|
||||
@@ -652,9 +757,14 @@ static int airoha_qdma_rx_process(struct
|
||||
@@ -652,9 +763,14 @@ static int airoha_qdma_rx_process(struct
|
||||
__skb_put(q->skb, len);
|
||||
skb_mark_for_recycle(q->skb);
|
||||
q->skb->dev = port->dev;
|
||||
@@ -158,7 +164,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
} else { /* scattered frame */
|
||||
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
|
||||
int nr_frags = shinfo->nr_frags;
|
||||
@@ -743,23 +853,19 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||
@@ -743,23 +859,19 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||
static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
|
||||
struct airoha_qdma *qdma, int ndesc)
|
||||
{
|
||||
@@ -185,7 +191,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
GFP_KERNEL);
|
||||
if (!q->entry)
|
||||
@@ -770,6 +876,12 @@ static int airoha_qdma_init_rx_queue(str
|
||||
@@ -770,6 +882,12 @@ static int airoha_qdma_init_rx_queue(str
|
||||
if (!q->desc)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -198,7 +204,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
q->page_pool = page_pool_create(&pp_params);
|
||||
if (IS_ERR(q->page_pool)) {
|
||||
int err = PTR_ERR(q->page_pool);
|
||||
@@ -778,6 +890,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||
@@ -778,6 +896,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -206,7 +212,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
q->ndesc = ndesc;
|
||||
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
|
||||
@@ -2032,6 +2145,45 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
@@ -2032,6 +2151,64 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,13 +225,17 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+ struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_eth *eth = qdma->eth;
|
||||
+ int qdma_id = qdma - ð->qdma[0];
|
||||
+ int i;
|
||||
+
|
||||
+ if (!(diff & NETIF_F_LRO))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* reset LRO configuration */
|
||||
+ if (features & NETIF_F_LRO) {
|
||||
+ int i, lro_queue_index = 0;
|
||||
+ int lro_queue_index = 0;
|
||||
+
|
||||
+ if (airoha_fe_lro_is_enabled(eth, qdma_id))
|
||||
+ return 0;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
+ struct airoha_queue *q = &qdma->q_rx[i];
|
||||
@@ -243,6 +253,21 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+ lro_queue_index++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *p = eth->ports[i];
|
||||
+
|
||||
+ if (!p)
|
||||
+ continue;
|
||||
+
|
||||
+ if (p->qdma != qdma)
|
||||
+ continue;
|
||||
+
|
||||
+ if (p->dev == dev)
|
||||
+ continue;
|
||||
+
|
||||
+ if (p->dev->features & NETIF_F_LRO)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ airoha_fe_lro_disable(eth, qdma_id);
|
||||
+ }
|
||||
+
|
||||
@@ -252,7 +277,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@@ -2931,6 +3083,7 @@ static const struct net_device_ops airoh
|
||||
@@ -2931,6 +3108,7 @@ static const struct net_device_ops airoh
|
||||
.ndo_stop = airoha_dev_stop,
|
||||
.ndo_change_mtu = airoha_dev_change_mtu,
|
||||
.ndo_select_queue = airoha_dev_select_queue,
|
||||
@@ -260,7 +285,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
.ndo_start_xmit = airoha_dev_xmit,
|
||||
.ndo_get_stats64 = airoha_dev_get_stats64,
|
||||
.ndo_set_mac_address = airoha_dev_set_macaddr,
|
||||
@@ -3153,12 +3306,9 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3148,12 +3326,9 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->ethtool_ops = &airoha_ethtool_ops;
|
||||
dev->max_mtu = AIROHA_MAX_MTU;
|
||||
dev->watchdog_timeo = 5 * HZ;
|
||||
|
||||
+51
-41
@@ -1,6 +1,7 @@
|
||||
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 15 Jul 2025 12:37:45 +0200
|
||||
Subject: [PATCH] net: pppoe: implement GRO support
|
||||
Date: Wed, 13 May 2026 09:33:48 +0800
|
||||
Subject: [PATCH] net: pppoe: implement GRO/GSO support
|
||||
|
||||
Only handles packets where the pppoe header length field matches the exact
|
||||
packet length. Significantly improves rx throughput.
|
||||
@@ -11,7 +12,15 @@ that the device is able to handle improves from ~130 Mbit/s to ~630 Mbit/s,
|
||||
using fraglist GRO.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
|
||||
Tested-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Link: https://patch.msgid.link/20260513013400.7467-1-qingfang.deng@linux.dev
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ppp/pppoe.c | 161 +++++++++++++++++++++++++++++++++++++++-
|
||||
net/ipv4/af_inet.c | 2 +
|
||||
net/ipv6/ip6_offload.c | 2 +
|
||||
3 files changed, 164 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ppp/pppoe.c
|
||||
+++ b/drivers/net/ppp/pppoe.c
|
||||
@@ -32,28 +41,34 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
goto drop;
|
||||
|
||||
ph = pppoe_hdr(skb);
|
||||
@@ -1176,6 +1177,161 @@ static struct pernet_operations pppoe_ne
|
||||
@@ -1176,6 +1177,160 @@ static struct pernet_operations pppoe_ne
|
||||
.size = sizeof(struct pppoe_net),
|
||||
};
|
||||
|
||||
+static u16
|
||||
+compare_pppoe_header(struct pppoe_hdr *phdr, struct pppoe_hdr *phdr2)
|
||||
+compare_pppoe_header(const struct pppoe_hdr *phdr,
|
||||
+ const struct pppoe_hdr *phdr2)
|
||||
+{
|
||||
+ return (__force __u16)((phdr->sid ^ phdr2->sid) |
|
||||
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type));
|
||||
+ __be16 proto = *(const __be16 *)(phdr + 1);
|
||||
+ __be16 proto2 = *(const __be16 *)(phdr2 + 1);
|
||||
+
|
||||
+ return (__force u16)((phdr->sid ^ phdr2->sid) | (proto ^ proto2));
|
||||
+}
|
||||
+
|
||||
+static __be16 pppoe_hdr_proto(struct pppoe_hdr *phdr)
|
||||
+static __be16 pppoe_hdr_proto(const struct pppoe_hdr *phdr)
|
||||
+{
|
||||
+ switch (phdr->tag[0].tag_type) {
|
||||
+ __be16 proto = *(const __be16 *)(phdr + 1);
|
||||
+
|
||||
+ switch (proto) {
|
||||
+ case cpu_to_be16(PPP_IP):
|
||||
+ return cpu_to_be16(ETH_P_IP);
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ case cpu_to_be16(PPP_IPV6):
|
||||
+ return cpu_to_be16(ETH_P_IPV6);
|
||||
+#endif
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *pppoe_gro_receive(struct list_head *head,
|
||||
@@ -61,26 +76,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+{
|
||||
+ const struct packet_offload *ptype;
|
||||
+ unsigned int hlen, off_pppoe;
|
||||
+ const struct pppoe_hdr *phdr;
|
||||
+ struct sk_buff *pp = NULL;
|
||||
+ struct pppoe_hdr *phdr;
|
||||
+ struct sk_buff *p;
|
||||
+ int flush = 1;
|
||||
+ __be16 type;
|
||||
+
|
||||
+ off_pppoe = skb_gro_offset(skb);
|
||||
+ hlen = off_pppoe + sizeof(*phdr);
|
||||
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe);
|
||||
+ hlen = off_pppoe + PPPOE_SES_HLEN;
|
||||
+ phdr = skb_gro_header(skb, hlen, off_pppoe);
|
||||
+ if (unlikely(!phdr))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* filter for session packets (type:1, ver:1, code:0) */
|
||||
+ if (*(const __be16 *)phdr != cpu_to_be16(0x1100))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* ignore packets with padding or invalid length */
|
||||
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + hlen)
|
||||
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + sizeof(*phdr))
|
||||
+ goto out;
|
||||
+
|
||||
+ type = pppoe_hdr_proto(phdr);
|
||||
+ if (!type)
|
||||
+ goto out;
|
||||
+
|
||||
+ ptype = gro_find_receive_by_type(type);
|
||||
+ if (!ptype)
|
||||
+ goto out;
|
||||
@@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ flush = 0;
|
||||
+
|
||||
+ list_for_each_entry(p, head, list) {
|
||||
+ struct pppoe_hdr *phdr2;
|
||||
+ const struct pppoe_hdr *phdr2;
|
||||
+
|
||||
+ if (!NAPI_GRO_CB(p)->same_flow)
|
||||
+ continue;
|
||||
+
|
||||
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe);
|
||||
+ phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
|
||||
+ if (compare_pppoe_header(phdr, phdr2))
|
||||
+ NAPI_GRO_CB(p)->same_flow = 0;
|
||||
+ }
|
||||
+
|
||||
+ skb_gro_pull(skb, sizeof(*phdr) + 2);
|
||||
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2);
|
||||
+ skb_gro_pull(skb, PPPOE_SES_HLEN);
|
||||
+ skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
|
||||
+
|
||||
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
|
||||
+ ipv6_gro_receive, inet_gro_receive,
|
||||
@@ -116,32 +132,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
|
||||
+ __be16 type = pppoe_hdr_proto(phdr);
|
||||
+ struct packet_offload *ptype;
|
||||
+ int len, err;
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ ptype = gro_find_complete_by_type(type);
|
||||
+ if (!ptype)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
|
||||
+ ipv6_gro_complete, inet_gro_complete,
|
||||
+ skb, nhoff + sizeof(*phdr) + 2);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ len = skb->len - (nhoff + sizeof(*phdr));
|
||||
+ len = min(len, 0xFFFFU);
|
||||
+ phdr->length = cpu_to_be16(len);
|
||||
+
|
||||
+ return 0;
|
||||
+ return INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
|
||||
+ ipv6_gro_complete, inet_gro_complete,
|
||||
+ skb, nhoff + PPPOE_SES_HLEN);
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
|
||||
+ netdev_features_t features)
|
||||
+{
|
||||
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
|
||||
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
|
||||
+ u16 mac_offset = skb->mac_header;
|
||||
+ struct packet_offload *ptype;
|
||||
+ u16 mac_len = skb->mac_len;
|
||||
+ struct pppoe_hdr *phdr;
|
||||
+ __be16 orig_type, type;
|
||||
+ int len, nhoff;
|
||||
@@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ skb_reset_network_header(skb);
|
||||
+ nhoff = skb_network_header(skb) - skb_mac_header(skb);
|
||||
+
|
||||
+ if (unlikely(!pskb_may_pull(skb, pppoe_hlen)))
|
||||
+ if (unlikely(!pskb_may_pull(skb, PPPOE_SES_HLEN)))
|
||||
+ goto out;
|
||||
+
|
||||
+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
|
||||
@@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ goto out;
|
||||
+
|
||||
+ orig_type = skb->protocol;
|
||||
+ __skb_pull(skb, pppoe_hlen);
|
||||
+ __skb_pull(skb, PPPOE_SES_HLEN);
|
||||
+ features &= ~NETIF_F_GSO_SOFTWARE;
|
||||
+ segs = ptype->callbacks.gso_segment(skb, features);
|
||||
+ if (IS_ERR_OR_NULL(segs)) {
|
||||
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
|
||||
+ mac_len);
|
||||
+ if (IS_ERR_OR_NULL(segs))
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ skb = segs;
|
||||
+ do {
|
||||
@@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
static int __init pppoe_init(void)
|
||||
{
|
||||
int err;
|
||||
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void)
|
||||
@@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
|
||||
if (err)
|
||||
goto out_unregister_pppoe_proto;
|
||||
|
||||
+ dev_add_offload(&pppoe_packet_offload);
|
||||
+ if (IS_ENABLED(CONFIG_INET))
|
||||
+ dev_add_offload(&pppoe_packet_offload);
|
||||
dev_add_pack(&pppoes_ptype);
|
||||
dev_add_pack(&pppoed_ptype);
|
||||
register_netdevice_notifier(&pppoe_notifier);
|
||||
@@ -1211,6 +1368,7 @@ static void __exit pppoe_exit(void)
|
||||
@@ -1211,6 +1368,8 @@ static void __exit pppoe_exit(void)
|
||||
unregister_netdevice_notifier(&pppoe_notifier);
|
||||
dev_remove_pack(&pppoed_ptype);
|
||||
dev_remove_pack(&pppoes_ptype);
|
||||
+ dev_remove_offload(&pppoe_packet_offload);
|
||||
+ if (IS_ENABLED(CONFIG_INET))
|
||||
+ dev_remove_offload(&pppoe_packet_offload);
|
||||
unregister_pppox_proto(PX_PROTO_OE);
|
||||
proto_unregister(&pppoe_sk_proto);
|
||||
unregister_pernet_device(&pppoe_net_ops);
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From 33d35975cbead3fa6b738ee57e5e45e14fbe0886 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Jelonek <jelonek.jonas@gmail.com>
|
||||
Date: Fri, 15 May 2026 14:31:03 +0000
|
||||
Subject: [PATCH] net: pse-pd: fix sign on -ENOENT check in of_load_pse_pis()
|
||||
|
||||
of_count_phandle_with_args() returns the count on success and a negative
|
||||
errno on failure, including -ENOENT when the "pairsets" property is
|
||||
absent. The existing comparison in of_load_pse_pis() checks against
|
||||
ENOENT (positive 2) instead of -ENOENT, so the branch is taken for any
|
||||
error return: legitimate DTs that omit "pairsets" trigger a spurious
|
||||
"wrong number of pairsets" error and probe fails with -EINVAL.
|
||||
|
||||
Compare against -ENOENT so a missing "pairsets" property is correctly
|
||||
treated as "this PI has no pairsets, continue".
|
||||
|
||||
Fixes: 9be9567a7c59 ("net: pse-pd: Add support for PSE PIs")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
|
||||
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
Link: https://patch.msgid.link/20260515143103.1721888-1-jelonek.jonas@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/pse-pd/pse_core.c
|
||||
+++ b/drivers/net/pse-pd/pse_core.c
|
||||
@@ -210,7 +210,7 @@ static int of_load_pse_pis(struct pse_co
|
||||
ret = of_load_pse_pi_pairsets(node, &pi, ret);
|
||||
if (ret)
|
||||
goto out;
|
||||
- } else if (ret != ENOENT) {
|
||||
+ } else if (ret != -ENOENT) {
|
||||
dev_err(pcdev->dev,
|
||||
"error: wrong number of pairsets. Should be 1 or 2, got %d (%pOF)\n",
|
||||
ret, node);
|
||||
+51
-41
@@ -1,6 +1,7 @@
|
||||
From 55a5d8fca8365312ed53bc93ae1af67ee35c2915 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 15 Jul 2025 12:37:45 +0200
|
||||
Subject: [PATCH] net: pppoe: implement GRO support
|
||||
Date: Wed, 13 May 2026 09:33:48 +0800
|
||||
Subject: [PATCH] net: pppoe: implement GRO/GSO support
|
||||
|
||||
Only handles packets where the pppoe header length field matches the exact
|
||||
packet length. Significantly improves rx throughput.
|
||||
@@ -11,7 +12,15 @@ that the device is able to handle improves from ~130 Mbit/s to ~630 Mbit/s,
|
||||
using fraglist GRO.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
|
||||
Tested-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Link: https://patch.msgid.link/20260513013400.7467-1-qingfang.deng@linux.dev
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ppp/pppoe.c | 161 +++++++++++++++++++++++++++++++++++++++-
|
||||
net/ipv4/af_inet.c | 2 +
|
||||
net/ipv6/ip6_offload.c | 2 +
|
||||
3 files changed, 164 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ppp/pppoe.c
|
||||
+++ b/drivers/net/ppp/pppoe.c
|
||||
@@ -32,28 +41,34 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
goto drop;
|
||||
|
||||
ph = pppoe_hdr(skb);
|
||||
@@ -1176,6 +1177,161 @@ static struct pernet_operations pppoe_ne
|
||||
@@ -1176,6 +1177,160 @@ static struct pernet_operations pppoe_ne
|
||||
.size = sizeof(struct pppoe_net),
|
||||
};
|
||||
|
||||
+static u16
|
||||
+compare_pppoe_header(struct pppoe_hdr *phdr, struct pppoe_hdr *phdr2)
|
||||
+compare_pppoe_header(const struct pppoe_hdr *phdr,
|
||||
+ const struct pppoe_hdr *phdr2)
|
||||
+{
|
||||
+ return (__force __u16)((phdr->sid ^ phdr2->sid) |
|
||||
+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type));
|
||||
+ __be16 proto = *(const __be16 *)(phdr + 1);
|
||||
+ __be16 proto2 = *(const __be16 *)(phdr2 + 1);
|
||||
+
|
||||
+ return (__force u16)((phdr->sid ^ phdr2->sid) | (proto ^ proto2));
|
||||
+}
|
||||
+
|
||||
+static __be16 pppoe_hdr_proto(struct pppoe_hdr *phdr)
|
||||
+static __be16 pppoe_hdr_proto(const struct pppoe_hdr *phdr)
|
||||
+{
|
||||
+ switch (phdr->tag[0].tag_type) {
|
||||
+ __be16 proto = *(const __be16 *)(phdr + 1);
|
||||
+
|
||||
+ switch (proto) {
|
||||
+ case cpu_to_be16(PPP_IP):
|
||||
+ return cpu_to_be16(ETH_P_IP);
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ case cpu_to_be16(PPP_IPV6):
|
||||
+ return cpu_to_be16(ETH_P_IPV6);
|
||||
+#endif
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *pppoe_gro_receive(struct list_head *head,
|
||||
@@ -61,26 +76,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+{
|
||||
+ const struct packet_offload *ptype;
|
||||
+ unsigned int hlen, off_pppoe;
|
||||
+ const struct pppoe_hdr *phdr;
|
||||
+ struct sk_buff *pp = NULL;
|
||||
+ struct pppoe_hdr *phdr;
|
||||
+ struct sk_buff *p;
|
||||
+ int flush = 1;
|
||||
+ __be16 type;
|
||||
+
|
||||
+ off_pppoe = skb_gro_offset(skb);
|
||||
+ hlen = off_pppoe + sizeof(*phdr);
|
||||
+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe);
|
||||
+ hlen = off_pppoe + PPPOE_SES_HLEN;
|
||||
+ phdr = skb_gro_header(skb, hlen, off_pppoe);
|
||||
+ if (unlikely(!phdr))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* filter for session packets (type:1, ver:1, code:0) */
|
||||
+ if (*(const __be16 *)phdr != cpu_to_be16(0x1100))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* ignore packets with padding or invalid length */
|
||||
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + hlen)
|
||||
+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + sizeof(*phdr))
|
||||
+ goto out;
|
||||
+
|
||||
+ type = pppoe_hdr_proto(phdr);
|
||||
+ if (!type)
|
||||
+ goto out;
|
||||
+
|
||||
+ ptype = gro_find_receive_by_type(type);
|
||||
+ if (!ptype)
|
||||
+ goto out;
|
||||
@@ -88,18 +104,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ flush = 0;
|
||||
+
|
||||
+ list_for_each_entry(p, head, list) {
|
||||
+ struct pppoe_hdr *phdr2;
|
||||
+ const struct pppoe_hdr *phdr2;
|
||||
+
|
||||
+ if (!NAPI_GRO_CB(p)->same_flow)
|
||||
+ continue;
|
||||
+
|
||||
+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe);
|
||||
+ phdr2 = (const struct pppoe_hdr *)(p->data + off_pppoe);
|
||||
+ if (compare_pppoe_header(phdr, phdr2))
|
||||
+ NAPI_GRO_CB(p)->same_flow = 0;
|
||||
+ }
|
||||
+
|
||||
+ skb_gro_pull(skb, sizeof(*phdr) + 2);
|
||||
+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2);
|
||||
+ skb_gro_pull(skb, PPPOE_SES_HLEN);
|
||||
+ skb_gro_postpull_rcsum(skb, phdr, PPPOE_SES_HLEN);
|
||||
+
|
||||
+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
|
||||
+ ipv6_gro_receive, inet_gro_receive,
|
||||
@@ -116,32 +132,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff);
|
||||
+ __be16 type = pppoe_hdr_proto(phdr);
|
||||
+ struct packet_offload *ptype;
|
||||
+ int len, err;
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ ptype = gro_find_complete_by_type(type);
|
||||
+ if (!ptype)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
|
||||
+ ipv6_gro_complete, inet_gro_complete,
|
||||
+ skb, nhoff + sizeof(*phdr) + 2);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ len = skb->len - (nhoff + sizeof(*phdr));
|
||||
+ len = min(len, 0xFFFFU);
|
||||
+ phdr->length = cpu_to_be16(len);
|
||||
+
|
||||
+ return 0;
|
||||
+ return INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
|
||||
+ ipv6_gro_complete, inet_gro_complete,
|
||||
+ skb, nhoff + PPPOE_SES_HLEN);
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb,
|
||||
+ netdev_features_t features)
|
||||
+{
|
||||
+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2;
|
||||
+ struct sk_buff *segs = ERR_PTR(-EINVAL);
|
||||
+ u16 mac_offset = skb->mac_header;
|
||||
+ struct packet_offload *ptype;
|
||||
+ u16 mac_len = skb->mac_len;
|
||||
+ struct pppoe_hdr *phdr;
|
||||
+ __be16 orig_type, type;
|
||||
+ int len, nhoff;
|
||||
@@ -149,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ skb_reset_network_header(skb);
|
||||
+ nhoff = skb_network_header(skb) - skb_mac_header(skb);
|
||||
+
|
||||
+ if (unlikely(!pskb_may_pull(skb, pppoe_hlen)))
|
||||
+ if (unlikely(!pskb_may_pull(skb, PPPOE_SES_HLEN)))
|
||||
+ goto out;
|
||||
+
|
||||
+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
|
||||
@@ -159,13 +169,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ goto out;
|
||||
+
|
||||
+ orig_type = skb->protocol;
|
||||
+ __skb_pull(skb, pppoe_hlen);
|
||||
+ __skb_pull(skb, PPPOE_SES_HLEN);
|
||||
+ features &= ~NETIF_F_GSO_SOFTWARE;
|
||||
+ segs = ptype->callbacks.gso_segment(skb, features);
|
||||
+ if (IS_ERR_OR_NULL(segs)) {
|
||||
+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset,
|
||||
+ mac_len);
|
||||
+ if (IS_ERR_OR_NULL(segs))
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ skb = segs;
|
||||
+ do {
|
||||
@@ -194,19 +202,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
static int __init pppoe_init(void)
|
||||
{
|
||||
int err;
|
||||
@@ -1192,6 +1348,7 @@ static int __init pppoe_init(void)
|
||||
@@ -1192,6 +1347,8 @@ static int __init pppoe_init(void)
|
||||
if (err)
|
||||
goto out_unregister_pppoe_proto;
|
||||
|
||||
+ dev_add_offload(&pppoe_packet_offload);
|
||||
+ if (IS_ENABLED(CONFIG_INET))
|
||||
+ dev_add_offload(&pppoe_packet_offload);
|
||||
dev_add_pack(&pppoes_ptype);
|
||||
dev_add_pack(&pppoed_ptype);
|
||||
register_netdevice_notifier(&pppoe_notifier);
|
||||
@@ -1211,6 +1368,7 @@ static void __exit pppoe_exit(void)
|
||||
@@ -1211,6 +1368,8 @@ static void __exit pppoe_exit(void)
|
||||
unregister_netdevice_notifier(&pppoe_notifier);
|
||||
dev_remove_pack(&pppoed_ptype);
|
||||
dev_remove_pack(&pppoes_ptype);
|
||||
+ dev_remove_offload(&pppoe_packet_offload);
|
||||
+ if (IS_ENABLED(CONFIG_INET))
|
||||
+ dev_remove_offload(&pppoe_packet_offload);
|
||||
unregister_pppox_proto(PX_PROTO_OE);
|
||||
proto_unregister(&pppoe_sk_proto);
|
||||
unregister_pernet_device(&pppoe_net_ops);
|
||||
@@ -3259,8 +3259,6 @@ define Device/tplink_f65-v1
|
||||
endef
|
||||
TARGET_DEVICES += tplink_f65-v1
|
||||
|
||||
define Device/tplink_fr365-v1
|
||||
|
||||
define Device/tplink_re6000xd
|
||||
DEVICE_VENDOR := TP-Link
|
||||
DEVICE_MODEL := RE6000XD
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
led-failsafe = &led_status_green;
|
||||
led-running = &led_status_green;
|
||||
led-upgrade = &led_status_green;
|
||||
label-mac-device = &gmac1;
|
||||
label-mac-device = &gmac0;
|
||||
};
|
||||
|
||||
gpio_export {
|
||||
|
||||
Reference in New Issue
Block a user