6c0898c5eefdbeb1146031b0968c2e8f4e37c9dc
[openwrt.git] / target / linux / generic / patches-3.19 / 721-phy_packets.patch
1 --- a/include/linux/netdevice.h
2 +++ b/include/linux/netdevice.h
3 @@ -1253,6 +1253,7 @@ enum netdev_priv_flags {
4         IFF_XMIT_DST_RELEASE_PERM       = 1<<22,
5         IFF_IPVLAN_MASTER               = 1<<23,
6         IFF_IPVLAN_SLAVE                = 1<<24,
7 +       IFF_NO_IP_ALIGN                 = 1<<25,
8  };
9  
10  #define IFF_802_1Q_VLAN                        IFF_802_1Q_VLAN
11 @@ -1280,6 +1281,7 @@ enum netdev_priv_flags {
12  #define IFF_XMIT_DST_RELEASE_PERM      IFF_XMIT_DST_RELEASE_PERM
13  #define IFF_IPVLAN_MASTER              IFF_IPVLAN_MASTER
14  #define IFF_IPVLAN_SLAVE               IFF_IPVLAN_SLAVE
15 +#define IFF_NO_IP_ALIGN                IFF_NO_IP_ALIGN
16  
17  /**
18   *     struct net_device - The DEVICE structure.
19 @@ -1550,6 +1552,11 @@ struct net_device {
20         const struct ethtool_ops *ethtool_ops;
21         const struct forwarding_accel_ops *fwd_ops;
22  
23 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
24 +       void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb);
25 +       struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb);
26 +#endif
27 +
28         const struct header_ops *header_ops;
29  
30         unsigned int            flags;
31 @@ -1613,6 +1620,10 @@ struct net_device {
32         struct wireless_dev     *ieee80211_ptr;
33         struct wpan_dev         *ieee802154_ptr;
34  
35 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
36 +       void                    *phy_ptr; /* PHY device specific data */
37 +#endif
38 +
39  /*
40   * Cache lines mostly used on receive path (including eth_type_trans())
41   */
42 --- a/include/linux/skbuff.h
43 +++ b/include/linux/skbuff.h
44 @@ -2042,6 +2042,10 @@ static inline int pskb_trim(struct sk_bu
45         return (len < skb->len) ? __pskb_trim(skb, len) : 0;
46  }
47  
48 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
49 +               unsigned int length, gfp_t gfp);
50 +
51 +
52  /**
53   *     pskb_trim_unique - remove end from a paged unique (not cloned) buffer
54   *     @skb: buffer to alter
55 @@ -2168,16 +2172,6 @@ static inline struct sk_buff *dev_alloc_
56  }
57  
58  
59 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
60 -               unsigned int length, gfp_t gfp)
61 -{
62 -       struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
63 -
64 -       if (NET_IP_ALIGN && skb)
65 -               skb_reserve(skb, NET_IP_ALIGN);
66 -       return skb;
67 -}
68 -
69  static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
70                 unsigned int length)
71  {
72 --- a/net/Kconfig
73 +++ b/net/Kconfig
74 @@ -25,6 +25,12 @@ menuconfig NET
75  
76  if NET
77  
78 +config ETHERNET_PACKET_MANGLE
79 +       bool
80 +       help
81 +         This option can be selected by phy drivers that need to mangle
82 +         packets going in or out of an ethernet device.
83 +
84  config WANT_COMPAT_NETLINK_MESSAGES
85         bool
86         help
87 --- a/net/core/dev.c
88 +++ b/net/core/dev.c
89 @@ -2620,10 +2620,20 @@ static int xmit_one(struct sk_buff *skb,
90         if (!list_empty(&ptype_all))
91                 dev_queue_xmit_nit(skb, dev);
92  
93 -       len = skb->len;
94 -       trace_net_dev_start_xmit(skb, dev);
95 -       rc = netdev_start_xmit(skb, dev, txq, more);
96 -       trace_net_dev_xmit(skb, rc, dev, len);
97 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
98 +       if (!dev->eth_mangle_tx ||
99 +           (skb = dev->eth_mangle_tx(dev, skb)) != NULL)
100 +#else
101 +       if (1)
102 +#endif
103 +       {
104 +               len = skb->len;
105 +               trace_net_dev_start_xmit(skb, dev);
106 +               rc = netdev_start_xmit(skb, dev, txq, more);
107 +               trace_net_dev_xmit(skb, rc, dev, len);
108 +       } else {
109 +               rc = NETDEV_TX_OK;
110 +       }
111  
112         return rc;
113  }
114 --- a/net/core/skbuff.c
115 +++ b/net/core/skbuff.c
116 @@ -63,6 +63,7 @@
117  #include <linux/errqueue.h>
118  #include <linux/prefetch.h>
119  #include <linux/if_vlan.h>
120 +#include <linux/if.h>
121  
122  #include <net/protocol.h>
123  #include <net/dst.h>
124 @@ -548,6 +549,22 @@ struct sk_buff *__napi_alloc_skb(struct
125  }
126  EXPORT_SYMBOL(__napi_alloc_skb);
127  
128 +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
129 +               unsigned int length, gfp_t gfp)
130 +{
131 +       struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
132 +
133 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
134 +       if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN))
135 +               return skb;
136 +#endif
137 +
138 +       if (NET_IP_ALIGN && skb)
139 +               skb_reserve(skb, NET_IP_ALIGN);
140 +       return skb;
141 +}
142 +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align);
143 +
144  void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
145                      int size, unsigned int truesize)
146  {
147 --- a/net/ethernet/eth.c
148 +++ b/net/ethernet/eth.c
149 @@ -188,6 +188,12 @@ __be16 eth_type_trans(struct sk_buff *sk
150         const struct ethhdr *eth;
151  
152         skb->dev = dev;
153 +
154 +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
155 +       if (dev->eth_mangle_rx)
156 +               dev->eth_mangle_rx(dev, skb);
157 +#endif
158 +
159         skb_reset_mac_header(skb);
160         skb_pull_inline(skb, ETH_HLEN);
161         eth = eth_hdr(skb);