Netdev List
 help / color / mirror / Atom feed
* Re: debugging kernel during packet drops
From: Jan Engelhardt @ 2010-03-30 12:06 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Eric Dumazet, Jorrit Kronjee, netfilter-devel, netdev
In-Reply-To: <4BAB3C8B.3030104@trash.net>

On Thursday 2010-03-25 11:35, Patrick McHardy wrote:

>Eric Dumazet wrote:
>> Here is patch I cooked for xt_hashlimit (on top of net-next-2.6) to make
>> it use RCU and scale better in your case (allowing several concurrent
>> cpus once RPS is activated), but also on more general cases.
>> 
>> [PATCH] xt_hashlimit: RCU conversion
>> 
>> xt_hashlimit uses a central lock per hash table and suffers from
>> contention on some workloads.
>> 
>> After RCU conversion, central lock is only used when a writer wants to
>> add or delete an entry. For 'readers', updating an existing entry, they
>> use an individual lock per entry.
>
>This clashes with some recent cleanups in nf-next-2.6.git. I'm
>also expecting a patch from Jan to remove the old v0 revision
>very soon (probably today). Please rediff once I've pushed that out.

One 12-series request has been sitting there for a while. Was there 
something not in order with it?


^ permalink raw reply

* Re: [PATCH 1/7] xfrm: remove policy lock when accessing policy->walk.dead
From: Timo Teräs @ 2010-03-30 12:04 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev
In-Reply-To: <20100330115351.GA5731@gondor.apana.org.au>

Herbert Xu wrote:
> On Tue, Mar 30, 2010 at 07:55:07AM +0300, Timo Teräs wrote:
>> Herbert Xu wrote:
>>> On Mon, Mar 29, 2010 at 05:12:38PM +0300, Timo Teras wrote:
>>>> @@ -1132,7 +1119,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
>>>>  		__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
>>>>  	}
>>>>  	if (old_pol)
>>>> -		__xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
>>>> +		old_pol = __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
>>>>  	write_unlock_bh(&xfrm_policy_lock);
>>>>   	if (old_pol) {
>>> So when can this actually fail?
>> Considering that the socket reference is received from the sk->sk_policy,
>> and the hash bucket we use is "XFRM_POLICY_MAX+dir", it's non-obvious if
>> it can fail or not.
>>
>> It would look like the timer can kill a policy and unlink it, but it
>> would still be found from sk_policy.
> 
> Socket policies cannot expire.

Was not aware of that. The above is not needed then.

> In fact, they probably shouldn't even be on the bydst or any other
> hash table.  I think the only reason they're there at all is because
> the hash table was added to __xfrm_policy_link which happens to be
> used by socket policies.

I think it's hashed so socket policies are included in the policy
db dumps and counts.


^ permalink raw reply

* Re: [PATCH 2/7] flow: structurize flow cache
From: Timo Teräs @ 2010-03-30 12:02 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev
In-Reply-To: <20100330120104.GB5731@gondor.apana.org.au>

Herbert Xu wrote:
> On Mon, Mar 29, 2010 at 05:12:39PM +0300, Timo Teras wrote:
>> Group all per-cpu data to one structure instead of having many
>> globals. Also prepare the internals so that we can have multiple
>> instances of the flow cache if needed.
> 
> Grouping everything together looks sane.  But adding the flow
> cache pointer to everything seems to be unnecessary.  Why would
> we need multiple flow caches?

Just a precaution since it doable cheaply.

If we want generic flow cache, we might want to have multiple
instance in future. It might also make sense to have per-net
flow cache.

^ permalink raw reply

* Re: [PATCH 2/7] flow: structurize flow cache
From: Herbert Xu @ 2010-03-30 12:01 UTC (permalink / raw)
  To: Timo Teras; +Cc: netdev
In-Reply-To: <1269871964-5412-3-git-send-email-timo.teras@iki.fi>

On Mon, Mar 29, 2010 at 05:12:39PM +0300, Timo Teras wrote:
> Group all per-cpu data to one structure instead of having many
> globals. Also prepare the internals so that we can have multiple
> instances of the flow cache if needed.

Grouping everything together looks sane.  But adding the flow
cache pointer to everything seems to be unnecessary.  Why would
we need multiple flow caches?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 1/7] xfrm: remove policy lock when accessing policy->walk.dead
From: Herbert Xu @ 2010-03-30 11:53 UTC (permalink / raw)
  To: Timo Teräs; +Cc: netdev
In-Reply-To: <4BB1842B.9010704@iki.fi>

On Tue, Mar 30, 2010 at 07:55:07AM +0300, Timo Teräs wrote:
> Herbert Xu wrote:
>> On Mon, Mar 29, 2010 at 05:12:38PM +0300, Timo Teras wrote:
>>> @@ -1132,7 +1119,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
>>>  		__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
>>>  	}
>>>  	if (old_pol)
>>> -		__xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
>>> +		old_pol = __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
>>>  	write_unlock_bh(&xfrm_policy_lock);
>>>   	if (old_pol) {
>>
>> So when can this actually fail?
>
> Considering that the socket reference is received from the sk->sk_policy,
> and the hash bucket we use is "XFRM_POLICY_MAX+dir", it's non-obvious if
> it can fail or not.
>
> It would look like the timer can kill a policy and unlink it, but it
> would still be found from sk_policy.

Socket policies cannot expire.

In fact, they probably shouldn't even be on the bydst or any other
hash table.  I think the only reason they're there at all is because
the hash table was added to __xfrm_policy_link which happens to be
used by socket policies.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: Holger Schurig @ 2010-03-30 10:59 UTC (permalink / raw)
  To: Daniel Mack
  Cc: linux-kernel, Dan Williams, John W. Linville, Bing Zhao,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <20100330105029.GO30801@buzzloop.caiaq.de>

> I don't get your point. The patch I submitted fixes an Ooops in the
> driver, due to wrong handling of an API. What does that have to do with
> principle discussions about the frameworks in use?

I asked if there is a better method, and you said that you would test a better 
solution. That means that someone else should make a better solution.

I just pointed out that I won't be the one who creates the better solution, 
because for fundamental reasons I don't see the libertas+cfg80211 approach 
going forward. That issue has nothing to do with you or your patch, so please 
don't feel offended or confused.


Basically, I neither ack nor nak you patch. Given that it fixes an oops the 
patch should go in, and probably to stable at well. I just gave a hint, to 
make you think if you could come up with something better.



BTW, testing/fixing of failure paths in libertas as well as simplifying the 
call sequence of functions during initialisation could be quite useful.

^ permalink raw reply

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: Daniel Mack @ 2010-03-30 10:50 UTC (permalink / raw)
  To: Holger Schurig
  Cc: linux-kernel, Dan Williams, John W. Linville, Bing Zhao,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <201003301149.13462.hs4233@mail.mn-solutions.de>

On Tue, Mar 30, 2010 at 11:49:13AM +0200, Holger Schurig wrote:
> > If there's any better solution, I'd happily test it.
> 
> Not from me, unfortunately. I'm not really interested into getting full 
> cfg80211 into Libertas. That is, until either _one_ of this two options 
> happen:
> 
> * someone that actually uses/wants the proprietary Libertas mesh steps  
> forward and says "We'll look after this and make it work with cfg80211"
> * we remove the proprietary Libertas mesh support
> 
> That is: I won't work on Libertas mesh. I can't justify this time investment 
> with my employer for something that I'll never need. For my device, my own 
> version of Libertas + cfg80211 (without any WEXT anymore) works quite nice.
> 
> 
> So, if neither of the above things happens, then Libertas will work for the 
> rest of the world with WEXT, as it did before.

I don't get your point. The patch I submitted fixes an Ooops in the
driver, due to wrong handling of an API. What does that have to do with
principle discussions about the frameworks in use?

Daniel

^ permalink raw reply

* Re: which stable PCI DSL Modem card
From: Simon Farnsworth @ 2010-03-30  9:49 UTC (permalink / raw)
  To: Markus Feldmann; +Cc: netdev
In-Reply-To: <hoqbhd$pod$1@dough.gmane.org>

Markus Feldmann wrote:
> Hi All,
> 
> i am searching for a stable PCI DSL Modem card for Linux (Debian Lenny).
> It should be exist a driver in the Kernel not extra software driver. I
> have a 6000MBit/s DSL wire.
> 
You might want to look at the Solos cards from Traverse Technologies -
the driver for them is in the current Linux kernel.
http://www.traverse.com.au/productview.php?product_id=116 for more.

-- 
Simon

^ permalink raw reply

* [PATCH] Allow MACB to connect to a higher addresses PHY.
From: Anders Darander @ 2010-03-30  9:58 UTC (permalink / raw)
  To: David S. Miller
  Cc: Ralf Baechle, Maxime Bizon, Anders Darander, David Daney,
	Sekhar Nori, Anton Vorontsov, Andy Fleming, Grant Likely, netdev,
	linux-kernel

From: Anders Darander <ad@datarespons.se>

Using the Atmel MACB together with an integrated switch, can make only port 1
work. This is caused by macb_mii_probe trying to attach the MAC to the first
PHY, which often is on one of the external ports.

E.g. the Micrel KSZ8873 connects to the MAC on port 3, thus phy_addr should be
set to 3.

Signed-off-by: Anders Darander <ad@datarespons.se>
---
 drivers/net/phy/Kconfig      |   19 ++++++++++++++++++-
 drivers/net/phy/phy_device.c |    4 ++++
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index fc5938b..64aa003 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -15,11 +15,28 @@ if PHYLIB
 
 comment "MII PHY device drivers"
 
+config SWITCHING_PHY
+	bool "An Ethernet switch is connected to the MAC"
+	depends on MACB
+	help
+	  If an Ethernet switch is connected to the MAC, it
+	  is quite common to have the connection on a port
+	  higher than the first port. This option allows to
+	  select the desired port number
+
+config SWITCHING_PHY_ADDR
+	int "PHYA address"
+	depends on SWITCHING_PHY
+	default "3"
+	help
+	  On e.g. the Micrel KSZ8873MLL, port 3 (and thus phy_addr
+	  3) is the one connected to the MAC of the MCU.
+
 config MARVELL_PHY
 	tristate "Drivers for Marvell PHYs"
 	---help---
 	  Currently has a driver for the 88E1011S
-	
+
 config DAVICOM_PHY
 	tristate "Drivers for Davicom PHYs"
 	---help---
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index db17945..891bd0d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -284,7 +284,11 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
 {
 	int addr;
 
+#ifdef CONFIG_SWITCHING_PHY
+	for (addr = CONFIG_SWITCHING_PHY_ADDR; addr < PHY_MAX_ADDR; addr++) {
+#else
 	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+#endif
 		if (bus->phy_map[addr])
 			return bus->phy_map[addr];
 	}
-- 
1.7.0.3

^ permalink raw reply related

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: Holger Schurig @ 2010-03-30  9:49 UTC (permalink / raw)
  To: Daniel Mack
  Cc: linux-kernel, Dan Williams, John W. Linville, Bing Zhao,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <20100330085253.GL30801@buzzloop.caiaq.de>

> If there's any better solution, I'd happily test it.

Not from me, unfortunately. I'm not really interested into getting full 
cfg80211 into Libertas. That is, until either _one_ of this two options 
happen:

* someone that actually uses/wants the proprietary Libertas mesh steps  
forward and says "We'll look after this and make it work with cfg80211"
* we remove the proprietary Libertas mesh support

That is: I won't work on Libertas mesh. I can't justify this time investment 
with my employer for something that I'll never need. For my device, my own 
version of Libertas + cfg80211 (without any WEXT anymore) works quite nice.


So, if neither of the above things happens, then Libertas will work for the 
rest of the world with WEXT, as it did before.

^ permalink raw reply

* [patch] 9p: saving negative to unsigned char
From: Dan Carpenter @ 2010-03-30  9:42 UTC (permalink / raw)
  To: Eric Van Hensbergen
  Cc: David S. Miller, Abhishek Kulkarni, Sripathi Kodi,
	Latchesar Ionkov, Venkateswararao Jujjuri, linux-kernel, netdev,
	kernel-janitors

Saving -EINVAL as unsigned char truncates the high bits and changes it 
into 234 instead of -22.  This breaks the test for "if (ret == -EINVAL)"
in parse_opts().

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/net/9p/client.c b/net/9p/client.c
index e3e5bf4..edf31aa 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -71,9 +71,10 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
 EXPORT_SYMBOL(p9_is_proto_dotu);
 
 /* Interpret mount option for protocol version */
-static unsigned char get_protocol_version(const substring_t *name)
+static int get_protocol_version(const substring_t *name)
 {
-	unsigned char version = -EINVAL;
+	int version = -EINVAL;
+
 	if (!strncmp("9p2000", name->from, name->to-name->from)) {
 		version = p9_proto_legacy;
 		P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");

^ permalink raw reply related

* Re: Network performance - iperf
From: Michal Simek @ 2010-03-30  9:34 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: LKML, John Williams, netdev, Grant Likely, John Linn,
	Steven J. Magnani, Arnd Bergmann, akpm
In-Reply-To: <1269884717.1958.2.camel@edumazet-laptop>

[-- Attachment #1: Type: text/plain, Size: 8888 bytes --]

Eric Dumazet wrote:
> Le lundi 29 mars 2010 à 17:27 +0200, Michal Simek a écrit :
>> Michal Simek wrote:
>>> Eric Dumazet wrote:
>>>> Le lundi 29 mars 2010 à 13:33 +0200, Michal Simek a écrit :
>>>>
>>>>> Do you have any idea howto improve TCP/UDP performance in general?
>>>>> Or tests which can point me on weak places.
>>>> Could you post "netstat -s" on your receiver, after fresh boot and your
>>>> iperf session, for 32 MB and 256 MB ram case ?
>>>>
>>> I am not sure if is helpful but look below.
>>>
>> Sorry I forget to c&p that second part. :-(
>>
> 
> Sorry, your netstat is not up2date.

I am afraid that is up2date.

> 
> If you cannot correct it to last version
> [ net-tools 1.60 , netstat 1.42 ], please send
> 
> cat /proc/net/snmp
> cat /proc/net/netstat

There is small buffer for parsing /proc/net/netstat.
There is necessary to extend buffer size because one line is greater 
than 1024 chars.

~ # head -n 1 /proc/net/netstat
TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts 
PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps 
ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab 
DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops 
TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue 
TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks 
TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder 
TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo 
TCPDSACKUndo TCPLossUndo TCPLoss TCPLostRetransmit TCPRenoFailures 
TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans 
TCPSlowStartRetrans TCPTimeouts TCPRenoRecoveryFail TCPSackRecoveryFail 
TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent 
TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnSyn TCPAbortOnData 
TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger 
TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld 
TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected 
TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop 
TCPMinTTLDrop

Look at attached patch.
And updated results are below.

Thanks,
Michal





256M

~ # iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  6] local 192.168.0.10 port 5001 connected with 192.168.0.101 port 33261
[ ID] Interval       Transfer     Bandwidth
[  6]  0.0-50.2 sec  22.9 MBytes  3.83 Mbits/sec
~ # ./netstat -s
Ip:
     16618 total packets received
     0 forwarded
     0 incoming packets discarded
     16618 incoming packets delivered
     6490 requests sent out
Icmp:
     0 ICMP messages received
     0 input ICMP message failed.
     ICMP input histogram:
     0 ICMP messages sent
     0 ICMP messages failed
     ICMP output histogram:
Tcp:
     0 active connections openings
     1 passive connection openings
     0 failed connection attempts
     0 connection resets received
     0 connections established
     16618 segments received
     6490 segments send out
     0 segments retransmited
     0 bad segments received.
     0 resets sent
Udp:
     0 packets received
     0 packets to unknown port received.
     0 packet receive errors
     0 packets sent
     RcvbufErrors: 0
     SndbufErrors: 0
UdpLite:
     InDatagrams: 0
     NoPorts: 0
     InErrors: 0
     OutDatagrams: 0
     RcvbufErrors: 0
     SndbufErrors: 0
TcpExt:
     2233 packets pruned from receive queue because of socket buffer overrun
     ArpFilter: 0
     1 delayed acks sent
     5519 packets header predicted
     TCPPureAcks: 2
     TCPHPAcks: 0
     TCPRenoRecovery: 0
     TCPSackRecovery: 0
     TCPSACKReneging: 0
     TCPFACKReorder: 0
     TCPSACKReorder: 0
     TCPRenoReorder: 0
     TCPTSReorder: 0
     TCPFullUndo: 0
     TCPPartialUndo: 0
     TCPDSACKUndo: 0
     TCPLossUndo: 0
     TCPLoss: 0
     TCPLostRetransmit: 0
     TCPRenoFailures: 0
     TCPSackFailures: 0
     TCPLossFailures: 0
     TCPFastRetrans: 0
     TCPForwardRetrans: 0
     TCPSlowStartRetrans: 0
     TCPTimeouts: 0
     TCPRenoRecoveryFail: 0
     TCPSackRecoveryFail: 0
     TCPSchedulerFailed: 0
     TCPRcvCollapsed: 207654
     TCPDSACKOldSent: 0
     TCPDSACKOfoSent: 0
     TCPDSACKRecv: 0
     TCPDSACKOfoRecv: 0
     TCPAbortOnSyn: 0
     TCPAbortOnData: 0
     TCPAbortOnClose: 0
     TCPAbortOnMemory: 0
     TCPAbortOnTimeout: 0
     TCPAbortOnLinger: 0
     TCPAbortFailed: 0
     TCPMemoryPressures: 0
     TCPSACKDiscard: 0
     TCPDSACKIgnoredOld: 0
     TCPDSACKIgnoredNoUndo: 0
     TCPSpuriousRTOs: 0
     TCPMD5NotFound: 0
     TCPMD5Unexpected: 0
     TCPSackShifted: 0
     TCPSackMerged: 0
     TCPSackShiftFallback: 0
     TCPBacklogDrop: 0
     TCPMinTTLDrop: 0
IpExt:
     InNoRoutes: 0
     InTruncatedPkts: 0
     InMcastPkts: 0
     OutMcastPkts: 0
     InBcastPkts: 0
     OutBcastPkts: 0
     InOctets: 24915880
     OutOctets: 337488
     InMcastOctets: 0
     OutMcastOctets: 0
     InBcastOctets: 0
     OutBcastOctets: 0
~ # ./netstat --version
net-tools 1.60
netstat 1.42 (2001-04-15)
Fred Baumgarten, Alan Cox, Bernd Eckenfels, Phil Blundell, Tuan Hoang 
and others
+NEW_ADDRT +RTF_IRTT +RTF_REJECT +FW_MASQUERADE -I18N
AF: (inet) +UNIX +INET -INET6 -IPX -AX25 -NETROM -X25 -ATALK -ECONET -ROSE
HW:  +ETHER -ARC +SLIP +PPP -TUNNEL -TR -AX25 -NETROM -X25 -FR -ROSE 
-ASH -SIT -FDDI -HIPPI -HDLC/LAPB
~ # head -n 1 /proc/meminfo
MemTotal:         257108 kB



32MB

~ # head -n 1 /proc/meminfo
MemTotal:          29920 kB
~ # iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  6] local 192.168.0.10 port 5001 connected with 192.168.0.101 port 50088
[ ID] Interval       Transfer     Bandwidth
[  6]  0.0-50.0 sec    109 MBytes  18.3 Mbits/sec
~ # ./netstat -s
Ip:
     79040 total packets received
     0 forwarded
     0 incoming packets discarded
     79040 incoming packets delivered
     29655 requests sent out
Icmp:
     0 ICMP messages received
     0 input ICMP message failed.
     ICMP input histogram:
     0 ICMP messages sent
     0 ICMP messages failed
     ICMP output histogram:
Tcp:
     0 active connections openings
     1 passive connection openings
     0 failed connection attempts
     0 connection resets received
     0 connections established
     79040 segments received
     29655 segments send out
     0 segments retransmited
     0 bad segments received.
     0 resets sent
Udp:
     0 packets received
     0 packets to unknown port received.
     0 packet receive errors
     0 packets sent
     RcvbufErrors: 0
     SndbufErrors: 0
UdpLite:
     InDatagrams: 0
     NoPorts: 0
     InErrors: 0
     OutDatagrams: 0
     RcvbufErrors: 0
     SndbufErrors: 0
TcpExt:
     9773 packets pruned from receive queue because of socket buffer overrun
     ArpFilter: 0
     1 delayed acks sent
     101 packets directly queued to recvmsg prequeue.
     558928 packets directly received from prequeue
     33274 packets header predicted
     378 packets header predicted and directly queued to user
     TCPPureAcks: 2
     TCPHPAcks: 0
     TCPRenoRecovery: 0
     TCPSackRecovery: 0
     TCPSACKReneging: 0
     TCPFACKReorder: 0
     TCPSACKReorder: 0
     TCPRenoReorder: 0
     TCPTSReorder: 0
     TCPFullUndo: 0
     TCPPartialUndo: 0
     TCPDSACKUndo: 0
     TCPLossUndo: 0
     TCPLoss: 0
     TCPLostRetransmit: 0
     TCPRenoFailures: 0
     TCPSackFailures: 0
     TCPLossFailures: 0
     TCPFastRetrans: 0
     TCPForwardRetrans: 0
     TCPSlowStartRetrans: 0
     TCPTimeouts: 0
     TCPRenoRecoveryFail: 0
     TCPSackRecoveryFail: 0
     TCPSchedulerFailed: 0
     TCPRcvCollapsed: 120195
     TCPDSACKOldSent: 0
     TCPDSACKOfoSent: 0
     TCPDSACKRecv: 0
     TCPDSACKOfoRecv: 0
     TCPAbortOnSyn: 0
     TCPAbortOnData: 0
     TCPAbortOnClose: 0
     TCPAbortOnMemory: 0
     TCPAbortOnTimeout: 0
     TCPAbortOnLinger: 0
     TCPAbortFailed: 0
     TCPMemoryPressures: 0
     TCPSACKDiscard: 0
     TCPDSACKIgnoredOld: 0
     TCPDSACKIgnoredNoUndo: 0
     TCPSpuriousRTOs: 0
     TCPMD5NotFound: 0
     TCPMD5Unexpected: 0
     TCPSackShifted: 0
     TCPSackMerged: 0
     TCPSackShiftFallback: 0
     TCPBacklogDrop: 0
     TCPMinTTLDrop: 0
IpExt:
     InNoRoutes: 0
     InTruncatedPkts: 0
     InMcastPkts: 0
     OutMcastPkts: 0
     InBcastPkts: 0
     OutBcastPkts: 0
     InOctets: 118232864
     OutOctets: 1542068
     InMcastOctets: 0
     OutMcastOctets: 0
     InBcastOctets: 0
     OutBcastOctets: 0
~ #










-- 
Michal Simek, Ing. (M.Eng)
PetaLogix - Linux Solutions for a Reconfigurable World
w: www.petalogix.com p: +61-7-30090663,+42-0-721842854 f: +61-7-30090663

[-- Attachment #2: 0001-Extend-buffer-size-because-line-size-is-greater-than.patch --]
[-- Type: text/x-patch, Size: 988 bytes --]

>From e2d160e2e235103af3e08b5bbbc451982bc0fed0 Mon Sep 17 00:00:00 2001
From: Michal Simek <monstr@monstr.eu>
Date: Tue, 30 Mar 2010 10:45:06 +0200
Subject: [PATCH] Extend buffer size because line size is greater than 1024 chars

Error shown on console

UdpLite:
    InDatagrams: 0
    NoPorts: 0
    InErrors: 0
    OutDatagrams: 0
    RcvbufErrors: 0
    SndbufErrors: 0
error parsing /proc/net/snmp: Success

It is easy to check size of line which is necessary to check.

1151

Signed-off-by: Michal Simek <monstr@monstr.eu>
---
 statistics.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/statistics.c b/statistics.c
index a878df8..51beb8a 100644
--- a/statistics.c
+++ b/statistics.c
@@ -291,7 +291,7 @@ struct tabtab *newtable(struct tabtab *tabs, char *title)
 
 void process_fd(FILE *f)
 {
-    char buf1[1024], buf2[1024];
+    char buf1[2048], buf2[2048];
     char *sp, *np, *p;
     while (fgets(buf1, sizeof buf1, f)) {
 	int endflag;
-- 
1.5.5.1


^ permalink raw reply related

* Re: which stable PCI DSL Modem card
From: Michael Tokarev @ 2010-03-30  9:32 UTC (permalink / raw)
  To: Markus Feldmann; +Cc: netdev
In-Reply-To: <hoqbhd$pod$1@dough.gmane.org>

Markus Feldmann Wrote:
> Hi All,
> 
> i am searching for a stable PCI DSL Modem card for Linux (Debian Lenny).
> It should be exist a driver in the Kernel not extra software driver. I
> have a 6000MBit/s DSL wire.
> 
> Does anybody know some interesting device for me? Any further information?

As far as I can see they stopped producing PCI DSL modems quite a while
ago.  They sell USB and ethernet ones, but not PCI.  And even at "old
good" times there were only 2 or 3 models with PCI interface, the rest
were USB or Ether.

I personally recommend ethernet modem - it will work with any OS including
linux.  USB modems with linux support exists, but that support is somewhat
flaky.

Also, many DSL modems nowadays comes with 4-port ethernet switch and
wireless access point, which may be handy too.  Both optional.

/mjt

^ permalink raw reply

* XT_ALIGN changed to use ALIGN breaks iproute2
From: Andreas Henriksson @ 2010-03-30  9:28 UTC (permalink / raw)
  To: Alexey Dobriyan, Patrick McHardy; +Cc: Stephen Hemminger, jamal, netdev

Hello Alexey (and everyone else)!

You updated the kernel header include/linux/netfilter/x_tables.h
in torvalds/linux-2.6.git commit 42107f5009da223daa800d6da6904d77297ae829
with the comment "Use ALIGN() macro while I'm at it for same types.".

When this header was synced into iproute2 the build broke because the
ALIGN macro apparently only is defined in kernel headers.

(For iproute2 the problem was introduced in
8ecdcce08319d0e39b0d32c1d17db3f69d85a35c and found by Stephen
and worked around in 609ceb807deba8e23 and edaaa11e5a3cf2c9c1a39)

I'm guessing the problem in the iproute2 header sync is just a heads
up for what's going to happen when distributions updates their
system headers to match linux 2.6.33.


Could someone who knows how the userspace version of the kernel
headers are generated please find a suitable solution?

-- 
Andreas Henriksson

^ permalink raw reply

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: Daniel Mack @ 2010-03-30  8:52 UTC (permalink / raw)
  To: Holger Schurig
  Cc: linux-kernel, Dan Williams, John W. Linville, Bing Zhao,
	libertas-dev, linux-wireless, netdev
In-Reply-To: <201003300849.07441.hs4233@mail.mn-solutions.de>

On Tue, Mar 30, 2010 at 08:49:07AM +0200, Holger Schurig wrote:
> > The libertas driver calls wiphy_unregister() without a prior
> > wiphy_register() when a devices fails initialization. Fix this by
> > introducing a private flag.
> 
> Nice.
> 
> However, I wonder: do we really need a private variable?  Does each driver 
> introduce a private variable for this?

I didn't check other drivers thoroughly. I just saw the comment on the
function which does the wiphy allocation and considered libertas to be
special in the way it deals with the wireless core:

/*
 * At this time lbs_private *priv doesn't even exist, so we just allocate
 * memory and don't initialize the wiphy further. This is postponed until we
 * can talk to the firmware and happens at registration time in
 * lbs_cfg_wiphy_register().
 */

And as I didn't find any function to tell me whether a wiphy has been
registered and not just allocated, I saw no other way than manually
track what the libertas driver does.

If there's any better solution, I'd happily test it.

Thanks,
Daniel

^ permalink raw reply

* Re: UDP path MTU discovery
From: Edgar E. Iglesias @ 2010-03-30  8:20 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Templin, Fred L, Eric Dumazet, Rick Jones, Glen Turner,
	netdev@vger.kernel.org
In-Reply-To: <20100330061952.GO20695@one.firstfloor.org>

On Tue, Mar 30, 2010 at 08:19:52AM +0200, Andi Kleen wrote:
> > If you don't want to hassle with all of that, the app can stick to
> > 1280 (or I guess for the extreme/lazy cases turn on fragmentation)..
> 
> See the early mails in this thread. This is about apps who can't
> limit themselves to 1280, but still don't want full blown PMTU.
> [They probably should, but it can be a lot of work]
> 
> The MTU would allow to force fragmentation on the sending host
> as a workaround similar to IPv4.

Yes, but I dont see why you need an option with semantics of setting an MTU.

If an UDP app wants to use fragmentation (for whatever reason) setting
a boolean flag like XXX_PMTUDISC_DONT should be enough. The kernel will for
IPv6 have to work with the real PMTU or stick to 1280 when generating the
fragments. Keep in mind that unlike IPv4, IPv6 has no DF flag. It's up to
the sender to create the the fragments.

Where does the application controllable per socket MTU come into the
picture?

Cheers

^ permalink raw reply

* Re: [PATCH 09/17] pcmcia: update gfp/slab.h includes
From: Stephen Rothwell @ 2010-03-30  8:23 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dominik Brodowski, Tejun Heo, linux-next, linux-kernel, netdev
In-Reply-To: <20100330065605.GA12764@core.coreip.homeip.net>

[-- Attachment #1: Type: text/plain, Size: 316 bytes --]

Hi Dmitry,

On Mon, 29 Mar 2010 23:56:05 -0700 Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>
> Yes, I will roll teh relevant parts into respective patches if you don't
> mind.

Great, thanks.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH 09/17] pcmcia: update gfp/slab.h includes
From: Stephen Rothwell @ 2010-03-30  8:22 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: Tejun Heo, Dmitry Torokhov, linux-next, linux-kernel, netdev
In-Reply-To: <20100330063609.GA4498@comet.dominikbrodowski.net>

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

Hi Dominik,

On Tue, 30 Mar 2010 08:36:09 +0200 Dominik Brodowski <linux@dominikbrodowski.net> wrote:
>
> Okay, applied it.

Great, thanks.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH 2/3] can: add support for Janz VMOD-ICAN3 Intelligent CAN module
From: Wolfgang Grandegger @ 2010-03-30  8:14 UTC (permalink / raw)
  To: Ira W. Snyder
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sameo-VuQAYsv1563Yd54FQh9/CA
In-Reply-To: <1269881932-3803-3-git-send-email-iws-lulEs6mt1IksTUYHLfqkUA@public.gmane.org>

Ira W. Snyder wrote:
> The Janz VMOD-ICAN3 is a MODULbus daughterboard which fits onto any
> MODULbus carrier board. It is an intelligent CAN controller with a
> microcontroller and associated firmware.
> 
> Signed-off-by: Ira W. Snyder <iws-lulEs6mt1IksTUYHLfqkUA@public.gmane.org>

Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

^ permalink raw reply

* Re: [PATCH net-next-2.6 v8 00/12] net-caif: introducing CAIF protocol stack
From: David Miller @ 2010-03-30  8:05 UTC (permalink / raw)
  To: sjur.brandeland; +Cc: netdev, marcel, daniel.martensson, sjurbr
In-Reply-To: <1269934228-23292-1-git-send-email-sjur.brandeland@stericsson.com>


You're directly accessing SKB data members instead of using
the portable interfaces defined in linux/skbuff.h, therefore
the build fails on 64-bit.

How many revisions of this patch set and not once has it been even
build tested on 64-bit?

net/caif/cfpkt_skbuff.c: In function ‘cfpkt_peek_head’:
net/caif/cfpkt_skbuff.c:121: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c: In function ‘cfpkt_append’:
net/caif/cfpkt_skbuff.c:336: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c:352: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c:358: warning: assignment makes integer from pointer without a cast
net/caif/cfpkt_skbuff.c:364: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c:364: warning: passing argument 1 of ‘__builtin_memcpy’ makes pointer from integer without a cast
net/caif/cfpkt_skbuff.c:364: note: expected ‘void *’ but argument is of type ‘sk_buff_data_t’
net/caif/cfpkt_skbuff.c: In function ‘cfpkt_split’:
net/caif/cfpkt_skbuff.c:377: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘u8 *’)
net/caif/cfpkt_skbuff.c:382: warning: comparison between pointer and integer
net/caif/cfpkt_skbuff.c:397: warning: assignment makes integer from pointer without a cast
net/caif/cfpkt_skbuff.c: In function ‘cfpkt_log_pkt’:
net/caif/cfpkt_skbuff.c:425: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c:427: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)
net/caif/cfpkt_skbuff.c:430: error: invalid operands to binary - (have ‘sk_buff_data_t’ and ‘unsigned char *’)

^ permalink raw reply

* Re: Re [RFC PATCH 1/2] iproute2: Add libnl support.
From: James Chapman @ 2010-03-30  7:48 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20100329140642.7305bdfc@nehalam>

Stephen Hemminger wrote:
>> This patch links the ip utility with libnl, which must be separately
>> installed. This lets new functionality use libnl to implement its
>> netlink interfaces.
>>
>> Package developers will need to add libnl to the iproute2 package
>> dependencies.
>> ---
>>  Makefile |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> No. I don't want to make iproute2 dependent on libnl.
> It doesn't make sense to have dependency without major need for new
> functionality.  There are already netlink library routines in iproute2

True, but libnetlink doesn't provide utility routines for building genl
interfaces like it does, say, for rtnl. To use libnetlink for this code,
we'd have to c&p some code from genl/ctrl.c to handle the interface
family registration, for example. It's all there in libnl already.

But I understand your reservation about introducing a new library
dependency. Since the rest of our netlink code uses libnl, I'm leaning
towards having a separate utility for these commands so we can keep it
libnl.

-- 
James Chapman
Katalix Systems Ltd
http://www.katalix.com
Catalysts for your Embedded Linux software development


^ permalink raw reply

* [PATCH net-next-2.6 v8 12/12] net-caif-driver: add CAIF serial driver (ldisc)
From: sjur.brandeland @ 2010-03-30  7:30 UTC (permalink / raw)
  To: davem, netdev, marcel; +Cc: daniel.martensson, sjurbr, Sjur Braendeland
In-Reply-To: <1269934228-23292-12-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Add CAIF Serial driver. This driver is implemented as a line discipline.

caif_serial uses the following module parameters:
ser_use_stx - specifies if STart of frame eXtension is in use.
ser_loop    - sets the interface in loopback mode.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 drivers/net/Kconfig            |    2 +
 drivers/net/Makefile           |    1 +
 drivers/net/caif/Kconfig       |   14 ++
 drivers/net/caif/Makefile      |   12 +
 drivers/net/caif/caif_serial.c |  441 ++++++++++++++++++++++++++++++++++++++++
 include/linux/tty.h            |    4 +-
 6 files changed, 472 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/caif/Kconfig
 create mode 100644 drivers/net/caif/Makefile
 create mode 100644 drivers/net/caif/caif_serial.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dd9a09c..c2e670c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2789,6 +2789,8 @@ source "drivers/ieee802154/Kconfig"
 
 source "drivers/s390/net/Kconfig"
 
+source "drivers/net/caif/Kconfig"
+
 config XEN_NETDEV_FRONTEND
 	tristate "Xen network device frontend driver"
 	depends on XEN
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ad1346d..b7ffa35 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -285,5 +285,6 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_SFC) += sfc/
 
 obj-$(CONFIG_WIMAX) += wimax/
+obj-$(CONFIG_CAIF) += caif/
 
 obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
new file mode 100644
index 0000000..49c1c07
--- /dev/null
+++ b/drivers/net/caif/Kconfig
@@ -0,0 +1,14 @@
+#
+# CAIF physical drivers
+#
+
+if CAIF
+
+comment "CAIF transport drivers"
+
+config CAIF_TTY
+	tristate "CAIF TTY transport driver"
+	default n
+	---help---
+	The CAIF TTY transport driver.
+endif # CAIF
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
new file mode 100644
index 0000000..52b6d1f
--- /dev/null
+++ b/drivers/net/caif/Makefile
@@ -0,0 +1,12 @@
+ifeq ($(CONFIG_CAIF_DEBUG),1)
+CAIF_DBG_FLAGS := -DDEBUG
+endif
+
+KBUILD_EXTRA_SYMBOLS=net/caif/Module.symvers
+
+ccflags-y := $(CAIF_FLAGS) $(CAIF_DBG_FLAGS)
+clean-dirs:= .tmp_versions
+clean-files:= Module.symvers modules.order *.cmd *~ \
+
+# Serial interface
+obj-$(CONFIG_CAIF_TTY) += caif_serial.o
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
new file mode 100644
index 0000000..44d5cde
--- /dev/null
+++ b/drivers/net/caif/caif_serial.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/tty.h>
+#include <linux/file.h>
+#include <linux/if_arp.h>
+#include <net/caif/caif_device.h>
+#include <net/caif/cfcnfg.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brendeland<sjur.brandeland@stericsson.com>");
+MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_CAIF);
+
+#define SEND_QUEUE_LOW 10
+#define SEND_QUEUE_HIGH 100
+#define CAIF_SENDING	        1 /* Bit 1 = 0x02*/
+#define CAIF_FLOW_OFF_SENT	4 /* Bit 4 = 0x10 */
+#define MAX_WRITE_CHUNK	     4096
+#define ON 1
+#define OFF 0
+#define CAIF_MAX_MTU 4096
+
+/*This list is protected by the rtnl lock. */
+static LIST_HEAD(ser_list);
+
+static int ser_loop;
+module_param(ser_loop, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
+
+static int ser_use_stx = 1;
+module_param(ser_use_stx, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
+
+static int ser_use_fcs = 1;
+
+module_param(ser_use_fcs, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
+
+static int ser_write_chunk = MAX_WRITE_CHUNK;
+module_param(ser_write_chunk, int, S_IRUGO);
+
+MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
+
+static struct dentry *debugfsdir;
+
+static int caif_net_open(struct net_device *dev);
+static int caif_net_close(struct net_device *dev);
+
+struct ser_device {
+	struct caif_dev_common common;
+	struct list_head node;
+	struct net_device *dev;
+	struct sk_buff_head head;
+	struct tty_struct *tty;
+	bool tx_started;
+	unsigned long state;
+	char *tty_name;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_tty_dir;
+	struct debugfs_blob_wrapper tx_blob;
+	struct debugfs_blob_wrapper rx_blob;
+	u8 rx_data[128];
+	u8 tx_data[128];
+	u8 tty_status;
+
+#endif
+};
+
+static void caifdev_setup(struct net_device *dev);
+static void ldisc_tx_wakeup(struct tty_struct *tty);
+#ifdef CONFIG_DEBUG_FS
+static inline void update_tty_status(struct ser_device *ser)
+{
+	ser->tty_status =
+		ser->tty->stopped << 5 |
+		ser->tty->hw_stopped << 4 |
+		ser->tty->flow_stopped << 3 |
+		ser->tty->packet << 2 |
+		ser->tty->low_latency << 1 |
+		ser->tty->warned;
+}
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+	ser->debugfs_tty_dir =
+			debugfs_create_dir(tty->name, debugfsdir);
+	if (!IS_ERR(ser->debugfs_tty_dir)) {
+		debugfs_create_blob("last_tx_msg", S_IRUSR,
+				ser->debugfs_tty_dir,
+				&ser->tx_blob);
+
+		debugfs_create_blob("last_rx_msg", S_IRUSR,
+				ser->debugfs_tty_dir,
+				&ser->rx_blob);
+
+		debugfs_create_x32("ser_state", S_IRUSR,
+				ser->debugfs_tty_dir,
+				(u32 *)&ser->state);
+
+		debugfs_create_x8("tty_status", S_IRUSR,
+				ser->debugfs_tty_dir,
+				&ser->tty_status);
+
+	}
+	ser->tx_blob.data = ser->tx_data;
+	ser->tx_blob.size = 0;
+	ser->rx_blob.data = ser->rx_data;
+	ser->rx_blob.size = 0;
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+	debugfs_remove_recursive(ser->debugfs_tty_dir);
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+	if (size > sizeof(ser->rx_data))
+		size = sizeof(ser->rx_data);
+	memcpy(ser->rx_data, data, size);
+	ser->rx_blob.data = ser->rx_data;
+	ser->rx_blob.size = size;
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+	if (size > sizeof(ser->tx_data))
+		size = sizeof(ser->tx_data);
+	memcpy(ser->tx_data, data, size);
+	ser->tx_blob.data = ser->tx_data;
+	ser->tx_blob.size = size;
+}
+#else
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+}
+
+static inline void update_tty_status(struct ser_device *ser)
+{
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+#endif
+
+static void ldisc_receive(struct tty_struct *tty, const u8 *data,
+			char *flags, int count)
+{
+	struct sk_buff *skb = NULL;
+	struct ser_device *ser;
+	int ret;
+	u8 *p;
+	ser = tty->disc_data;
+
+	/*
+	 * NOTE: flags may contain information about break or overrun.
+	 * This is not yet handled.
+	 */
+
+
+	/*
+	 * Workaround for garbage at start of transmission,
+	 * only enable if STX handling is not enabled.
+	 */
+	if (!ser->common.use_stx && !ser->tx_started) {
+		dev_info(&ser->dev->dev,
+			"Bytes received before initial transmission -"
+			"bytes discarded.\n");
+		return;
+	}
+
+	BUG_ON(ser->dev == NULL);
+
+	/* Get a suitable caif packet and copy in data. */
+	skb = netdev_alloc_skb(ser->dev, count+1);
+	BUG_ON(skb == NULL);
+	p = skb_put(skb, count);
+	memcpy(p, data, count);
+
+	skb->protocol = htons(ETH_P_CAIF);
+	skb_reset_mac_header(skb);
+	skb->dev = ser->dev;
+	debugfs_rx(ser, data, count);
+	/* Push received packet up the stack. */
+	ret = netif_rx_ni(skb);
+	if (!ret) {
+		ser->dev->stats.rx_packets++;
+		ser->dev->stats.rx_bytes += count;
+	} else
+		++ser->dev->stats.rx_dropped;
+	update_tty_status(ser);
+}
+
+static int handle_tx(struct ser_device *ser)
+{
+	struct tty_struct *tty;
+	struct sk_buff *skb;
+	int tty_wr, len, room;
+	tty = ser->tty;
+	ser->tx_started = true;
+
+	/* Enter critical section */
+	if (test_and_set_bit(CAIF_SENDING, &ser->state))
+		return 0;
+
+	/* skb_peek is safe because handle_tx is called after skb_queue_tail */
+	while ((skb = skb_peek(&ser->head)) != NULL) {
+
+		/* Make sure you don't write too much */
+		len = skb->len;
+		room = tty_write_room(tty);
+		if (!room)
+			break;
+		if (room > ser_write_chunk)
+			room = ser_write_chunk;
+		if (len > room)
+			len = room;
+
+		/* Write to tty or loopback */
+		if (!ser_loop) {
+			tty_wr = tty->ops->write(tty, skb->data, len);
+			update_tty_status(ser);
+		} else {
+			tty_wr = len;
+			ldisc_receive(tty, skb->data, 0, len);
+		}
+		ser->dev->stats.tx_packets++;
+		ser->dev->stats.tx_bytes += tty_wr;
+
+		/* Error on TTY ?! */
+		if (tty_wr < 0)
+			goto error;
+		/* Reduce buffer written, and discard if empty */
+		skb_pull(skb, tty_wr);
+		if (skb->len == 0) {
+			struct sk_buff *tmp = skb_dequeue(&ser->head);
+			BUG_ON(tmp != skb);
+			if (in_interrupt())
+				dev_kfree_skb_irq(skb);
+			else
+				kfree_skb(skb);
+		}
+	}
+	/* Send flow off if queue is empty */
+	if (ser->head.qlen <= SEND_QUEUE_LOW &&
+		test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
+		ser->common.flowctrl != NULL)
+				ser->common.flowctrl(ser->dev, ON);
+	clear_bit(CAIF_SENDING, &ser->state);
+	return 0;
+error:
+	clear_bit(CAIF_SENDING, &ser->state);
+	return tty_wr;
+}
+
+static int caif_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ser_device *ser;
+	BUG_ON(dev == NULL);
+	ser = netdev_priv(dev);
+
+	/* Send flow off once, on high water mark */
+	if (ser->head.qlen > SEND_QUEUE_HIGH &&
+		!test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
+		ser->common.flowctrl != NULL)
+
+		ser->common.flowctrl(ser->dev, OFF);
+
+	skb_queue_tail(&ser->head, skb);
+	return handle_tx(ser);
+}
+
+
+static void ldisc_tx_wakeup(struct tty_struct *tty)
+{
+	struct ser_device *ser;
+	ser = tty->disc_data;
+	BUG_ON(ser == NULL);
+	BUG_ON(ser->tty != tty);
+	handle_tx(ser);
+}
+
+
+static int ldisc_open(struct tty_struct *tty)
+{
+	struct ser_device *ser;
+	struct net_device *dev;
+	char name[64];
+	int result;
+
+	sprintf(name, "cf%s", tty->name);
+	dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
+	ser = netdev_priv(dev);
+	ser->tty = tty;
+	ser->dev = dev;
+	debugfs_init(ser, tty);
+	tty->receive_room = N_TTY_BUF_SIZE;
+	tty->disc_data = ser;
+	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+	rtnl_lock();
+	result = register_netdevice(dev);
+	if (result) {
+		rtnl_unlock();
+		free_netdev(dev);
+		return -ENODEV;
+	}
+
+	list_add(&ser->node, &ser_list);
+	rtnl_unlock();
+	netif_stop_queue(dev);
+	update_tty_status(ser);
+	return 0;
+}
+
+static void ldisc_close(struct tty_struct *tty)
+{
+	struct ser_device *ser = tty->disc_data;
+	/* Remove may be called inside or outside of rtnl_lock */
+	int islocked = rtnl_is_locked();
+	if (!islocked)
+		rtnl_lock();
+	/* device is freed automagically by net-sysfs */
+	dev_close(ser->dev);
+	unregister_netdevice(ser->dev);
+	list_del(&ser->node);
+	debugfs_deinit(ser);
+	if (!islocked)
+		rtnl_unlock();
+}
+
+/* The line discipline structure. */
+static struct tty_ldisc_ops caif_ldisc = {
+	.owner =	THIS_MODULE,
+	.magic =	TTY_LDISC_MAGIC,
+	.name =		"n_caif",
+	.open =		ldisc_open,
+	.close =	ldisc_close,
+	.receive_buf =	ldisc_receive,
+	.write_wakeup =	ldisc_tx_wakeup
+};
+
+static int register_ldisc(void)
+{
+	int result;
+	result = tty_register_ldisc(N_CAIF, &caif_ldisc);
+	if (result < 0) {
+		pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF,
+			result);
+		return result;
+	}
+	return result;
+}
+static const struct net_device_ops netdev_ops = {
+	.ndo_open = caif_net_open,
+	.ndo_stop = caif_net_close,
+	.ndo_start_xmit = caif_xmit
+};
+
+static void caifdev_setup(struct net_device *dev)
+{
+	struct ser_device *serdev = netdev_priv(dev);
+	dev->features = 0;
+	dev->netdev_ops = &netdev_ops;
+	dev->type = ARPHRD_CAIF;
+	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+	dev->mtu = CAIF_MAX_MTU;
+	dev->hard_header_len = CAIF_NEEDED_HEADROOM;
+	dev->tx_queue_len = 0;
+	dev->destructor = free_netdev;
+	skb_queue_head_init(&serdev->head);
+	serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
+	serdev->common.use_frag = true;
+	serdev->common.use_stx = ser_use_stx;
+	serdev->common.use_fcs = ser_use_fcs;
+	serdev->dev = dev;
+}
+
+
+static int caif_net_open(struct net_device *dev)
+{
+	struct ser_device *ser;
+	ser = netdev_priv(dev);
+	netif_wake_queue(dev);
+	return 0;
+}
+
+static int caif_net_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	return 0;
+}
+
+static int __init caif_ser_init(void)
+{
+	int ret;
+	ret = register_ldisc();
+	debugfsdir = debugfs_create_dir("caif_serial", NULL);
+	return ret;
+}
+
+static void __exit caif_ser_exit(void)
+{
+	struct ser_device *ser = NULL;
+	struct list_head *node;
+	struct list_head *_tmp;
+	list_for_each_safe(node, _tmp, &ser_list) {
+		ser = list_entry(node, struct ser_device, node);
+		dev_close(ser->dev);
+		unregister_netdevice(ser->dev);
+		list_del(node);
+	}
+	tty_unregister_ldisc(N_CAIF);
+	debugfs_remove_recursive(debugfsdir);
+}
+
+module_init(caif_ser_init);
+module_exit(caif_ser_exit);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index ef3a294..5dd674b 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,7 +23,7 @@
  */
 #define NR_UNIX98_PTY_DEFAULT	4096      /* Default maximum for Unix98 ptys */
 #define NR_UNIX98_PTY_MAX	(1 << MINORBITS) /* Absolute limit */
-#define NR_LDISCS		20
+#define NR_LDISCS		21
 
 /* line disciplines */
 #define N_TTY		0
@@ -46,8 +46,8 @@
 #define N_GIGASET_M101	16	/* Siemens Gigaset M101 serial DECT adapter */
 #define N_SLCAN		17	/* Serial / USB serial CAN Adaptors */
 #define N_PPS		18	/* Pulse per Second */
-
 #define N_V253		19	/* Codec control over voice modem */
+#define N_CAIF		20      /* CAIF protocol for talking to modems */
 
 /*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v8 11/12] net-caif: add CAIF documentation
From: sjur.brandeland @ 2010-03-30  7:30 UTC (permalink / raw)
  To: davem, netdev, marcel; +Cc: daniel.martensson, sjurbr, Sjur Braendeland
In-Reply-To: <1269934228-23292-11-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Documentation of the CAIF Protocol.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 Documentation/networking/caif/Linux-CAIF.txt |  212 ++++++++++++++++++++++++++
 Documentation/networking/caif/README         |  109 +++++++++++++
 2 files changed, 321 insertions(+), 0 deletions(-)

diff --git a/Documentation/networking/caif/Linux-CAIF.txt b/Documentation/networking/caif/Linux-CAIF.txt
new file mode 100644
index 0000000..7fe7a9a
--- /dev/null
+++ b/Documentation/networking/caif/Linux-CAIF.txt
@@ -0,0 +1,212 @@
+Linux CAIF
+===========
+copyright (C) ST-Ericsson AB 2010
+Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+License terms: GNU General Public License (GPL) version 2
+
+
+Introduction
+------------
+CAIF is a MUX protocol used by ST-Ericsson cellular modems for
+communication between Modem and host. The host processes can open virtual AT
+channels, initiate GPRS Data connections, Video channels and Utility Channels.
+The Utility Channels are general purpose pipes between modem and host.
+
+ST-Ericsson modems support a number of transports between modem
+and host. Currently, UART and Loopback are available for Linux.
+
+
+Architecture:
+------------
+The implementation of CAIF is divided into:
+* CAIF Socket Layer, Kernel API, and  Net Device.
+* CAIF Core Protocol Implementation
+* CAIF Link Layer, implemented as NET devices.
+
+
+  RTNL
+   !
+   !	 +------+   +------+   +------+
+   !	+------+!  +------+!  +------+!
+   !	! Sock !!  !Kernel!!  ! Net  !!
+   !	! API  !+  ! API  !+  ! Dev  !+	  <- CAIF Client APIs
+   !	+------+   +------!   +------+
+   !	   !	      !		 !
+   !	   +----------!----------+
+   !		   +------+		  <- CAIF Protocol Implementation
+   +------->	   ! CAIF !
+		   ! Core !
+		   +------+
+	     +--------!--------+
+	     !		       !
+	  +------+	    +-----+
+	  !    	 !	    ! TTY !	  <- Link Layer (Net Devices)
+	  +------+	    +-----+
+
+
+Using the Kernel API
+----------------------
+The Kernel API is used for accessing CAIF channels from the
+kernel.
+The user of the API has to implement two callbacks for receive
+and control.
+The receive callback gives a CAIF packet as a SKB. The control
+callback will
+notify of channel initialization complete, and flow-on/flow-
+off.
+
+
+  struct caif_device caif_dev = {
+    .caif_config = {
+     .name = "MYDEV"
+     .type = CAIF_CHTY_AT
+    }
+   .receive_cb = my_receive,
+   .control_cb = my_control,
+  };
+  caif_add_device(&caif_dev);
+  caif_transmit(&caif_dev, skb);
+
+See the caif_kernel.h for details about the CAIF kernel API.
+
+
+I M P L E M E N T A T I O N
+===========================
+===========================
+
+CAIF Core Protocol Layer
+=========================================
+
+CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
+It implements the CAIF protocol stack in a layered approach, where
+each layer described in the specification is implemented as a separate layer.
+The architecture is inspired by the design patterns "Protocol Layer" and
+"Protocol Packet".
+
+== CAIF structure ==
+The Core CAIF implementation contains:
+      -	Simple implementation of CAIF.
+      -	Layered architecture (a la Streams), each layer in the CAIF
+	specification is implemented in a separate c-file.
+      -	Clients must implement PHY layer to access physical HW
+	with receive and transmit functions.
+      -	Clients must call configuration function to add PHY layer.
+      -	Clients must implement CAIF layer to consume/produce
+	CAIF payload with receive and transmit functions.
+      -	Clients must call configuration function to add and connect the
+	Client layer.
+      - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
+	to the called function (except for framing layers' receive functions
+	or if a transmit function returns an error, in which case the caller
+	must free the packet).
+
+Layered Architecture
+--------------------
+The CAIF protocol can be divided into two parts: Support functions and Protocol
+Implementation. The support functions include:
+
+      - CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The
+	CAIF Packet has functions for creating, destroying and adding content
+	and for adding/extracting header and trailers to protocol packets.
+
+      - CFLST CAIF list implementation.
+
+      - CFGLUE CAIF Glue. Contains OS Specifics, such as memory
+	allocation, endianness, etc.
+
+The CAIF Protocol implementation contains:
+
+      - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
+	Stack and provides a Client interface for adding Link-Layer and
+	Driver interfaces on top of the CAIF Stack.
+
+      - CFCTRL CAIF Control layer. Encodes and Decodes control messages
+	such as enumeration and channel setup. Also matches request and
+	response messages.
+
+      - CFSERVL General CAIF Service Layer functionality; handles flow
+	control and remote shutdown requests.
+
+      - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
+        External Interface). This layer encodes/decodes VEI frames.
+
+      - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
+	traffic), encodes/decodes Datagram frames.
+
+      - CFMUX CAIF Mux layer. Handles multiplexing between multiple
+	physical bearers and multiple channels such as VEI, Datagram, etc.
+	The MUX keeps track of the existing CAIF Channels and
+	Physical Instances and selects the apropriate instance based
+	on Channel-Id and Physical-ID.
+
+      - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length
+	and frame checksum.
+
+      - CFSERL CAIF Serial layer. Handles concatenation/split of frames
+	into CAIF Frames with correct length.
+
+
+
+		    +---------+
+		    | Config  |
+		    | CFCNFG  |
+		    +---------+
+			 !
+    +---------+	    +---------+	    +---------+
+    |	AT    |	    | Control |	    | Datagram|
+    | CFVEIL  |	    | CFCTRL  |	    | CFDGML  |
+    +---------+	    +---------+	    +---------+
+	   \_____________!______________/
+			 !
+		    +---------+
+		    |	MUX   |
+		    |	      |
+		    +---------+
+		    _____!_____
+		   /	       \
+	    +---------+	    +---------+
+	    | CFFRML  |	    | CFFRML  |
+	    | Framing |	    | Framing |
+	    +---------+	    +---------+
+		 !		!
+	    +---------+	    +---------+
+	    |         |	    | Serial  |
+	    |	      |	    | CFSERL  |
+	    +---------+	    +---------+
+
+
+In this layered approach the following "rules" apply.
+      - All layers embed the same structure "struct cflayer"
+      - A layer does not depend on any other layer's private data.
+      - Layers are stacked by setting the pointers
+		  layer->up , layer->dn
+      -	In order to send data upwards, each layer should do
+		 layer->up->receive(layer->up, packet);
+      - In order to send data downwards, each layer should do
+		 layer->dn->transmit(layer->dn, packet);
+
+
+Linux Driver Implementation
+===========================
+
+Linux GPRS Net Device and CAIF socket are implemented on top of the
+CAIF Core protocol. The Net device and CAIF socket have an instance of
+'struct cflayer', just like the CAIF Core protocol stack.
+Net device and Socket implement the 'receive()' function defined by
+'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
+receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
+function is called in order to transmit data.
+
+The layer on top of the CAIF Core implementation is
+sometimes referred to as the "Client layer".
+
+
+Configuration of Link Layer
+---------------------------
+The Link Layer is implemented as Linux net devices (struct net_device).
+Payload handling and registration is done using standard Linux mechanisms.
+
+The CAIF Protocol relies on a loss-less link layer without implementing
+retransmission. This implies that packet drops must not happen.
+Therefore a flow-control mechanism is implemented where the physical
+interface can initiate flow stop for all CAIF Channels.
diff --git a/Documentation/networking/caif/README b/Documentation/networking/caif/README
new file mode 100644
index 0000000..757ccfa
--- /dev/null
+++ b/Documentation/networking/caif/README
@@ -0,0 +1,109 @@
+Copyright (C) ST-Ericsson AB 2010
+Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+License terms: GNU General Public License (GPL) version 2
+---------------------------------------------------------
+
+=== Start ===
+If you have compiled CAIF for modules do:
+
+$modprobe crc_ccitt
+$modprobe caif
+$modprobe caif_socket
+$modprobe chnl_net
+
+
+=== Preparing the setup with a STE modem ===
+
+If you are working on integration of CAIF you should make sure
+that the kernel is built with module support.
+
+There are some things that need to be tweaked to get the host TTY correctly
+set up to talk to the modem.
+Since the CAIF stack is running in the kernel and we want to use the existing
+TTY, we are installing our physical serial driver as a line discipline above
+the TTY device.
+
+To achieve this we need to install the N_CAIF ldisc from user space.
+The benefit is that we can hook up to any TTY.
+
+The use of Start-of-frame-extension (STX) must also be set as
+module parameter "ser_use_stx".
+
+Normally Frame Checksum is always used on UART, but this is also provided as a
+module parameter "ser_use_fcs".
+
+$ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
+$ ifconfig caif_ttyS0 up
+
+PLEASE NOTE: 	There is a limitation in Android shell.
+		It only accepts one argument to insmod/modprobe!
+
+=== Trouble shooting ===
+
+There are debugfs parameters provided for serial communication.
+/sys/kernel/debug/caif_serial/<tty-name>/
+
+* ser_state:   Prints the bit-mask status where
+  - 0x02 means SENDING, this is a transient state.
+  - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
+	and is blocking further send operation. Flow OFF has been propagated
+	to all CAIF Channels using this TTY.
+
+* tty_status: Prints the bit-mask tty status information
+  - 0x01 - tty->warned is on.
+  - 0x02 - tty->low_latency is on.
+  - 0x04 - tty->packed is on.
+  - 0x08 - tty->flow_stopped is on.
+  - 0x10 - tty->hw_stopped is on.
+  - 0x20 - tty->stopped is on.
+
+* last_tx_msg: Binary blob Prints the last transmitted frame.
+	This can be printed with
+	$od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg.
+	The first two tx messages sent look like this. Note: The initial
+	byte 02 is start of frame extension (STX) used for re-syncing
+	upon errors.
+
+  - Enumeration:
+        0000000  02 05 00 00 03 01 d2 02
+                 |  |     |  |  |  |
+                 STX(1)   |  |  |  |
+                    Length(2)|  |  |
+                          Control Channel(1)
+                             Command:Enumeration(1)
+                                Link-ID(1)
+                                    Checksum(2)
+  - Channel Setup:
+        0000000  02 07 00 00 00 21 a1 00 48 df
+                 |  |     |  |  |  |  |  |
+                 STX(1)   |  |  |  |  |  |
+                    Length(2)|  |  |  |  |
+                          Control Channel(1)
+                             Command:Channel Setup(1)
+                                Channel Type(1)
+                                    Priority and Link-ID(1)
+				      Endpoint(1)
+					  Checksum(2)
+
+* last_rx_msg: Prints the last transmitted frame.
+	The RX messages for LinkSetup look almost identical but they have the
+	bit 0x20 set in the command bit, and Channel Setup has added one byte
+	before Checksum containing Channel ID.
+	NOTE: Several CAIF Messages might be concatenated. The maximum debug
+	buffer size is 128 bytes.
+
+== Error Scenarios:
+- last_tx_msg contains channel setup message and last_rx_msg is empty ->
+  The host seems to be able to send over the UART, at least the CAIF ldisc get
+  notified that sending is completed.
+
+- last_tx_msg contains enumeration message and last_rx_msg is empty ->
+  The host is not able to send the message from UART, the tty has not been
+  able to complete the transmit operation.
+
+- if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there
+  might be problems transmitting over UART.
+  E.g. host and modem wiring is not correct you will typically see
+  tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT).
+  You will probably see the enumeration message in last_tx_message
+  and empty last_rx_message.
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v8 10/12] net-caif: add CAIF Kconfig and Makefiles
From: sjur.brandeland @ 2010-03-30  7:30 UTC (permalink / raw)
  To: davem, netdev, marcel; +Cc: daniel.martensson, sjurbr, Sjur Braendeland
In-Reply-To: <1269934228-23292-10-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Kconfig and Makefiles with options for:
CAIF:        Including caif
CAIF_DEBUG:  CAIF Debug
CAIF_NETDEV: CAIF Network Device for GPRS Contexts

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 net/Kconfig       |    2 ++
 net/Makefile      |    1 +
 net/caif/Kconfig  |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/caif/Makefile |   26 ++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/net/Kconfig b/net/Kconfig
index 041c35e..9342f7b 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -275,5 +275,7 @@ source "net/wimax/Kconfig"
 
 source "net/rfkill/Kconfig"
 source "net/9p/Kconfig"
+source "net/caif/Kconfig"
+
 
 endif   # if NET
diff --git a/net/Makefile b/net/Makefile
index 1542e72..a5eae27 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_NETLABEL)		+= netlabel/
 obj-$(CONFIG_IUCV)		+= iucv/
 obj-$(CONFIG_RFKILL)		+= rfkill/
 obj-$(CONFIG_NET_9P)		+= 9p/
+obj-$(CONFIG_CAIF)		+= caif/
 ifneq ($(CONFIG_DCB),)
 obj-y				+= dcb/
 endif
diff --git a/net/caif/Kconfig b/net/caif/Kconfig
new file mode 100644
index 0000000..cd1daf6
--- /dev/null
+++ b/net/caif/Kconfig
@@ -0,0 +1,48 @@
+#
+# CAIF net configurations
+#
+
+#menu "CAIF Support"
+comment "CAIF Support"
+menuconfig CAIF
+	tristate "Enable CAIF support"
+	select CRC_CCITT
+	default n
+	---help---
+	The "Communication CPU to Application CPU Interface" (CAIF) is a packet
+	based connection-oriented MUX protocol developed by ST-Ericsson for use
+	with its modems. It is accessed from user space as sockets (PF_CAIF).
+
+	Say Y (or M) here if you build for a phone product (e.g. Android or
+	MeeGo ) that uses CAIF as transport, if unsure say N.
+
+	If you select to build it as module then CAIF_NETDEV also needs to be
+	built as modules. You will also need to say yes to any CAIF physical
+	devices that your platform requires.
+
+	See Documentation/networking/caif for a further explanation on how to
+	use and configure CAIF.
+
+if CAIF
+
+config  CAIF_DEBUG
+	bool "Enable Debug"
+	default n
+	--- help ---
+	Enable the inclusion of debug code in the CAIF stack.
+	Be aware that doing this will impact performance.
+	If unsure say N.
+
+
+config CAIF_NETDEV
+	tristate "CAIF GPRS Network device"
+	default CAIF
+	---help---
+	Say Y if you will be using a CAIF based GPRS network device.
+	This can be either built-in or a loadable module,
+	If you select to build it as a built-in then the main CAIF device must
+	also be a built-in.
+	If unsure say Y.
+
+endif
+#endmenu
diff --git a/net/caif/Makefile b/net/caif/Makefile
new file mode 100644
index 0000000..34852af
--- /dev/null
+++ b/net/caif/Makefile
@@ -0,0 +1,26 @@
+ifeq ($(CONFIG_CAIF_DEBUG),1)
+CAIF_DBG_FLAGS := -DDEBUG
+endif
+
+ccflags-y := $(CAIF_FLAGS) $(CAIF_DBG_FLAGS)
+
+caif-objs := caif_dev.o \
+	cfcnfg.o cfmuxl.o cfctrl.o  \
+	cffrml.o cfveil.o cfdbgl.o\
+	cfserl.o cfdgml.o  \
+	cfrfml.o cfvidl.o cfutill.o \
+	cfsrvl.o cfpkt_skbuff.o caif_config_util.o
+clean-dirs:= .tmp_versions
+
+clean-files:= \
+	Module.symvers \
+	modules.order \
+	*.cmd \
+	*.o \
+	*~
+
+obj-$(CONFIG_CAIF) += caif.o
+obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
+obj-$(CONFIG_CAIF) += caif_socket.o
+
+export-objs := caif.o
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v8 09/12] net-caif: add CAIF netdevice
From: sjur.brandeland @ 2010-03-30  7:30 UTC (permalink / raw)
  To: davem, netdev, marcel; +Cc: daniel.martensson, sjurbr, Sjur Braendeland
In-Reply-To: <1269934228-23292-9-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Adding GPRS Net Device for PDP Contexts.
The device can be managed by RTNL as defined in if_caif.h.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 net/caif/chnl_net.c |  451 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 451 insertions(+), 0 deletions(-)

diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
new file mode 100644
index 0000000..73e639d
--- /dev/null
+++ b/net/caif/chnl_net.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Authors:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ *		Daniel Martensson / Daniel.Martensson@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/moduleparam.h>
+#include <linux/ip.h>
+#include <linux/sched.h>
+#include <linux/sockios.h>
+#include <linux/caif/if_caif.h>
+#include <net/rtnetlink.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfcnfg.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/caif_dev.h>
+
+#define CAIF_CONNECT_TIMEOUT 30
+#define SIZE_MTU 1500
+#define SIZE_MTU_MAX 4080
+#define SIZE_MTU_MIN 68
+#define CAIF_NET_DEFAULT_QUEUE_LEN 500
+
+#undef pr_debug
+#define pr_debug pr_warning
+
+/*This list is protected by the rtnl lock. */
+static LIST_HEAD(chnl_net_list);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("caif");
+
+struct chnl_net {
+	struct cflayer chnl;
+	struct net_device_stats stats;
+	struct caif_connect_request conn_req;
+	struct list_head list_field;
+	struct net_device *netdev;
+	char name[256];
+	wait_queue_head_t netmgmt_wq;
+	/* Flow status to remember and control the transmission. */
+	bool flowenabled;
+	bool pending_close;
+};
+
+static void robust_list_del(struct list_head *delete_node)
+{
+	struct list_head *list_node;
+	struct list_head *n;
+	ASSERT_RTNL();
+	list_for_each_safe(list_node, n, &chnl_net_list) {
+		if (list_node == delete_node) {
+			list_del(list_node);
+			break;
+		}
+	}
+}
+
+static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
+{
+	struct sk_buff *skb;
+	struct chnl_net *priv  = NULL;
+	int pktlen;
+	int err = 0;
+
+	priv = container_of(layr, struct chnl_net, chnl);
+
+	if (!priv)
+		return -EINVAL;
+
+	/* Get length of CAIF packet. */
+	pktlen = cfpkt_getlen(pkt);
+
+	skb = (struct sk_buff *) cfpkt_tonative(pkt);
+	/* Pass some minimum information and
+	 * send the packet to the net stack.
+	 */
+	skb->dev = priv->netdev;
+	skb->protocol = htons(ETH_P_IP);
+
+	/* If we change the header in loop mode, the checksum is corrupted. */
+	if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	else
+		skb->ip_summed = CHECKSUM_NONE;
+
+	/* FIXME: Drivers should call this in tasklet context. */
+	if (in_interrupt())
+		netif_rx(skb);
+	else
+		netif_rx_ni(skb);
+
+	/* Update statistics. */
+	priv->netdev->stats.rx_packets++;
+	priv->netdev->stats.rx_bytes += pktlen;
+
+	return err;
+}
+
+static int delete_device(struct chnl_net *dev)
+{
+	ASSERT_RTNL();
+	if (dev->netdev)
+		unregister_netdevice(dev->netdev);
+	return 0;
+}
+
+static void close_work(struct work_struct *work)
+{
+	struct chnl_net *dev = NULL;
+	struct list_head *list_node;
+	struct list_head *_tmp;
+	rtnl_lock();
+	list_for_each_safe(list_node, _tmp, &chnl_net_list) {
+		dev = list_entry(list_node, struct chnl_net, list_field);
+		if (!dev->pending_close)
+			continue;
+		list_del(list_node);
+		delete_device(dev);
+	}
+	rtnl_unlock();
+}
+DECLARE_WORK(close_worker, close_work);
+
+static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
+				int phyid)
+{
+	struct chnl_net *priv;
+	pr_debug("CAIF: %s(): NET flowctrl func called flow: %s.\n",
+		__func__,
+		flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" :
+		flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" :
+		flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" :
+		flow == CAIF_CTRLCMD_DEINIT_RSP ? "CLOSE/DEINIT" :
+		flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "OPEN_FAIL" :
+		flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ?
+		 "REMOTE_SHUTDOWN" : "UKNOWN CTRL COMMAND");
+
+	priv = container_of(layr, struct chnl_net, chnl);
+
+	switch (flow) {
+	case CAIF_CTRLCMD_FLOW_OFF_IND:
+	case CAIF_CTRLCMD_DEINIT_RSP:
+	case CAIF_CTRLCMD_INIT_FAIL_RSP:
+	case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
+		priv->flowenabled = false;
+		netif_tx_disable(priv->netdev);
+		pr_warning("CAIF: %s(): done\n", __func__);
+		priv->pending_close = 1;
+		schedule_work(&close_worker);
+		break;
+	case CAIF_CTRLCMD_FLOW_ON_IND:
+	case CAIF_CTRLCMD_INIT_RSP:
+		priv->flowenabled = true;
+		netif_wake_queue(priv->netdev);
+		wake_up_interruptible(&priv->netmgmt_wq);
+		break;
+	default:
+		break;
+	}
+}
+
+static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct chnl_net *priv;
+	struct cfpkt *pkt = NULL;
+	int len;
+	int result = -1;
+	/* Get our private data. */
+	priv = netdev_priv(dev);
+
+	if (skb->len > priv->netdev->mtu) {
+		pr_warning("CAIF: %s(): Size of skb exceeded MTU\n", __func__);
+		return -ENOSPC;
+	}
+
+	if (!priv->flowenabled) {
+		pr_debug("CAIF: %s(): dropping packets flow off\n", __func__);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
+		swap(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
+
+	/* Store original SKB length. */
+	len = skb->len;
+
+	pkt = cfpkt_fromnative(CAIF_DIR_OUT, (void *) skb);
+
+	pr_debug("CAIF: %s(): transmit inst %s %d,%p\n",
+		__func__, dev->name, priv->chnl.dn->id, &priv->chnl.dn);
+
+	/* Send the packet down the stack. */
+	result = priv->chnl.dn->transmit(priv->chnl.dn, pkt);
+	if (result) {
+		if (result == -EAGAIN)
+			result = NETDEV_TX_BUSY;
+		return result;
+	}
+
+	/* Update statistics. */
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += len;
+
+	return NETDEV_TX_OK;
+}
+
+static int chnl_net_open(struct net_device *dev)
+{
+	struct chnl_net *priv = NULL;
+	int result = -1;
+	ASSERT_RTNL();
+
+	priv = netdev_priv(dev);
+	pr_debug("CAIF: %s(): dev name: %s\n", __func__, priv->name);
+
+	if (!priv) {
+		pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__);
+		return -ENODEV;
+	}
+	result = caif_connect_client(&priv->conn_req, &priv->chnl);
+	if (result != 0) {
+		pr_debug("CAIF: %s(): err: "
+			 "Unable to register and open device, Err:%d\n",
+			__func__,
+			result);
+		return -ENODEV;
+	}
+	result = wait_event_interruptible(priv->netmgmt_wq, priv->flowenabled);
+
+	if (result == -ERESTARTSYS) {
+		pr_debug("CAIF: %s(): wait_event_interruptible"
+			 " woken by a signal\n", __func__);
+		return -ERESTARTSYS;
+	} else
+		pr_debug("CAIF: %s(): Flow on recieved\n", __func__);
+
+	return 0;
+}
+
+static int chnl_net_stop(struct net_device *dev)
+{
+	struct chnl_net *priv;
+	int result = -1;
+	ASSERT_RTNL();
+	priv = netdev_priv(dev);
+
+	result = caif_disconnect_client(&priv->chnl);
+	if (result != 0) {
+		pr_debug("CAIF: %s(): chnl_net_stop: err: "
+			 "Unable to STOP device, Err:%d\n",
+			 __func__, result);
+		return -EBUSY;
+	}
+	result = wait_event_interruptible(priv->netmgmt_wq,
+					  !priv->flowenabled);
+
+	if (result == -ERESTARTSYS) {
+		pr_debug("CAIF: %s(): wait_event_interruptible woken by"
+			 " signal, signal_pending(current) = %d\n",
+			 __func__,
+			 signal_pending(current));
+	} else {
+		pr_debug("CAIF: %s(): disconnect received\n", __func__);
+
+	}
+
+	return 0;
+}
+
+int chnl_net_init(struct net_device *dev)
+{
+	struct chnl_net *priv;
+	ASSERT_RTNL();
+	priv = netdev_priv(dev);
+	strncpy(priv->name, dev->name, sizeof(priv->name));
+	return 0;
+}
+
+void chnl_net_uninit(struct net_device *dev)
+{
+	struct chnl_net *priv;
+	ASSERT_RTNL();
+	priv = netdev_priv(dev);
+	robust_list_del(&priv->list_field);
+}
+
+static const struct net_device_ops netdev_ops = {
+	.ndo_open = chnl_net_open,
+	.ndo_stop = chnl_net_stop,
+	.ndo_init = chnl_net_init,
+	.ndo_uninit = chnl_net_uninit,
+	.ndo_start_xmit = chnl_net_start_xmit,
+};
+
+static void ipcaif_net_setup(struct net_device *dev)
+{
+	struct chnl_net *priv;
+	dev->netdev_ops = &netdev_ops;
+	dev->destructor = free_netdev;
+	dev->flags |= IFF_NOARP;
+	dev->flags |= IFF_POINTOPOINT;
+	dev->needed_headroom = CAIF_NEEDED_HEADROOM;
+	dev->needed_tailroom = CAIF_NEEDED_TAILROOM;
+	dev->mtu = SIZE_MTU;
+	dev->tx_queue_len = CAIF_NET_DEFAULT_QUEUE_LEN;
+
+	priv = netdev_priv(dev);
+	priv->chnl.receive = chnl_recv_cb;
+	priv->chnl.ctrlcmd = chnl_flowctrl_cb;
+	priv->netdev = dev;
+	priv->conn_req.protocol = CAIFPROTO_DATAGRAM;
+	priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW;
+	priv->conn_req.priority = CAIF_PRIO_LOW;
+	/* Insert illegal value */
+	priv->conn_req.sockaddr.u.dgm.connection_id = -1;
+	priv->flowenabled = false;
+
+	ASSERT_RTNL();
+	init_waitqueue_head(&priv->netmgmt_wq);
+	list_add(&priv->list_field, &chnl_net_list);
+}
+
+
+static int ipcaif_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+	struct chnl_net *priv;
+	u8 loop;
+	priv = netdev_priv(dev);
+	NLA_PUT_U32(skb, IFLA_CAIF_IPV4_CONNID,
+		    priv->conn_req.sockaddr.u.dgm.connection_id);
+	NLA_PUT_U32(skb, IFLA_CAIF_IPV6_CONNID,
+		    priv->conn_req.sockaddr.u.dgm.connection_id);
+	loop = priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP;
+	NLA_PUT_U8(skb, IFLA_CAIF_LOOPBACK, loop);
+
+
+	return 0;
+nla_put_failure:
+	return -EMSGSIZE;
+
+}
+
+static void caif_netlink_parms(struct nlattr *data[],
+				struct caif_connect_request *conn_req)
+{
+	if (!data) {
+		pr_warning("CAIF: %s: no params data found\n", __func__);
+		return;
+	}
+	if (data[IFLA_CAIF_IPV4_CONNID])
+		conn_req->sockaddr.u.dgm.connection_id =
+			nla_get_u32(data[IFLA_CAIF_IPV4_CONNID]);
+	if (data[IFLA_CAIF_IPV6_CONNID])
+		conn_req->sockaddr.u.dgm.connection_id =
+			nla_get_u32(data[IFLA_CAIF_IPV6_CONNID]);
+	if (data[IFLA_CAIF_LOOPBACK]) {
+		if (nla_get_u8(data[IFLA_CAIF_LOOPBACK]))
+			conn_req->protocol = CAIFPROTO_DATAGRAM_LOOP;
+		else
+			conn_req->protocol = CAIFPROTO_DATAGRAM;
+	}
+}
+
+static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
+			  struct nlattr *tb[], struct nlattr *data[])
+{
+	int ret;
+	struct chnl_net *caifdev;
+	ASSERT_RTNL();
+	caifdev = netdev_priv(dev);
+	caif_netlink_parms(data, &caifdev->conn_req);
+	ret = register_netdevice(dev);
+	if (ret)
+		pr_warning("CAIF: %s(): device rtml registration failed\n",
+			   __func__);
+	return ret;
+}
+
+static int ipcaif_changelink(struct net_device *dev, struct nlattr *tb[],
+				struct nlattr *data[])
+{
+	struct chnl_net *caifdev;
+	ASSERT_RTNL();
+	caifdev = netdev_priv(dev);
+	caif_netlink_parms(data, &caifdev->conn_req);
+	netdev_state_change(dev);
+	return 0;
+}
+
+static size_t ipcaif_get_size(const struct net_device *dev)
+{
+	return
+		/* IFLA_CAIF_IPV4_CONNID */
+		nla_total_size(4) +
+		/* IFLA_CAIF_IPV6_CONNID */
+		nla_total_size(4) +
+		/* IFLA_CAIF_LOOPBACK */
+		nla_total_size(2) +
+		0;
+}
+
+static const struct nla_policy ipcaif_policy[IFLA_CAIF_MAX + 1] = {
+	[IFLA_CAIF_IPV4_CONNID]	      = { .type = NLA_U32 },
+	[IFLA_CAIF_IPV6_CONNID]	      = { .type = NLA_U32 },
+	[IFLA_CAIF_LOOPBACK]	      = { .type = NLA_U8 }
+};
+
+
+static struct rtnl_link_ops ipcaif_link_ops __read_mostly = {
+	.kind		= "caif",
+	.priv_size	= sizeof(struct chnl_net),
+	.setup		= ipcaif_net_setup,
+	.maxtype	= IFLA_CAIF_MAX,
+	.policy		= ipcaif_policy,
+	.newlink	= ipcaif_newlink,
+	.changelink	= ipcaif_changelink,
+	.get_size	= ipcaif_get_size,
+	.fill_info	= ipcaif_fill_info,
+
+};
+
+static int __init chnl_init_module(void)
+{
+	return rtnl_link_register(&ipcaif_link_ops);
+}
+
+static void __exit chnl_exit_module(void)
+{
+	struct chnl_net *dev = NULL;
+	struct list_head *list_node;
+	struct list_head *_tmp;
+	rtnl_link_unregister(&ipcaif_link_ops);
+	rtnl_lock();
+	list_for_each_safe(list_node, _tmp, &chnl_net_list) {
+		dev = list_entry(list_node, struct chnl_net, list_field);
+		list_del(list_node);
+		delete_device(dev);
+	}
+	rtnl_unlock();
+}
+
+module_init(chnl_init_module);
+module_exit(chnl_exit_module);
-- 
1.6.3.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox