* [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB.
@ 2013-12-13 9:25 freddy
[not found] ` <1386926708-2343-1-git-send-email-freddy-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: freddy @ 2013-12-13 9:25 UTC (permalink / raw)
To: netdev, davem, linux-usb, linux-kernel, louis, allan; +Cc: Freddy Xin
From: Freddy Xin <freddy@asix•com.tw>
The AX88179_178A has a hardware feature that it can insert a
2-bytes pseudo header in front of each received frame by setting
the AX_RX_CTL_IPE bit. This feature is used to let the IP header
be aligned on a doubleword-aligned address, so the rx_submit() of
usbnet.c needn't reserve NET_IP_ALIGN bytes for an SKB in the case.
This patch adds a flag of driver_info "FLAG_HW_IPALIGN" which is
used in rx_submit() of usbnet.c to determine whether reserving
NET_IP_ALIGN bytes for an SKB.
Signed-off-by: Freddy Xin <freddy@asix•com.tw>
---
drivers/net/usb/ax88179_178a.c | 8 ++++----
drivers/net/usb/usbnet.c | 5 ++++-
include/linux/usb/usbnet.h | 3 +++
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 8e8d0fc..04a2cc9 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1374,7 +1374,7 @@ static const struct driver_info ax88179_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_HW_IPALIGN,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@@ -1387,7 +1387,7 @@ static const struct driver_info ax88178a_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_HW_IPALIGN,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@@ -1400,7 +1400,7 @@ static const struct driver_info sitecom_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_HW_IPALIGN,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@@ -1413,7 +1413,7 @@ static const struct driver_info samsung_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_HW_IPALIGN,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 8494bb5..8a618b8 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -473,7 +473,10 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
return -ENOLINK;
}
- skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
+ if (dev->driver_info->flags & FLAG_HW_IPALIGN)
+ skb = __netdev_alloc_skb(dev->net, size, flags);
+ else
+ skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
if (!skb) {
netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index e303eef..e4855cf 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -116,6 +116,9 @@ struct driver_info {
#define FLAG_MULTI_PACKET 0x2000
#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
#define FLAG_NOARP 0x8000 /* device can't do ARP */
+#define FLAG_HW_IPALIGN 0x10000 /* hardware adds headers to let the
+ * IP header align on a dword-aligned
+ * address */
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 6+ messages in thread[parent not found: <1386926708-2343-1-git-send-email-freddy-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org>]
* RE: [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB. [not found] ` <1386926708-2343-1-git-send-email-freddy-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org> @ 2013-12-13 10:36 ` David Laight 2013-12-16 6:54 ` Freddy Xin 0 siblings, 1 reply; 6+ messages in thread From: David Laight @ 2013-12-13 10:36 UTC (permalink / raw) To: freddy-knRN6Y/kmf1NUHwG+Fw1Kw, netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q, linux-usb-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, louis-knRN6Y/kmf1NUHwG+Fw1Kw, allan-knRN6Y/kmf1NUHwG+Fw1Kw > From: freddy-knRN6Y/kmf1NUHwG+Fw1Kw@public•gmane.org ... > - skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); > + if (dev->driver_info->flags & FLAG_HW_IPALIGN) > + skb = __netdev_alloc_skb(dev->net, size, flags); > + else > + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); Given the definition: 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; } It really ought to be possible to code that without an extra conditional. David -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public•gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB. 2013-12-13 10:36 ` David Laight @ 2013-12-16 6:54 ` Freddy Xin [not found] ` <52AEA3A8.2020906-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org> 0 siblings, 1 reply; 6+ messages in thread From: Freddy Xin @ 2013-12-16 6:54 UTC (permalink / raw) To: David Laight, netdev, davem, linux-usb, linux-kernel, louis, allan On 2013年12月13日 18:36, David Laight wrote: >> From: freddy@asix•com.tw > ... >> - skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); >> + if (dev->driver_info->flags & FLAG_HW_IPALIGN) >> + skb = __netdev_alloc_skb(dev->net, size, flags); >> + else >> + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); > Given the definition: > 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; > } > > It really ought to be possible to code that without an extra conditional. > > David > > > > The AX88179_178A driver do need to know the value of NET_IP_ALIGN to determine whether enabling the feature that makes IP header align on a dword-aligned address, but according to the comments from David Miller, I need to consider all situations, not just for the case that NET_IP_ALIGN is zero, so the condition added in rx_submit is just used to determine whether reserving NET_IP_ALIGN bytes for each SKB. Freddy ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <52AEA3A8.2020906-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org>]
* RE: [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB. [not found] ` <52AEA3A8.2020906-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org> @ 2013-12-16 10:09 ` David Laight 2013-12-19 3:14 ` Freddy Xin 0 siblings, 1 reply; 6+ messages in thread From: David Laight @ 2013-12-16 10:09 UTC (permalink / raw) To: Freddy Xin, netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q, linux-usb-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, louis-knRN6Y/kmf1NUHwG+Fw1Kw, allan-knRN6Y/kmf1NUHwG+Fw1Kw > From: Freddy Xin > On 2013年12月13日 18:36, David Laight wrote: > >> From: freddy@asix•com.tw > > ... > >> - skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); > >> + if (dev->driver_info->flags & FLAG_HW_IPALIGN) > >> + skb = __netdev_alloc_skb(dev->net, size, flags); > >> + else > >> + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); > > Given the definition: > > 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; > > } > > > > It really ought to be possible to code that without an extra conditional. > > > > David > > The AX88179_178A driver do need to know the value of NET_IP_ALIGN > to determine whether enabling the feature that makes IP header align > on a dword-aligned address, but according to the comments from David > Miller, I need to consider all situations, not just for the case that > NET_IP_ALIGN is zero, so the condition added in rx_submit is just used to > determine whether reserving NET_IP_ALIGN bytes for each SKB. I was thinking of something like: skb = netdev_alloc_skb(dev, length + dev->skb_align, gfp); if (NET_IP_ALIGN && skb && !(ev->driver_flags & FLAG_HW_IPALIGN)) skb_reserve(skb, NET_IP_ALIGN); It might even be reasonable to remove the length adjustment - provided that all the later code uses the skb length. David ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB. 2013-12-16 10:09 ` David Laight @ 2013-12-19 3:14 ` Freddy Xin 2013-12-19 10:01 ` David Laight 0 siblings, 1 reply; 6+ messages in thread From: Freddy Xin @ 2013-12-19 3:14 UTC (permalink / raw) To: David Laight, netdev, davem, linux-usb, linux-kernel, louis, allan On 2013年12月16日 18:09, David Laight wrote: >> I was thinking of something like: skb = netdev_alloc_skb(dev, length >> + dev->skb_align, gfp); if (NET_IP_ALIGN && skb && !(ev->driver_flags >> & FLAG_HW_IPALIGN)) skb_reserve(skb, NET_IP_ALIGN); It might even be >> reasonable to remove the length adjustment - provided that all the >> later code uses the skb length. David Thanks for your advice. In the way you advised, does the dev->skb_align equal to NET_IP_ALIGN in the case that HW doesn't supoort IP alignment? In other words, dev->skb_align should be initialized to NET_IP_ALIGN in USBNET, and I can change its value to 0 in AX88179_178A driver, right? Freddy ^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB. 2013-12-19 3:14 ` Freddy Xin @ 2013-12-19 10:01 ` David Laight 0 siblings, 0 replies; 6+ messages in thread From: David Laight @ 2013-12-19 10:01 UTC (permalink / raw) To: Freddy Xin, netdev, davem, linux-usb, linux-kernel, louis, allan > From: Freddy Xin > On 2013年12月16日 18:09, David Laight wrote: > >> I was thinking of something like: skb = netdev_alloc_skb(dev, length > >> + dev->skb_align, gfp); if (NET_IP_ALIGN && skb && !(ev->driver_flags > >> & FLAG_HW_IPALIGN)) skb_reserve(skb, NET_IP_ALIGN); It might even be > >> reasonable to remove the length adjustment - provided that all the > >> later code uses the skb length. David > > Thanks for your advice. > In the way you advised, does the dev->skb_align equal > to NET_IP_ALIGN in the case that HW doesn't supoort > IP alignment? Yes > In other words, dev->skb_align should be initialized to > NET_IP_ALIGN in USBNET, and I can change its value to > 0 in AX88179_178A driver, right? I'd probably set a flag to request that usbnet set the offset to the correct value. That makes the initialisation a bit clearer. David ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-12-19 10:01 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-13 9:25 [PATCH 1/1] AX88179_178A: Add FLAG_HW_IPALIGN to determine whether reserving NET_IP_ALIGN bytes for an SKB freddy
[not found] ` <1386926708-2343-1-git-send-email-freddy-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org>
2013-12-13 10:36 ` David Laight
2013-12-16 6:54 ` Freddy Xin
[not found] ` <52AEA3A8.2020906-knRN6Y/kmf1NUHwG+Fw1Kw@public.gmane.org>
2013-12-16 10:09 ` David Laight
2013-12-19 3:14 ` Freddy Xin
2013-12-19 10:01 ` David Laight
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox