* Re: Linux TCP's Robustness to Multipath Packet Reordering
From: Dominik Kaspar @ 2011-06-19 16:25 UTC (permalink / raw)
To: Alexander Zimmermann
Cc: netdev, Yuchung Cheng, Carsten Wolff, John Heffner, Eric Dumazet,
Lennart Schulte, Arnd Hannemann
In-Reply-To: <C040825C-480A-46C6-AF32-76D90717BA06@comsys.rwth-aachen.de>
Hi Alexander,
Ah... the receiver DSACKs the "original" packet. However, the sender
already received an ACK for its retransmission and advances SND.UNA.
When the DSACK finally arrives, it is actually outside of the SND.UNA
- SND.NXT range, which causes the DSACK to trigger "SACK reneging".
Did I get that right? :-)
Cheers,
Dominik
On Sun, Jun 19, 2011 at 5:38 PM, Alexander Zimmermann
<alexander.zimmermann@comsys.rwth-aachen.de> wrote:
> Hi,
>
> Am 19.06.2011 um 17:22 schrieb Dominik Kaspar:
>
>> Hello again,
>>
>> I have another question to Linux TCP and packet reordering. What
>> exactly happens, when a packet is so much delayed (but not causing a
>> timeout), that it gets overtaken by a retransmitted version of itself?
>> It seems to me that this results in "SACK reneging", but I don't
>> really understand why...
>
> in theory, you can detect this case with a combination of DSACK
> and timestamps. However, in practice a reordering delay greater than
> RTT will likely case an RTO (see RFC4653). IMO, if you have an packet
> reordering with an delay greater that the RTT, you have much more problems
> that SACK reneging
>
>>
>> The simplified situation goes this:
>> - Segment A gets sent and very much delayed (but not causing RTO)
>> - Segments B, C, D cause dupACKs
>> - Segment A_ret is retransmitted and ACKed (sent over new path)
>> - Some more segments E, F, ... are sent and ACKed
>> - Segment A (the delayed one) arrives at the receiver.
>> - Now what exactly happens next...?
>
> Receiver sends a DSACK
>
>>
>> I use default Linux TCP (with sack=1, dsack=1, fack=1, timestamps=1,
>> ...) and the above described series of events is cause why
>> transparently forwarding IP packets over multiple paths with RTTs of
>> 10 and 100 milliseconds.
>>
>> I'd appreciate your help - best regards,
>> Dominik
>
> //
> // Dipl.-Inform. Alexander Zimmermann
> // Department of Computer Science, Informatik 4
> // RWTH Aachen University
> // Ahornstr. 55, 52056 Aachen, Germany
> // phone: (49-241) 80-21422, fax: (49-241) 80-22222
> // email: zimmermann@cs.rwth-aachen.de
> // web: http://www.umic-mesh.net
> //
>
>
^ permalink raw reply
* [PATCH V2 00/11] net: expand time stamping, batch #2
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet
This patch series represents a continuation of the effort to get
better coverage of the SO_TIMESTAMPING socket API in the Ethernet
drivers. Adding time stamping support to a given driver solves two
separate issues, namely software transmit time stamping and hardware
time stamping in PHY devices.
This second batch adds the hooks into all remaining (?) arm and
powerpc MAC drivers using phylib. The first patch exports the receive
hook for use by non-NAPI drivers when compiled as modules. Patch #5
has been tested on real hardware, but the rest have only been compile
tested.
Richard Cochran (11):
net: export the receive time stamping hook for non-NAPI drivers
lib8390: enable transmit and receive time stamping.
emaclite: enable transmit and receive time stamping.
ll_temac: enable transmit and receive time stamping.
fec_mpc52xx: enable transmit and receive time stamping.
macb: enable transmit time stamping.
fs_enet: enable transmit time stamping.
smsc911x: enable transmit time stamping.
pxa168_eth: enable transmit time stamping.
mv643xx_eth: enable transmit time stamping.
ucc_geth: enable transmit time stamping.
drivers/net/fec_mpc52xx.c | 4 +++-
drivers/net/fs_enet/fs_enet-main.c | 2 ++
drivers/net/lib8390.c | 5 +++--
drivers/net/ll_temac_main.c | 5 ++++-
drivers/net/macb.c | 2 ++
drivers/net/mv643xx_eth.c | 2 ++
drivers/net/pxa168_eth.c | 3 +++
drivers/net/smsc911x.c | 1 +
drivers/net/ucc_geth.c | 2 ++
drivers/net/xilinx_emaclite.c | 9 +++++++--
net/core/timestamping.c | 1 +
11 files changed, 30 insertions(+), 6 deletions(-)
^ permalink raw reply
* [PATCH V2 01/11] net: export the receive time stamping hook for non-NAPI drivers
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
Ethernet MAC drivers based on phylib (but not using NAPI) can
enable hardware time stamping in phy devices by calling netif_rx()
conditionally based on a call to skb_defer_rx_timestamp().
This commit exports that function so that drivers calling it may
be compiled as modules.
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
net/core/timestamping.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 3b00a6b..98a5264 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -122,6 +122,7 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
return false;
}
+EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp);
void __init skb_timestamping_init(void)
{
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 02/11] lib8390: enable transmit and receive time stamping.
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) time stamping. This file is
included by drivers/net/ax88796.c, which is based on phylib. So, this
patch makes hardware time stamping in the PHY possible.
Compile tested only.
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/lib8390.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 17b75e5..70eb207 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -410,7 +410,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb,
spin_unlock(&ei_local->page_lock);
enable_irq_lockdep_irqrestore(dev->irq, &flags);
-
+ skb_tx_timestamp(skb);
dev_kfree_skb (skb);
dev->stats.tx_bytes += send_length;
@@ -758,7 +758,8 @@ static void ei_receive(struct net_device *dev)
skb_put(skb, pkt_len); /* Make room */
ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 04/11] ll_temac: enable transmit and receive time stamping.
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Grant Likely
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) time stamping. Since this MAC
is based on phylib, adding the hooks makes hardware time stamping in the
phy possible.
Compile tested only.
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/ll_temac_main.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index b7948cc..ce9a607 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -727,6 +727,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
if (lp->tx_bd_tail >= TX_BD_NUM)
lp->tx_bd_tail = 0;
+ skb_tx_timestamp(skb);
+
/* Kick off the transfer */
lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
@@ -772,7 +774,8 @@ static void ll_temac_recv(struct net_device *ndev)
skb->ip_summed = CHECKSUM_COMPLETE;
}
- netif_rx(skb);
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(skb);
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += length;
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 05/11] fec_mpc52xx: enable transmit and receive time stamping.
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Grant Likely
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) time stamping. Software
time stamping using the SO_TIMESTAMPING API was tested and found to be
working on the LITE5200B board.
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/fec_mpc52xx.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 9f81b1a..a4dd6a4 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -335,6 +335,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
bd->skb_pa = dma_map_single(dev->dev.parent, skb->data, skb->len,
DMA_TO_DEVICE);
+ skb_tx_timestamp(skb);
bcom_submit_next_buffer(priv->tx_dmatsk, skb);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -434,7 +435,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
length = status & BCOM_FEC_RX_BD_LEN_MASK;
skb_put(rskb, length - 4); /* length without CRC32 */
rskb->protocol = eth_type_trans(rskb, dev);
- netif_rx(rskb);
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(rskb);
spin_lock(&priv->lock);
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 06/11] macb: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Nicolas Ferre
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping
Compile tested only.
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/macb.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 6c6a028..fab63bf 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -669,6 +669,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
entry = NEXT_TX(entry);
bp->tx_head = entry;
+ skb_tx_timestamp(skb);
+
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
if (TX_BUFFS_AVAIL(bp) < 1)
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 07/11] fs_enet: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:57 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Pantelis Antoniou, Vitaly Bordug
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping.
Compile tested only.
Cc: Pantelis Antoniou <pantelis.antoniou@gmail.com>
Cc: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/fs_enet/fs_enet-main.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 21abb5c..329ef23 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -697,6 +697,8 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
sc |= BD_ENET_TX_PAD;
CBDS_SC(bdp, sc);
+ skb_tx_timestamp(skb);
+
(*fep->ops->tx_kickstart)(dev);
spin_unlock_irqrestore(&fep->tx_lock, flags);
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 08/11] smsc911x: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:57 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Steve Glendinning
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping.
Compile tested only.
Cc: Steve Glendinning <steve.glendinning@smsc.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/smsc911x.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index c6d47d1..6d08b0f 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1473,6 +1473,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
freespace -= (skb->len + 32);
+ skb_tx_timestamp(skb);
dev_kfree_skb(skb);
if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30))
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 09/11] pxa168_eth: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:57 UTC (permalink / raw)
To: netdev
Cc: David Miller, Eric Dumazet, Sachin Sanap, Zhangfei Gao,
Philip Rakity
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping
Compile tested only.
Cc: Sachin Sanap <ssanap@marvell.com>
Cc: Zhangfei Gao <zgao6@marvell.com>
Cc: Philip Rakity <prakity@marvell.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/pxa168_eth.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index 89f7540..e224740 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -1267,6 +1267,9 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
pep->tx_skb[tx_index] = skb;
desc->byte_cnt = length;
desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+
+ skb_tx_timestamp(skb);
+
wmb();
desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC |
TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT;
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 10/11] mv643xx_eth: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:57 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Lennert Buytenhek
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping.
Compile tested only.
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/mv643xx_eth.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a5d9b1c..b63a074 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -847,6 +847,8 @@ no_csum:
/* clear TX_END status */
mp->work_tx_end &= ~(1 << txq->index);
+ skb_tx_timestamp(skb);
+
/* ensure all descriptors are written before poking hardware */
wmb();
txq_enable(txq);
--
1.7.0.4
^ permalink raw reply related
* [PATCH V2 11/11] ucc_geth: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 17:57 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, Shlomi Gridish, Li Yang
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) transmit time stamping.
Compile tested only.
Cc: Shlomi Gridish <gridish@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/ucc_geth.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index ef04105..3127700 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3165,6 +3165,8 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
ugeth->txBd[txQ] = bd;
+ skb_tx_timestamp(skb);
+
if (ugeth->p_scheduler) {
ugeth->cpucount[txQ]++;
/* Indicate to QE that there are more Tx bds ready for
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 07/11] fs_enet: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 18:12 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, David Miller, Pantelis Antoniou, Vitaly Bordug
In-Reply-To: <1308484684.3539.76.camel@edumazet-laptop>
On Sun, Jun 19, 2011 at 01:58:04PM +0200, Eric Dumazet wrote:
>
> Well, I'll stop my review here, there is the same problem I guess in all
> your patches.
Thanks for your review. I have posted a fix for the first batch (since
they are already in next) and reposted this series.
But, considering your point, it looks like pxa168_eth and mv643xx_eth
(see patches 9 and 10 of this series) already access skb->len unsafely.
Would you care to comment on those spots, too?
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH 09/11] pxa168_eth: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 18:15 UTC (permalink / raw)
To: netdev
Cc: David Miller, Sachin Sanap, Zhangfei Gao, Philip Rakity,
Eric Dumazet
In-Reply-To: <bda59e6bdd024ed1c3249b1708900d0fa0baa994.1308481492.git.richard.cochran@omicron.at>
On Sun, Jun 19, 2011 at 01:20:05PM +0200, Richard Cochran wrote:
> This patch enables software (and phy device) transmit time stamping
> Compile tested only.
>
> Cc: Sachin Sanap <ssanap@marvell.com>
> Cc: Zhangfei Gao <zgao6@marvell.com>
> Cc: Philip Rakity <prakity@marvell.com>
> Cc: Mark Brown <markb@marvell.com>
> Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
> ---
> drivers/net/pxa168_eth.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
> index 89f7540..cd2e471 100644
> --- a/drivers/net/pxa168_eth.c
> +++ b/drivers/net/pxa168_eth.c
> @@ -1273,6 +1273,7 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
> wmb();
> wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
>
> + skb_tx_timestamp(skb);
> stats->tx_bytes += skb->len;
And the line above is unsafe, too.
> stats->tx_packets++;
> dev->trans_start = jiffies;
> --
> 1.7.0.4
>
^ permalink raw reply
* Re: [PATCH 10/11] mv643xx_eth: enable transmit time stamping.
From: Richard Cochran @ 2011-06-19 18:17 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Lennert Buytenhek, Eric Dumazet
In-Reply-To: <1b5632e5cd90ed390245f3d1264e42fdd760dd7e.1308481492.git.richard.cochran@omicron.at>
On Sun, Jun 19, 2011 at 01:20:06PM +0200, Richard Cochran wrote:
> This patch enables software (and phy device) transmit time stamping.
> Compile tested only.
>
> Cc: Lennert Buytenhek <buytenh@wantstofly.org>
> Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
> ---
> drivers/net/mv643xx_eth.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
> index a5d9b1c..c7a8f10 100644
> --- a/drivers/net/mv643xx_eth.c
> +++ b/drivers/net/mv643xx_eth.c
> @@ -884,6 +884,8 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
> if (!txq_submit_skb(txq, skb)) {
> int entries_left;
>
> + skb_tx_timestamp(skb);
> +
> txq->tx_bytes += skb->len;
And the line above is unsafe, as well.
> txq->tx_packets++;
>
> --
> 1.7.0.4
>
^ permalink raw reply
* Re: [PATCH 07/11] fs_enet: enable transmit time stamping.
From: Eric Dumazet @ 2011-06-19 18:30 UTC (permalink / raw)
To: Richard Cochran; +Cc: netdev, David Miller, Pantelis Antoniou, Vitaly Bordug
In-Reply-To: <20110619181212.GA3594@riccoc20.at.omicron.at>
Le dimanche 19 juin 2011 à 20:12 +0200, Richard Cochran a écrit :
> Thanks for your review. I have posted a fix for the first batch (since
> they are already in next) and reposted this series.
>
> But, considering your point, it looks like pxa168_eth and mv643xx_eth
> (see patches 9 and 10 of this series) already access skb->len unsafely.
>
> Would you care to comment on those spots, too?
They certainly are buggy, at a first glance.
Not only skb->len is unsafe, but netif_tx_stop_queue() calls are unsafe
too.
Not sure anyone still use these drivers...
^ permalink raw reply
* Re: [PATCH 10/11] mv643xx_eth: enable transmit time stamping.
From: Eric Dumazet @ 2011-06-19 18:33 UTC (permalink / raw)
To: Richard Cochran; +Cc: netdev, David Miller, Lennert Buytenhek
In-Reply-To: <20110619181740.GC3594@riccoc20.at.omicron.at>
Le dimanche 19 juin 2011 à 20:17 +0200, Richard Cochran a écrit :
> On Sun, Jun 19, 2011 at 01:20:06PM +0200, Richard Cochran wrote:
> > This patch enables software (and phy device) transmit time stamping.
> > Compile tested only.
> >
> > Cc: Lennert Buytenhek <buytenh@wantstofly.org>
> > Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
> > ---
> > drivers/net/mv643xx_eth.c | 2 ++
> > 1 files changed, 2 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
> > index a5d9b1c..c7a8f10 100644
> > --- a/drivers/net/mv643xx_eth.c
> > +++ b/drivers/net/mv643xx_eth.c
> > @@ -884,6 +884,8 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
> > if (!txq_submit_skb(txq, skb)) {
> > int entries_left;
> >
> > + skb_tx_timestamp(skb);
> > +
> > txq->tx_bytes += skb->len;
>
> And the line above is unsafe, as well.
>
Yes, for sure, please submit patches to fix this (before adding time
stamping patches), as this should go to stable.
^ permalink raw reply
* Re: [PATCH 2/3] net/fec: add device tree support
From: Grant Likely @ 2011-06-19 18:43 UTC (permalink / raw)
To: Rob Herring
Cc: Arnd Bergmann, Shawn Guo, linux-arm-kernel, Greg Ungerer, patches,
netdev, devicetree-discuss, Jason Liu, linux-kernel,
David S. Miller
In-Reply-To: <4DFE111B.8010001@gmail.com>
On Sun, Jun 19, 2011 at 9:09 AM, Rob Herring <robherring2@gmail.com> wrote:
> On 06/19/2011 07:11 AM, Arnd Bergmann wrote:
>> On Sunday 19 June 2011 13:39:32 Greg Ungerer wrote:
>>>> +#ifdef CONFIG_OF
>>>> +static const struct of_device_id fec_dt_ids[] = {
>>>> + { .compatible = "fsl,fec", .data =&fec_devtype[0], },
>>>> + {},
>>>> +};
>>>> +
>>>> +static const struct of_device_id *
>>>> +fec_get_of_device_id(struct platform_device *pdev)
>>>> +{
>>>> + return of_match_device(fec_dt_ids,&pdev->dev);
>>>> +}
>>>> +#else
>>>> +#define fec_dt_ids NULL
>>>> +static inline struct of_device_id *
>>>> +fec_get_of_device_id(struct platform_device *pdev)
>>>> +{
>>>> + return NULL;
>>>> +}
>>>> +#endif
>>>> +
>>>> static unsigned char macaddr[ETH_ALEN];
>>>> module_param_array(macaddr, byte, NULL, 0);
>>>> MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
>>>> @@ -1363,6 +1385,11 @@ fec_probe(struct platform_device *pdev)
>>>> struct net_device *ndev;
>>>> int i, irq, ret = 0;
>>>> struct resource *r;
>>>> + const struct of_device_id *of_id;
>>>> +
>>>> + of_id = fec_get_of_device_id(pdev);
>>>
>>> fec_get_of_device_id() is defined inside of "#ifdef CONFIG_OF". This
>>> use of it will break compilation when this is not defined.
>>>
>>
>>
>> Why? Note the #else path defining an empty function.
>>
>
> None of this is necessary in the first place. Just call of_match_device
> directly. There is already an empty function to return NULL when
> CONFIG_OF is not defined.
Heh, right you are. I should have caught on to that. :-)
g.
^ permalink raw reply
* Re: [PATCH 1/3] serial/imx: add device tree support
From: Grant Likely @ 2011-06-19 18:44 UTC (permalink / raw)
To: Rob Herring
Cc: Shawn Guo, patches, netdev, devicetree-discuss, Jason Liu,
linux-kernel, Jeremy Kerr, Sascha Hauer, linux-arm-kernel
In-Reply-To: <4DFE129E.1010800@gmail.com>
On Sun, Jun 19, 2011 at 9:15 AM, Rob Herring <robherring2@gmail.com> wrote:
> On 06/19/2011 10:05 AM, Grant Likely wrote:
>> On Sun, Jun 19, 2011 at 1:30 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
>>> On Sat, Jun 18, 2011 at 10:19:34AM -0600, Grant Likely wrote:
>>>> On Sat, Jun 18, 2011 at 11:19:12PM +0800, Shawn Guo wrote:
>>>>> It adds device tree data parsing support for imx tty/serial driver.
>>>>>
>>>>> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
>>>>> Signed-off-by: Jason Liu <jason.hui@linaro.org>
>>>>> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>>>>> Cc: Sascha Hauer <s.hauer@pengutronix.de>
>>>>> ---
>>>>> .../bindings/tty/serial/fsl-imx-uart.txt | 21 +++++
>>>>> drivers/tty/serial/imx.c | 81 +++++++++++++++++---
>>>>> 2 files changed, 92 insertions(+), 10 deletions(-)
>>>>> create mode 100644 Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
>>>>> new file mode 100644
>>>>> index 0000000..7648e17
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
>>>>> @@ -0,0 +1,21 @@
>>>>> +* Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)
>>>>> +
>>>>> +Required properties:
>>>>> +- compatible : should be "fsl,<soc>-uart", "fsl,imx-uart"
>>>>
>>>> I'd make this "fsl,<soc>-uart", "fsl,imx51-uart"
>>>>
>>>> It's better to anchor these things on real silicon, or a real ip block
>>>> specification rather than something pseudo-generic. Subsequent chips,
>>>> like the imx53, should simply claim compatibility with the older
>>>> fsl,imx51-uart.
>>>
>>> It is a real IP block on all imx silicons (except imx23 and imx28
>>> which are known as former stmp).
>>>
>>>>
>>>> (in essence, "fsl,imx51-uart" becomes the generic string without the
>>>> downside of having no obvious recourse when new silicon shows up that
>>>> is an imx part, but isn't compatible with the imx51 uart.
>>>>
>>> In this case, should imx1 the ancestor of imx family than imx51
>>> becomes part of that generic string? Claiming uart of imx1, imx21
>>> and imx31 (senior than imx51) compatible with the imx51 uart seems
>>> odd to me.
>>>
>>> That said, IMO, "fsl,imx-uart" stands a real IP block specification
>>> here and can be a perfect generic compatibility string to tell the
>>> recourse of any imx silicon using this IP.
>>
>> Yes, but which /version/ of the IP block? Hardware designers are
>> notorious for changing hardware designs for newer silicon, sometimes
>> to add features, sometimes to fix bugs. While I understand the
>> temptation to boil a compatible value down to a nice clean generic
>> string, doing so only works in a perfect world. In the real world,
>> you still need to have some information about the specific
>> implementation. I prefer this specifying it to the SoC name, but I've
>> been known to be convinced that specifying it to the ip-block name &
>> version in certain circumstances, like for IP blocks in an FPGA, or
>> some of the Freescale powerpc pXXXX SoCs which actually had an IP
>> block swapped out midway through the life of the chip.
>>
>
> There are definitely uart changes along the way with each generation.
>
>> Besides, encoding an soc or ip block version into the 'generic'
>> compatible values is not just good practice, it has *zero downside*.
>> That's the beauty of the compatible property semantics. Any node can
>> claim compatibility with an existing device. If no existing device
>> fits correctly, then the node simple does not claim compatibility.
>> Drivers can bind to any number of compatible strings, so it would be
>> just fine for the of_match_table list to include both "fsl,imx-21" and
>> "fsl,imx-51" (assuming that is the appropriate solution in this case).
>>
>
> Don't you need uart or serial in here somewhere.
you are of course correct. The examples should be "fsl,imx21-uart" &
"fsl,imx51-uart". I was just writing too quickly.
g.
^ permalink raw reply
* [PATCH V2 03/11] emaclite: enable transmit and receive time stamping.
From: Richard Cochran @ 2011-06-19 17:56 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eric Dumazet, John Linn
In-Reply-To: <cover.1308499701.git.richard.cochran@omicron.at>
This patch enables software (and phy device) time stamping. Since this
MAC uses phylib, adding the hooks make hardware time stamping in the phy
possible.
Compile tested only.
Cc: John Linn <john.linn@xilinx.com>
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
drivers/net/xilinx_emaclite.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 372572c..8cae4f6 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -647,7 +647,8 @@ static void xemaclite_rx_handler(struct net_device *dev)
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
- netif_rx(skb); /* Send the packet upstream */
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(skb); /* Send the packet upstream */
}
/**
@@ -1029,15 +1030,19 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
spin_lock_irqsave(&lp->reset_lock, flags);
if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) {
/* If the Emaclite Tx buffer is busy, stop the Tx queue and
- * defer the skb for transmission at a later point when the
+ * defer the skb for transmission during the ISR, after the
* current transmission is complete */
netif_stop_queue(dev);
lp->deferred_skb = new_skb;
+ /* Take the time stamp now, since we can't do this in an ISR. */
+ skb_tx_timestamp(new_skb);
spin_unlock_irqrestore(&lp->reset_lock, flags);
return 0;
}
spin_unlock_irqrestore(&lp->reset_lock, flags);
+ skb_tx_timestamp(new_skb);
+
dev->stats.tx_bytes += len;
dev_kfree_skb(new_skb);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 10/11] mv643xx_eth: enable transmit time stamping.
From: David Miller @ 2011-06-19 19:05 UTC (permalink / raw)
To: eric.dumazet; +Cc: richardcochran, netdev, buytenh
In-Reply-To: <1308508398.3539.80.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 19 Jun 2011 20:33:18 +0200
> Yes, for sure, please submit patches to fix this (before adding time
> stamping patches), as this should go to stable.
Agreed.
^ permalink raw reply
* Re: [PATCH v2 1/5] net: Support ethtool ops for rx of errored frames.
From: Ben Greear @ 2011-06-19 20:11 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20110618213400.GA2741@electric-eye.fr.zoreil.com>
On 06/18/2011 02:34 PM, Francois Romieu wrote:
> greearb@candelatech.com<greearb@candelatech.com> :
> [...]
>> This can be useful when sniffing dodgy networks.
>
> Do you plan to add something similar - i.e. not per packet - for the Tx path ?
Ability to tx errored frames? I posted a patch to enable sending
frames with custom (ie, invalid) Ethernet FCS, but you have to
enable it per-socket, and it will only work with AF_PACKET sockets.
Can you offer more details on what you are asking for?
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Ethernet low-level frame debugging support
From: Ben Greear @ 2011-06-19 20:19 UTC (permalink / raw)
To: Mark Smith; +Cc: netdev
In-Reply-To: <20110619104431.23a22fe9@opy.nosense.org>
On 06/18/2011 06:14 PM, Mark Smith wrote:
> Hi,
>
> Firstly, I think this is a potentially quite useful feature for
> networking people and that I hope it makes it into the kernel proper.
>
> One thing I've thought is that perhaps it might be made and named a bit
> more generally, as NICs will also drop frames for other reasons other
> than FCs failures e.g. runt frames. So perhaps something like "true
> promiscuous" or "full promiscuous" might be a more general name, and if
> it is enabled, then all NIC error checking that can be switched off is
> switched off. Looking at the chipset data sheets for a few NICs that I
> have / have had (netgear FA312 (natsemi ns83815), smc epic100, ne2000),
> they all seem to have registers which allow switching off many if not
> all of the NIC error checking settings.
I called it 'save-rxerr' in ethtool...I think that is general enough?
The early patch that saves the FCS just passes the 4-byte FCS up the stack.
It doesn't change the ability to receive bad frames or not..that is in the
later patches.
>
> The other thing I've thought could be useful would be to be able to
> send runts by not padding the frames when they're less then 64 bytes.
> I've been able to test if this is possible with the netgear FA312, as
> the chipset does the padding. I connected it back to back with an
> e1000e I have, switched off the chipset automatic padding on the FA312,
> sent small traffic, and then saw that the e1000e's internal
> rx_short_length_errors counter correspondingly increased. Of course I
> can't see them with tcpdump on the e1000e because it is dropping them.
Maybe the SO_NOFCS option could change to SO_DRVOPTS and take a bit-field
instead of just be on/off. NOFCS could be one flag, NOPAD another, etc.
That would give ability to send non-padded frames if the driver has
support.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: rcu_sched_state detected stall on CPU 0, 3.0-rc2
From: Andy Isaacson @ 2011-06-19 21:20 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Paul E. McKenney, linux-kernel, netdev, linux-pm
In-Reply-To: <20110613060453.GA21778@hexapodia.org>
On Sun, Jun 12, 2011 at 11:04:53PM -0700, Andy Isaacson wrote:
> On Sun, Jun 12, 2011 at 10:30:05PM -0400, Ben Hutchings wrote:
> > > Of course now that I'm trying to debug, I am seeing many successful
> > > suspend-resume cycles. I don't see any signs of difference between the
> > > cases that hung and the cases that are now succeeding.
> > >
> > > CCing netdev, because I suspend by running pm-suspend, and in at least
> > > one failure, an ethtool running under pm-suspend seemed to be the
> > > problem:
> > >
> > > root 11558 pts/8 S+ \_ /bin/sh /usr/lib/pm-utils/sleep.d/00powers
> > > root 11559 pts/8 S+ \_ /bin/sh /usr/sbin/pm-powersave
> > > root 11576 pts/8 S+ \_ /bin/sh /usr/lib/pm-utils/power.d/
> > > root 11577 pts/8 D+ \_ ethtool -s eth0 wol g
> > [...]
> >
> > Wake-on-LAN configuration is entirely handled by the relevant driver;
> > the ethtool core just copies the parameters in and out. It looks like
> > there is some sort of deadlock or missing unlock in the driver. So my
> > question would be which driver is running eth0?
>
> I attached the whole gzipped dmesg, but anyways, it's e1000e:
>
> [ 1.168733] e1000e: Intel(R) PRO/1000 Network Driver - 1.3.10-k2
> [ 1.168879] e1000e: Copyright(c) 1999 - 2011 Intel Corporation.
> [ 1.169346] e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
> [ 1.169494] e1000e 0000:00:19.0: setting latency timer to 64
> [ 1.169603] usbcore: registered new interface driver usbfs
> [ 1.169675] e1000e 0000:00:19.0: irq 40 for MSI/MSI-X
> [ 1.169794] usbcore: registered new interface driver hub
> [ 1.181231] usbcore: registered new device driver usb
> [ 1.181879] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> [ 1.190984] thermal LNXTHERM:00: registered as thermal_zone0
> [ 1.191129] ACPI: Thermal Zone [THM0] (48 C)
> [ 1.205191] SCSI subsystem initialized
> [ 1.207349] libata version 3.00 loaded.
> [ 1.352926] e1000e 0000:00:19.0: eth0: (PCI Express:2.5GT/s:Width x1) 00:26:2d:f3:14:0f
> [ 1.353243] e1000e 0000:00:19.0: eth0: Intel(R) PRO/1000 Network Connection
> [ 1.353473] e1000e 0000:00:19.0: eth0: MAC: 9, PHY: 10, PBA No: A002FF-0FF
> [snip]
> [ 1221.836727] PM: Entering mem sleep
> [ 1221.836855] Suspending console(s) (use no_console_suspend to debug)
> [ 1222.018735] sd 0:0:0:0: [sda] Synchronizing SCSI cache
> [ 1222.063181] sd 0:0:0:0: [sda] Stopping disk
> [ 1222.272665] ehci_hcd 0000:00:1d.0: PCI INT D disabled
> [ 1222.272668] ehci_hcd 0000:00:1a.0: PCI INT D disabled
> [ 1222.304428] i915 0000:00:02.0: power state changed by ACPI to D3
> [ 1222.378384] e1000e 0000:00:19.0: PCI INT A disabled
> [ 1222.378393] e1000e 0000:00:19.0: PME# enabled
> [ 1222.378400] e1000e 0000:00:19.0: wake-up capability enabled by ACPI
>
> ethtool does show up in the failure dmesg:
>
> [56520.872462] INFO: task ethtool:18105 blocked for more than 120 seconds.
> [56520.872465] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [56520.872468] ethtool D 7fffffffffffffff 0 18105 18104 0x00000000
> [56520.872473] ffff880105d99ad8 0000000000000082 ffffffff810d0c05 ffff880137d15730
> [56520.872479] ffff880130fd3780 ffff880105d99fd8 ffff880105d99fd8 0000000000012500
> [56520.872485] ffff8801333794d0 ffff880130fd3780 ffff880105d99fd8 ffff880137ffbe00
> [56520.872490] Call Trace:
> [56520.872499] [<ffffffff810d0c05>] ? zone_statistics+0x7c/0x83
> [56520.872504] [<ffffffff8131c13e>] schedule_timeout+0x34/0xde
> [56520.872509] [<ffffffff8131bef8>] wait_for_common+0xa3/0x11a
> [56520.872514] [<ffffffff8103c393>] ? try_to_wake_up+0x1ac/0x1ac
> [56520.872519] [<ffffffff8131c023>] wait_for_completion+0x1d/0x1f
> [56520.872524] [<ffffffff8109557d>] synchronize_sched+0x5a/0x5c
> [56520.872528] [<ffffffff8105beac>] ? find_ge_pid+0x41/0x41
> [56520.872536] [<ffffffff8122f67a>] wakeup_source_remove+0x60/0x64
> [56520.872541] [<ffffffff8122f785>] wakeup_source_unregister+0x13/0x1f
> [56520.872546] [<ffffffff8122f7f1>] device_wakeup_disable+0x60/0x6b
> [56520.872550] [<ffffffff8122f942>] device_set_wakeup_enable+0x2d/0x2f
> [56520.872573] [<ffffffffa003a56a>] e1000_set_wol+0x9b/0x9f [e1000e]
> [56520.872580] [<ffffffff81261c8e>] dev_ethtool+0x338/0x1c06
> [56520.872585] [<ffffffff810d4be4>] ? __do_fault+0x313/0x34a
> [56520.872591] [<ffffffff810329ef>] ? should_resched+0xe/0x2d
> [56520.872595] [<ffffffff8131be41>] ? _cond_resched+0xe/0x22
> [56520.872600] [<ffffffff8126019d>] dev_ioctl+0x503/0x688
> [56520.872605] [<ffffffff81319009>] ? __slab_alloc+0x330/0x342
> [56520.872610] [<ffffffff8124ac72>] ? sock_alloc_inode+0x24/0xb7
> [56520.872615] [<ffffffff8124b0c2>] sock_do_ioctl+0x3b/0x46
> [56520.872619] [<ffffffff8124b4f1>] sock_ioctl+0x20d/0x21b
> [56520.872625] [<ffffffff810feb02>] ? get_empty_filp+0x93/0x11b
> [56520.872630] [<ffffffff8110b218>] do_vfs_ioctl+0x460/0x4a1
> [56520.872635] [<ffffffff8124ca82>] ? sock_alloc_file+0xb3/0x114
> [56520.872640] [<ffffffff8131d13e>] ? _raw_spin_lock+0xe/0x10
> [56520.872646] [<ffffffff810fc23d>] ? fd_install+0x31/0x5d
> [56520.872650] [<ffffffff8110b2a0>] sys_ioctl+0x47/0x6b
> [56520.872655] [<ffffffff8131ddc2>] system_call_fastpath+0x16/0x1b
I've been using 3.0.0-rc2 at 3c25fa74 and haven't seen this problem
reoccur, so I guess it was either transient or fixed by something in
7f45e5c..3c25fa7. Thanks for the help, everyone.
-andy
^ permalink raw reply
* [PATCH 1/2] net/usb: Add Samsung Kalmia driver for Samsung GT-B3730
From: Marius B. Kotsbak @ 2011-06-19 21:45 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Marius B. Kotsbak
In-Reply-To: <201106141146.19097.oneukum-l3A5Bk7waGM@public.gmane.org>
Introducing driver for the network port of Samsung Kalmia based USB LTE modems.
It has also an ACM interface that previous patches associates with the "option"
module. To access those interfaces, the modem must first be switched from modem
mode using a tool like usb_modeswitch.
As the proprietary protocol has been discovered by watching the MS Windows driver
behavior, there might be errors in the protocol handling, but stable and fast
connection has been established for hours with Norwegian operator NetCom that
distributes this modem with their LTE/4G subscription.
More and updated information about how to use this driver is available here:
http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
Signed-off-by: Marius B. Kotsbak <marius-iy5w9mehe2BBDgjK7y7TUQ@public.gmane.org>
---
drivers/net/usb/Kconfig | 10 ++
drivers/net/usb/Makefile | 1 +
drivers/net/usb/kalmia.c | 384 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 395 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/usb/kalmia.c
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 9d4f911..84d4608 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -385,6 +385,16 @@ config USB_NET_CX82310_ETH
router with USB ethernet port. This driver is for routers only,
it will not work with ADSL modems (use cxacru driver instead).
+config USB_NET_KALMIA
+ tristate "Samsung Kalmia based LTE USB modem"
+ depends on USB_USBNET
+ help
+ Choose this option if you have a Samsung Kalmia based USB modem
+ as Samsung GT-B3730.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kalmia.
+
config USB_HSO
tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index c7ec8a5..c203fa2 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
+obj-$(CONFIG_USB_NET_KALMIA) += kalmia.o
obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
new file mode 100644
index 0000000..d965fb1
--- /dev/null
+++ b/drivers/net/usb/kalmia.c
@@ -0,0 +1,384 @@
+/*
+ * USB network interface driver for Samsung Kalmia based LTE USB modem like the
+ * Samsung GT-B3730 and GT-B3710.
+ *
+ * Copyright (C) 2011 Marius Bjoernstad Kotsbak <marius-iy5w9mehe2BBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Sponsored by Quicklink Video Distribution Services Ltd.
+ *
+ * Based on the cdc_eem module.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
+
+/*
+ * The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control
+ * handled by the "option" module and an ethernet data port handled by this
+ * module.
+ *
+ * The stick must first be switched into modem mode by usb_modeswitch
+ * or similar tool. Then the modem gets sent two initialization packets by
+ * this module, which gives the MAC address of the device. User space can then
+ * connect the modem using AT commands through the ACM port and then use
+ * DHCP on the network interface exposed by this module. Network packets are
+ * sent to and from the modem in a proprietary format discovered after watching
+ * the behavior of the windows driver for the modem.
+ *
+ * More information about the use of the modem is available in usb_modeswitch
+ * forum and the project page:
+ *
+ * http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
+ * https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
+ */
+
+/* #define DEBUG */
+/* #define VERBOSE */
+
+#define KALMIA_HEADER_LENGTH 6
+#define KALMIA_ALIGN_SIZE 4
+#define KALMIA_USB_TIMEOUT 10000
+
+/*-------------------------------------------------------------------------*/
+
+static int
+kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
+ u8 *buffer, u8 expected_len)
+{
+ int act_len;
+ int status;
+
+ netdev_dbg(dev->net, "Sending init packet");
+
+ status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02),
+ init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT);
+ if (status != 0) {
+ netdev_err(dev->net,
+ "Error sending init packet. Status %i, length %i\n",
+ status, act_len);
+ return status;
+ }
+ else if (act_len != init_msg_len) {
+ netdev_err(dev->net,
+ "Did not send all of init packet. Bytes sent: %i",
+ act_len);
+ }
+ else {
+ netdev_dbg(dev->net, "Successfully sent init packet.");
+ }
+
+ status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81),
+ buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT);
+
+ if (status != 0)
+ netdev_err(dev->net,
+ "Error receiving init result. Status %i, length %i\n",
+ status, act_len);
+ else if (act_len != expected_len)
+ netdev_err(dev->net, "Unexpected init result length: %i\n",
+ act_len);
+
+ return status;
+}
+
+static int
+kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
+{
+ char init_msg_1[] =
+ { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00 };
+ char init_msg_2[] =
+ { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
+ 0x00, 0x00 };
+ char receive_buf[28];
+ int status;
+
+ status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1)
+ / sizeof(init_msg_1[0]), receive_buf, 24);
+ if (status != 0)
+ return status;
+
+ status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2)
+ / sizeof(init_msg_2[0]), receive_buf, 28);
+ if (status != 0)
+ return status;
+
+ memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN);
+
+ return status;
+}
+
+static int
+kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 status;
+ u8 ethernet_addr[ETH_ALEN];
+
+ /* Don't bind to AT command interface */
+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+ return -EINVAL;
+
+ dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK);
+ dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK);
+ dev->status = NULL;
+
+ dev->net->hard_header_len += KALMIA_HEADER_LENGTH;
+ dev->hard_mtu = 1400;
+ dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing
+
+ status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
+
+ if (status < 0) {
+ usb_set_intfdata(intf, NULL);
+ usb_driver_release_interface(driver_of(intf), intf);
+ return status;
+ }
+
+ memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
+ memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN);
+
+ return status;
+}
+
+static struct sk_buff *
+kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+ struct sk_buff *skb2 = NULL;
+ u16 content_len;
+ unsigned char *header_start;
+ unsigned char ether_type_1, ether_type_2;
+ u8 remainder, padlen = 0;
+
+ if (!skb_cloned(skb)) {
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+
+ if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom
+ >= KALMIA_HEADER_LENGTH))
+ goto done;
+
+ if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH
+ + KALMIA_ALIGN_SIZE)) {
+ skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH,
+ skb->data, skb->len);
+ skb_set_tail_pointer(skb, skb->len);
+ goto done;
+ }
+ }
+
+ skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH,
+ KALMIA_ALIGN_SIZE, flags);
+ if (!skb2)
+ return NULL;
+
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+
+ done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
+ ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
+ ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
+
+ netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1,
+ ether_type_2);
+
+ /* According to empiric data for data packages */
+ header_start[0] = 0x57;
+ header_start[1] = 0x44;
+ content_len = skb->len - KALMIA_HEADER_LENGTH;
+ header_start[2] = (content_len & 0xff); /* low byte */
+ header_start[3] = (content_len >> 8); /* high byte */
+
+ header_start[4] = ether_type_1;
+ header_start[5] = ether_type_2;
+
+ /* Align to 4 bytes by padding with zeros */
+ remainder = skb->len % KALMIA_ALIGN_SIZE;
+ if (remainder > 0) {
+ padlen = KALMIA_ALIGN_SIZE - remainder;
+ memset(skb_put(skb, padlen), 0, padlen);
+ }
+
+ netdev_dbg(
+ dev->net,
+ "Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.",
+ content_len, padlen, header_start[0], header_start[1],
+ header_start[2], header_start[3], header_start[4],
+ header_start[5]);
+
+ return skb;
+}
+
+static int
+kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ /*
+ * Our task here is to strip off framing, leaving skb with one
+ * data frame for the usbnet framework code to process.
+ */
+ const u8 HEADER_END_OF_USB_PACKET[] =
+ { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
+ const u8 EXPECTED_UNKNOWN_HEADER_1[] =
+ { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
+ const u8 EXPECTED_UNKNOWN_HEADER_2[] =
+ { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
+ u8 i = 0;
+
+ /* incomplete header? */
+ if (skb->len < KALMIA_HEADER_LENGTH)
+ return 0;
+
+ do {
+ struct sk_buff *skb2 = NULL;
+ u8 *header_start;
+ u16 usb_packet_length, ether_packet_length;
+ int is_last;
+
+ header_start = skb->data;
+
+ if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) {
+ if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1,
+ sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp(
+ header_start, EXPECTED_UNKNOWN_HEADER_2,
+ sizeof(EXPECTED_UNKNOWN_HEADER_2))) {
+ netdev_dbg(
+ dev->net,
+ "Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+ header_start[0], header_start[1],
+ header_start[2], header_start[3],
+ header_start[4], header_start[5],
+ skb->len - KALMIA_HEADER_LENGTH);
+ }
+ else {
+ netdev_err(
+ dev->net,
+ "Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+ header_start[0], header_start[1],
+ header_start[2], header_start[3],
+ header_start[4], header_start[5],
+ skb->len - KALMIA_HEADER_LENGTH);
+ return 0;
+ }
+ }
+ else
+ netdev_dbg(
+ dev->net,
+ "Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+ header_start[0], header_start[1], header_start[2],
+ header_start[3], header_start[4], header_start[5],
+ skb->len - KALMIA_HEADER_LENGTH);
+
+ /* subtract start header and end header */
+ usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
+ ether_packet_length = header_start[2] + (header_start[3] << 8);
+ skb_pull(skb, KALMIA_HEADER_LENGTH);
+
+ /* Some small packets misses end marker */
+ if (usb_packet_length < ether_packet_length) {
+ ether_packet_length = usb_packet_length
+ + KALMIA_HEADER_LENGTH;
+ is_last = true;
+ }
+ else {
+ netdev_dbg(dev->net, "Correct package length #%i", i
+ + 1);
+
+ is_last = (memcmp(skb->data + ether_packet_length,
+ HEADER_END_OF_USB_PACKET,
+ sizeof(HEADER_END_OF_USB_PACKET)) == 0);
+ if (!is_last) {
+ header_start = skb->data + ether_packet_length;
+ netdev_dbg(
+ dev->net,
+ "End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+ header_start[0], header_start[1],
+ header_start[2], header_start[3],
+ header_start[4], header_start[5],
+ skb->len - KALMIA_HEADER_LENGTH);
+ }
+ }
+
+ if (is_last) {
+ skb2 = skb;
+ }
+ else {
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (unlikely(!skb2))
+ return 0;
+ }
+
+ skb_trim(skb2, ether_packet_length);
+
+ if (is_last) {
+ return 1;
+ }
+ else {
+ usbnet_skb_return(dev, skb2);
+ skb_pull(skb, ether_packet_length);
+ }
+
+ i++;
+ }
+ while (skb->len);
+
+ return 1;
+}
+
+static const struct driver_info kalmia_info = {
+ .description = "Samsung Kalmia LTE USB dongle",
+ .flags = FLAG_WWAN,
+ .bind = kalmia_bind,
+ .rx_fixup = kalmia_rx_fixup,
+ .tx_fixup = kalmia_tx_fixup
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products[] = {
+ /* The unswitched USB ID, to get the module auto loaded: */
+ { USB_DEVICE(0x04e8, 0x689a) },
+ /* The stick swithed into modem (by e.g. usb_modeswitch): */
+ { USB_DEVICE(0x04e8, 0x6889),
+ .driver_info = (unsigned long) &kalmia_info, },
+ { /* EMPTY == end of list */} };
+MODULE_DEVICE_TABLE( usb, products);
+
+static struct usb_driver kalmia_driver = {
+ .name = "kalmia",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume
+};
+
+static int __init kalmia_init(void)
+{
+ return usb_register(&kalmia_driver);
+}
+module_init( kalmia_init);
+
+static void __exit kalmia_exit(void)
+{
+ usb_deregister(&kalmia_driver);
+}
+module_exit( kalmia_exit);
+
+MODULE_AUTHOR("Marius Bjoernstad Kotsbak <marius-iy5w9mehe2BBDgjK7y7TUQ@public.gmane.org>");
+MODULE_DESCRIPTION("Samsung Kalmia USB network driver");
+MODULE_LICENSE("GPL");
--
1.7.4.1
--
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 related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox