* [PATCH] smsc95xx: add tx checksum offload support
@ 2008-10-14 15:17 Steve Glendinning
2008-10-14 18:52 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Steve Glendinning @ 2008-10-14 15:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Ian Saturley, Jeff Garzik, Steve Glendinning
LAN9500 supports tx checksum offload, which slightly decreases cpu
utilisation. The benefit isn't very large because we still require
the skb to be linearized, but it does save a few cycles.
This patch adds support for it, and enables it by default.
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
drivers/net/usb/smsc95xx.c | 75 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 51e2f5d..202979d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -31,7 +31,7 @@
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
-#define SMSC_DRIVER_VERSION "1.0.3"
+#define SMSC_DRIVER_VERSION "1.0.4"
#define HS_USB_PKT_SIZE (512)
#define FS_USB_PKT_SIZE (64)
#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
@@ -40,15 +40,18 @@
#define MAX_SINGLE_PACKET_SIZE (2048)
#define LAN95XX_EEPROM_MAGIC (0x9500)
#define EEPROM_MAC_OFFSET (0x01)
+#define DEFAULT_TX_CSUM_ENABLE (true)
#define DEFAULT_RX_CSUM_ENABLE (true)
#define SMSC95XX_INTERNAL_PHY_ID (1)
#define SMSC95XX_TX_OVERHEAD (8)
+#define SMSC95XX_TX_OVERHEAD_CSUM (12)
#define FLOW_CTRL_TX (1)
#define FLOW_CTRL_RX (2)
struct smsc95xx_priv {
u32 mac_cr;
spinlock_t mac_cr_lock;
+ bool use_tx_csum;
bool use_rx_csum;
};
@@ -556,9 +559,10 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata);
}
-/* Enable or disable Rx checksum offload engine */
-static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
+/* Enable or disable Tx & Rx checksum offload engines */
+static int smsc95xx_set_csums(struct usbnet *dev)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
u32 read_buf;
int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
if (ret < 0) {
@@ -566,7 +570,12 @@ static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
return ret;
}
- if (enable)
+ if (pdata->use_tx_csum)
+ read_buf |= Tx_COE_EN_;
+ else
+ read_buf &= ~Tx_COE_EN_;
+
+ if (pdata->use_rx_csum)
read_buf |= Rx_COE_EN_;
else
read_buf &= ~Rx_COE_EN_;
@@ -626,7 +635,26 @@ static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
pdata->use_rx_csum = !!val;
- return smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ return smsc95xx_set_csums(dev);
+}
+
+static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ return pdata->use_tx_csum;
+}
+
+static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ pdata->use_tx_csum = !!val;
+
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ return smsc95xx_set_csums(dev);
}
static struct ethtool_ops smsc95xx_ethtool_ops = {
@@ -640,6 +668,8 @@ static struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_tx_csum = smsc95xx_ethtool_get_tx_csum,
+ .set_tx_csum = smsc95xx_ethtool_set_tx_csum,
.get_rx_csum = smsc95xx_ethtool_get_rx_csum,
.set_rx_csum = smsc95xx_ethtool_set_rx_csum,
};
@@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct net_device *netdev = dev->net;
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
DECLARE_MAC_BUF(mac);
@@ -970,10 +1001,11 @@ static int smsc95xx_reset(struct usbnet *dev)
return ret;
}
- /* Enable or disable Rx checksum offload engine */
- ret = smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ /* Enable or disable checksum offload engines */
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ ret = smsc95xx_set_csums(dev);
if (ret < 0) {
- devwarn(dev, "Failed to set Rx csum offload: %d", ret);
+ devwarn(dev, "Failed to set csum offload: %d", ret);
return ret;
}
@@ -1029,6 +1061,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
spin_lock_init(&pdata->mac_cr_lock);
+ pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
/* Init all registers */
@@ -1148,22 +1181,44 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1;
}
+static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
+{
+ int len = skb->data - skb->head;
+ u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len);
+ u16 low_16 = (u16)(skb->csum_start - len);
+ return (high_16 << 16) | low_16;
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
- if (skb_headroom(skb) < SMSC95XX_TX_OVERHEAD) {
+ /* We do not advertise SG, so skbs should be already linearized */
+ BUG_ON(skb_shinfo(skb)->nr_frags);
+
+ if (skb_headroom(skb) < overhead) {
struct sk_buff *skb2 = skb_copy_expand(skb,
- SMSC95XX_TX_OVERHEAD, 0, flags);
+ overhead, 0, flags);
dev_kfree_skb_any(skb);
skb = skb2;
if (!skb)
return NULL;
}
+ if (csum) {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
+
skb_push(skb, 4);
tx_cmd_b = (u32)(skb->len - 4);
+ if (csum)
+ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
cpu_to_le32s(&tx_cmd_b);
memcpy(skb->data, &tx_cmd_b, 4);
--
1.5.5.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-10-14 15:17 [PATCH] smsc95xx: add tx checksum offload support Steve Glendinning
@ 2008-10-14 18:52 ` David Miller
2008-10-14 19:00 ` Roland Dreier
2008-10-14 19:04 ` David Miller
0 siblings, 2 replies; 11+ messages in thread
From: David Miller @ 2008-10-14 18:52 UTC (permalink / raw)
To: steve.glendinning; +Cc: netdev, ian.saturley, jeff
DO NOT email patches privately to us.
Send it to netdev@vger.kernel.org
If you email us patches privately:
1) no other developer in the world can review it
2) It doesn't get tracked at:
http://patchwork.ozlabs.org/project/netdev/list/
3) I have to spend 5 minutes typing this stupid email in
to explain things to you :-) Time I could spend reviewing
and processing patches.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-10-14 18:52 ` David Miller
@ 2008-10-14 19:00 ` Roland Dreier
2008-10-14 19:05 ` David Miller
2008-10-14 19:04 ` David Miller
1 sibling, 1 reply; 11+ messages in thread
From: Roland Dreier @ 2008-10-14 19:00 UTC (permalink / raw)
To: David Miller; +Cc: steve.glendinning, netdev, ian.saturley, jeff
> DO NOT email patches privately to us.
> Send it to netdev@vger.kernel.org
...
> 3) I have to spend 5 minutes typing this stupid email in
> to explain things to you :-) Time I could spend reviewing
> and processing patches.
Dave, I got the original email and it did have a netdev cc. You could
have saved yourself 4 minutes by taking 1 minute to double check the
original email ;)
- R.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-10-14 19:00 ` Roland Dreier
@ 2008-10-14 19:05 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-10-14 19:05 UTC (permalink / raw)
To: rdreier; +Cc: steve.glendinning, netdev, ian.saturley, jeff
From: Roland Dreier <rdreier@cisco.com>
Date: Tue, 14 Oct 2008 12:00:20 -0700
> > DO NOT email patches privately to us.
>
> > Send it to netdev@vger.kernel.org
>
> ...
>
> > 3) I have to spend 5 minutes typing this stupid email in
> > to explain things to you :-) Time I could spend reviewing
> > and processing patches.
>
> Dave, I got the original email and it did have a netdev cc. You could
> have saved yourself 4 minutes by taking 1 minute to double check the
> original email ;)
Indeed, see my followup. :-/
I'll go drink some more coffee now.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-10-14 18:52 ` David Miller
2008-10-14 19:00 ` Roland Dreier
@ 2008-10-14 19:04 ` David Miller
1 sibling, 0 replies; 11+ messages in thread
From: David Miller @ 2008-10-14 19:04 UTC (permalink / raw)
To: steve.glendinning; +Cc: netdev, ian.saturley, jeff
From: David Miller <davem@davemloft.net>
Date: Tue, 14 Oct 2008 11:52:15 -0700 (PDT)
>
> DO NOT email patches privately to us.
>
> Send it to netdev@vger.kernel.org
I am an asshole, sorry :-(
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] smsc95xx: add tx checksum offload support
@ 2008-11-17 10:50 Steve Glendinning
2008-11-19 22:28 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Steve Glendinning @ 2008-11-17 10:50 UTC (permalink / raw)
To: netdev; +Cc: Ian Saturley, Steve Glendinning
LAN9500 supports tx checksum offload, which slightly decreases cpu
utilisation. The benefit isn't very large because we still require
the skb to be linearized, but it does save a few cycles.
This patch adds support for it, and enables it by default.
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
drivers/net/usb/smsc95xx.c | 75 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 51e2f5d..202979d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -31,7 +31,7 @@
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
-#define SMSC_DRIVER_VERSION "1.0.3"
+#define SMSC_DRIVER_VERSION "1.0.4"
#define HS_USB_PKT_SIZE (512)
#define FS_USB_PKT_SIZE (64)
#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
@@ -40,15 +40,18 @@
#define MAX_SINGLE_PACKET_SIZE (2048)
#define LAN95XX_EEPROM_MAGIC (0x9500)
#define EEPROM_MAC_OFFSET (0x01)
+#define DEFAULT_TX_CSUM_ENABLE (true)
#define DEFAULT_RX_CSUM_ENABLE (true)
#define SMSC95XX_INTERNAL_PHY_ID (1)
#define SMSC95XX_TX_OVERHEAD (8)
+#define SMSC95XX_TX_OVERHEAD_CSUM (12)
#define FLOW_CTRL_TX (1)
#define FLOW_CTRL_RX (2)
struct smsc95xx_priv {
u32 mac_cr;
spinlock_t mac_cr_lock;
+ bool use_tx_csum;
bool use_rx_csum;
};
@@ -556,9 +559,10 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata);
}
-/* Enable or disable Rx checksum offload engine */
-static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
+/* Enable or disable Tx & Rx checksum offload engines */
+static int smsc95xx_set_csums(struct usbnet *dev)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
u32 read_buf;
int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
if (ret < 0) {
@@ -566,7 +570,12 @@ static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
return ret;
}
- if (enable)
+ if (pdata->use_tx_csum)
+ read_buf |= Tx_COE_EN_;
+ else
+ read_buf &= ~Tx_COE_EN_;
+
+ if (pdata->use_rx_csum)
read_buf |= Rx_COE_EN_;
else
read_buf &= ~Rx_COE_EN_;
@@ -626,7 +635,26 @@ static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
pdata->use_rx_csum = !!val;
- return smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ return smsc95xx_set_csums(dev);
+}
+
+static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ return pdata->use_tx_csum;
+}
+
+static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ pdata->use_tx_csum = !!val;
+
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ return smsc95xx_set_csums(dev);
}
static struct ethtool_ops smsc95xx_ethtool_ops = {
@@ -640,6 +668,8 @@ static struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_tx_csum = smsc95xx_ethtool_get_tx_csum,
+ .set_tx_csum = smsc95xx_ethtool_set_tx_csum,
.get_rx_csum = smsc95xx_ethtool_get_rx_csum,
.set_rx_csum = smsc95xx_ethtool_set_rx_csum,
};
@@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct net_device *netdev = dev->net;
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
DECLARE_MAC_BUF(mac);
@@ -970,10 +1001,11 @@ static int smsc95xx_reset(struct usbnet *dev)
return ret;
}
- /* Enable or disable Rx checksum offload engine */
- ret = smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ /* Enable or disable checksum offload engines */
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ ret = smsc95xx_set_csums(dev);
if (ret < 0) {
- devwarn(dev, "Failed to set Rx csum offload: %d", ret);
+ devwarn(dev, "Failed to set csum offload: %d", ret);
return ret;
}
@@ -1029,6 +1061,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
spin_lock_init(&pdata->mac_cr_lock);
+ pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
/* Init all registers */
@@ -1148,22 +1181,44 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1;
}
+static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
+{
+ int len = skb->data - skb->head;
+ u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len);
+ u16 low_16 = (u16)(skb->csum_start - len);
+ return (high_16 << 16) | low_16;
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
- if (skb_headroom(skb) < SMSC95XX_TX_OVERHEAD) {
+ /* We do not advertise SG, so skbs should be already linearized */
+ BUG_ON(skb_shinfo(skb)->nr_frags);
+
+ if (skb_headroom(skb) < overhead) {
struct sk_buff *skb2 = skb_copy_expand(skb,
- SMSC95XX_TX_OVERHEAD, 0, flags);
+ overhead, 0, flags);
dev_kfree_skb_any(skb);
skb = skb2;
if (!skb)
return NULL;
}
+ if (csum) {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
+
skb_push(skb, 4);
tx_cmd_b = (u32)(skb->len - 4);
+ if (csum)
+ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
cpu_to_le32s(&tx_cmd_b);
memcpy(skb->data, &tx_cmd_b, 4);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-11-17 10:50 Steve Glendinning
@ 2008-11-19 22:28 ` David Miller
2008-11-20 8:50 ` Steve.Glendinning
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2008-11-19 22:28 UTC (permalink / raw)
To: steve.glendinning; +Cc: netdev, ian.saturley
From: Steve Glendinning <steve.glendinning@smsc.com>
Date: Mon, 17 Nov 2008 10:50:00 +0000
> @@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
> static int smsc95xx_reset(struct usbnet *dev)
> {
> struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
> + struct net_device *netdev = dev->net;
> u32 read_buf, write_buf, burst_cap;
> int ret = 0, timeout;
> DECLARE_MAC_BUF(mac);
This smsc95xx_reset function doesn't even exist in the current driver.
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-11-19 22:28 ` David Miller
@ 2008-11-20 8:50 ` Steve.Glendinning
2008-11-20 8:54 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Steve.Glendinning @ 2008-11-20 8:50 UTC (permalink / raw)
To: David Miller; +Cc: ian.saturley, netdev
Hi David,
David Miller <davem@davemloft.net> wrote on 19/11/2008 22:28:55:
> From: Steve Glendinning <steve.glendinning@smsc.com>
> Date: Mon, 17 Nov 2008 10:50:00 +0000
>
> > @@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet
*dev)
> > static int smsc95xx_reset(struct usbnet *dev)
> > {
> > struct smsc95xx_priv *pdata = (struct smsc95xx_priv
*)(dev->data[0]);
> > + struct net_device *netdev = dev->net;
> > u32 read_buf, write_buf, burst_cap;
> > int ret = 0, timeout;
> > DECLARE_MAC_BUF(mac);
>
> This smsc95xx_reset function doesn't even exist in the current driver.
Are you sure you're looking at the same drivers/net/usb/smsc95xx.c? In
both Linus's tree and net-next-2.6 this function is on line 757.
The patch was against Linus's tree, the version in net-next-2.6 also has
Johannes Berg's print_mac patch applied so this section of code no longer
has DECLARE_MAC_BUF(mac);. Would you like me to rebase against
net-next-2.6 and resubmit?
Regards,
--
Steve Glendinning
SMSC GmbH
m: +44 777 933 9124
e: steve.glendinning@smsc.com
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-11-20 8:50 ` Steve.Glendinning
@ 2008-11-20 8:54 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-11-20 8:54 UTC (permalink / raw)
To: Steve.Glendinning; +Cc: ian.saturley, netdev
From: Steve.Glendinning@smsc.com
Date: Thu, 20 Nov 2008 08:50:16 +0000
> Hi David,
>
> David Miller <davem@davemloft.net> wrote on 19/11/2008 22:28:55:
>
> > From: Steve Glendinning <steve.glendinning@smsc.com>
> > Date: Mon, 17 Nov 2008 10:50:00 +0000
> >
> > > @@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet
> *dev)
> > > static int smsc95xx_reset(struct usbnet *dev)
> > > {
> > > struct smsc95xx_priv *pdata = (struct smsc95xx_priv
> *)(dev->data[0]);
> > > + struct net_device *netdev = dev->net;
> > > u32 read_buf, write_buf, burst_cap;
> > > int ret = 0, timeout;
> > > DECLARE_MAC_BUF(mac);
> >
> > This smsc95xx_reset function doesn't even exist in the current driver.
>
> Are you sure you're looking at the same drivers/net/usb/smsc95xx.c? In
> both Linus's tree and net-next-2.6 this function is on line 757.
I think I was looking at drivers/net/smsc*.c :-) Silly me.
> The patch was against Linus's tree, the version in net-next-2.6 also has
> Johannes Berg's print_mac patch applied so this section of code no longer
> has DECLARE_MAC_BUF(mac);. Would you like me to rebase against
> net-next-2.6 and resubmit?
Yes, please do, that's where I was going to apply it anyways.
Thanks!
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] smsc95xx: add tx checksum offload support
@ 2008-11-20 9:02 Steve Glendinning
2008-11-20 12:19 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Steve Glendinning @ 2008-11-20 9:02 UTC (permalink / raw)
To: davem; +Cc: Ian Saturley, netdev, Steve Glendinning
LAN9500 supports tx checksum offload, which slightly decreases cpu
utilisation. The benefit isn't very large because we still require
the skb to be linearized, but it does save a few cycles.
This patch adds support for it, and enables it by default.
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
drivers/net/usb/smsc95xx.c | 75 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index e0d349f..4638a7b 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -31,7 +31,7 @@
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
-#define SMSC_DRIVER_VERSION "1.0.3"
+#define SMSC_DRIVER_VERSION "1.0.4"
#define HS_USB_PKT_SIZE (512)
#define FS_USB_PKT_SIZE (64)
#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
@@ -40,15 +40,18 @@
#define MAX_SINGLE_PACKET_SIZE (2048)
#define LAN95XX_EEPROM_MAGIC (0x9500)
#define EEPROM_MAC_OFFSET (0x01)
+#define DEFAULT_TX_CSUM_ENABLE (true)
#define DEFAULT_RX_CSUM_ENABLE (true)
#define SMSC95XX_INTERNAL_PHY_ID (1)
#define SMSC95XX_TX_OVERHEAD (8)
+#define SMSC95XX_TX_OVERHEAD_CSUM (12)
#define FLOW_CTRL_TX (1)
#define FLOW_CTRL_RX (2)
struct smsc95xx_priv {
u32 mac_cr;
spinlock_t mac_cr_lock;
+ bool use_tx_csum;
bool use_rx_csum;
};
@@ -556,9 +559,10 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata);
}
-/* Enable or disable Rx checksum offload engine */
-static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
+/* Enable or disable Tx & Rx checksum offload engines */
+static int smsc95xx_set_csums(struct usbnet *dev)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
u32 read_buf;
int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
if (ret < 0) {
@@ -566,7 +570,12 @@ static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
return ret;
}
- if (enable)
+ if (pdata->use_tx_csum)
+ read_buf |= Tx_COE_EN_;
+ else
+ read_buf &= ~Tx_COE_EN_;
+
+ if (pdata->use_rx_csum)
read_buf |= Rx_COE_EN_;
else
read_buf &= ~Rx_COE_EN_;
@@ -626,7 +635,26 @@ static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
pdata->use_rx_csum = !!val;
- return smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ return smsc95xx_set_csums(dev);
+}
+
+static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ return pdata->use_tx_csum;
+}
+
+static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ pdata->use_tx_csum = !!val;
+
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ return smsc95xx_set_csums(dev);
}
static struct ethtool_ops smsc95xx_ethtool_ops = {
@@ -640,6 +668,8 @@ static struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_tx_csum = smsc95xx_ethtool_get_tx_csum,
+ .set_tx_csum = smsc95xx_ethtool_set_tx_csum,
.get_rx_csum = smsc95xx_ethtool_get_rx_csum,
.set_rx_csum = smsc95xx_ethtool_set_rx_csum,
};
@@ -757,6 +787,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct net_device *netdev = dev->net;
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
@@ -968,10 +999,11 @@ static int smsc95xx_reset(struct usbnet *dev)
return ret;
}
- /* Enable or disable Rx checksum offload engine */
- ret = smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ /* Enable or disable checksum offload engines */
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ ret = smsc95xx_set_csums(dev);
if (ret < 0) {
- devwarn(dev, "Failed to set Rx csum offload: %d", ret);
+ devwarn(dev, "Failed to set csum offload: %d", ret);
return ret;
}
@@ -1027,6 +1059,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
spin_lock_init(&pdata->mac_cr_lock);
+ pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
/* Init all registers */
@@ -1146,22 +1179,44 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1;
}
+static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
+{
+ int len = skb->data - skb->head;
+ u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len);
+ u16 low_16 = (u16)(skb->csum_start - len);
+ return (high_16 << 16) | low_16;
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
- if (skb_headroom(skb) < SMSC95XX_TX_OVERHEAD) {
+ /* We do not advertise SG, so skbs should be already linearized */
+ BUG_ON(skb_shinfo(skb)->nr_frags);
+
+ if (skb_headroom(skb) < overhead) {
struct sk_buff *skb2 = skb_copy_expand(skb,
- SMSC95XX_TX_OVERHEAD, 0, flags);
+ overhead, 0, flags);
dev_kfree_skb_any(skb);
skb = skb2;
if (!skb)
return NULL;
}
+ if (csum) {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
+
skb_push(skb, 4);
tx_cmd_b = (u32)(skb->len - 4);
+ if (csum)
+ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
cpu_to_le32s(&tx_cmd_b);
memcpy(skb->data, &tx_cmd_b, 4);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] smsc95xx: add tx checksum offload support
2008-11-20 9:02 Steve Glendinning
@ 2008-11-20 12:19 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-11-20 12:19 UTC (permalink / raw)
To: steve.glendinning; +Cc: ian.saturley, netdev
From: Steve Glendinning <steve.glendinning@smsc.com>
Date: Thu, 20 Nov 2008 09:02:36 +0000
> LAN9500 supports tx checksum offload, which slightly decreases cpu
> utilisation. The benefit isn't very large because we still require
> the skb to be linearized, but it does save a few cycles.
>
> This patch adds support for it, and enables it by default.
>
> Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
Applied, thanks for refreshing this against net-next-2.6
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-11-20 12:19 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-14 15:17 [PATCH] smsc95xx: add tx checksum offload support Steve Glendinning
2008-10-14 18:52 ` David Miller
2008-10-14 19:00 ` Roland Dreier
2008-10-14 19:05 ` David Miller
2008-10-14 19:04 ` David Miller
-- strict thread matches above, loose matches on Subject: below --
2008-11-17 10:50 Steve Glendinning
2008-11-19 22:28 ` David Miller
2008-11-20 8:50 ` Steve.Glendinning
2008-11-20 8:54 ` David Miller
2008-11-20 9:02 Steve Glendinning
2008-11-20 12:19 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox