diff options
Diffstat (limited to 'target/linux/generic/patches-4.1/721-phy_packets.patch')
-rw-r--r-- | target/linux/generic/patches-4.1/721-phy_packets.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/target/linux/generic/patches-4.1/721-phy_packets.patch b/target/linux/generic/patches-4.1/721-phy_packets.patch new file mode 100644 index 0000000000..4855186b9f --- /dev/null +++ b/target/linux/generic/patches-4.1/721-phy_packets.patch @@ -0,0 +1,161 @@ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1270,6 +1270,7 @@ enum netdev_priv_flags { + IFF_XMIT_DST_RELEASE_PERM = 1<<22, + IFF_IPVLAN_MASTER = 1<<23, + IFF_IPVLAN_SLAVE = 1<<24, ++ IFF_NO_IP_ALIGN = 1<<25, + }; + + #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN +@@ -1297,6 +1298,7 @@ enum netdev_priv_flags { + #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM + #define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER + #define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE ++#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN + + /** + * struct net_device - The DEVICE structure. +@@ -1567,6 +1569,11 @@ struct net_device { + const struct swdev_ops *swdev_ops; + #endif + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); ++ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); ++#endif ++ + const struct header_ops *header_ops; + + unsigned int flags; +@@ -1633,6 +1640,10 @@ struct net_device { + struct mpls_dev __rcu *mpls_ptr; + #endif + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ void *phy_ptr; /* PHY device specific data */ ++#endif ++ + /* + * Cache lines mostly used on receive path (including eth_type_trans()) + */ +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2062,6 +2062,10 @@ static inline int pskb_trim(struct sk_bu + return (len < skb->len) ? __pskb_trim(skb, len) : 0; + } + ++extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length, gfp_t gfp); ++ ++ + /** + * pskb_trim_unique - remove end from a paged unique (not cloned) buffer + * @skb: buffer to alter +@@ -2188,16 +2192,6 @@ static inline struct sk_buff *dev_alloc_ + } + + +-static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, +- unsigned int length, gfp_t gfp) +-{ +- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); +- +- if (NET_IP_ALIGN && skb) +- skb_reserve(skb, NET_IP_ALIGN); +- return skb; +-} +- + static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, + unsigned int length) + { +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -25,6 +25,12 @@ menuconfig NET + + if NET + ++config ETHERNET_PACKET_MANGLE ++ bool ++ help ++ This option can be selected by phy drivers that need to mangle ++ packets going in or out of an ethernet device. ++ + config WANT_COMPAT_NETLINK_MESSAGES + bool + help +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2649,10 +2649,20 @@ static int xmit_one(struct sk_buff *skb, + if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) + dev_queue_xmit_nit(skb, dev); + +- len = skb->len; +- trace_net_dev_start_xmit(skb, dev); +- rc = netdev_start_xmit(skb, dev, txq, more); +- trace_net_dev_xmit(skb, rc, dev, len); ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (!dev->eth_mangle_tx || ++ (skb = dev->eth_mangle_tx(dev, skb)) != NULL) ++#else ++ if (1) ++#endif ++ { ++ len = skb->len; ++ trace_net_dev_start_xmit(skb, dev); ++ rc = netdev_start_xmit(skb, dev, txq, more); ++ trace_net_dev_xmit(skb, rc, dev, len); ++ } else { ++ rc = NETDEV_TX_OK; ++ } + + return rc; + } +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -63,6 +63,7 @@ + #include <linux/errqueue.h> + #include <linux/prefetch.h> + #include <linux/if_vlan.h> ++#include <linux/if.h> + + #include <net/protocol.h> + #include <net/dst.h> +@@ -568,6 +569,22 @@ struct sk_buff *__napi_alloc_skb(struct + } + EXPORT_SYMBOL(__napi_alloc_skb); + ++struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length, gfp_t gfp) ++{ ++ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); ++ ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) ++ return skb; ++#endif ++ ++ if (NET_IP_ALIGN && skb) ++ skb_reserve(skb, NET_IP_ALIGN); ++ return skb; ++} ++EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); ++ + void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, + int size, unsigned int truesize) + { +--- a/net/ethernet/eth.c ++++ b/net/ethernet/eth.c +@@ -167,6 +167,12 @@ __be16 eth_type_trans(struct sk_buff *sk + const struct ethhdr *eth; + + skb->dev = dev; ++ ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ if (dev->eth_mangle_rx) ++ dev->eth_mangle_rx(dev, skb); ++#endif ++ + skb_reset_mac_header(skb); + skb_pull_inline(skb, ETH_HLEN); + eth = eth_hdr(skb); |