Netdev List
 help / color / mirror / Atom feed
* linux-next: build warning after merge of the net tree
From: Stephen Rothwell @ 2010-03-01  5:47 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Marcel Holtmann

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

Hi Dave,

After merging the net tree, today's linux-next build (x86_64 allmodconfig)
produced this warning:

net/bluetooth/hci_sysfs.c: In function 'inquiry_cache_read':
net/bluetooth/hci_sysfs.c:441: warning: the frame size of 4208 bytes is larger than 2048 bytes

Introduced by commit ca325f698996c1a0770a67f41e7dc97a007d8bc2
("Bluetooth: Convert inquiry cache to use debugfs instead of sysfs")
which introduces a function with a 4096 char array on the stack.
-- 
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: linux-next: build warning after merge of the net tree
From: David Miller @ 2010-03-01  7:02 UTC (permalink / raw)
  To: sfr; +Cc: netdev, linux-next, linux-kernel, marcel
In-Reply-To: <20100301164721.f8ce9fac.sfr@canb.auug.org.au>

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Mon, 1 Mar 2010 16:47:21 +1100

> After merging the net tree, today's linux-next build (x86_64 allmodconfig)
> produced this warning:
> 
> net/bluetooth/hci_sysfs.c: In function 'inquiry_cache_read':
> net/bluetooth/hci_sysfs.c:441: warning: the frame size of 4208 bytes is larger than 2048 bytes
> 
> Introduced by commit ca325f698996c1a0770a67f41e7dc97a007d8bc2
> ("Bluetooth: Convert inquiry cache to use debugfs instead of sysfs")
> which introduces a function with a 4096 char array on the stack.

Thanks Stephen, I'll look into this.

^ permalink raw reply

* [GIT]: Networking
From: David Miller @ 2010-03-01  7:05 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


Here we have the usual smattering of driver updates, but outside of
that the highlights are:

1) Preliminary IGMP snooping support for the bridging layer, from
   Herbert Xu.

2) Support ipsec tunnels in network namespaces, from Alexey Dobriyan.

3) Better MSG_TRUNC support for DCCP sockets, from Gerrit Renker.

4) Proper CONFIG_COMPAT support for bridging netfilter.  From Florian
   Westphal.

5) Major ISDN CAPI layer cleanups from Jan Kiszka.

6) Abstraction of unicast and multicast device list accesses by Jiri
   Pirko.

7) Add and use seq_file helpers for iterating over an hlist in the
   networking.  From Li Zefan.

8) Netfilter conntrack "zones" support from Patrick McHardy.

9) Support for taking advantage of n-tuple filters in networking
   cards.  From Peter Waskiewicz.

10) Several locking changes from Stephen Hemminger, including a couple
    rwlock --> spinlock conversions, and changing AF_PACKET socket
    handling over to RCU.

11) Convert several drivers to use %pM for MAC address printing.
    From hartleys.

12) Avoid emitting empty events when flushing IPSEC tables, from
    Jamal Hadi Salim.

13) Work towards more consistent networking driver log messages.
    From Joe Perches.

Please pull, thanks a lot!

The following changes since commit 30ff056c42c665b9ea535d8515890857ae382540:
  Linus Torvalds (1):
        Merge branch 'x86-uv-for-linus' of git://git.kernel.org/.../tip/linux-2.6-tip

are available in the git repository at:

  master.kernel.org:/pub/scm/linux/kernel/git/davem/net-next-2.6.git master

Abhijeet Kolekar (4):
      iwlwifi: enable DC calibration
      iwlwifi: cleanup return values
      iwlwifi: indicate calib version for 6050 series
      iwlwifi: increase command buffer size

Ajit Khaparde (14):
      bonding: Remove net_device_stats from bonding struct
      be2net: remove unused pci device id
      be2net: bug fix for flashing the BladeEngine3 ASIC
      be2net: bug fix in be_change_mtu
      be2net: minor code optimizations
      be2net: fix to limit max vlans supported in certain skews
      be2net: change the driver description
      be2net: remove ASIC generation number from Kconfig
      be2net: bug fix in be_read_eeprom
      net: bug fix for vlan + gro issue
      be2net: update copyright dates
      be2net: Maintain tx and rx counters in driver
      be2net: Bump the driver version number
      MAINTAINERS: Add two maintainers for be2net driver

Alban Browaeys (4):
      rt2x00 : bail out of regbusy_read if device is removed.
      rt2x00 : modify padding location.
      rt2x00 : avoid timestamp for monitor injected frame.
      rt2x00 : trim the skb after having the l2pad removed.

Alexander Beregalov (1):
      eepro: fix netdev_mc_count conversion

Alexander Duyck (4):
      igb: add support for device reset interrupt
      igb: remove unecessary q_vector declarations and remove itr_shift
      igb: Allocate rings seperately instead of as a block
      pci: add support for 82576NS serdes to existing SR-IOV quirk

Alexey Dobriyan (38):
      drivers/net/: use DEFINE_PCI_DEVICE_TABLE()
      netfilter: nfnetlink: netns support
      netfilter: ctnetlink: netns support
      proc_fops: convert drivers/isdn/ to seq_file
      net: spread __net_init, __net_exit
      netfilter: xt_connlimit: netns support
      netfilter: netns: #ifdef ->iptable_security, ->ip6table_security
      netfilter: xt_hashlimit: simplify seqfile code
      netfilter: xtables: add struct xt_mtchk_param::net
      netfilter: xtables: add struct xt_mtdtor_param::net
      netfilter: xt_recent: netns support
      netfilter: xt_hashlimit: netns support
      netfiltr: ipt_CLUSTERIP: simplify seq_file codeA
      netdev: remove certain HAVE_ macros
      neigh: simplify seq_file code
      net: constify MIB name tables
      icmp: move icmp_err_convert[] to .rodata
      netdev: remove HAVE_ leftovers
      netns xfrm: fixup xfrm6_tunnel error propagation
      netns xfrm: xfrm6_tunnel in netns
      netns xfrm: ipcomp support
      netns xfrm: ipcomp6 support
      netfilter: xtables: CONFIG_COMPAT redux
      net: CONFIG_COMPAT redux
      netfilter: xtables: consistent struct compat_xt_counters definition
      netfilter: xtables: symmetric COMPAT_XT_ALIGN definition
      netfilter: xtables: fix mangle tables
      netfilter: nf_conntrack: elegantly simplify nf_ct_exp_net()
      netfilter: don't use INIT_RCU_HEAD()
      gre: fix netns vs proto registration ordering
      tunnels: fix netns vs proto registration ordering
      net: remove INIT_RCU_HEAD() usage
      net: use kasprintf() for socket cache names
      ipv6: remove stale MIB definitions
      ipv6: use standard lists for FIB walks
      ipv6: drop unused "dev" arg of icmpv6_send()
      const: struct nla_policy
      netfilter: nfnetlink_log: fix silly refcount leak

Allan Stephens (1):
      tipc: Clean up configuration file

Amerigo Wang (1):
      tipc: use kconfig to limit numeric ranges

Amit Kucheria (2):
      fec: Add LAN8700 phy support
      fec: Add ARCH_MX5 as a dependency

Amit Kumar Salecha (16):
      netxen: minor suspend resume fixes
      netxen: fix tx timeout recovery
      netxen: support pci error handlers
      netxen: fix unified fw size check
      netxen: fix endianness read mac address
      netxen: fix endianness intr coalesce
      netxen: fix license header
      netxen: fix sparse warning
      qlcnic: Qlogic ethernet driver for CNA devices
      NET: Add Qlogic ethernet driver for CNA devices
      qlcnic: use DEFINE_PCI_DEVICE_TABLE
      qlcnic: add ethernet identifier in board info
      qlcnic: clear device reset state after fw recovery
      qlcnic: protect resoruce cleanup by rtnl lock
      qlcnic: add interrupt diagnostic test
      qlcnic: add loopback diagnostic test

Anatolij Gustschin (3):
      fs_enet: use dev_xxx instead of printk
      fs_enet: Add support for MPC512x to fs_enet driver
      fs_enet: add FEC TX buffer alignment workaround for MPC5121

Andreas Mohr (4):
      MCS7830 USB-Ether: add Rx error support
      MCS7830 USB-Ether: Spelling corrections
      MCS7830 USB-Ether: change register define
      MCS7830 USB-Ether: resume _with_ working link, via .reset_resume support

Andreas Petlund (3):
      net: TCP thin-stream detection
      net: TCP thin linear timeouts
      net: TCP thin dupack

Andres Salomon (1):
      mac80211: make rate_control_alloc static

Andriy Tkachuk (3):
      mac80211: Account HT Control field in Data frame hdrlen according to 802.11n-2009
      lib80211: Cosmetics - make room for MIC/CRC near the actual calculation
      lib80211: Introduce TKIP_HDR_LEN define for code clarity

Andy Gospodarek (2):
      bonding: allow arp_ip_targets on separate vlans to use arp validation
      fix bonding: allow arp_ip_targets on separate vlans to use arp validation

Andy Shevchenko (1):
      isdn: remove ishexdigit() in regard to isxdigit()

Arnd Bergmann (7):
      net: maintain namespace isolation between vlan and real device
      macvlan: allow multiple driver backends
      net: macvtap driver
      net/macvtap: fix reference counting
      macvtap: rework object lifetime rules
      net/macvtap: add vhost support
      macvtap: add GSO/csum offload support

Atsushi Nemoto (2):
      isa-skelton: Remove a wrong netif_wake_queue() call
      tc35815: Fix double locking on NAPI

Ben Hutchings (8):
      sfc: Update MCDI protocol definitions
      sfc: Replace PHY MDIO test with an 'alive' test
      sfc: Implement NVRAM selftest for SFC9000 family
      sfc: Remove declarations of nonexistent functions
      sfc: Fix some incorrect or redundant comments
      sfc: Do not include unneeded headers
      net: Fix first line of kernel-doc for a few functions
      ethtool: Don't flush n-tuple list from ethtool_reset()

Ben M Cahill (2):
      iwlwifi: Add chain noise scaling factor
      iwlwifi: Add chain_noise support for 6050

Benjamin Li (1):
      bnx2: Flush the register writes which setup the MSI-X table

Benoit PAPILLAULT (1):
      rt2x00: Disable RX aggregation for rt2800usb

Benoit Papillault (5):
      rt2x00: Fix rt2800usb RX frame format and as such L2PAD
      mac80211: Fixed netif_tx_wake_all_queues in IBSS mode
      mac80211: removed useless code in IBSS management
      mac80211: Fixed a bug in IBSS merge
      mac80211: Added a new debugfs file for reading channel_type

Bob Copeland (4):
      mac80211: pid: replace open-coded msecs_to_jiffies
      ath5k: dont use external sleep clock in AP mode
      ath5k: fix setup for CAB queue
      ath5k: use correct packet type when transmitting

Breno Leitao (2):
      qlge: removing unreachable block of code
      qlge: Code clean up

Brian Haley (1):
      doc: document IPv6 parameters

Brice Goglin (1):
      myri10ge: optimize 4k-boundary check when stocking rx pages

Bruce Allan (3):
      e1000e: use alternate MAC address on ESB2 if available
      e1000e: provide MAC-family-specific function to set LAN ID
      e1000e: genericize the update multicast address list

Catalin(ux) M. BOIE (1):
      IPVS: Allow boot time change of hash size

Chrissie Caulfield (1):
      Orphan DECnet

Christian Lamparter (10):
      ar9170: remove dead definitions
      ar9170: improve network latency
      ar9170: remove redundant frame flags
      ar9170: small misc changes
      ar9170: fix AC_VIDEO txop parameter
      mac80211: fix ampdu_action tx_start ssn
      p54pci: handle dma mapping errors
      p54pci: move tx cleanup into tasklet
      p54pci: revise tx locking
      ath: fix WARN_ON with Polish (Poland) Contry code

Christian Pellegrin (2):
      can: Proper ctrlmode handling for CAN devices
      can: mcp251x: Move to threaded interrupts instead of workqueues.

Christoph Egger (2):
      Remove config option B43_LEGACY_RFKILL completely
      ipv4: obsolete config in kernel source (IP_ROUTE_PERVASIVE)

Colin Ian King (1):
      wireless: hostap, fix oops due to early probing interrupt

Dan Carpenter (1):
      Bluetooth: Add missing kfree() on error path in Atheros driver

Daniel Borkmann (1):
      netpoll: allow execution of multiple rx_hooks per interface

Daniel Halperin (2):
      iwlwifi: fix throughput degradation in aggregation mode
      iwlwifi: optimize power saving

Darren Jenkins (2):
      hardware/mISDN/mISDNinfineon.c: bail out of loop on error
      drivers/net/wireless/p54/txrx.c Fix off by one error

David S. Miller (35):
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      ipv4: Use less conflicting local var name in change_nexthops() loop macro.
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      net: Unexport napi_gro_flush().
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      ariadne: Fix build.
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      e1000e: Fix namespace conflicts wrt. e1000_has_link
      packet: Kill CONFIG_PACKET_MMAP.
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      Merge branch 'master' of ssh://master.kernel.org/.../linville/wireless-next-2.6
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      ethtool: Fix includes build break
      mac80211: Fix error introduced in netdev_mc_count() changes.
      niu: Refinements to kernel logging.
      Merge branch 'master' of git://git.kernel.org/.../kaber/nf-next-2.6
      sparc64: Kill bogus ip_tables.h include.
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      xfrm: Revert false event eliding commits.
      net: Make GRETH driver depend on SPARC.
      Merge branch 'master' of git://git.kernel.org/.../kaber/nf-next-2.6
      Merge branch 'master' of git://git.kernel.org/.../kaber/nf-next-2.6
      Merge branch 'master' of master.kernel.org:/.../davem/net-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      Revert "ethtool: Add n-tuple string length to drvinfo and return it"
      Merge branch 'master' of git://git.kernel.org/.../kaber/nf-next-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6
      bridge: Make IGMP snooping depend upon BRIDGE.
      Merge branch 'master' of git://git.kernel.org/.../holtmann/bluetooth-next-2.6
      Merge branch 'master' of /home/davem/src/GIT/linux-2.6/

Deepak Saxena (1):
      Add Station and AdHoc mode support to libertas_tf

Divy Le Ray (3):
      cxgb3: add memory barriers
      cxgb3: FIx VLAN over Jumbo frames
      cxgb3: fix link flap

Eddie Wai (2):
      cnic: Finetune iSCSI connection set up.
      cnic: Finetune iSCSI connection reset.

Einar Lueck (1):
      qeth: default BLKT values for new OSA/3 hardware

Emese Revfy (1):
      iwlwifi: Constify struct iwl_ops

Eric Dumazet (4):
      xfrm: avoid spinlock in get_acqseq()
      ethtool: reduce stack usage
      xt_hashlimit: fix locking
      netfilter: nf_queue: fix NF_STOLEN skb leak

Eric Leblond (1):
      netfilter: nfnetlink_queue: simplify warning message

Eric W. Biederman (3):
      net ipv4: Decouple ipv4 interface parameters from binary sysctl numbers
      net neigh: Decouple per interface neighbour table controls from binary sysctls
      scm: Only support SCM_RIGHTS on unix domain sockets.

FUJITA Tomonori (1):
      mlx4: replace the dma_sync_single_range_for_cpu/device API

Felix Fietkau (19):
      mac80211: use nullfunc frames for 4-addr sta detection
      mac80211: allow station updates on ap interfaces for vlan stations
      mac80211: do not transmit frames on unconfigured 4-addr vlan interfaces
      mac80211: force use_short_slot=true for 5GHz
      ath9k: cleanup slot time and ack/cts timeout handling
      ath9k: implement coverage class support
      mac80211: fix WMM AC default for non-QoS data frames
      ath9k: fix RTS/CTS handling
      mac80211: fix rx data handling for non-data frames on multiple vifs
      ath9k: improve max rate retry handling
      mac80211: fix WARN_ON in the new work code
      mac80211: fix sta lookup for received action frames on an AP VLAN
      mac80211: fix monitor mode tx radiotap header handling
      mac80211: fix sta lookup with AP VLAN interfaces and injected frames
      ath9k: add a workaround for ack timeout issues
      ath9k: fix rate control fallback rate selection
      ath9k: fix beacon timer restart after a card reset
      ath9k: disable RIFS search for AR91xx based chips
      skbuff: align sk_buff::cb to 64 bit and close some potential holes

Flavio Leitner (1):
      igmp: fix ip_mc_sf_allow race [v5]

Florian Westphal (11):
      netfilter: fix build failure with CONNTRACK=y NAT=n
      netfilter: ebtables: abort if next_offset is too small
      netfilter: ebtables: avoid explicit XT_ALIGN() in match/targets
      netfilter: CONFIG_COMPAT: allow delta to exceed 32767
      netfilter: ebtables: split do_replace into two functions
      netfilter: ebtables: split copy_everything_to_user into two functions
      netfilter: ebtables: split update_counters into two functions
      netfilter: ebtables: add CONFIG_COMPAT support
      netfilter: ebtables: try native set/getsockopt handlers, too
      netfilter: ebt_limit: add CONFIG_COMPAT support
      netfilter: ebtables: mark: add CONFIG_COMPAT support

Frederic Leroy (1):
      staging: rtl8192su: fix compile error from wireless-testing commit

Geert Uytterhoeven (1):
      mac8390: Fix build breakage

Gerrit Renker (3):
      dccp: allow probing of CCID-array length
      dccp: support for passing MSG_TRUNC
      udp: remove redundant variable

Gertjan van Wingerde (16):
      rt2x00: Further L2 padding fixes.
      rt2x00: Remove SKBDESC_L2_PADDED flag.
      rt2x00: Reorganize L2 padding inserting function.
      rt2x00: Only remove L2 padding in received frames if there is payload.
      rt2x00: Fix trimming of L2 padded frames.
      rt2x00: Fix checks for rt2800 SOC support.
      rt2x00: Let rt2800lib check CONFIG_RT2X00_LIB_USB instead of CONFIG_RT2800USB
      rt2x00: convert RT2800PCI_PCI and RT2800PCI_SOC Kconfig symbols to booleans.
      rt2x00: Cleanup chip handling helper functions.
      rt2x00: RF3052 is a valid RF chipset for USB devices as well.
      rt2x00: Unify rt2800 WPDMA ready waiting functions.
      rt2x00: Make rt2800_init_led static and don't export it.
      rt2x00: Introduce SoC interface type.
      rt2x00: Reorganize RT chipset setting for PCI/SOC devices.
      rt2x00: rework RT chipset and revision determination for PCI an SOC devices.
      rt2x00: rt2800 - Make rt30xx and rt35xx chipsets configurable.

Giuseppe CAVALLARO (13):
      stmmac: use MII_BUS_ID_SIZE instead of BUS_ID_SIZE
      stmmac: convert unicast addr list to list_head
      stmmac: add the new Header file for stmmac platform data
      stmmac: rewiew platform data
      stmmac: perform hw bus configuration
      stmmac: do not call fix_mac_speed if NULL
      stmmac: reorganise class operations.
      stmmac: move the dma out from the main
      stmmac: rename mac100 as dwmac100 and fix spare coding style
      stmmac: rename the gmac as dwmac1000 and split core and dma parts
      stmmac: include netdevice.h into the common.h header
      stmmac: improve Kconfig help
      stmmac: update the driver's module version

Giuseppe Cavallaro (2):
      phy: SMSC device Energy Detect power-down mode
      stmmac: fix 'lenght' typo in comments and code

Greg Rose (20):
      ixgbevf: Macros, data structures, useful defines and registers
      ixgbevf: 82599 Virtual Function core functions and header
      ixgbevf: Mailbox communication
      ixgbevf: Driver main and ethool interface module and main header
      ixgbevf: Driver Makefile
      ixgbevf: Kconfig, Makefile and Documentation
      ixgbe: Mailbox header and code module
      ixgbe: Add SR-IOV register, structure and bit defines
      ixgbe: Add SR-IOV specific features
      ixgbe: Add SR-IOV specific modules to driver Makefile
      ixgbe: Add SR-IOV feature enablement code
      ixgbe: Add SR-IOV features to main module
      ixgbe: Fix ethtool diag test for VT mode operation
      ixgbe: Set the correct pool when VLANs are added in SR-IOV mode.
      ixgbe: Remove unused emulation MAC storage from the per VF data structure.
      ixgbe: Allow the VF driver to be loaded before the PF driver
      ixgbe: Improve reset coordination between the PF and the VF
      ixgbevf: Take action when the PF notifies the VF it is resetting.
      ixgbevf: Fix panics in the VF driver
      ixgbevf: Tell network stack to stop tx when the VF detects PF reset

Guido Barzini (1):
      sfc: Survive ISR0=0 bug in the shared IRQ case

H Hartley Sweeten (17):
      drivers/net/lib82596.c: use %pM to shown MAC address
      drivers/net/igbvf/netdev.c: use %pM to shown MAC address
      drivers/net/usb/rtl8150.c: use %pM to shown MAC address
      drivers/net/via-velocity.c: use %pM to shown MAC address
      drivers/net/xilinx_emaclite.c: use %pM to shown MAC address
      drivers/s390/net/qeth_l2_main.c: use %pM to shown MAC address
      drivers/net/usb/catc.c: use %pM to shown MAC address
      drivers/net/sunvnet.c: use %pM to shown MAC address
      drivers/net/smc911x.c: use %pM to shown MAC address
      drivers/net/octeon/octeon_mgmt.c: use %pM to shown MAC address
      drivers/net/r8169.c: use %pM to shown MAC address
      Subject: drivers/net/sh_eth.c: use %pM to shown MAC address
      drivers/infiniband/hw/cxgb3/iwch_cm.c: use %pM to show MAC address
      drivers/message/i2o/i2o_proc.c: use %pM to show MAC address
      ep93xx_eth.c general cleanup
      iwl-debugfs.c: remove unnecessary casts of void *
      net/core/sock.c: quiet sparse noise

Hagen Paul Pfeifer (1):
      sched: add head drop fifo queue

Hamish Guthrie (3):
      ps3_gelic_wireless: Remove PS3 gelic legacy wpa support
      ps3_gelic_wireless: fix directed ssid scan
      ps3_gelic_wireless: Remove superfluous debug info

Hauke Mehrtens (5):
      b43legacy: fix typo in ifdef comment
      rtl8187: fix typo in ifdef comment
      ssb: fix typo in ifdef comment
      b44: Set PHY address to NO_PHY if reset fails.
      b44: use netdev_alloc_skb instead of dev_alloc_skb

Helmut Schaa (1):
      mac80211: use listen interval 5 as default

Henry Zhangh (1):
      iwlwifi: Fix A band scanning when associated

Herbert Xu (14):
      bridge: Remove unused age_list
      bridge: Do br_pass_frame_up after other ports
      bridge: Allow tail-call on br_pass_frame_up
      bridge: Avoid unnecessary clone on forward path
      bridge: Use BR_INPUT_SKB_CB on xmit path
      bridge: Split may_deliver/deliver_clone out of br_flood
      bridge: Add core IGMP snooping support
      bridge: Add multicast forwarding functions
      bridge: Add multicast start/stop hooks
      bridge: Add multicast data-path hooks
      bridge: Add multicast_router sysfs entries
      bridge: Add multicast_snooping sysfs toggle
      bridge: Add hash elasticity/max sysfs entries
      bridge: Add multicast count/interval sysfs entries

Holger Schurig (10):
      libertas: use priv->mesh_tlv instead of priv->mesh_fw_ver
      libertas: remove mesh_autostart_enabled and sync_channel
      libertas: move mesh-related definitions into mesh.h
      libertas: decouple mesh and rtap
      libertas: move mesh SSID initialization into mesh.c
      libertas: add access functions for mesh open/connect status
      libertas: make mesh configurable
      libertas: remove priv->capability
      libertas: remove priv->ratebitmap
      libertas: don't retry commands

Jamal Hadi Salim (11):
      pfkey: fix SA and SP flush sequence
      xfrm: Flushing empty SAD generates false events
      xfrm: Flushing empty SPD generates false events
      xfrm: introduce basic mark infrastructure
      xfrm: SA lookups signature with mark
      xfrm: SA lookups with mark
      xfrm: SP lookups signature with mark
      xfrm: SP lookups with mark
      xfrm: Allow user space config of SAD mark
      xfrm: Allow user space manipulation of SPD mark
      xfrm: clone mark when cloning policy

Jan Engelhardt (20):
      netfilter: xt_recent: save 8 bytes per htable
      netfilter: xtables: do not grab random bytes at __init
      netfilter: xtables: obtain random bytes earlier, in checkentry
      netfilter: xtables: compact table hook functions (1/2)
      netfilter: xtables: compact table hook functions (2/2)
      netfilter: xtables: use xt_table for hook instantiation
      netfilter: xtables: generate initial table on-demand
      netfilter: xt_recent: inform user when hitcount is too large
      netfilter: iptables: remove unused function arguments
      netfilter: reduce NF_HOOK by one argument
      netfilter: get rid of the grossness in netfilter.h
      netfilter: xtables: print details on size mismatch
      netfilter: xtables: constify args in compat copying functions
      netfilter: xtables: add const qualifiers
      netfilter: xtables: replace XT_ENTRY_ITERATE macro
      netfilter: xtables: optimize call flow around xt_entry_foreach
      netfilter: xtables: replace XT_MATCH_ITERATE macro
      netfilter: xtables: optimize call flow around xt_ematch_foreach
      netfilter: xtables: reduce arguments to translate_table
      netfilter: xtables: restore indentation

Jan Kiszka (41):
      CAPI: Fix leaks in capifs_new_ncci
      CAPI: Sanitize capifs API
      CAPI: Eliminate capifs_root variable
      CAPI: Pin capifs instead of mounting it
      CAPI: Reduce chattiness during module loading/removal
      CAPI: Call a controller 'controller', not 'card'
      CAPI: Convert capi drivers rwlock into mutex
      CAPI: Rework capi_ctr_ready/down
      CAPI: Rework controller state notifier
      CAPI: Rework locking of controller data structures
      CAPI: Rework application locking
      CAPI: Reduce #ifdef mess around CONFIG_ISDN_CAPI_MIDDLEWARE
      CAPI: Convert capidev_list_lock into a mutex
      CAPI: Clean up capi_open/release
      CAPI: Rework locking of capidev members
      CAPI: Use non-atomic allocation during NCCI setup
      CAPI: Fix racy capi_read
      CAPI: Switch NCCI list to standard doubly linked list
      CAPI: Switch capiminor list to array
      CAPI: Clean up capinc_tty_init/exit
      CAPI: Dynamically register minor devices
      CAPI: Use dynamic major for NCCI TTYs by default
      CAPI: Use kref on capiminor
      CAPI: Establish install/cleanup handlers for capiminor TTYs
      CAPI: Use tty_port to keep track of capiminor's tty
      CAPI: Drop remaining NULL checks on tty->driver_data
      CAPI: Issue synchronous hangup on capincci_free_minor
      CAPI: Drop obsolete nccip from capiminor struct
      CAPI: Clean up capiminors_lock
      CAPI: Drop atomic ttyopencount
      CAPI: Drop handle_minor_recv from capinc_tty_write
      CAPI: Rework capiminor RX handler
      CAPI: Rename datahandle_queue -> ackqueue_entry
      CAPI: Use atomics for capiminor's datahandle and msgid
      CAPI: Drop capiminor's unused inbytes counter
      CAPI: Fix locking around capiminor's output queue and drop workaround_lock
      CAPI: Clean up capiminor_*_ack
      CAPI: Drop return value of handle_minor_send
      CAPI: Drop special controller lookup from capi20_put_message
      CAPI: Schedule capifs for removal
      CAPI: Remove experimental tag from middleware feature

Jarek Poplawski (1):
      sky2: Fix TX_MAP_PAGE misspelling

Jean-François Moine (1):
      p54usb: Add the USB ID for Belkin (Accton) FD7050E ver 1010ec

Jeff Garzik (2):
      net: Delete isa-skeleton net driver
      ethtool: do not set some flags, if others failed

Jeff Kirsher (1):
      ixgbevf: Fix IPv6 GSO type checks

Jeff Mahoney (1):
      ipg: Remove device claimed by dl2k from pci id table

Jesper Dangaard Brouer (2):
      net: RFC3069, private VLAN proxy arp support
      net: Make it easier to parse /proc/net/dev contents.

Jesse Brandeburg (1):
      ixgbe: Allocate driver resources per NUMA node

Jiri Pirko (35):
      net: use helpers to access uc list V2
      net: use helpers to access mc list V2
      libphy: add phy_find_first function
      net: 8139cp: convert to use mc helpers
      net: 8139too: convert to use mc helpers
      net: dm9601: convert to use mc helpers
      net: e1000e: convert to use mc helpers
      net: use netdev_mc_count and netdev_mc_empty when appropriate
      macb: straighten out macb_mii_probe function
      cassini: convert to use netdev_for_each_mc_addr
      net: convert multiple drivers to use netdev_for_each_mc_addr
      cxgb3: convert to use netdev_for_each_addr
      chelsio: convert to use netdev_for_each_mc_addr
      depca: remove forgotten needless inicialization
      3c5xx: use netdev_mc_* helpers
      smsc911x: convert to use netdev_for_each_mc_addr
      net: convert multiple drivers to use netdev_for_each_mc_addr, part2
      tulip: convert to use netdev_for_each_mc_addr
      net/usb: convert to use netdev_for_each_mc_addr
      staging: convert to use netdev_for_each_mc_addr
      tokenring: convert to use netdev_for_each_mc_addr
      net/pcmcia: convert to use netdev_for_each_mc_addr
      net/arm: convert to use netdev_for_each_mc_addr
      net: convert multiple drivers to use netdev_for_each_mc_addr, part3
      e1000: convert to use netdev_for_each_mc_addr
      net: convert multiple drivers to use netdev_for_each_mc_addr, part4
      e1000: correct wrong coding style for "else"
      net: convert multiple drivers to use netdev_for_each_mc_addr, part5 V2
      net: convert multiple drivers to use netdev_for_each_mc_addr, part6
      octeon: convert to use netdev_for_each_mc_addr
      af_packet: do not accept mc address smaller then dev->addr_len in packet_mc_add()
      net: add addr len check to dev_mc_add
      infiniband: convert to use netdev_for_each_mc_addr
      ipoib: returned back addrlen check for mc addresses
      wireless: convert to use netdev_for_each_mc_addr

Jiri Slaby (3):
      NET: ipv6, remove unnecessary check
      NET: irda, remove unnecessary checks
      isdn: mISDN, don't compile unused stuff

Jochen Friedrich (2):
      ssb: fix interrupt assignment
      b44: Ratelimit timeout error message.

Joe Perches (88):
      iwmc3200wifi: Avoid an offset calculation for each management frame.
      drivers/net/mac8390.c: Indent case labels
      drivers/net/mac8390.c: Remove useless memcpy casting
      drivers/net/mac8390.c: Convert printk(KERN_<level> to pr_<level>(
      drivers/net/mac8390.c: Checkpatch cleanups
      drivers/net/mac8390.c: Add mac8390_init function
      lib/vsprintf.c: Add %pMF to format FDDI bit reversed MAC addresses
      net/ipv6/tcp_ipv6.c: Use compressed IPv6 address
      lib: Kill bit-reversed FDDI MAC output case, it's bogus.
      netfilter: nf_nat_ftp: remove (*mangle[]) array and functions, use %pI4
      ipvs: use standardized format in sprintf
      netfilter: xt_osf: change %pi4 to %pI4
      net/mac80211/mlme.c: Remove unnecessary semicolons
      lib/vsprintf.c: Add IPV4 options %pI4[hnbl] for host, network, big and little endian
      drivers/net/tlan: Remove TRUE/FALSE defines, use bool
      net/atm: Convert printk to pr_<level>
      net/atm/addr.c: Convert include <asm to include <linux
      net/atm/atm_misc.c: checkpatch cleanups
      net/atm/atm_sysfs.c: checkpatch cleanups
      net/atm/br2684.c: checkpatch cleanups
      net/atm/clip.c: checkpatch cleanups
      net/atm/common.c: checkpatch cleanups
      net/atm/ioctl.c: checkpatch cleanups
      net/atm/lec.c: checkpatch cleanups
      net/atm/mpc.c: checkpatch cleanups
      net/atm/mpoa_caches.c: checkpatch cleanups
      net/atm/mpoa_proc.c: checkpatch cleanups
      net/atm/pppoatm.c: checkpatch cleanups
      net/atm/proc.c: checkpatch cleanups
      net/atm/pvc.c: checkpatch cleanups
      net/atm/raw.c: checkpatch cleanups
      net/atm/resources.c: checkpatch cleanups
      net/atm/signaling.c: checkpatch cleanups
      net/atm/svc.c: checkpatch cleanups
      net/atm/lec.c: Add __lec_arp_check_expire and other cleanups
      net/atm: Cleanup dprint/ddprintk #defines and uses
      tulip_core: Use dev_<level> and pr_<level>
      tulip/21142.c: Use dev_<level> and pr_<level>
      tulip/de2104x.c: Use dev_<level> and pr_<level>
      tulip/dmfe.c: Use dev_<level> and pr_<level>
      tulip/eeprom.c: Use dev_<level> and pr_<level>
      tulip/interrupt.c: Use dev_<level> and pr_<level>
      tulip/media.c: Use dev_<level> and pr_<level>
      tulip/pnic.c: Use dev_<level> and pr_<level>
      tulip/pnic2.c: Use dev_<level> and pr_<level>
      tulip/timer.c: Use dev_<level> and pr_<level>
      tulip/uli526x.c: Use dev_<level> and pr_<level>
      tulip/winbond-840.c: Use dev_<level> and pr_<level>
      tulip/xircom_cb.c: Use dev_<level> and pr_<level>
      drivers/net/amd8111e.c: Fix continuation line formats
      net/rds: remove uses of NIPQUAD, use %pI4
      drivers/net/davinci_emac.c: Fix continuation line formats
      netdevice.h: Add netdev_printk helpers like dev_printk
      drivers/net/atl1e: Use netdev_printk helpers
      include/linux/netdevice.h: Add netif_printk helpers
      drivers/net/r8196.c: Use netif_printk macros
      drivers/net/jme: Use netif_printk helpers
      drivers/net/qlge: Use netif_printk helpers
      drivers/net/skge.c: Use netif_printk macros
      niu: Use pr_<level>, netdev_<level> and netif_<level> macros
      drivers/net/ixgb: Use netif_printk macros
      drivers/net/sky2: Convert to use netif_printk macros
      drivers/net/tehuti.c: Use (pr|netdev|netif)_<levels> macro helpers
      drivers/net/tehuti.c: Hoist assigns out of ifs
      drivers/net/tehuti.c: trivial checkpatch cleanups
      drivers/net/pcnet32.c: Use (pr|netdev|netif)_<levels> macro helpers
      drivers/net/pcnet32.c: Checkpatch cleaning
      ipv6.h: reassembly: replace calculated magic number with multiplication
      usbnet: Convert dev(dbg|err|warn|info) macros to netdev_<level>
      drivers/net/usb: Use netif_<level> logging facilities
      drivers/net/8139cp.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/8139too.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/b44.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/bnx2.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/bnx2x: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/cassini.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/cnic.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/pci-skeleton.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/skge.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/skge.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/sky2.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/yellowfin.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/tehuti.c: Reapply use DEFINE_PCI_DEVICE_TABLE()
      drivers/net/tg3.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/sis190.c: Use (pr|netdev|netif)_<level> macro helpers
      drivers/net/typhoon.c: Use (pr|netdev)_<level> macro helpers
      drivers/net/chelsio: Use pr_<level>, netif_msg_<type>
      drivers/net/myri10ge: Use pr_<level> and netdev_<level>

Johann Felix Soden (1):
      Bluetooth: Fix out of scope variable access in hci_sock_cmsg()

Johannes Berg (66):
      mac80211: make station management completely depend on vif
      mac80211: reduce reliance on netdev
      mac80211: trace interface name
      mac80211: enable spatial multiplexing powersave
      mac80211_hwsim: implement ampdu action
      mac80211: allow disabling 40MHz on 2.4GHz
      cfg80211: avoid sending spurious deauth to userspace
      mac80211: dont try to use existing sta for AP
      mac80211: disallow fixing bitrates with hw rate control
      iwlwifi: use new mac80211 SMPS
      mac80211: add ieee80211_sdata_running
      mac80211: introduce flush operation
      mac80211: let cfg80211 manage auth state
      mac80211: generalise management work a bit
      mac80211: generalise work handling
      mac80211: rewrite a few work messages
      mac80211: refactor association
      mac80211: split up and insert custom IEs correctly
      mac80211: proper bss private data handling
      mac80211: support remain-on-channel command
      mac80211: make off-channel work generic
      mac80211/cfg80211: add station events
      mac80211: remove struct ieee80211_if_init_conf
      mac80211: remove requeue from work
      mac80211: fix a few work bugs
      mac80211: fix return from ieee80211_assoc_success
      mac80211: remove unused type argument
      mac80211: move and rename misc tx handler
      mac80211: clear TX control on filtered frames
      mac80211: remove useless setting of IEEE80211_TX_INTFL_DONT_ENCRYPT
      mac80211: move control.hw_key assignment
      mac80211: re-enable re-transmission of filtered frames
      cfg80211: rcu-ify rdev and wdev
      mac80211: pass vif and station to update_tkip_key
      cfg80211: export multiple MAC addresses in sysfs
      mac80211: add missing key check
      iwlwifi: is no longer experimental
      iwlwifi: reorder device setup
      iwlwifi: clean up debugfs code
      iwlwifi: fix sparse warning
      iwlwifi: check endianness annotations by default
      mac80211: fix sw crypto
      mac80211: track work started through callbacks
      mac80211: fill jiffies/vif on filtered frames
      cfg80211: export cfg80211_find_ie
      mac80211: wait for beacon before enabling powersave
      iwlwifi: fix locking in iwl_mac_add_interface
      iwlwifi: no need to test iw_mode in power saving
      iwlagn: simplify ucode loading
      iwlwifi: remove bg_up work
      iwlwifi: remove unused work structs
      iwlwifi: fix typo in IWL_CCK_RATES_MASK
      mac80211_hwsim: add fake hw scan handler
      wireless: update radiotap parser
      mac80211: don't probe if we have probe response
      mac80211: allow station add/remove to sleep
      mac80211: fix bss_conf.dtim_period
      mac80211: fix deauth race
      mac80211: fix netdev rename
      mac80211: reject unhandled action frames
      mac80211: split ieee80211_drop_unencrypted
      ar9170: convert to new station add/remove callbacks
      p54: convert to new station add/remove callbacks
      mac80211_hwsim: convert to new station add/remove callbacks
      ath9k: convert to new station add/remove callbacks
      mwl8k: convert to new station add/remove callbacks

John Fastabend (4):
      ixgbe: only process one ixgbe_watchdog_task at a time.
      ixgbe: do not stop tx queues in ixgbe_set_tso
      ixgbe: Do not allocate too many netdev txqueues
      ixgbe: move TC_PRIO_CONTROL check into ixgbe_select_queue()

John Linn (1):
      net: emaclite: adding MDIO and phy lib support

John W. Linville (26):
      wireless: report reasonable bitrate for MCS rates through wext
      wireless: support internal statically compiled regulatory database
      wireless: fix comments in genregdb.awk
      Merge git://git.kernel.org/.../linville/wireless-2.6
      wireless: remove CONFIG_WIRELESS_OLD_REGULATORY
      rtl8180: remove priv->mode
      rtl8187: remove priv->mode
      Merge git://git.kernel.org/.../linville/wireless-2.6
      mac80211: fix typo added by "mac80211: fix propagation of failed..."
      Merge git://git.kernel.org/.../linville/wireless-2.6
      wireless: fix build breakage when CONFIG_CFG80211_REG_DEBUG not set
      Merge git://git.kernel.org/.../linville/wireless-2.6
      Revert "iwmc3200wifi: fix array out-of-boundary access"
      Merge git://git.kernel.org/.../linville/wireless-2.6
      libertas/assoc.c: rearrange some strange line breaks
      mac80211: avoid NULL ptr deref when using WEP
      libertas: add comment re: v10 firmware key handling
      rtl8180: implement get_tsf op for mac80211
      cfg80211: fix wext-compat for setting rate to 'auto'
      ps3_gelic_wireless: fix format warning
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
      Merge branch 'wireless-next-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
      Merge branch 'wireless-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
      Merge branch 'wireless-next-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
      netdevice.h: check for CONFIG_WLAN instead of CONFIG_WLAN_80211

Jouni Malinen (11):
      mac80211_hwsim: Check all local addresses for TX Ack status
      mac80211: Generalize off-channel operation helpers from scan code
      cfg80211: add remain-on-channel command
      mac80211: No need to include WEXT headers here
      mac80211: Select lowest rate based on basic rate set in AP mode
      cfg80211/mac80211: Use more generic bitrate mask for rate control
      nl80211: New command for setting TX rate mask for rate control
      cfg80211: Store IEs from both Beacon and Probe Response frames
      nl80211: Allow association to change channels during reassociation
      cfg80211/mac80211: allow registering for and sending action frames
      ath9k: Use the Beacon TX rate from mac80211

Juha Leppanen (1):
      wl1271: fix timeout in wl1271_top_reg_read

Julia Lawall (4):
      drivers/net/cxgb3: Use kzalloc for allocating only one thing
      netfilter: SNMP NAT: correct the size argument to kzalloc
      drivers/net: Eliminate useless code
      net/sctp: Eliminate useless code

Jussi Kivilinna (2):
      rndis_wlan: move copy of module parameters to separate function
      rndis_wlan: copy module parameters for bcm4320a devices too

Juuso Oikarinen (27):
      wl1271: Configure smart-reflex paramter values.
      wl1271: Remove smart reflex ACX
      wl1271: Use slow rates for association messages
      wl1271: Fix event acknowledging functionality
      wl1271: prevent power save entry while not associated
      wl1271: Implement chipset boot retry
      wl1271: Add pre-power-on sleep
      wl1271: Remove beacon-loss-ind from PSM entry failure handling
      wl1271: Add rudimentary ad-hoc support
      wl1271: Change rates configured for templates
      wl1271: Fix supported rate management
      wl1271: Change booleans in struct wl1271 into a flags bitmask
      wl1271: Add support for acx_pm_config
      wl1271: Check vif for NULL when indicating beacon-loss
      wl1271: Prevent performing "join" before association
      wl1271: Fix PSM entry
      wl1271: Fix channel changing code
      wl1271: Add SSID configuration for JOIN in ad-hoc
      wl1271: Use NVS INI file configuration
      wl1271: Retrieve device mac address from the nvs file
      wl1271: Fix random MAC address setting
      wl1271: Optimized RX path packet retrieval
      wl1271: Fix key-remove error
      wl1271: Fix WEP key handling
      wl1271: Fix ad-hoc SSID update
      wl1271: Fix beacon filter table configuration
      mac80211: fix direct probe loop on ieee80211_work_purge

Kalle Valo (53):
      wl1251: add tx queue status to debugfs
      wl1251: print a debug message when tx_queue is full
      wl1251: fix error handling in wl1251_op_config()
      wl1251: reduce ELP wakeup timeout
      wl1251: simplify ELP wakeup time calculation
      wl1251: use __dev_alloc_skb() on RX
      wl1251: implement acx_ac_cfg to configure hardware queues
      wl1251: implement wl1251_acx_tid_cfg()
      wl1251: implement WMM
      wl1251: update tx_hdr when aliging skb in tx
      wl1251: enable WMM
      mac80211: remove payload alignment warning
      mac80211: annotate sleeping driver ops
      mac80211: fix a warning related to pointer conversion to u64 cookie
      mac80211: fix ieee80211_change_mac() to use struct sockaddr
      mac80211: add functions to create PS Poll and Nullfunc templates
      mac80211: use PS Poll and Nullfunc templates when sending such frames
      wl1251: get PS Poll and Nullfunc templates from mac80211
      mac80211: create Probe Request template
      mac80211: use Probe Request template when sending a direct scan
      wl1251: cleanup scanning code
      wl1251: get probe request template from mac80211
      wl1251: use mac80211 provided channel parameters in scanning
      wl1251: fix sleep related error paths in wl1251_op_bss_info_changed()
      mac80211: add U-APSD client support
      mac80211: add debugfs interface for U-APSD queue configuration
      mac80211: create tx handler for dynamic ps
      mac80211: check uapsd state for dynamic power save
      ieee80211: add struct ieee80211_hdr_qos
      wl1251: create qos null data template
      wl1251: add U-APSD support
      mac80211: fix mac80211.h documentation warnings
      mac80211: improve powersave documentation
      mac80211: fix tx select key null pointer crash with hostapd
      mac80211: fix update_tkip_key() documentation about the context
      wl1251: fix txop unit
      adm821: remove get_tx_stats() mac80211 op
      mwl8k: remove get_tx_stats() mac80211 op
      ar9170: remove get_tx_stats() mac80211 op
      ath5k: remove get_tx_stats() mac80211 op
      b43: remove get_tx_stats() mac80211 op
      b43legacy: remove get_tx_stats() mac80211 op
      iwlwifi: remove get_tx_stats() mac80211 op
      p54: remove get_tx_stats() mac80211 op
      rt2x00: remove get_tx_stats() mac80211 op
      mac80211: remove get_tx_stats() driver op
      nl80211: add power save commands
      wl1271: modify wl1271_acx_ac_cfg() to use function parameters
      wl1271: modify wl1271_acx_tid_cfg() to use function parameters
      wl1271: implement WMM
      wl1271: wakeup chip in op_conf_tx()
      wl1271: add testmode support
      MAINTAINERS: update Kalle's email address

Ken Kawasaki (2):
      axnet_cs: remove unnecessary spin_unlock_irqrestore
      axnet_cs: add new id

Kenichi HORIO (1):
      rt73usb: add WLI-U2-H54HP

Krishna Kumar (5):
      tcp: Remove check in __tcp_push_pending_frames
      tcp: Remove unrequired operations in tcp_push()
      tcp: Slightly optimize tcp_sendmsg
      net: release dst entry while cache-hot for GSO case too
      net: Optimize non-gso test checks

Kristoffer Glembo (1):
      net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver

Kuninori Morimoto (1):
      net/irda: sh_sir: Add SuperH IrDA driver

Larry Finger (7):
      rtl8180: Remove usage of deprecated 'qual'
      b43: Allow PIO mode to be selected at module load
      Staging: r8187se: Fix compile error from wireless-testing commit 7044cc56
      b43: N PHY: Fix compilation after removal of typdef b43_c32
      rtl8187: Add callback for get_tsf
      b43/b43legacy: Wake queues in wireless_core_start
      ssb: Add PCI ID 0x4322 to PHU handling

Lennart Sorensen (1):
      ppp_generic.c severly whitespace damanged by 9c705260feea6ae329bc6b6d5f6d2ef0227eda0a

Lennert Buytenhek (56):
      mwl8k: firmware command code cleanup
      mwl8k: hw is never NULL in mwl8k_set_radio_preamble()
      mwl8k: get rid of the AMSDU check in the transmit path
      mwl8k: inline qos field manipulation functions
      mwl8k: initialize the mwl8k_info_tbl table using the MWL* enums
      mwl8k: add 2.4GHz channels 12, 13 and 14
      mwl8k: get rid of the struct mwl8k_firmware abstraction
      mwl8k: do rx/tx ring initialisation after loading firmware
      mwl8k: fix up AP vs. STA firmware image receive descriptor handling
      mwl8k: remove unused mwl8k_vif::priv
      mwl8k: remove duplicate local per-vif copy of ieee80211_bss_conf
      mwl8k: update version number to 0.11
      mwl8k: bail out if there is no AP firmware image support for this chip
      mwl8k: prevent freeing free IRQ if ieee80211_register_hw() fails
      mwl8k: make the tx ring drain status messages somewhat more friendly
      mwl8k: move struct peer_capability_info to its only user
      mwl8k: handle station database update for AP's sta entry via ->sta_notify()
      mwl8k: remove mwl8k_vif::bssid, which is now useless
      mwl8k: move ->peer_id from mwl8k_vif to mwl8k_sta
      mwl8k: honor peer rate set
      mwl8k: fix changed flags handling in mwl8k_bss_info_changed()
      mwl8k: add support for 88w8363 in STA mode
      mwl8k: allow setting HT channels
      mwl8k: pass in HT capabilities and rates when associating
      mwl8k: trivial rx-only ampdu implementation
      mwl8k: pass GET_HW_SPEC capability bitmask up the stack
      mwl8k: minor cleanups
      mwl8k: undo transmit queue 0/1 swapping in mwl8k_cmd_set_edca_params()
      mwl8k: bump the transmit wait timeout to 5 seconds
      mwl8k: simplify mwl8k_cmd_use_fixed_rate()
      mwl8k: add the AP version of USE_FIXED_RATE
      mwl8k: implement AP firmware station database maintenance
      mwl8k: correctly set the mac_type field for AP SET_MAC_ADDR
      mwl8k: basic AP interface support
      mwl8k: allow limiting the amount of transmit reclaim done
      mwl8k: keep TX_DONE interrupt masked while transmit reclaim is running
      mwl8k: move receive processing to tasklet
      mac80211: flush workqueue before calling driver ->stop() method
      mwl8k: update MODULE_FIRMWARE tags
      mwl8k: remove (mostly) write-only variable priv->current_channel
      mwl8k: don't call SET_AID if we're not associated
      mwl8k: simplify sequence number assignment
      mwl8k: add another 88w8366 PCI ID
      mwl8k: rename 2.4 GHz band/channels/rates related variables from FOO to FOO_24
      mwl8k: move responsibility for initialising wiphy bands to GET_HW_SPEC
      mwl8k: add 5 GHz band channels and rates
      mwl8k: properly set receive status rate index on 5 GHz receive
      mwl8k: handle 5 GHz legacy rate bitmaps in firmware commands
      mwl8k: allow selecting 5 GHz channels
      mwl8k: use firmware capability field to decide which bands to register
      mwl8k: convert the priv->vif pointer to a list of vifs
      mwl8k: prepare for posting per-vif firmware commands
      mwl8k: post per-vif firmware commands as per-vif commands
      mwl8k: enable multi-BSS AP operation
      mwl8k: update version number (to 0.12) and copyright
      MAINTAINERS: update mwl8k maintenance status

Li Zefan (13):
      seq_file: Add helpers for iteration over a hlist
      net: add a wrapper sk_entry()
      net: x25: use seq_hlist_foo() helpers
      net: rose: use seq_hlist_foo() helpers
      net: packet: use seq_hlist_foo() helpers
      net: netrom: use seq_hlist_foo() helpers
      net: ax25: use seq_hlist_foo() helpers
      net: appletalk: use seq_hlist_foo() helpers
      net: af_key: use seq_hlist_foo() helpers
      net: x25: use seq_list_foo() helpers
      net: irda: use seq_list_foo() helpers
      net: ipx: use seq_list_foo() helpers
      net: atm: use seq_list_foo() helpers

Linus Torvalds (1):
      b43: fall back gracefully to PIO mode after fatal DMA errors

Liu Yu-B13201 (4):
      dts/mpc8569mds: Cleanup tbi phy to support rtbi
      mpc8569mds: Add bscr setting for rtbi mode
      ucc_geth: update the tbi-phy setting
      phy: add RTBI mode for m88e1111

Luca Verdesca (1):
      ath5k: adding LED support for AR5BXB63 cards

Luciano Coelho (18):
      wl1271: updated radio parameters structure for newer firmwares
      wl1271: updated general parameters structure for newer firmwares
      wl1271: update radio and general parameters values
      wl1271: added radio parameters configuration values newer firmwares
      wl1271: use join command with dummy BSSID
      wl1271: remove workaround for disconnection
      wl1271: limit TX power to 25dBm for every channel
      wl1271: check result code from the join command
      wl1271: set null data template when BSSID is known
      wl1271: use the correct macro when setting the basic rates
      wl1271: implement dco itrim parameters setting
      wl1271: fix one typo in the rx_rssi_and_proc_compens values
      wl1271: add gpio_power file in debugfs to power the chip on and off
      wl1271: upload only the first 468 bytes from the NVS file
      wl1271: some new configuration values according to new reference
      wl1271: use channel 1 when configuring the data path
      wl1271: add most of the normal initialization commands to PLT mode
      wl1271: skip 3 unused bytes from the NVS

Luis R. Rodriguez (19):
      ath9k_hw: remove unused ath9k_hw_devname() and ath9k_hw_probe()
      ath9k: add MCS rate index back to debufs rcstat
      mac80211: make debugfs mcs set entry reflect 16 bits
      mac80211: parse the HT capabilities info through debugfs
      mac80211: only bother printing highest data rate on debugfs if its set
      cfg80211: add a regulatory debug print
      ath9k: re-enable ps by default for new single chip families
      cfg80211: add debug print when we drop a bogus country IE
      cfg80211: process the max power on a country IE
      cfg80211: Fix country IE parsing for single channel triplets
      cfg80211: fix 2 GHz subband calculation for country IEs
      wl1271: remove unused flags
      cfg80211: Ingore country IEs with a zero set of number of channels
      cfg80211: make regulatory_hint_11d() band specific
      ath9k: make tx power config changes take effect immediatley
      cfg80211: avoid flushing the global workqueue for core reg hints
      cfg80211: add regulatory hint disconnect support
      ath9k: add support for 802.11n bonded out AR2427
      atl1c: Add support for Atheros AR8152 and AR8152

Lukáš Turek (5):
      nl80211: Add new WIPHY attribute COVERAGE_CLASS
      mac80211: Add new callback set_coverage_class
      ath5k: Fix functions for getting/setting slot time
      ath5k: Reimplement clock rate to usec conversion
      ath5k: Implement mac80211 callback set_coverage_class

Mallikarjuna R Chilakala (1):
      ixgbe: Fix DMA mapping/unmapping issues when HWRSC is enabled on IOMMU enabled kernels

Marc Kleine-Budde (1):
      can/netlink: add CAN_CTRLMODE_ONE_SHOT

Marcel Holtmann (4):
      Bluetooth: Convert controller hdev->type to hdev->bus
      Bluetooth: Convert inquiry cache to use debugfs instead of sysfs
      Bluetooth: Convert Marvell driver to use per adapter debugfs
      Bluetooth: Add controller types for BR/EDR and 802.11 AMP

Masatake YAMATO (1):
      netlink: Adding inode field to /proc/net/netlink

Matt Carlson (38):
      tg3: Enable PLL PD when CLKREQ disabled for 5717A0
      tg3: Improve internal resource allocations
      tg3: Add 5717 serdes phy ID
      tg3: Abort phy init for 5717 serdes devices
      tg3: Fix 5717 and 57765 memory selftests
      tg3: Supply a nicaddr for 57765 jumbo RCB
      tg3: Fix tx mailbox initialization
      tg3: Turn off the debug UART for 57765
      tg3: Bypass power source switching for 57765
      tg3: Add 57765 phy ID and enable devices.
      tg3: Give MSI-X vec 1 rx backlog space
      tg3: Prevent rx producer ring overruns
      tg3: Unwedge stuck MSI-X vectors
      tg3: Fix 57765 A0 bootcode race condition
      tg3: Turn off multiple DMA reads for 5717
      tg3: Reset phy during bringup when using phylib
      tg3: Fix napi assignments in loopback test
      tg3: Fix AC131 loopback test errors for 5785
      tg3: Update driver version to 3.107
      tg3: Enforce DMA mapping / skb assignment ordering
      tg3: Make 57791 and 57795 10/100 only
      tg3: Add support for 2 new selfboot formats
      tg3: Allow phylib flowctrl changes anytime
      tg3: Add more partno entries for fallback path
      tg3: Rename TG3_FLG3_RGMII_STD_IBND_DISABLE
      tg3: Reduce indent level of tg3_rx_prodring_alloc
      tg3: Discover phy address once
      tg3: Reformat SSID to phy ID table
      tg3: Rename tg3 phy ID preprocessor definitions
      tg3: Push phylib definitions to phylib
      tg3: Update version to 3.108
      pci: Add PCI LRDT tag size and section size
      pci: Add large and small resource data type code
      pci: Add helper to find a VPD resource data type
      pci: Add VPD information field helper functions
      pci: Add helper to search for VPD keywords
      bnx2: Remove now useless VPD code
      tg3: Remove now useless VPD code

Michael Buesch (1):
      b43: Workaround circular locking in hw-tkip key update callback

Michael Chan (11):
      bnx2: Refine statistics code.
      bnx2: Save statistics during reset.
      bnx2: Check BNX2_FLAG_USING_MSIX flag when setting up MSIX.
      bnx2: Need to call cnic_setup_cnic_irq_info() after MTU change.
      bnx2: Adjust flow control water marks.
      bnx2: Allow user-specified multiple advertisement speed values.
      bnx2: Update firmwares and update version to 2.0.8.
      cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
      cnic: Simplify route checking during iSCSI connection.
      cnic: Use union for the status blocks of different devices.
      cnic: Update version to 2.1.1.

Michael S. Tsirkin (10):
      tun: export underlying socket
      mm: export use_mm/unuse_mm to modules
      vhost_net: a kernel-level virtio server
      vhost: fix TUN=m VHOST_NET=y
      vhost-net: switch to smp barriers
      net: export attach/detach filter routines
      tun: socket filter support
      vhost: logging thinko fix
      vhost: initialize log eventfd context pointer
      vhost: fix get_user_pages_fast error handling

Mike Frysinger (1):
      netdev: bfin_mac: drop experimental markings on RMII support

Mike McCormack (7):
      sky2: Refactor sky2_get_regs into two functions
      sky2: Lock transmit queue while disabling device
      sky2: Factor out code to calculate packet sizes
      sky2: Allocate initial skbs in sky2_alloc_buffers
      sky2: Refactor sky2_up into two functions
      sky2: Refactor sky2_down into two functions
      sky2: Avoid down and up during sky2_reset

Milton Miller (1):
      ixgbe: prevent speculative processing of descriptors before ready

Ming Lei (2):
      mac80211: fix memory leak in ieee80211_send_probe_req
      ath9k: fix keycache leak in split tkip case

Márton Németh (2):
      8139too: make PCI device ids constant
      Bluetooth: Make USB device id constant

Nick Nunley (18):
      e1000: Report link status in ethtool when interface is down
      e1000: call pci_save_state after pci_restore_state
      igb: add support for wake-on-link
      igb: Report link status in ethtool when interface is down
      igb: ignore EEPROM APME check when shutting down serdes link
      igb: Power down link when interface is down
      igb: call pci_save_state after pci_restore_state
      igb: remove adaptive IFS from driver
      igb: cap interrupts at 20K per queue when in itr mode 3
      igb: only support SRRCTL_DROP_EN when using multiple queues
      igb: only read phy specific stats if in internal phy mode
      igb: inline igb_maybe_stop_tx
      igb: move gso_segs into buffer_info structure
      igb: minor type cleanups
      igb: remove unused vmolr value
      igb: use igb_free_q_vectors to cleanup failure in igb_alloc_q_vectors
      igb: change descriptor control thresholds
      igb: update tx DMA mapping error handling

Octavian Purdila (11):
      llc: use dev_hard_header
      llc: add support for LLC_OPT_PKTINFO
      llc: add support for SO_BINDTODEVICE
      llc: convert the socket list to RCU locking
      llc: optimize multicast delivery
      llc: use a device based hash table to speed up multicast delivery
      llc: replace the socket list with a local address based hash
      llc: convert llc_sap_list to RCU
      llc: fix SAP reference counting w.r.t. socket handling
      tcp: account SYN-ACK timeouts & retransmissions
      ipv4: allow warming up the ARP cache with request type gratuitous ARP

Oliver Hartkopp (3):
      can: Speed up CAN frame receiption by using ml_priv
      can: Unify droping of invalid tx skbs and netdev stats
      can: deny filterlist access on non-CAN interfaces

PJ Waskiewicz (1):
      ixgbe: Make descriptor ring allocations NUMA-aware

Pablo Neira Ayuso (1):
      netfilter: ctnetlink: fix creation of conntrack with helpers

Patrick McHardy (32):
      ipv4: ip_fragment: fix unbalanced rcu_read_unlock()
      netfilter: xt_hashlimit: fix race condition and simplify locking
      netfilter: ctnetlink: only assign helpers for matching protocols
      netfilter: add struct net * to target parameters
      netfilter: nf_conntrack: split up IPCT_STATUS event
      netfilter: ctnetlink: support selective event delivery
      netfilter: nf_conntrack: support conntrack templates
      netfilter: xtables: add CT target
      Merge branch 'master' of /repos/git/net-next-2.6
      netfilter: ctnetlink: add missing netlink attribute policies
      Merge branch 'master' of git://dev.medozas.de/linux
      netfilter: ctnetlink: dump expectation helper name
      netfilter: nf_conntrack: show helper and class in /proc/net/nf_conntrack_expect
      netfilter: nf_conntrack_sip: fix ct_sip_parse_request() REGISTER request parsing
      netfilter: nf_conntrack_sip: pass data offset to NAT functions
      netfilter: nf_conntrack_sip: add TCP support
      netfilter: nf_nat: support mangling a single TCP packet multiple times
      netfilter: nf_nat_sip: add TCP support
      netfilter: nf_conntrack_sip: add T.38 FAX support
      ipv6: fib: fix crash when changing large fib while dumping it
      netfilter: nf_conntrack: pass template to l4proto ->error() handler
      netfilter: nf_conntrack: add support for "conntrack zones"
      netfilter: ctnetlink: add zone support
      Merge branch 'ebt_config_compat_v4' of git://git.breakpoint.cc/fw/nf-next-2.6
      netfilter: nf_defrag_ipv4: fix compilation error with NF_CONNTRACK=n
      netfilter: restore POST_ROUTING hook in NF_HOOK_COND
      netfilter: nf_conntrack_reasm: properly handle packets fragmented into a single fragment
      rtnetlink: ignore NETDEV_PRE_UP notifier in rtnetlink_event()
      rtnetlink: handle rtnl_link netlink notifications manually
      dev: support deferring device flag change notifications
      rtnetlink: support specifying device flags on device creation
      bonding: fix device leak on error in bond_create()

Patrick Mullaney (1):
      macvlan: add GRO bit to features mask

Patrick Rabau (1):
      bnx2: Fix bug when saving statistics.

Pavel Cheblakov (1):
      can: add support for CAN interface cards based on the PLX90xx PCI bridge

Pavel Emelyanov (1):
      ipmr: remove useless checks from ipmr_device_event

Pavel Roskin (7):
      ath: make gcc check format arguments of ath_print(), fix all misuses
      ath9k: allocate string buffer in read_file_dma() by kmalloc()
      mac80211: reduce stack usage in sta_ht_capa_read()
      mac80211: reduce stack usage in sta_agg_status_read()
      ath9k: fix access to freed data on unload
      mwl8k: disable softirqs when accessing sta_notify_list
      Introduce PCMCIA_DEVICE_PROD_ID3

Peter Huewe (1):
      Bluetooth: Add __init/__exit macros to Marvell SDIO driver

Peter P Waskiewicz Jr (1):
      ethtool: Introduce n-tuple filter programming support

Peter Waskiewicz (6):
      ixgbe: Add support for the new ethtool n-tuple programming interface
      ixgbe: Bump driver version up
      ethtool: Fix filter addition when caching n-tuple filters
      ethtool: Move n-tuple capability check into set_flags
      ixgbe: Cleanup incorrect header comments
      ethtool: Add n-tuple string length to drvinfo and return it

Rafał Miłecki (67):
      b43: LP-PHY: note and explain specs inconsistency
      b43: use standard fls for finding the most significant bit
      b43: add new SSB's core id for BCM4328
      b43: N-PHY: clean table init, check PHY rev
      b43: N-PHY: add shared memory offsets definitions
      b43: N-PHY: add needed struct definitions
      b43: N-PHY: add missing register definitions
      b43: N-PHY: add global variables to b43_phy_n struct
      b43: N-PHY: add various tables
      b43: N-PHY: update init code to match current specs
      b43: N-PHY: update CCA reset
      b43: N-PHY: split RSSI calibration into 2 functions (rev2, rev3)
      b43: N-PHY: add clip detection reading/writing and some classifier function
      b43: N-PHY: implement RSSI selection and offset scaling
      b43: N-PHY: add RSSI polling and setting 2055 (radio) VCM
      b43: N-PHY: RSSI calibration for rev < 3
      b43: N-PHY: implement PA overriding (RF control related)
      b43: N-PHY: add RSSI calibration restore
      b43: N-PHY: add function than forces (not) staying in carrier search
      b43: N-PHY: implement RX IQ coeffs
      b43: N-PHY: implement workaround for TX IQ
      b43: N-PHY: implement restoring general configuration
      b43: N-PHY: implement RX IQ estimation
      b43: N-PHY: implement calculating RX IQ comp
      b43: N-PHY: implement getting TX gains
      b43: N-PHY: add TX LP FBW (TX filter 40 related)
      b43: N-PHY: add RX radio cores calibration
      b43: N-PHY: update TX calibration ladder
      b43: N-PHY: implement calculating IQ gain params
      b43: N-PHY: add huge calculating TX IQ LO
      b43: N-PHY: add RX IQ calibrationi for rev < 3
      b43: N-PHY: implement TX power control coef setup
      b43: N-PHY: drop unused definition, uncomment needed call
      b43: N-PHY: implement RX PHY cleanup and setup
      b43: N-PHY: implement TX PHY cleanup and setup
      b43: N-PHY: implement MIMO config update
      b43: N-PHY: implement stopping playback
      b43: N-PHY: implement chain selection
      b43: N-PHY: move RF sequence declarations top, add missing calls
      b43: N-PHY: store seq mode for proper restoring (follow specs)
      b43: N-PHY: add writing one element tables
      b43: N-PHY: implement and add multi-dimensional table writing
      b43: N-PHY: implement and add reading one element tables
      b43: N-PHY: implement and add multi-dimensional table reading
      b43: N-PHY: silence warnings, add missing call
      b43: check band width
      b43: N-PHY: implement overriding RF control
      b43: N-PHY: add running samples
      b43: N-PHY: add setting power amplifier filters
      b43: N-PHY: add TX tone
      b43: N-PHY: fix one bit off in parsing RF Ctrl Override arguments
      b43: make cordic common (LP-PHY and N-PHY need it)
      b43: update cordic code to match current specs
      b43: N-PHY: use cordic to generate samples
      b43: N-PHY: update general workarounds
      b43: N-PHY: add workarounds for gain control
      b43: N-PHY: split RSSI selection into two per-PHY-revision functions
      b43: N-PHY: add RSSI selection for newer PHYs
      b43: N-PHY: fix Cal TX IQ LO for newer PHYs
      b43: N-PHY: add TX radio setup for newer PHYs
      b43: N-PHY: implement setting RF sequence
      b43: N-PHY: implement overriding RF control intc
      b43: N-PHY: prepare code for reapplying TX cal coeffs
      b43: N-PHY: save calibration for further restore
      b43: N-PHY: partly implement SPUR workaround
      b43: N-PHY: load generated samples
      b43: N-PHY: handle allocation fail in samples generation

Randy Dunlap (2):
      libertas/if_spi: needs linux/semaphore.h
      wireless: airo_cs build fixes

Reinette Chatre (10):
      iwlwifi: update copyright year to 2010
      iwlwifi: cleanup station adding code
      iwlwifi: make broadcast station addition generic
      iwlwifi: cleanup spectrum measurement command support
      iwlwifi: iwl_power_update_mode always hold mutex
      iwlwifi: fix scan race
      iwlwifi: reset card during probe
      iwl3945: remove STATUS macros from header
      iwlwifi: enable serialization of synchronous commands
      Revert "iwlwifi: Monitor and recover the aggregation TX flow failure"

Riccardo Ghetta (1):
      SiS190/191 half-duplex initialization fix

Rob Herring (1):
      fec: fix uninitialized rx buffer usage

Robert Hancock (1):
      r8169: enable 64-bit DMA by default for PCI Express devices (v2)

Roel Kluin (2):
      hisax: timeout off by one in waitrecmsg()
      mISDN: positive error return should be negative in mode_hfcmulti()

Roland Dreier (1):
      ethtool: Use explicit designated initializers for .cmd

Ron Mercer (17):
      qlge: Turn on RX header split based on platform.
      qlge: Add RX frame handlers for non-split frames.
      qlge: Add napi gro frags interface.
      qlge: Add data for firmware dump.
      qlge: Add basic firmware dump.
      qlge: Add probe regs to firmware dump.
      qlge: Add RAM dump to firmware dump.
      qlge: Add alternate function's reg dump to fw dump.
      qlge: Add serdes reg blocks dump to firmware dump.
      qlge: Add xgmac reg blocks to firwmare dump.
      qlge: Add module param to force firmware core dump.
      qlge: Move reset from eeh io_resume to slot_reset.
      qlge: Add check for eeh failure when closing device.
      qlge: Add watchdog timer.
      qlge: Fix dropping of large non-TCP/UDP frames.
      qlge: Fix bonding mac address bug.
      qlge: Fix occasional loopback test failure.

Rémi Denis-Courmont (3):
      Phonet: zero-copy aligned GPRS RX
      Phonet: zero-copy GPRS TX
      Phonet: reject unsupported sendmsg/recvmsg flags

Samir Bellabes (1):
      genetlink: optimize ctrl_dumpfamily()

Samuel Ortiz (2):
      libertas: Set/clear WPA keys before the WEP ones
      iwlwifi: Send broadcast probe request only when asked to

Sarveshwar Bandi (3):
      be2net: implements ethtool function to read eeprom data.
      be2net: ethtool self test reorganization.
      be2net: Add link test to list of ethtool self tests.

Sathya Perla (6):
      be2net: implement EEH pci error recovery handlers
      be2net: a mini optimization in rx_compl_process() code
      be2net: don't rearm mcc cq when device is not open
      be2net: fix rx-path to ignore a flush completion
      be2net: implement pci shutdown handler
      be2net: free tx buffers when completions never arrive

Scott Feldman (6):
      enic: Bug fix: use safe queue shutdown in dev->stop
      enic: Bug fix: try harder to fill Rx ring on skb allocation failures
      enic: minimize pkt filter updates to firmware
      enic: Bug fix: align desc ring sizes to 32 descs
      enic: feature add: add ethtool -c/C support
      enic: whitespace cleanup; #define cleanup; more verbose err msg

Senthil Balasubramanian (2):
      ath9k: configure the beacon only if the STA is associated
      ath9k: Enable TIM timer interrupt only when needed.

Shan Wei (4):
      netfilter: nf_conntrack_ipv6: delete the redundant macro definitions
      IPv6: reassembly: replace magic number with macro definitions
      IP: Send an ICMP "Fragment Reassembly Timeout" message when enabling connection track
      IPv6: Delete redundant counter of IPSTATS_MIB_REASMFAILS

Shimada Hirofumi (1):
      p54usb: Add usbid for Corega CG-WLUSB2GT.

Shirley Ma (3):
      virtio: Add ability to detach unused buffers from vrings
      virtio_net: Defer skb allocation in receive path Date: Wed, 13 Jan 2010 12:53:38 -0800
      virtio_net: remove send queue

Simon Arlott (1):
      netfilter: xt_TCPMSS: SYN packets are allowed to contain data

Simon Horman (2):
      greth: fall through to common return statement on error
      IPVS: ip_vs_lblcr: use list headA

Simon Kagstrom (1):
      via-velocity: Enable scatter/gather IO by default

Sridhar Samudrala (2):
      packet: Add GSO/csum offload support.
      vhost-net: restart tx poll on sk_sndbuf full

Sriram (1):
      can:ti_hecc: Add pm hook-up

Sriramakrishnan (1):
      can: ti hecc module : add platform specific initialization callback.

Stanislaw Gruszka (2):
      airo: fix setting zero length WEP key
      iwlwifi: use dma_alloc_coherent

Stefan Seyfried (2):
      ar9170usb: add Sphairon Homelink 1202 USB ID
      zd1211rw: improve ejecting of fake CDROM

Stephen Coe (1):
      Bluetooth: Add SCO fallback for unsupported feature error

Stephen Hemminger (4):
      tcp: Generalized TTL Security Mechanism
      sky2: Flow control frames recorded as dropped packets
      IPv6: convert mc_lock to spinlock
      AF_UNIX: update locking comment

Stephen Rothwell (1):
      net: merge fixup for qlge_main

Steve Hodgson (3):
      sfc: Handle firmware assertion failure while resetting
      sfc: Enable autonegotiated flow-control by default if supported
      sfc: Add some missing bits to register self-test masks

Steven J. Magnani (2):
      ll_temac: Add support for V2 LLTEMAC core
      ll_temac: Fix MAC address configuration from userland

Sucheta Chakraborty (1):
      qlcnic: support LED blink for device identification

Sujith (12):
      ath9k: Clarify Interrupt mitigation
      ath9k: Remove ANI lock
      ath9k: Fix TX poll routine
      ath9k: Add a new file for GPIO
      ath9k: Add new file init.c
      ath9k: Cleanup Powersave flags
      ath9k: Cleanup init/deinit routines
      ath9k: Fix queue handling
      ath9k: Add debugfs file for RX errors
      ath9k: Fix monitor mode handling
      ath9k: Fix panic on driver load
      mac80211: Deny TX BA session requests during disassociation

Teemu Paasikivi (4):
      wl1271: Moved common IO functions from wl271_spi.c to wl1271_io.c
      wl1271: Renamed IO functions
      wl1271: Added IO reset and init functions
      wl1271: Added alloc and free hw functions

Tejun Heo (2):
      percpu: add __percpu sparse annotations to net
      percpu: add __percpu sparse annotations to net drivers

Thadeu Lima de Souza Cascardo (3):
      trivial: remove duplicated "from" in CAN USB EMS Kconfig help
      can: ems_usb: removed duplicated code setting local echo support
      nl80211: does not allow NEW_STATION and DEL_STATION for mesh

Tilman Schmidt (4):
      isdn: fix a few Kconfig imperfections
      gigaset: small documentation improvement
      bas_gigaset: collapse CR/LF at end of AT response
      gigaset: reduce syslog clutter

Tim Gardner (4):
      b43: Declare at least one real firmware file using MODULE_FIRMWARE.
      b43legacy: Declare all possible ucodeX.fw files
      netfilter: xt_recent: fix buffer overflow
      netfilter: xt_recent: fix false match

Tobias Klauser (1):
      ethoc: Use resource_size

Tomas Winkler (3):
      iwmc3200top: clean up fw_download
      iwmc3200top: cleanup log messages
      iwmc3200top: simplify imwct_tx

Trieu 'Andrew' Nguyen (3):
      iwlwifi: Tune radio to prevent unexpected behavior
      iwlwifi: Adjusting PLCP error threshold for 1000 NIC
      iwlwifi: Monitor and recover the aggregation TX flow failure

Tristram Ha (3):
      net: Micrel KSZ8841/2 PCI Ethernet driver
      net: Kconfig change for KSZ884X driver
      net: Makefile change for KSZ884X driver

Ulrich Weber (2):
      ipv6: Remove IPV6_ADDR_RESERVED
      ipv6: Use 1280 as min MTU for ipv6 forwarding

Ursula Braun (2):
      qeth: HiperSockets Network Traffic Analyzer
      qeth: avoid recovery during device online setting

Uwe Kleine-König (1):
      net: move am79c961's probe function to .devinit.text

Vasanthakumar (1):
      mac80211: Don't call rate control when HW handles it

Vasanthakumar Thiagarajan (1):
      ath9k: Fix wifi disconnection when collocated bt scan is active

Venkata Mohan Reddy (1):
      ipvs: SCTP Trasport Loadbalancing Support

Vivek Natarajan (4):
      ath9k: Handle full sleep in ps_restore.
      mac80211: Reset dynamic ps timer in Rx path.
      mac80211: Retry null data frame for power save.
      ath9k: Enable IEEE80211_HW_REPORTS_TX_ACK_STATUS flag for ath9k.

Vladislav Zolotarov (8):
      bnx2x: Properly release allocated MSI-X/MSI vectors
      bnx2x: clean up in case of error in bnx2x_init_hw()
      bnx2x: Do not allow enabling LRO if disable_tpa=1
      bnx2x: fix in 57710 self-test
      bnx2x: FW 5.2.13
      bnx2x: Use firmware 5.2.13
      bnx2x: version number and date
      bnx2x: Tx barriers and locks

Wey-Yi Guy (35):
      iwlwifi: log CT_CARD_DISABLED flag
      iwlwifi: dump "Control and Status Register" when detect uCode HW/SW error
      iwlwifi: add continuous uCode event log capability
      iwlwifi: on-screen event log dump
      iwlwifi: remove extra error msg on sensitivity calibration
      iwlwifi: add IEEE80211_AMPDU_TX_OPERATIONAL
      iwlwifi: ucode statistics data structure update
      iwlwifi: remove obsoleted host command
      iwlwifi: fix bug in tx byte count table
      iwlwifi: fix clear statistics counter command
      iwlwifi: format and show statistics counter from uCode
      iwlwifi: add num_of_sos_stats to statistics counter
      iwlwifi: correct return code for log_event
      iwlwifi: set interrupt coalescing timer range and default
      iwlwifi: software w/a for h/w bug cause Rx bit get clear
      iwlwifi: display flowhandler register when sw error or on-demand
      iwlwifi: remove extra statistics request from debugfs
      iwlwifi: configure missed beacon threshold
      iwlwifi: add function to reset/tune radio if needed
      iwlwifi: Logic to control how frequent radio should be reset if needed
      iwlwifi: bit field description for BT Config command
      iwlwifi: module parameter to enable/disable bt co-exist
      iwlwifi: sysassert identifier change
      iwlwifi: update sensitivity calibration data for 6x00 series
      iwlwifi: update sensitivity calibration data for 5x00 series
      iwlwifi: update sensitivity calibration data for 1000 series
      mac80211: tear down all agg queues when restart/reconfig hw
      iwlwifi: clear all tx queues when firmware ready
      iwlwifi: multiple force reset mode
      iwlwifi: add debug function to reset/reload radio/firmware
      iwlwifi: check for aggregation frame and queue
      iwlwifi: remove unused op-code in PHY Calibration command
      iwlwifi: clear all the stop_queue flag after load firmware
      iwlwifi: separated time check for different type of force reset
      iwlwifi: add debugfs to monitor force reset parameters

Williams, Mitch A (6):
      pci: Add SR-IOV convenience functions and macros
      if_link: Add SR-IOV configuration methods
      net: Add netdev ops for SR-IOV configuration
      rtnetlink: Add VF config code to rtnetlink
      igb: support for VF configuration tools
      rtnetlink: clean up SR-IOV config interface

Wolfgang Grandegger (5):
      can: mscan: fix improper return if dlc < 8 in start_xmit function
      can: mscan-mpc5xxx: add support for the MPC512x processor
      powerpc/mpc5xxx: add OF platform binding doc for FSL MSCAN devices
      can: mscan-mpc5xxx: fix broken support for the MPC5200
      can: netlink support for bus-error reporting and counters

Yegor Yefremov (1):
      KS8695: Don't call netif_carrier_off() from ndo_stop()

Zhu Yi (4):
      wireless: add ieee80211_amsdu_to_8023s
      iwmc3200wifi: rx aggregation support
      iwlwifi: remove linux/utsrelease.h dependency
      mac80211: quit addba_resp_timer if Tx BA session is torn down

andrew hendry (2):
      X25: Fix x25_create errors for bad protocol and ENOBUFS
      X25: Dont let x25_bind use addresses containing characters

gregor kowski (1):
      mac80211 : fix a race with update_tkip_key

hartleys (15):
      drivers/atm/nicstar.c: use %pM to show MAC address
      drivers/net/ixgbe/ixgbe_common.c: use %pM to show MAC address
      drivers/atm/idt77252.c: use %pM to show MAC address
      drivers/firmware/iscsi_ibft.c: use %pM to show MAC address
      drivers/atm/fore200e.c: use %pM to show MAC address
      drivers/atm/lanai.c: use %pM to show MAC address
      drivers/media/dvb/dvb-core/dvb_net.c: use %pM to show MAC address
      drivers/net/vxge/vxge-main.c: use %pM to show MAC address
      drivers/net/atl1c/atl1c_main.c: use %pM to show MAC address
      drivers/net/wimax/i2400m/fw.c: use %pM to show MAC address
      drivers/net/atl1e/atl1e_main.c: use %pM to show MAC address
      drivers/net/qlge/qlge_main.c: use %pM to show MAC address
      drivers/net/wimax/i2400m/driver.c: use %pM to show MAC address
      drivers/net/defxx.c: use %pMF to show MAC address
      drivers/net/skfp/skfddi.c: use %pMF to show MAC address

jamal (6):
      xfrm: validate attributes
      xfrm: use proper kernel types
      xfrm: Flushing empty SAD generates false events
      xfrm: Flushing empty SPD generates false events
      xfrm: avoid spinlock in get_acqseq() used by xfrm user
      xfrm: Introduce LINUX_MIB_XFRMFWDHDRERROR

kirjanov@gmail.com (5):
      mv643xx_eth: fix missing validate_addr hook
      smsc911x: replace manual phy lookup.
      greth: some driver cleanups
      sis190: handle DMA mapping errors
      greth: convert to netdev_tx_t

laurent chavey (1):
      net: Add rtnetlink init_rcvwnd to set the TCP initial receive window

stephen hemminger (15):
      sky2: hand receive DMA mapping failures
      sky2: resume clocks
      sky2: disable ASF on Yukon Supreme
      sky2: receive checksum refactoring
      IPv6: keep permanent addresses on admin down
      IPv6: remove trivial nested _bh suffix
      sky2: fix sparse warning
      sky2: WoL changes
      sky2: dont enable PME legacy mode
      sky2: jumbo packet changes
      sky2: version 1.27
      seq_file: add RCU versions of new hlist/list iterators (v3)
      packet: convert socket list to RCU (v3)
      af_key: locking change
      netdev: use list_first_entry macro

 Documentation/DocBook/mac80211.tmpl                |    3 +-
 Documentation/feature-removal-schedule.txt         |   31 +-
 Documentation/isdn/INTERFACE.CAPI                  |    9 +-
 Documentation/isdn/README.gigaset                  |   10 +-
 Documentation/kernel-parameters.txt                |   10 +
 Documentation/networking/dccp.txt                  |    6 +-
 Documentation/networking/ip-sysctl.txt             |   58 +-
 Documentation/networking/ixgbevf.txt               |   90 +
 Documentation/networking/packet_mmap.txt           |    8 +-
 Documentation/networking/regulatory.txt            |   24 +
 Documentation/networking/tcp-thin.txt              |   47 +
 Documentation/powerpc/dts-bindings/fsl/can.txt     |   53 +
 Documentation/powerpc/dts-bindings/fsl/mpc5200.txt |    9 +-
 MAINTAINERS                                        |   30 +-
 arch/ia64/kvm/Kconfig                              |    1 +
 arch/powerpc/boot/dts/mpc8569mds.dts               |   47 +-
 arch/powerpc/configs/ppc64_defconfig               |    1 -
 arch/powerpc/configs/ps3_defconfig                 |    1 -
 arch/powerpc/kvm/Kconfig                           |    1 +
 arch/powerpc/platforms/85xx/mpc85xx_mds.c          |   24 +
 arch/s390/kvm/Kconfig                              |    1 +
 arch/sparc/kernel/sys_sparc32.c                    |    1 -
 arch/x86/kvm/Kconfig                               |    1 +
 arch/xtensa/platforms/iss/network.c                |    2 +-
 drivers/Makefile                                   |    1 +
 drivers/atm/fore200e.c                             |   11 +-
 drivers/atm/idt77252.c                             |    5 +-
 drivers/atm/lanai.c                                |   14 +-
 drivers/atm/nicstar.c                              |    4 +-
 drivers/bluetooth/ath3k.c                          |    2 +
 drivers/bluetooth/bcm203x.c                        |    2 +-
 drivers/bluetooth/bfusb.c                          |    2 +-
 drivers/bluetooth/bluecard_cs.c                    |    2 +-
 drivers/bluetooth/bpa10x.c                         |    2 +-
 drivers/bluetooth/bt3c_cs.c                        |    2 +-
 drivers/bluetooth/btmrvl_debugfs.c                 |   14 +-
 drivers/bluetooth/btmrvl_main.c                    |    2 +-
 drivers/bluetooth/btmrvl_sdio.c                    |    4 +-
 drivers/bluetooth/btsdio.c                         |    2 +-
 drivers/bluetooth/btuart_cs.c                      |    2 +-
 drivers/bluetooth/btusb.c                          |    2 +-
 drivers/bluetooth/dtl1_cs.c                        |    2 +-
 drivers/bluetooth/hci_ldisc.c                      |    2 +-
 drivers/bluetooth/hci_vhci.c                       |    2 +-
 drivers/firmware/iscsi_ibft.c                      |    6 +-
 drivers/infiniband/hw/cxgb3/iwch_cm.c              |   11 +-
 drivers/infiniband/hw/nes/nes_nic.c                |   85 +-
 drivers/infiniband/ulp/ipoib/ipoib_cm.c            |    2 +-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c     |    2 +-
 drivers/isdn/Kconfig                               |   43 +-
 drivers/isdn/capi/Kconfig                          |   16 +-
 drivers/isdn/capi/capi.c                           | 1203 +-
 drivers/isdn/capi/capidrv.c                        |  103 +-
 drivers/isdn/capi/capifs.c                         |  126 +-
 drivers/isdn/capi/capifs.h                         |   21 +-
 drivers/isdn/capi/kcapi.c                          |  817 +-
 drivers/isdn/capi/kcapi.h                          |   13 +-
 drivers/isdn/capi/kcapi_proc.c                     |   41 +-
 drivers/isdn/gigaset/asyncdata.c                   |    6 +-
 drivers/isdn/gigaset/bas-gigaset.c                 |   18 +-
 drivers/isdn/gigaset/capi.c                        |  106 +-
 drivers/isdn/gigaset/common.c                      |   49 +-
 drivers/isdn/gigaset/ev-layer.c                    |   63 +-
 drivers/isdn/gigaset/gigaset.h                     |   11 +-
 drivers/isdn/gigaset/i4l.c                         |   52 +-
 drivers/isdn/gigaset/interface.c                   |   12 +-
 drivers/isdn/gigaset/isocdata.c                    |   44 +-
 drivers/isdn/gigaset/proc.c                        |    2 -
 drivers/isdn/gigaset/usb-gigaset.c                 |    2 +-
 drivers/isdn/hardware/avm/avmcard.h                |    6 +-
 drivers/isdn/hardware/avm/b1.c                     |   54 +-
 drivers/isdn/hardware/avm/b1dma.c                  |   71 +-
 drivers/isdn/hardware/avm/b1isa.c                  |    2 +-
 drivers/isdn/hardware/avm/b1pci.c                  |    4 +-
 drivers/isdn/hardware/avm/b1pcmcia.c               |    2 +-
 drivers/isdn/hardware/avm/c4.c                     |   53 +-
 drivers/isdn/hardware/avm/t1isa.c                  |    2 +-
 drivers/isdn/hardware/avm/t1pci.c                  |    2 +-
 drivers/isdn/hardware/eicon/capimain.c             |   40 +-
 drivers/isdn/hardware/eicon/diva_didd.c            |   45 +-
 drivers/isdn/hardware/eicon/divasi.c               |   48 +-
 drivers/isdn/hardware/eicon/divasproc.c            |  198 +-
 drivers/isdn/hardware/mISDN/hfcmulti.c             |    2 +-
 drivers/isdn/hardware/mISDN/mISDNinfineon.c        |    1 +
 drivers/isdn/hardware/mISDN/w6692.c                |    2 +
 drivers/isdn/hisax/isar.c                          |    2 +-
 drivers/isdn/hysdn/hycapi.c                        |   56 +-
 drivers/isdn/i4l/Kconfig                           |    7 -
 drivers/media/dvb/dvb-core/dvb_net.c               |   14 +-
 drivers/message/i2o/i2o_proc.c                     |   11 +-
 drivers/misc/iwmc3200top/fw-download.c             |   50 +-
 drivers/misc/iwmc3200top/iwmc3200top.h             |    4 +-
 drivers/misc/iwmc3200top/log.h                     |   31 +-
 drivers/misc/iwmc3200top/main.c                    |   59 +-
 drivers/net/3c501.c                                |    2 +-
 drivers/net/3c505.c                                |   13 +-
 drivers/net/3c509.c                                |   10 +-
 drivers/net/3c515.c                                |    2 +-
 drivers/net/3c523.c                                |   13 +-
 drivers/net/3c527.c                                |   17 +-
 drivers/net/3c59x.c                                |    4 +-
 drivers/net/7990.c                                 |    6 +-
 drivers/net/8139cp.c                               |   81 +-
 drivers/net/8139too.c                              |  196 +-
 drivers/net/82596.c                                |   15 +-
 drivers/net/Kconfig                                |   82 +-
 drivers/net/Makefile                               |    5 +
 drivers/net/a2065.c                                |    6 +-
 drivers/net/acenic.c                               |    4 +-
 drivers/net/amd8111e.c                             |   21 +-
 drivers/net/amd8111e.h                             |    1 -
 drivers/net/appletalk/ltpc.c                       |    1 -
 drivers/net/arcnet/com20020-pci.c                  |    2 +-
 drivers/net/ariadne.c                              |    4 +-
 drivers/net/arm/am79c961a.c                        |   12 +-
 drivers/net/arm/at91_ether.c                       |    9 +-
 drivers/net/arm/ep93xx_eth.c                       |  140 +-
 drivers/net/arm/ether3.c                           |    2 +-
 drivers/net/arm/ixp4xx_eth.c                       |   13 +-
 drivers/net/arm/ks8695net.c                        |   23 +-
 drivers/net/arm/w90p910_ether.c                    |    8 +-
 drivers/net/at1700.c                               |    8 +-
 drivers/net/atarilance.c                           |    2 +-
 drivers/net/atl1c/atl1c.h                          |   11 +-
 drivers/net/atl1c/atl1c_ethtool.c                  |    2 +-
 drivers/net/atl1c/atl1c_hw.c                       |   83 +-
 drivers/net/atl1c/atl1c_hw.h                       |    5 +
 drivers/net/atl1c/atl1c_main.c                     |  126 +-
 drivers/net/atl1e/atl1e_hw.c                       |   23 +-
 drivers/net/atl1e/atl1e_main.c                     |  160 +-
 drivers/net/atl1e/atl1e_param.c                    |   35 +-
 drivers/net/atlx/atl1.c                            |    2 +-
 drivers/net/atlx/atl2.c                            |    4 +-
 drivers/net/atlx/atlx.c                            |    2 +-
 drivers/net/atp.c                                  |    9 +-
 drivers/net/au1000_eth.c                           |    7 +-
 drivers/net/b44.c                                  |   94 +-
 drivers/net/bcm63xx_enet.c                         |   15 +-
 drivers/net/benet/Kconfig                          |    4 +-
 drivers/net/benet/be.h                             |   19 +-
 drivers/net/benet/be_cmds.c                        |   94 +-
 drivers/net/benet/be_cmds.h                        |   27 +-
 drivers/net/benet/be_ethtool.c                     |   65 +-
 drivers/net/benet/be_hw.h                          |  121 +-
 drivers/net/benet/be_main.c                        |  495 +-
 drivers/net/bfin_mac.c                             |    8 +-
 drivers/net/bmac.c                                 |   13 +-
 drivers/net/bnx2.c                                 |  410 +-
 drivers/net/bnx2.h                                 |    3 +-
 drivers/net/bnx2x.h                                |   53 +-
 drivers/net/bnx2x_fw_defs.h                        |    7 +-
 drivers/net/bnx2x_hsi.h                            |   10 +-
 drivers/net/bnx2x_init_ops.h                       |   13 +-
 drivers/net/bnx2x_link.c                           |   21 +-
 drivers/net/bnx2x_main.c                           |  284 +-
 drivers/net/bonding/bond_main.c                    |   27 +-
 drivers/net/bonding/bonding.h                      |    1 -
 drivers/net/can/at91_can.c                         |    4 +
 drivers/net/can/bfin_can.c                         |    4 +
 drivers/net/can/dev.c                              |    8 +
 drivers/net/can/mcp251x.c                          |  426 +-
 drivers/net/can/mscan/Kconfig                      |    7 +-
 drivers/net/can/mscan/mpc5xxx_can.c                |  248 +-
 drivers/net/can/mscan/mscan.c                      |   58 +-
 drivers/net/can/mscan/mscan.h                      |   86 +-
 drivers/net/can/sja1000/Kconfig                    |   12 +
 drivers/net/can/sja1000/Makefile                   |    1 +
 drivers/net/can/sja1000/ems_pci.c                  |    2 +-
 drivers/net/can/sja1000/kvaser_pci.c               |    2 +-
 drivers/net/can/sja1000/plx_pci.c                  |  472 +
 drivers/net/can/sja1000/sja1000.c                  |   27 +-
 drivers/net/can/ti_hecc.c                          |   73 +-
 drivers/net/can/usb/Kconfig                        |    2 +-
 drivers/net/can/usb/ems_usb.c                      |    6 +-
 drivers/net/can/vcan.c                             |   12 +-
 drivers/net/cassini.c                              |  437 +-
 drivers/net/chelsio/common.h                       |   44 +-
 drivers/net/chelsio/cxgb2.c                        |   20 +-
 drivers/net/chelsio/espi.c                         |    4 +-
 drivers/net/chelsio/pm3393.c                       |   22 +-
 drivers/net/chelsio/sge.c                          |   12 +-
 drivers/net/chelsio/subr.c                         |   34 +-
 drivers/net/chelsio/vsc7326.c                      |   24 +-
 drivers/net/cnic.c                                 |  206 +-
 drivers/net/cnic.h                                 |   13 +-
 drivers/net/cnic_defs.h                            |    2 +-
 drivers/net/cnic_if.h                              |    6 +-
 drivers/net/cpmac.c                                |    4 +-
 drivers/net/cris/eth_v10.c                         |    8 +-
 drivers/net/cs89x0.c                               |    2 +-
 drivers/net/cxgb3/common.h                         |   28 +-
 drivers/net/cxgb3/cxgb3_main.c                     |   10 +-
 drivers/net/cxgb3/cxgb3_offload.c                  |    2 +-
 drivers/net/cxgb3/sge.c                            |   16 +-
 drivers/net/cxgb3/t3_hw.c                          |    3 +-
 drivers/net/cxgb3/xgmac.c                          |   18 +-
 drivers/net/davinci_emac.c                         |   12 +-
 drivers/net/de620.c                                |    2 +-
 drivers/net/declance.c                             |    6 +-
 drivers/net/defxx.c                                |   24 +-
 drivers/net/depca.c                                |    5 +-
 drivers/net/dl2k.c                                 |    9 +-
 drivers/net/dl2k.h                                 |    2 +-
 drivers/net/dm9000.c                               |    5 +-
 drivers/net/e100.c                                 |   18 +-
 drivers/net/e1000/e1000.h                          |    1 +
 drivers/net/e1000/e1000_ethtool.c                  |   19 +-
 drivers/net/e1000/e1000_main.c                     |   46 +-
 drivers/net/e1000e/82571.c                         |   68 +-
 drivers/net/e1000e/defines.h                       |    2 +
 drivers/net/e1000e/e1000.h                         |   19 +-
 drivers/net/e1000e/es2lan.c                        |   32 +-
 drivers/net/e1000e/ethtool.c                       |    2 +-
 drivers/net/e1000e/hw.h                            |   12 +-
 drivers/net/e1000e/ich8lan.c                       |    1 +
 drivers/net/e1000e/lib.c                           |  230 +-
 drivers/net/e1000e/netdev.c                        |   45 +-
 drivers/net/eepro.c                                |   21 +-
 drivers/net/eexpress.c                             |   22 +-
 drivers/net/ehea/ehea_main.c                       |    9 +-
 drivers/net/enc28j60.c                             |    2 +-
 drivers/net/enic/enic.h                            |    5 +-
 drivers/net/enic/enic_main.c                       |  208 +-
 drivers/net/enic/enic_res.c                        |   16 +-
 drivers/net/enic/vnic_dev.c                        |    1 -
 drivers/net/enic/vnic_enet.h                       |    5 +
 drivers/net/enic/vnic_intr.c                       |    8 +-
 drivers/net/enic/vnic_intr.h                       |    3 +
 drivers/net/enic/vnic_nic.h                        |   12 +-
 drivers/net/epic100.c                              |    9 +-
 drivers/net/eth16i.c                               |    2 +-
 drivers/net/ethoc.c                                |   14 +-
 drivers/net/ewrk3.c                                |    5 +-
 drivers/net/fealnx.c                               |    8 +-
 drivers/net/fec.c                                  |   84 +-
 drivers/net/fec_mpc52xx.c                          |    5 +-
 drivers/net/forcedeth.c                            |    8 +-
 drivers/net/fs_enet/Kconfig                        |   10 +-
 drivers/net/fs_enet/fs_enet-main.c                 |   93 +-
 drivers/net/fs_enet/fs_enet.h                      |   49 +-
 drivers/net/fs_enet/mac-fcc.c                      |    9 +-
 drivers/net/fs_enet/mac-fec.c                      |   62 +-
 drivers/net/fs_enet/mac-scc.c                      |   13 +-
 drivers/net/fs_enet/mii-fec.c                      |    4 +-
 drivers/net/gianfar.c                              |    4 +-
 drivers/net/greth.c                                | 1634 +++
 drivers/net/greth.h                                |  143 +
 drivers/net/hamachi.c                              |   13 +-
 drivers/net/hp100.c                                |   13 +-
 drivers/net/ibm_newemac/core.c                     |    8 +-
 drivers/net/ibmlana.c                              |    2 +-
 drivers/net/ibmveth.c                              |    8 +-
 drivers/net/igb/e1000_82575.c                      |   65 +-
 drivers/net/igb/e1000_82575.h                      |    5 +
 drivers/net/igb/e1000_defines.h                    |    7 +-
 drivers/net/igb/e1000_hw.h                         |    7 -
 drivers/net/igb/e1000_mac.c                        |   70 -
 drivers/net/igb/e1000_mac.h                        |    2 -
 drivers/net/igb/e1000_phy.c                        |   35 +
 drivers/net/igb/e1000_phy.h                        |    2 +
 drivers/net/igb/e1000_regs.h                       |    1 +
 drivers/net/igb/igb.h                              |   16 +-
 drivers/net/igb/igb_ethtool.c                      |   93 +-
 drivers/net/igb/igb_main.c                         |  414 +-
 drivers/net/igbvf/netdev.c                         |   31 +-
 drivers/net/ioc3-eth.c                             |   11 +-
 drivers/net/ipg.c                                  |   13 +-
 drivers/net/irda/Kconfig                           |   10 +
 drivers/net/irda/Makefile                          |    1 +
 drivers/net/irda/donauboe.c                        |    2 +-
 drivers/net/irda/sh_sir.c                          |  823 ++
 drivers/net/irda/via-ircc.c                        |    2 +-
 drivers/net/irda/vlsi_ir.c                         |    2 +-
 drivers/net/isa-skeleton.c                         |  718 --
 drivers/net/iseries_veth.c                         |    8 +-
 drivers/net/ixgb/ixgb.h                            |   11 +-
 drivers/net/ixgb/ixgb_main.c                       |  104 +-
 drivers/net/ixgbe/Makefile                         |    3 +-
 drivers/net/ixgbe/ixgbe.h                          |   54 +-
 drivers/net/ixgbe/ixgbe_82599.c                    |  233 +-
 drivers/net/ixgbe/ixgbe_common.c                   |   19 +-
 drivers/net/ixgbe/ixgbe_common.h                   |    2 +-
 drivers/net/ixgbe/ixgbe_ethtool.c                  |  195 +-
 drivers/net/ixgbe/ixgbe_fcoe.c                     |    4 +-
 drivers/net/ixgbe/ixgbe_main.c                     |  676 +-
 drivers/net/ixgbe/ixgbe_mbx.c                      |  479 +
 drivers/net/ixgbe/ixgbe_mbx.h                      |   96 +
 drivers/net/ixgbe/ixgbe_sriov.c                    |  362 +
 drivers/net/ixgbe/ixgbe_sriov.h                    |   47 +
 drivers/net/ixgbe/ixgbe_type.h                     |   66 +-
 drivers/net/ixgbevf/Makefile                       |   38 +
 drivers/net/ixgbevf/defines.h                      |  292 +
 drivers/net/ixgbevf/ethtool.c                      |  716 ++
 drivers/net/ixgbevf/ixgbevf.h                      |  318 +
 drivers/net/ixgbevf/ixgbevf_main.c                 | 3578 ++++++
 drivers/net/ixgbevf/mbx.c                          |  341 +
 drivers/net/ixgbevf/mbx.h                          |  100 +
 drivers/net/ixgbevf/regs.h                         |   85 +
 drivers/net/ixgbevf/vf.c                           |  387 +
 drivers/net/ixgbevf/vf.h                           |  168 +
 drivers/net/jme.c                                  |   62 +-
 drivers/net/jme.h                                  |   41 +-
 drivers/net/korina.c                               |   10 +-
 drivers/net/ks8851.c                               |    7 +-
 drivers/net/ks8851_mll.c                           |    7 +-
 drivers/net/ksz884x.c                              | 7335 +++++++++++
 drivers/net/lance.c                                |    2 +-
 drivers/net/lib82596.c                             |   21 +-
 drivers/net/lib8390.c                              |   15 +-
 drivers/net/ll_temac_main.c                        |   25 +-
 drivers/net/loopback.c                             |   16 +-
 drivers/net/lp486e.c                               |   16 +-
 drivers/net/mac8390.c                              |  632 +-
 drivers/net/mac89x0.c                              |    4 +-
 drivers/net/macb.c                                 |   38 +-
 drivers/net/mace.c                                 |   11 +-
 drivers/net/macmace.c                              |   12 +-
 drivers/net/macvlan.c                              |  117 +-
 drivers/net/macvtap.c                              |  803 ++
 drivers/net/meth.c                                 |    3 -
 drivers/net/mlx4/en_rx.c                           |    8 +-
 drivers/net/mlx4/main.c                            |    2 +-
 drivers/net/mv643xx_eth.c                          |    6 +-
 drivers/net/myri10ge/myri10ge.c                    |  198 +-
 drivers/net/myri_sbus.c                            |    6 +-
 drivers/net/natsemi.c                              |    8 +-
 drivers/net/ne2k-pci.c                             |    2 +-
 drivers/net/netxen/Makefile                        |    2 +-
 drivers/net/netxen/netxen_nic.h                    |    8 +-
 drivers/net/netxen/netxen_nic_ctx.c                |    2 +-
 drivers/net/netxen/netxen_nic_ethtool.c            |    2 +-
 drivers/net/netxen/netxen_nic_hdr.h                |    5 +-
 drivers/net/netxen/netxen_nic_hw.c                 |   46 +-
 drivers/net/netxen/netxen_nic_hw.h                 |    2 +-
 drivers/net/netxen/netxen_nic_init.c               |    5 +-
 drivers/net/netxen/netxen_nic_main.c               |  213 +-
 drivers/net/ni5010.c                               |    3 +-
 drivers/net/ni52.c                                 |   10 +-
 drivers/net/ni65.c                                 |    2 +-
 drivers/net/niu.c                                  |  699 +-
 drivers/net/ns83820.c                              |    4 +-
 drivers/net/octeon/octeon_mgmt.c                   |   18 +-
 drivers/net/pasemi_mac.c                           |    2 +-
 drivers/net/pci-skeleton.c                         | 1029 +-
 drivers/net/pcmcia/3c574_cs.c                      |    2 +-
 drivers/net/pcmcia/3c589_cs.c                      |    2 +-
 drivers/net/pcmcia/axnet_cs.c                      |   11 +-
 drivers/net/pcmcia/fmvj18x_cs.c                    |   10 +-
 drivers/net/pcmcia/nmclan_cs.c                     |   18 +-
 drivers/net/pcmcia/smc91c92_cs.c                   |   35 +-
 drivers/net/pcmcia/xirc2ps_cs.c                    |   88 +-
 drivers/net/pcnet32.c                              |  507 +-
 drivers/net/phy/broadcom.c                         |    5 +-
 drivers/net/phy/marvell.c                          |   38 +
 drivers/net/phy/phy_device.c                       |   16 +
 drivers/net/phy/smsc.c                             |   21 +-
 drivers/net/ppp_generic.c                          |  122 +-
 drivers/net/ps3_gelic_net.c                        |    4 +-
 drivers/net/ps3_gelic_wireless.c                   |  149 +-
 drivers/net/qla3xxx.c                              |    3 +-
 drivers/net/qlcnic/Makefile                        |    8 +
 drivers/net/qlcnic/qlcnic.h                        | 1126 ++
 drivers/net/qlcnic/qlcnic_ctx.c                    |  534 +
 drivers/net/qlcnic/qlcnic_ethtool.c                | 1015 ++
 drivers/net/qlcnic/qlcnic_hdr.h                    |  937 ++
 drivers/net/qlcnic/qlcnic_hw.c                     | 1274 ++
 drivers/net/qlcnic/qlcnic_init.c                   | 1541 +++
 drivers/net/qlcnic/qlcnic_main.c                   | 2720 +++++
 drivers/net/qlge/qlge.h                            |  446 +-
 drivers/net/qlge/qlge_dbg.c                        | 1183 ++-
 drivers/net/qlge/qlge_ethtool.c                    |   56 +-
 drivers/net/qlge/qlge_main.c                       | 1189 ++-
 drivers/net/qlge/qlge_mpi.c                        |  340 +-
 drivers/net/r6040.c                                |   37 +-
 drivers/net/r8169.c                                |  166 +-
 drivers/net/rrunner.c                              |    2 +-
 drivers/net/s2io.c                                 |   13 +-
 drivers/net/sb1250-mac.c                           |    6 +-
 drivers/net/sc92031.c                              |    6 +-
 drivers/net/sfc/efx.c                              |    8 +-
 drivers/net/sfc/efx.h                              |    2 -
 drivers/net/sfc/ethtool.c                          |   10 +-
 drivers/net/sfc/falcon.c                           |    6 +-
 drivers/net/sfc/mcdi.c                             |  109 +-
 drivers/net/sfc/mcdi.h                             |    1 +
 drivers/net/sfc/mcdi_pcol.h                        |  202 +-
 drivers/net/sfc/mcdi_phy.c                         |   36 +-
 drivers/net/sfc/mdio_10g.c                         |   24 +
 drivers/net/sfc/mdio_10g.h                         |    3 +
 drivers/net/sfc/net_driver.h                       |   17 +-
 drivers/net/sfc/nic.c                              |   13 +-
 drivers/net/sfc/qt202x_phy.c                       |    1 +
 drivers/net/sfc/selftest.c                         |   42 +-
 drivers/net/sfc/selftest.h                         |    4 +-
 drivers/net/sfc/siena.c                            |   16 +-
 drivers/net/sfc/tenxpress.c                        |    2 +
 drivers/net/sgiseeq.c                              |    2 +-
 drivers/net/sh_eth.c                               |   10 +-
 drivers/net/sis190.c                               |  198 +-
 drivers/net/sis900.c                               |    9 +-
 drivers/net/skfp/skfddi.c                          |   35 +-
 drivers/net/skge.c                                 |  218 +-
 drivers/net/sky2.c                                 |  726 +-
 drivers/net/sky2.h                                 |   10 +-
 drivers/net/smc911x.c                              |   14 +-
 drivers/net/smc9194.c                              |   12 +-
 drivers/net/smc91x.c                               |   11 +-
 drivers/net/smsc911x.c                             |   53 +-
 drivers/net/smsc9420.c                             |    9 +-
 drivers/net/sonic.c                                |   13 +-
 drivers/net/spider_net.c                           |    4 +-
 drivers/net/starfire.c                             |   13 +-
 drivers/net/stmmac/Kconfig                         |    8 +-
 drivers/net/stmmac/Makefile                        |    5 +-
 drivers/net/stmmac/common.h                        |  279 +-
 drivers/net/stmmac/descs.h                         |    4 +-
 drivers/net/stmmac/{mac100.c => dwmac100.c}        |  212 +-
 drivers/net/stmmac/{mac100.h => dwmac100.h}        |    0
 drivers/net/stmmac/{gmac.h => dwmac1000.h}         |   18 +-
 drivers/net/stmmac/dwmac1000_core.c                |  243 +
 drivers/net/stmmac/{gmac.c => dwmac1000_dma.c}     |  351 +-
 drivers/net/stmmac/dwmac_dma.h                     |  107 +
 drivers/net/stmmac/dwmac_lib.c                     |  263 +
 drivers/net/stmmac/stmmac.h                        |   28 +-
 drivers/net/stmmac/stmmac_ethtool.c                |   11 +-
 drivers/net/stmmac/stmmac_main.c                   |  436 +-
 drivers/net/stmmac/stmmac_mdio.c                   |   11 +-
 drivers/net/sun3_82586.c                           |   10 +-
 drivers/net/sun3lance.c                            |    2 +-
 drivers/net/sunbmac.c                              |    7 +-
 drivers/net/sundance.c                             |    9 +-
 drivers/net/sungem.c                               |   14 +-
 drivers/net/sunhme.c                               |   26 +-
 drivers/net/sunlance.c                             |    6 +-
 drivers/net/sunqe.c                                |   11 +-
 drivers/net/sunvnet.c                              |    7 +-
 drivers/net/tc35815.c                              |   27 +-
 drivers/net/tehuti.c                               |  159 +-
 drivers/net/tehuti.h                               |   30 +-
 drivers/net/tg3.c                                  |  965 +-
 drivers/net/tg3.h                                  |  162 +-
 drivers/net/tlan.c                                 |   37 +-
 drivers/net/tlan.h                                 |    3 -
 drivers/net/tokenring/3c359.c                      |    7 +-
 drivers/net/tokenring/abyss.c                      |    2 +-
 drivers/net/tokenring/ibmtr.c                      |    4 +-
 drivers/net/tokenring/lanstreamer.c                |    6 +-
 drivers/net/tokenring/olympic.c                    |    7 +-
 drivers/net/tokenring/tms380tr.c                   |    8 +-
 drivers/net/tokenring/tmspci.c                     |    2 +-
 drivers/net/tsi108_eth.c                           |   22 +-
 drivers/net/tulip/21142.c                          |   76 +-
 drivers/net/tulip/de2104x.c                        |  163 +-
 drivers/net/tulip/de4x5.c                          |   16 +-
 drivers/net/tulip/dmfe.c                           |  103 +-
 drivers/net/tulip/eeprom.c                         |   47 +-
 drivers/net/tulip/interrupt.c                      |  100 +-
 drivers/net/tulip/media.c                          |   74 +-
 drivers/net/tulip/pnic.c                           |   33 +-
 drivers/net/tulip/pnic2.c                          |   59 +-
 drivers/net/tulip/timer.c                          |   52 +-
 drivers/net/tulip/tulip_core.c                     |  187 +-
 drivers/net/tulip/uli526x.c                        |   64 +-
 drivers/net/tulip/winbond-840.c                    |  186 +-
 drivers/net/tulip/xircom_cb.c                      |   46 +-
 drivers/net/tun.c                                  |  127 +-
 drivers/net/typhoon.c                              |  253 +-
 drivers/net/ucc_geth.c                             |   29 +-
 drivers/net/usb/asix.c                             |  117 +-
 drivers/net/usb/catc.c                             |    9 +-
 drivers/net/usb/cdc_eem.c                          |   10 +-
 drivers/net/usb/cdc_ether.c                        |   22 +-
 drivers/net/usb/dm9601.c                           |   59 +-
 drivers/net/usb/int51x1.c                          |   17 +-
 drivers/net/usb/kaweth.c                           |    2 +-
 drivers/net/usb/mcs7830.c                          |  256 +-
 drivers/net/usb/net1080.c                          |  109 +-
 drivers/net/usb/pegasus.c                          |  172 +-
 drivers/net/usb/rndis_host.c                       |   24 +-
 drivers/net/usb/rtl8150.c                          |    9 +-
 drivers/net/usb/smsc95xx.c                         |  245 +-
 drivers/net/usb/usbnet.c                           |  238 +-
 drivers/net/veth.c                                 |   19 +-
 drivers/net/via-rhine.c                            |    9 +-
 drivers/net/via-velocity.c                         |   16 +-
 drivers/net/virtio_net.c                           |  473 +-
 drivers/net/vmxnet3/vmxnet3_drv.c                  |   19 +-
 drivers/net/vxge/vxge-main.c                       |   16 +-
 drivers/net/wan/dscc4.c                            |    2 +-
 drivers/net/wan/farsync.c                          |    2 +-
 drivers/net/wan/lmc/lmc_main.c                     |    2 +-
 drivers/net/wan/pc300_drv.c                        |    2 +-
 drivers/net/wan/pc300too.c                         |    2 +-
 drivers/net/wan/pci200syn.c                        |    2 +-
 drivers/net/wan/wanxl.c                            |    2 +-
 drivers/net/wimax/i2400m/driver.c                  |   17 +-
 drivers/net/wimax/i2400m/fw.c                      |   11 +-
 drivers/net/wireless/Kconfig                       |    1 +
 drivers/net/wireless/adm8211.c                     |   27 +-
 drivers/net/wireless/airo.c                        |   39 +-
 drivers/net/wireless/at76c50x-usb.c                |    6 +-
 drivers/net/wireless/ath/ar9170/ar9170.h           |   17 +-
 drivers/net/wireless/ath/ar9170/hw.h               |    1 +
 drivers/net/wireless/ath/ar9170/mac.c              |    2 +-
 drivers/net/wireless/ath/ar9170/main.c             |  193 +-
 drivers/net/wireless/ath/ar9170/usb.c              |    2 +
 drivers/net/wireless/ath/ath.h                     |    1 -
 drivers/net/wireless/ath/ath5k/ath5k.h             |   27 +-
 drivers/net/wireless/ath/ath5k/base.c              |  108 +-
 drivers/net/wireless/ath/ath5k/base.h              |    1 -
 drivers/net/wireless/ath/ath5k/led.c               |    2 +
 drivers/net/wireless/ath/ath5k/pcu.c               |  121 +-
 drivers/net/wireless/ath/ath5k/qcu.c               |   25 +-
 drivers/net/wireless/ath/ath5k/reset.c             |   14 +-
 drivers/net/wireless/ath/ath9k/Makefile            |    2 +
 drivers/net/wireless/ath/ath9k/ahb.c               |   31 +-
 drivers/net/wireless/ath/ath9k/ath9k.h             |   80 +-
 drivers/net/wireless/ath/ath9k/beacon.c            |   30 +-
 drivers/net/wireless/ath/ath9k/btcoex.h            |    2 +
 drivers/net/wireless/ath/ath9k/debug.c             |  199 +-
 drivers/net/wireless/ath/ath9k/debug.h             |   32 +
 drivers/net/wireless/ath/ath9k/gpio.c              |  442 +
 drivers/net/wireless/ath/ath9k/hw.c                |  178 +-
 drivers/net/wireless/ath/ath9k/hw.h                |   10 +-
 drivers/net/wireless/ath/ath9k/init.c              |  863 ++
 drivers/net/wireless/ath/ath9k/mac.h               |   34 +
 drivers/net/wireless/ath/ath9k/main.c              | 1451 +--
 drivers/net/wireless/ath/ath9k/pci.c               |   75 +-
 drivers/net/wireless/ath/ath9k/phy.h               |    3 +
 drivers/net/wireless/ath/ath9k/rc.c                |   27 +-
 drivers/net/wireless/ath/ath9k/rc.h                |    4 +
 drivers/net/wireless/ath/ath9k/recv.c              |   40 +-
 drivers/net/wireless/ath/ath9k/reg.h               |    6 +-
 drivers/net/wireless/ath/ath9k/virtual.c           |    2 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |   62 +-
 drivers/net/wireless/ath/debug.h                   |    8 +-
 drivers/net/wireless/ath/regd.c                    |    5 +-
 drivers/net/wireless/atmel_pci.c                   |    2 +-
 drivers/net/wireless/b43/Kconfig                   |    6 +-
 drivers/net/wireless/b43/Makefile                  |    2 +-
 drivers/net/wireless/b43/b43.h                     |   20 +-
 drivers/net/wireless/b43/dma.c                     |   19 -
 drivers/net/wireless/b43/dma.h                     |    5 -
 drivers/net/wireless/b43/main.c                    |   98 +-
 drivers/net/wireless/b43/phy_common.c              |   45 +
 drivers/net/wireless/b43/phy_common.h              |   10 +
 drivers/net/wireless/b43/phy_lp.c                  |   76 +-
 drivers/net/wireless/b43/phy_n.c                   | 3033 +++++-
 drivers/net/wireless/b43/phy_n.h                   |   98 +-
 drivers/net/wireless/b43/pio.c                     |   17 -
 drivers/net/wireless/b43/pio.h                     |   45 -
 drivers/net/wireless/b43/tables_nphy.c             |  744 ++-
 drivers/net/wireless/b43/tables_nphy.h             |  100 +-
 drivers/net/wireless/b43legacy/dma.c               |   20 -
 drivers/net/wireless/b43legacy/dma.h               |   10 -
 drivers/net/wireless/b43legacy/leds.h              |    2 +-
 drivers/net/wireless/b43legacy/main.c              |   61 +-
 drivers/net/wireless/b43legacy/pio.c               |   13 -
 drivers/net/wireless/b43legacy/pio.h               |   11 -
 drivers/net/wireless/hostap/hostap_cs.c            |   17 +-
 drivers/net/wireless/hostap/hostap_hw.c            |    9 +
 drivers/net/wireless/hostap/hostap_pci.c           |    2 +-
 drivers/net/wireless/hostap/hostap_plx.c           |    2 +-
 drivers/net/wireless/ipw2x00/ipw2100.c             |    2 +-
 drivers/net/wireless/ipw2x00/ipw2200.c             |    2 +-
 drivers/net/wireless/iwlwifi/Kconfig               |   14 +-
 drivers/net/wireless/iwlwifi/Makefile              |    3 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c            |   84 +-
 drivers/net/wireless/iwlwifi/iwl-3945-fh.h         |    4 +-
 drivers/net/wireless/iwlwifi/iwl-3945-hw.h         |    4 +-
 drivers/net/wireless/iwlwifi/iwl-3945-led.c        |    2 +-
 drivers/net/wireless/iwlwifi/iwl-3945-led.h        |    2 +-
 drivers/net/wireless/iwlwifi/iwl-3945-rs.c         |    2 +-
 drivers/net/wireless/iwlwifi/iwl-3945.c            |   25 +-
 drivers/net/wireless/iwlwifi/iwl-3945.h            |   25 +-
 drivers/net/wireless/iwlwifi/iwl-4965-hw.h         |    4 +-
 drivers/net/wireless/iwlwifi/iwl-4965.c            |   14 +-
 drivers/net/wireless/iwlwifi/iwl-5000-hw.h         |    4 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c            |  125 +-
 drivers/net/wireless/iwlwifi/iwl-6000-hw.h         |    4 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c            |  116 +-
 drivers/net/wireless/iwlwifi/iwl-agn-led.c         |    2 +-
 drivers/net/wireless/iwlwifi/iwl-agn-led.h         |    2 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c          |   17 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.h          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c             |  354 +-
 drivers/net/wireless/iwlwifi/iwl-calib.c           |   11 +-
 drivers/net/wireless/iwlwifi/iwl-calib.h           |    4 +-
 drivers/net/wireless/iwlwifi/iwl-commands.h        |   68 +-
 drivers/net/wireless/iwlwifi/iwl-core.c            |  388 +-
 drivers/net/wireless/iwlwifi/iwl-core.h            |   55 +-
 drivers/net/wireless/iwlwifi/iwl-csr.h             |    6 +-
 drivers/net/wireless/iwlwifi/iwl-debug.h           |   60 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c         | 1461 ++-
 drivers/net/wireless/iwlwifi/iwl-dev.h             |   97 +-
 drivers/net/wireless/iwlwifi/iwl-devtrace.c        |    2 +
 drivers/net/wireless/iwlwifi/iwl-devtrace.h        |   44 +
 drivers/net/wireless/iwlwifi/iwl-eeprom.c          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-eeprom.h          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-fh.h              |   23 +-
 drivers/net/wireless/iwlwifi/iwl-hcmd.c            |   17 +-
 drivers/net/wireless/iwlwifi/iwl-helpers.h         |    9 +-
 drivers/net/wireless/iwlwifi/iwl-io.h              |    2 +-
 drivers/net/wireless/iwlwifi/iwl-led.c             |    2 +-
 drivers/net/wireless/iwlwifi/iwl-led.h             |    2 +-
 drivers/net/wireless/iwlwifi/iwl-power.c           |    9 +-
 drivers/net/wireless/iwlwifi/iwl-power.h           |    2 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h            |    4 +-
 drivers/net/wireless/iwlwifi/iwl-rx.c              |  136 +-
 drivers/net/wireless/iwlwifi/iwl-scan.c            |  258 +-
 drivers/net/wireless/iwlwifi/iwl-spectrum.c        |  198 -
 drivers/net/wireless/iwlwifi/iwl-spectrum.h        |    2 +-
 drivers/net/wireless/iwlwifi/iwl-sta.c             |  150 +-
 drivers/net/wireless/iwlwifi/iwl-sta.h             |    3 +-
 drivers/net/wireless/iwlwifi/iwl-tx.c              |   77 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c        |  197 +-
 drivers/net/wireless/iwmc3200wifi/iwm.h            |    2 +-
 drivers/net/wireless/iwmc3200wifi/rx.c             |   71 +-
 drivers/net/wireless/libertas/Kconfig              |    6 +
 drivers/net/wireless/libertas/Makefile             |    2 +-
 drivers/net/wireless/libertas/assoc.c              |   95 +-
 drivers/net/wireless/libertas/cmd.c                |   22 +-
 drivers/net/wireless/libertas/cmd.h                |   12 -
 drivers/net/wireless/libertas/cmdresp.c            |   21 +-
 drivers/net/wireless/libertas/defs.h               |    7 -
 drivers/net/wireless/libertas/dev.h                |    8 +-
 drivers/net/wireless/libertas/ethtool.c            |    2 +
 drivers/net/wireless/libertas/if_spi.c             |    1 +
 drivers/net/wireless/libertas/main.c               |   81 +-
 drivers/net/wireless/libertas/mesh.c               |   29 +-
 drivers/net/wireless/libertas/mesh.h               |   32 +
 drivers/net/wireless/libertas/scan.c               |    2 +-
 drivers/net/wireless/libertas/tx.c                 |    2 +-
 drivers/net/wireless/libertas/wext.c               |   26 +-
 drivers/net/wireless/libertas_tf/main.c            |   13 +-
 drivers/net/wireless/mac80211_hwsim.c              |  198 +-
 drivers/net/wireless/mwl8k.c                       | 2084 ++--
 drivers/net/wireless/orinoco/hw.c                  |   22 +-
 drivers/net/wireless/orinoco/hw.h                  |    2 +-
 drivers/net/wireless/orinoco/main.c                |    7 +-
 drivers/net/wireless/orinoco/orinoco_cs.c          |    9 +-
 drivers/net/wireless/orinoco/orinoco_nortel.c      |    2 +-
 drivers/net/wireless/orinoco/orinoco_pci.c         |    2 +-
 drivers/net/wireless/orinoco/orinoco_plx.c         |    2 +-
 drivers/net/wireless/orinoco/orinoco_tmd.c         |    2 +-
 drivers/net/wireless/p54/main.c                    |   51 +-
 drivers/net/wireless/p54/p54.h                     |    8 +-
 drivers/net/wireless/p54/p54pci.c                  |   76 +-
 drivers/net/wireless/p54/p54pci.h                  |    6 +-
 drivers/net/wireless/p54/p54usb.c                  |    2 +
 drivers/net/wireless/p54/txrx.c                    |    4 +-
 drivers/net/wireless/prism54/islpci_hotplug.c      |    2 +-
 drivers/net/wireless/ray_cs.c                      |   10 +-
 drivers/net/wireless/rndis_wlan.c                  |  388 +-
 drivers/net/wireless/rt2x00/Kconfig                |   71 +-
 drivers/net/wireless/rt2x00/rt2400pci.c            |   12 +-
 drivers/net/wireless/rt2x00/rt2400pci.h            |    1 +
 drivers/net/wireless/rt2x00/rt2500pci.c            |   48 +-
 drivers/net/wireless/rt2x00/rt2500pci.h            |    1 +
 drivers/net/wireless/rt2x00/rt2500usb.c            |   39 +-
 drivers/net/wireless/rt2x00/rt2800.h               |   14 +-
 drivers/net/wireless/rt2x00/rt2800lib.c            |  203 +-
 drivers/net/wireless/rt2x00/rt2800lib.h            |    3 +-
 drivers/net/wireless/rt2x00/rt2800pci.c            |  104 +-
 drivers/net/wireless/rt2x00/rt2800usb.c            |  373 +-
 drivers/net/wireless/rt2x00/rt2800usb.h            |   90 +-
 drivers/net/wireless/rt2x00/rt2x00.h               |   96 +-
 drivers/net/wireless/rt2x00/rt2x00debug.c          |    4 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c            |   10 +-
 drivers/net/wireless/rt2x00/rt2x00mac.c            |   42 +-
 drivers/net/wireless/rt2x00/rt2x00pci.c            |   10 +-
 drivers/net/wireless/rt2x00/rt2x00pci.h            |    1 +
 drivers/net/wireless/rt2x00/rt2x00queue.c          |   79 +-
 drivers/net/wireless/rt2x00/rt2x00queue.h          |    5 +-
 drivers/net/wireless/rt2x00/rt2x00soc.c            |   11 +-
 drivers/net/wireless/rt2x00/rt2x00soc.h            |   10 +-
 drivers/net/wireless/rt2x00/rt61pci.c              |   46 +-
 drivers/net/wireless/rt2x00/rt61pci.h              |    9 +
 drivers/net/wireless/rt2x00/rt73usb.c              |   41 +-
 drivers/net/wireless/rt2x00/rt73usb.h              |    2 +
 drivers/net/wireless/rtl818x/rtl8180.h             |    1 -
 drivers/net/wireless/rtl818x/rtl8180_dev.c         |   37 +-
 drivers/net/wireless/rtl818x/rtl8187.h             |    2 +-
 drivers/net/wireless/rtl818x/rtl8187_dev.c         |   26 +-
 drivers/net/wireless/rtl818x/rtl8187_leds.c        |    6 +-
 drivers/net/wireless/rtl818x/rtl8187_leds.h        |    2 +-
 drivers/net/wireless/wl12xx/Makefile               |    4 +-
 drivers/net/wireless/wl12xx/wl1251.h               |    4 +-
 drivers/net/wireless/wl12xx/wl1251_acx.c           |   69 +
 drivers/net/wireless/wl12xx/wl1251_acx.h           |   87 +
 drivers/net/wireless/wl12xx/wl1251_cmd.c           |   83 +
 drivers/net/wireless/wl12xx/wl1251_cmd.h           |   22 +-
 drivers/net/wireless/wl12xx/wl1251_debugfs.c       |   23 +
 drivers/net/wireless/wl12xx/wl1251_init.c          |    5 +
 drivers/net/wireless/wl12xx/wl1251_init.h          |   47 +
 drivers/net/wireless/wl12xx/wl1251_main.c          |  375 +-
 drivers/net/wireless/wl12xx/wl1251_ps.c            |    9 +-
 drivers/net/wireless/wl12xx/wl1251_rx.c            |    2 +-
 drivers/net/wireless/wl12xx/wl1251_tx.c            |    9 +-
 drivers/net/wireless/wl12xx/wl1251_tx.h            |   17 +
 drivers/net/wireless/wl12xx/wl1271.h               |   67 +-
 drivers/net/wireless/wl12xx/wl1271_acx.c           |  196 +-
 drivers/net/wireless/wl12xx/wl1271_acx.h           |   50 +-
 drivers/net/wireless/wl12xx/wl1271_boot.c          |  102 +-
 drivers/net/wireless/wl12xx/wl1271_cmd.c           |  137 +-
 drivers/net/wireless/wl12xx/wl1271_cmd.h           |   67 +-
 drivers/net/wireless/wl12xx/wl1271_conf.h          |  174 +-
 drivers/net/wireless/wl12xx/wl1271_debugfs.c       |   62 +
 drivers/net/wireless/wl12xx/wl1271_event.c         |   68 +-
 drivers/net/wireless/wl12xx/wl1271_event.h         |    2 +-
 drivers/net/wireless/wl12xx/wl1271_init.c          |   50 +-
 drivers/net/wireless/wl12xx/wl1271_init.h          |    4 +
 drivers/net/wireless/wl12xx/wl1271_io.c            |  213 +
 drivers/net/wireless/wl12xx/wl1271_io.h            |   68 +
 drivers/net/wireless/wl12xx/wl1271_main.c          |  823 +-
 drivers/net/wireless/wl12xx/wl1271_ps.c            |   37 +-
 drivers/net/wireless/wl12xx/wl1271_ps.h            |    3 +-
 drivers/net/wireless/wl12xx/wl1271_reg.h           |   99 -
 drivers/net/wireless/wl12xx/wl1271_rx.c            |   11 +-
 drivers/net/wireless/wl12xx/wl1271_spi.c           |  158 -
 drivers/net/wireless/wl12xx/wl1271_spi.h           |   30 -
 drivers/net/wireless/wl12xx/wl1271_testmode.c      |  283 +
 drivers/net/wireless/wl12xx/wl1271_testmode.h      |   31 +
 drivers/net/wireless/wl12xx/wl1271_tx.c            |   71 +-
 drivers/net/wireless/wl12xx/wl1271_tx.h            |   36 +
 drivers/net/wireless/zd1201.c                      |   14 +-
 drivers/net/wireless/zd1211rw/zd_mac.c             |   10 +-
 drivers/net/wireless/zd1211rw/zd_usb.c             |   14 +-
 drivers/net/xilinx_emaclite.c                      |  384 +-
 drivers/net/yellowfin.c                            |  173 +-
 drivers/net/znet.c                                 |    3 +-
 drivers/pci/Makefile                               |    2 +-
 drivers/pci/iov.c                                  |   15 +
 drivers/pci/quirks.c                               |    1 +
 drivers/pci/vpd.c                                  |   61 +
 drivers/s390/net/qeth_core.h                       |    5 +-
 drivers/s390/net/qeth_core_main.c                  |  169 +-
 drivers/s390/net/qeth_core_mpc.h                   |   44 +-
 drivers/s390/net/qeth_core_sys.c                   |   14 +-
 drivers/s390/net/qeth_l2_main.c                    |   30 +-
 drivers/s390/net/qeth_l3.h                         |    2 +
 drivers/s390/net/qeth_l3_main.c                    |  176 +-
 drivers/s390/net/qeth_l3_sys.c                     |   56 +
 drivers/ssb/driver_chipcommon_pmu.c                |    7 +
 drivers/ssb/driver_mipscore.c                      |    5 +-
 drivers/ssb/ssb_private.h                          |    4 +-
 drivers/staging/arlan/arlan-main.c                 |   25 +-
 drivers/staging/et131x/et131x_netdev.c             |   19 +-
 drivers/staging/netwave/netwave_cs.c               |    8 +-
 drivers/staging/octeon/ethernet.c                  |    2 +-
 drivers/staging/rtl8187se/ieee80211/ieee80211.h    |    9 -
 .../rtl8187se/ieee80211/ieee80211_softmac.c        |   24 +-
 drivers/staging/rtl8187se/r8180_core.c             |    4 +-
 drivers/staging/rtl8192su/ieee80211/ieee80211.h    |   12 +-
 .../staging/rtl8192su/ieee80211/ieee80211_r8192s.h |    2 +-
 drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c |   18 +-
 .../rtl8192su/ieee80211/ieee80211_softmac.c        |   38 +-
 .../staging/rtl8192su/ieee80211/rtl819x_BAProc.c   |    4 +-
 drivers/staging/rtl8192su/r8192U_core.c            |    4 +-
 drivers/staging/slicoss/slicoss.c                  |   16 +-
 drivers/staging/vt6655/device_main.c               |    8 +-
 drivers/staging/vt6656/main_usb.c                  |    8 +-
 drivers/staging/wavelan/wavelan.c                  |   14 +-
 drivers/staging/wavelan/wavelan_cs.c               |   20 +-
 drivers/staging/wlags49_h2/wl_netdev.c             |   30 +-
 drivers/vhost/Kconfig                              |   11 +
 drivers/vhost/Makefile                             |    2 +
 drivers/vhost/net.c                                |  669 +
 drivers/vhost/vhost.c                              | 1104 ++
 drivers/vhost/vhost.h                              |  161 +
 firmware/Makefile                                  |   10 +-
 firmware/WHENCE                                    |    6 +-
 firmware/bnx2/bnx2-mips-06-5.0.0.j3.fw.ihex        | 5841 ---------
 firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex        | 5908 +++++++++
 ....0.j3.fw.ihex => bnx2-mips-09-5.0.0.j9.fw.ihex} | 4519 ++++----
 firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex       |  462 +
 firmware/bnx2/bnx2-rv2p-09-5.0.0.j3.fw.ihex        |  462 -
 firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex     |  499 +
 firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw.ihex      |  498 -
 firmware/bnx2x-e1-5.2.13.0.fw.ihex                 |10191 ++++++++++++++++
 firmware/bnx2x-e1h-5.2.13.0.fw.ihex                |12849 ++++++++++++++++++++
 fs/seq_file.c                                      |  130 +-
 include/linux/Kbuild                               |    1 +
 include/linux/brcmphy.h                            |   11 +
 include/linux/can/dev.h                            |   18 +
 include/linux/can/netlink.h                        |   17 +-
 include/linux/can/platform/ti_hecc.h               |    8 +-
 include/linux/ethtool.h                            |   51 +
 include/linux/icmpv6.h                             |    3 +-
 include/linux/ieee80211.h                          |  108 +-
 include/linux/if_link.h                            |   30 +
 include/linux/if_macvlan.h                         |   84 +
 include/linux/if_packet.h                          |    1 +
 include/linux/if_tun.h                             |   17 +
 include/linux/igmp.h                               |    2 +
 include/linux/in.h                                 |    2 +
 include/linux/inetdevice.h                         |   43 +-
 include/linux/isdn/capilli.h                       |    8 +-
 include/linux/kernelcapi.h                         |   17 +-
 include/linux/llc.h                                |    7 +
 include/linux/miscdevice.h                         |    1 +
 include/linux/net.h                                |    4 +
 include/linux/netdevice.h                          |  186 +-
 include/linux/netfilter.h                          |   63 +-
 include/linux/netfilter/Kbuild                     |    1 +
 include/linux/netfilter/nf_conntrack_common.h      |   22 +
 include/linux/netfilter/nf_conntrack_sip.h         |   19 +-
 include/linux/netfilter/nfnetlink.h                |    8 +-
 include/linux/netfilter/nfnetlink_conntrack.h      |    2 +
 include/linux/netfilter/x_tables.h                 |   70 +-
 include/linux/netfilter/xt_CT.h                    |   17 +
 include/linux/netfilter_arp/arp_tables.h           |   11 +-
 include/linux/netfilter_bridge/ebtables.h          |    2 +-
 include/linux/netfilter_ipv4/ip_tables.h           |   18 +-
 include/linux/netfilter_ipv6/ip6_tables.h          |   17 +-
 include/linux/netpoll.h                            |   11 +-
 include/linux/nl80211.h                            |  145 +-
 include/linux/pci.h                                |   99 +
 include/linux/phy.h                                |    1 +
 include/linux/rculist.h                            |    5 +
 include/linux/rtnetlink.h                          |    2 +
 include/linux/seq_file.h                           |   18 +
 include/linux/skbuff.h                             |   17 +-
 include/linux/snmp.h                               |    1 +
 include/linux/stmmac.h                             |   53 +
 include/linux/sysctl.h                             |    4 -
 include/linux/tcp.h                                |    7 +-
 include/linux/usb/usbnet.h                         |   21 -
 include/linux/vhost.h                              |  130 +
 include/linux/xfrm.h                               |   12 +-
 include/net/bluetooth/hci.h                        |    6 +-
 include/net/bluetooth/hci_core.h                   |    5 +-
 include/net/cfg80211.h                             |  287 +-
 include/net/dst.h                                  |    2 -
 include/net/icmp.h                                 |    2 +-
 include/net/ieee80211_radiotap.h                   |    4 +
 include/net/if_inet6.h                             |    2 +-
 include/net/inet_sock.h                            |    4 +-
 include/net/ip.h                                   |    9 +-
 include/net/ip6_fib.h                              |    4 +-
 include/net/ip_vs.h                                |   38 +-
 include/net/ipcomp.h                               |    2 +-
 include/net/ipv6.h                                 |    8 +-
 include/net/llc.h                                  |   39 +-
 include/net/llc_conn.h                             |    2 +
 include/net/mac80211.h                             |  386 +-
 include/net/neighbour.h                            |    3 +-
 include/net/net_namespace.h                        |    2 +
 include/net/netfilter/nf_conntrack.h               |   12 +-
 include/net/netfilter/nf_conntrack_core.h          |    3 +-
 include/net/netfilter/nf_conntrack_ecache.h        |   58 +-
 include/net/netfilter/nf_conntrack_expect.h        |   16 +-
 include/net/netfilter/nf_conntrack_extend.h        |    2 +
 include/net/netfilter/nf_conntrack_helper.h        |    8 +-
 include/net/netfilter/nf_conntrack_l4proto.h       |    4 +-
 include/net/netfilter/nf_conntrack_zones.h         |   25 +
 include/net/netfilter/nf_nat_helper.h              |   32 +-
 include/net/netlink.h                              |    2 +-
 include/net/netns/conntrack.h                      |    2 +-
 include/net/netns/core.h                           |    2 +-
 include/net/netns/ipv4.h                           |    2 +
 include/net/netns/ipv6.h                           |    2 +
 include/net/netns/packet.h                         |    4 +-
 include/net/phonet/pep.h                           |    3 +
 include/net/pkt_sched.h                            |    1 +
 include/net/regulatory.h                           |    1 +
 include/net/request_sock.h                         |    2 +
 include/net/route.h                                |    2 +-
 include/net/rtnetlink.h                            |    2 +
 include/net/sch_generic.h                          |   19 +
 include/net/snmp.h                                 |   14 +-
 include/net/sock.h                                 |   17 +-
 include/net/tcp.h                                  |   36 +-
 include/net/xfrm.h                                 |   82 +-
 include/pcmcia/device_id.h                         |    5 +
 kernel/taskstats.c                                 |    6 +-
 lib/vsprintf.c                                     |   48 +-
 mm/mmu_context.c                                   |    3 +
 net/8021q/vlan.c                                   |    4 +-
 net/8021q/vlan.h                                   |    2 +-
 net/8021q/vlan_core.c                              |    2 +
 net/8021q/vlan_dev.c                               |    9 +-
 net/8021q/vlanproc.c                               |    2 +-
 net/appletalk/atalk_proc.c                         |   30 +-
 net/atm/addr.c                                     |    2 +-
 net/atm/atm_misc.c                                 |   40 +-
 net/atm/atm_sysfs.c                                |   27 +-
 net/atm/br2684.c                                   |   90 +-
 net/atm/clip.c                                     |   86 +-
 net/atm/common.c                                   |  386 +-
 net/atm/ioctl.c                                    |  196 +-
 net/atm/lec.c                                      |  599 +-
 net/atm/mpc.c                                      |  540 +-
 net/atm/mpoa_caches.c                              |  190 +-
 net/atm/mpoa_proc.c                                |   89 +-
 net/atm/pppoatm.c                                  |   28 +-
 net/atm/proc.c                                     |   83 +-
 net/atm/pvc.c                                      |   43 +-
 net/atm/raw.c                                      |   26 +-
 net/atm/resources.c                                |  418 +-
 net/atm/signaling.c                                |  219 +-
 net/atm/svc.c                                      |  258 +-
 net/ax25/af_ax25.c                                 |   18 +-
 net/ax25/ax25_uid.c                                |   25 +-
 net/bluetooth/bnep/netdev.c                        |    6 +-
 net/bluetooth/cmtp/capi.c                          |   37 +-
 net/bluetooth/hci_core.c                           |   12 +-
 net/bluetooth/hci_event.c                          |    1 +
 net/bluetooth/hci_sock.c                           |    4 +-
 net/bluetooth/hci_sysfs.c                          |  122 +-
 net/bridge/Kconfig                                 |   13 +
 net/bridge/Makefile                                |    2 +
 net/bridge/br_device.c                             |   23 +-
 net/bridge/br_forward.c                            |  150 +-
 net/bridge/br_if.c                                 |    8 +-
 net/bridge/br_input.c                              |   39 +-
 net/bridge/br_multicast.c                          | 1304 ++
 net/bridge/br_private.h                            |  169 +-
 net/bridge/br_stp.c                                |    2 +
 net/bridge/br_stp_if.c                             |    1 +
 net/bridge/br_sysfs_br.c                           |  281 +
 net/bridge/br_sysfs_if.c                           |   18 +
 net/bridge/netfilter/ebt_802_3.c                   |    2 +-
 net/bridge/netfilter/ebt_arp.c                     |    2 +-
 net/bridge/netfilter/ebt_arpreply.c                |    2 +-
 net/bridge/netfilter/ebt_dnat.c                    |    2 +-
 net/bridge/netfilter/ebt_ip.c                      |    2 +-
 net/bridge/netfilter/ebt_ip6.c                     |    2 +-
 net/bridge/netfilter/ebt_limit.c                   |   18 +-
 net/bridge/netfilter/ebt_log.c                     |    2 +-
 net/bridge/netfilter/ebt_mark.c                    |   33 +-
 net/bridge/netfilter/ebt_mark_m.c                  |   39 +-
 net/bridge/netfilter/ebt_nflog.c                   |    2 +-
 net/bridge/netfilter/ebt_pkttype.c                 |    2 +-
 net/bridge/netfilter/ebt_redirect.c                |    2 +-
 net/bridge/netfilter/ebt_snat.c                    |    2 +-
 net/bridge/netfilter/ebt_stp.c                     |    2 +-
 net/bridge/netfilter/ebt_ulog.c                    |    2 +-
 net/bridge/netfilter/ebt_vlan.c                    |    2 +-
 net/bridge/netfilter/ebtable_broute.c              |    2 +-
 net/bridge/netfilter/ebtable_filter.c              |    2 +-
 net/bridge/netfilter/ebtable_nat.c                 |    2 +-
 net/bridge/netfilter/ebtables.c                    | 1241 ++-
 net/can/af_can.c                                   |  124 +-
 net/can/af_can.h                                   |    4 +-
 net/can/proc.c                                     |   93 +-
 net/core/dev.c                                     |  284 +-
 net/core/dev_mcast.c                               |    2 +
 net/core/drop_monitor.c                            |    1 -
 net/core/ethtool.c                                 |  386 +-
 net/core/fib_rules.c                               |    2 +-
 net/core/filter.c                                  |    2 +
 net/core/neighbour.c                               |   18 +-
 net/core/netpoll.c                                 |  169 +-
 net/core/pktgen.c                                  |    3 +-
 net/core/rtnetlink.c                               |  127 +-
 net/core/scm.c                                     |    2 +
 net/core/sock.c                                    |   16 +-
 net/dcb/dcbnl.c                                    |   16 +-
 net/dccp/ccid.c                                    |    9 +-
 net/dccp/ipv4.c                                    |    4 +-
 net/dccp/ipv6.c                                    |    4 +-
 net/dccp/proto.c                                   |    7 +-
 net/ethernet/eth.c                                 |    6 +-
 net/ipv4/af_inet.c                                 |   46 +-
 net/ipv4/ah4.c                                     |    2 +-
 net/ipv4/arp.c                                     |   58 +-
 net/ipv4/devinet.c                                 |   30 +-
 net/ipv4/esp4.c                                    |    2 +-
 net/ipv4/fib_frontend.c                            |    4 +-
 net/ipv4/fib_semantics.c                           |   80 +-
 net/ipv4/icmp.c                                    |    2 +-
 net/ipv4/igmp.c                                    |   87 +-
 net/ipv4/inet_connection_sock.c                    |    2 +
 net/ipv4/ip_fragment.c                             |   39 +-
 net/ipv4/ip_gre.c                                  |   25 +-
 net/ipv4/ip_sockglue.c                             |   14 +-
 net/ipv4/ipcomp.c                                  |   11 +-
 net/ipv4/ipip.c                                    |   20 +-
 net/ipv4/ipmr.c                                    |    3 -
 net/ipv4/netfilter/arp_tables.c                    |  386 +-
 net/ipv4/netfilter/arptable_filter.c               |   95 +-
 net/ipv4/netfilter/ip_tables.c                     |  557 +-
 net/ipv4/netfilter/ipt_CLUSTERIP.c                 |   14 +-
 net/ipv4/netfilter/ipt_ULOG.c                      |    4 +-
 net/ipv4/netfilter/iptable_filter.c                |  124 +-
 net/ipv4/netfilter/iptable_mangle.c                |  166 +-
 net/ipv4/netfilter/iptable_raw.c                   |   96 +-
 net/ipv4/netfilter/iptable_security.c              |  117 +-
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c     |    3 +-
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c       |   11 +-
 net/ipv4/netfilter/nf_defrag_ipv4.c                |   19 +-
 net/ipv4/netfilter/nf_nat_core.c                   |   24 +-
 net/ipv4/netfilter/nf_nat_ftp.c                    |  105 +-
 net/ipv4/netfilter/nf_nat_helper.c                 |   39 +-
 net/ipv4/netfilter/nf_nat_pptp.c                   |    3 +-
 net/ipv4/netfilter/nf_nat_rule.c                   |   41 +-
 net/ipv4/netfilter/nf_nat_sip.c                    |  154 +-
 net/ipv4/netfilter/nf_nat_snmp_basic.c             |   31 +-
 net/ipv4/proc.c                                    |   32 +-
 net/ipv4/route.c                                   |    9 +-
 net/ipv4/syncookies.c                              |    3 +-
 net/ipv4/sysctl_net_ipv4.c                         |   14 +
 net/ipv4/tcp.c                                     |   65 +-
 net/ipv4/tcp_input.c                               |   12 +
 net/ipv4/tcp_ipv4.c                                |   25 +-
 net/ipv4/tcp_output.c                              |   22 +-
 net/ipv4/tcp_timer.c                               |   27 +-
 net/ipv4/udp.c                                     |   19 +-
 net/ipv4/udplite.c                                 |    4 +-
 net/ipv6/addrconf.c                                |   94 +-
 net/ipv6/addrconf_core.c                           |    2 +-
 net/ipv6/af_inet6.c                                |   32 +-
 net/ipv6/ah6.c                                     |    2 +-
 net/ipv6/anycast.c                                 |    2 +-
 net/ipv6/esp6.c                                    |    2 +-
 net/ipv6/exthdrs.c                                 |    2 +-
 net/ipv6/fib6_rules.c                              |    4 +-
 net/ipv6/icmp.c                                    |   12 +-
 net/ipv6/ip6_fib.c                                 |   52 +-
 net/ipv6/ip6_flowlabel.c                           |    9 +-
 net/ipv6/ip6_input.c                               |    3 +-
 net/ipv6/ip6_output.c                              |   21 +-
 net/ipv6/ip6_tunnel.c                              |   43 +-
 net/ipv6/ipcomp6.c                                 |   15 +-
 net/ipv6/mcast.c                                   |   32 +-
 net/ipv6/mip6.c                                    |    2 +-
 net/ipv6/ndisc.c                                   |    7 +-
 net/ipv6/netfilter/ip6_tables.c                    |  559 +-
 net/ipv6/netfilter/ip6t_REJECT.c                   |    2 +-
 net/ipv6/netfilter/ip6table_filter.c               |  113 +-
 net/ipv6/netfilter/ip6table_mangle.c               |  141 +-
 net/ipv6/netfilter/ip6table_raw.c                  |   86 +-
 net/ipv6/netfilter/ip6table_security.c             |  109 +-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c     |   14 +-
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c     |   11 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c            |   15 +-
 net/ipv6/proc.c                                    |   39 +-
 net/ipv6/raw.c                                     |    4 +-
 net/ipv6/reassembly.c                              |   27 +-
 net/ipv6/route.c                                   |   12 +-
 net/ipv6/sit.c                                     |   25 +-
 net/ipv6/syncookies.c                              |    3 +-
 net/ipv6/sysctl_net_ipv6.c                         |    4 +-
 net/ipv6/tcp_ipv6.c                                |   22 +-
 net/ipv6/tunnel6.c                                 |    4 +-
 net/ipv6/udp.c                                     |   22 +-
 net/ipv6/udplite.c                                 |    4 +-
 net/ipv6/xfrm6_input.c                             |    2 +-
 net/ipv6/xfrm6_output.c                            |    2 +-
 net/ipv6/xfrm6_tunnel.c                            |  194 +-
 net/ipx/ipx_proc.c                                 |   90 +-
 net/irda/ircomm/ircomm_tty.c                       |    6 -
 net/irda/irlan/irlan_common.c                      |   28 +-
 net/irda/irlan/irlan_eth.c                         |    5 +-
 net/irda/irnetlink.c                               |    2 +-
 net/key/af_key.c                                   |  160 +-
 net/llc/af_llc.c                                   |   64 +-
 net/llc/llc_conn.c                                 |  143 +-
 net/llc/llc_core.c                                 |   53 +-
 net/llc/llc_output.c                               |   45 +-
 net/llc/llc_proc.c                                 |   69 +-
 net/llc/llc_sap.c                                  |  111 +-
 net/mac80211/Kconfig                               |   12 -
 net/mac80211/Makefile                              |    4 +-
 net/mac80211/agg-rx.c                              |   15 +-
 net/mac80211/agg-tx.c                              |   38 +-
 net/mac80211/cfg.c                                 |  198 +-
 net/mac80211/debugfs.c                             |  127 +
 net/mac80211/debugfs_key.c                         |    2 +-
 net/mac80211/debugfs_netdev.c                      |  212 +-
 net/mac80211/debugfs_netdev.h                      |    9 +-
 net/mac80211/debugfs_sta.c                         |   88 +-
 net/mac80211/driver-ops.h                          |  169 +-
 net/mac80211/driver-trace.h                        |  174 +-
 net/mac80211/ht.c                                  |   53 +-
 net/mac80211/ibss.c                                |  125 +-
 net/mac80211/ieee80211_i.h                         |  215 +-
 net/mac80211/iface.c                               |  108 +-
 net/mac80211/key.c                                 |   10 +-
 net/mac80211/key.h                                 |    8 +-
 net/mac80211/main.c                                |   74 +-
 net/mac80211/mesh.c                                |    6 +-
 net/mac80211/mesh_hwmp.c                           |   20 +-
 net/mac80211/mesh_pathtbl.c                        |    6 +-
 net/mac80211/mesh_plink.c                          |   23 +-
 net/mac80211/mlme.c                                | 1317 +--
 net/mac80211/offchannel.c                          |  170 +
 net/mac80211/pm.c                                  |   18 +-
 net/mac80211/rate.c                                |   90 +-
 net/mac80211/rate.h                                |   14 +-
 net/mac80211/rc80211_pid_algo.c                    |    8 +-
 net/mac80211/rx.c                                  |  473 +-
 net/mac80211/scan.c                                |  249 +-
 net/mac80211/spectmgmt.c                           |    4 +-
 net/mac80211/sta_info.c                            |  777 +-
 net/mac80211/sta_info.h                            |   68 +-
 net/mac80211/status.c                              |  107 +-
 net/mac80211/tkip.c                                |   47 +-
 net/mac80211/tx.c                                  |  376 +-
 net/mac80211/util.c                                |  319 +-
 net/mac80211/wep.c                                 |   17 +-
 net/mac80211/wme.c                                 |    2 +-
 net/mac80211/work.c                                | 1100 ++
 net/mac80211/wpa.c                                 |   57 +-
 net/netfilter/Kconfig                              |   25 +
 net/netfilter/Makefile                             |    1 +
 net/netfilter/ipvs/Kconfig                         |   11 +
 net/netfilter/ipvs/Makefile                        |    1 +
 net/netfilter/ipvs/ip_vs_conn.c                    |   42 +-
 net/netfilter/ipvs/ip_vs_core.c                    |   67 +-
 net/netfilter/ipvs/ip_vs_ctl.c                     |   13 +-
 net/netfilter/ipvs/ip_vs_ftp.c                     |    2 +-
 net/netfilter/ipvs/ip_vs_lblcr.c                   |   44 +-
 net/netfilter/ipvs/ip_vs_proto.c                   |    3 +
 net/netfilter/ipvs/ip_vs_proto_sctp.c              | 1183 ++
 net/netfilter/ipvs/ip_vs_sync.c                    |   14 +
 net/netfilter/ipvs/ip_vs_xmit.c                    |   10 +-
 net/netfilter/nf_conntrack_core.c                  |  164 +-
 net/netfilter/nf_conntrack_expect.c                |   31 +-
 net/netfilter/nf_conntrack_extend.c                |    1 -
 net/netfilter/nf_conntrack_h323_main.c             |    3 +-
 net/netfilter/nf_conntrack_helper.c                |   44 +-
 net/netfilter/nf_conntrack_netlink.c               |  230 +-
 net/netfilter/nf_conntrack_pptp.c                  |   14 +-
 net/netfilter/nf_conntrack_proto_dccp.c            |    5 +-
 net/netfilter/nf_conntrack_proto_gre.c             |    2 +-
 net/netfilter/nf_conntrack_proto_sctp.c            |    2 +-
 net/netfilter/nf_conntrack_proto_tcp.c             |    4 +-
 net/netfilter/nf_conntrack_proto_udp.c             |    6 +-
 net/netfilter/nf_conntrack_proto_udplite.c         |    4 +-
 net/netfilter/nf_conntrack_sip.c                   |  330 +-
 net/netfilter/nf_conntrack_standalone.c            |    6 +
 net/netfilter/nf_queue.c                           |    2 +-
 net/netfilter/nfnetlink.c                          |   65 +-
 net/netfilter/nfnetlink_log.c                      |    5 +-
 net/netfilter/nfnetlink_queue.c                    |    7 +-
 net/netfilter/x_tables.c                           |   80 +-
 net/netfilter/xt_CT.c                              |  164 +
 net/netfilter/xt_NFQUEUE.c                         |    6 +-
 net/netfilter/xt_RATEEST.c                         |    7 +-
 net/netfilter/xt_TCPMSS.c                          |   30 +-
 net/netfilter/xt_connlimit.c                       |   27 +-
 net/netfilter/xt_hashlimit.c                       |  215 +-
 net/netfilter/xt_limit.c                           |    4 +-
 net/netfilter/xt_osf.c                             |    4 +-
 net/netfilter/xt_recent.c                          |  168 +-
 net/netfilter/xt_repldata.h                        |   35 +
 net/netlabel/netlabel_domainhash.c                 |    1 -
 net/netlabel/netlabel_unlabeled.c                  |    3 -
 net/netlink/af_netlink.c                           |    7 +-
 net/netlink/genetlink.c                            |    4 +-
 net/netrom/af_netrom.c                             |   21 +-
 net/netrom/nr_route.c                              |   53 +-
 net/packet/Kconfig                                 |   10 -
 net/packet/af_packet.c                             |  300 +-
 net/phonet/datagram.c                              |    6 +-
 net/phonet/pep-gprs.c                              |    4 +-
 net/phonet/pep.c                                   |   29 +-
 net/phonet/pn_dev.c                                |    4 +-
 net/rds/tcp_connect.c                              |    7 +-
 net/rds/tcp_listen.c                               |    6 +-
 net/rds/tcp_send.c                                 |    4 +-
 net/rose/af_rose.c                                 |   22 +-
 net/sched/sch_api.c                                |    1 +
 net/sched/sch_fifo.c                               |   34 +
 net/sctp/bind_addr.c                               |    1 -
 net/sctp/ipv6.c                                    |    1 -
 net/sctp/proc.c                                    |    4 +-
 net/sctp/protocol.c                                |    6 +-
 net/sctp/socket.c                                  |    2 +-
 net/sunrpc/rpc_pipe.c                              |    2 +-
 net/sysctl_net.c                                   |    4 +-
 net/tipc/Kconfig                                   |   75 +-
 net/tipc/core.c                                    |   10 +-
 net/unix/af_unix.c                                 |    6 +-
 net/unix/sysctl_net_unix.c                         |    2 +-
 net/wimax/op-msg.c                                 |    3 +-
 net/wimax/op-reset.c                               |    3 +-
 net/wimax/op-rfkill.c                              |    3 +-
 net/wimax/op-state-get.c                           |    3 +-
 net/wimax/stack.c                                  |    3 +-
 net/wireless/.gitignore                            |    1 +
 net/wireless/Kconfig                               |   13 +-
 net/wireless/Makefile                              |    6 +
 net/wireless/chan.c                                |   41 +-
 net/wireless/core.c                                |   59 +-
 net/wireless/core.h                                |   20 +-
 net/wireless/db.txt                                |   17 +
 net/wireless/genregdb.awk                          |  118 +
 net/wireless/lib80211_crypt_ccmp.c                 |    2 +-
 net/wireless/lib80211_crypt_tkip.c                 |   23 +-
 net/wireless/mlme.c                                |  214 +-
 net/wireless/nl80211.c                             |  866 ++-
 net/wireless/nl80211.h                             |   23 +
 net/wireless/radiotap.c                            |  305 +-
 net/wireless/reg.c                                 |  687 +-
 net/wireless/reg.h                                 |   29 +
 net/wireless/regdb.h                               |    7 +
 net/wireless/scan.c                                |  158 +-
 net/wireless/sme.c                                 |   41 +
 net/wireless/sysfs.c                               |   20 +
 net/wireless/util.c                                |  137 +-
 net/wireless/wext-compat.c                         |   49 +-
 net/wireless/wext-proc.c                           |    4 +-
 net/x25/af_x25.c                                   |   24 +-
 net/x25/x25_proc.c                                 |  114 +-
 net/xfrm/xfrm_input.c                              |    2 +-
 net/xfrm/xfrm_ipcomp.c                             |   16 +-
 net/xfrm/xfrm_policy.c                             |   43 +-
 net/xfrm/xfrm_proc.c                               |    6 +-
 net/xfrm/xfrm_state.c                              |   88 +-
 net/xfrm/xfrm_sysctl.c                             |    4 +-
 net/xfrm/xfrm_user.c                               |  111 +-
 1214 files changed, 113853 insertions(+), 39098 deletions(-)
 create mode 100755 Documentation/networking/ixgbevf.txt
 create mode 100644 Documentation/networking/tcp-thin.txt
 create mode 100644 Documentation/powerpc/dts-bindings/fsl/can.txt
 create mode 100644 drivers/net/can/sja1000/plx_pci.c
 create mode 100644 drivers/net/greth.c
 create mode 100644 drivers/net/greth.h
 create mode 100644 drivers/net/irda/sh_sir.c
 delete mode 100644 drivers/net/isa-skeleton.c
 create mode 100644 drivers/net/ixgbe/ixgbe_mbx.c
 create mode 100644 drivers/net/ixgbe/ixgbe_mbx.h
 create mode 100644 drivers/net/ixgbe/ixgbe_sriov.c
 create mode 100644 drivers/net/ixgbe/ixgbe_sriov.h
 create mode 100644 drivers/net/ixgbevf/Makefile
 create mode 100644 drivers/net/ixgbevf/defines.h
 create mode 100644 drivers/net/ixgbevf/ethtool.c
 create mode 100644 drivers/net/ixgbevf/ixgbevf.h
 create mode 100644 drivers/net/ixgbevf/ixgbevf_main.c
 create mode 100644 drivers/net/ixgbevf/mbx.c
 create mode 100644 drivers/net/ixgbevf/mbx.h
 create mode 100644 drivers/net/ixgbevf/regs.h
 create mode 100644 drivers/net/ixgbevf/vf.c
 create mode 100644 drivers/net/ixgbevf/vf.h
 create mode 100644 drivers/net/ksz884x.c
 create mode 100644 drivers/net/macvtap.c
 create mode 100644 drivers/net/qlcnic/Makefile
 create mode 100644 drivers/net/qlcnic/qlcnic.h
 create mode 100644 drivers/net/qlcnic/qlcnic_ctx.c
 create mode 100644 drivers/net/qlcnic/qlcnic_ethtool.c
 create mode 100644 drivers/net/qlcnic/qlcnic_hdr.h
 create mode 100644 drivers/net/qlcnic/qlcnic_hw.c
 create mode 100644 drivers/net/qlcnic/qlcnic_init.c
 create mode 100644 drivers/net/qlcnic/qlcnic_main.c
 rename drivers/net/stmmac/{mac100.c => dwmac100.c} (68%)
 rename drivers/net/stmmac/{mac100.h => dwmac100.h} (100%)
 rename drivers/net/stmmac/{gmac.h => dwmac1000.h} (95%)
 create mode 100644 drivers/net/stmmac/dwmac1000_core.c
 rename drivers/net/stmmac/{gmac.c => dwmac1000_dma.c} (53%)
 create mode 100644 drivers/net/stmmac/dwmac_dma.h
 create mode 100644 drivers/net/stmmac/dwmac_lib.c
 create mode 100644 drivers/net/wireless/ath/ath9k/gpio.c
 create mode 100644 drivers/net/wireless/ath/ath9k/init.c
 delete mode 100644 drivers/net/wireless/iwlwifi/iwl-spectrum.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_io.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_io.h
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_testmode.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_testmode.h
 create mode 100644 drivers/pci/vpd.c
 create mode 100644 drivers/vhost/Kconfig
 create mode 100644 drivers/vhost/Makefile
 create mode 100644 drivers/vhost/net.c
 create mode 100644 drivers/vhost/vhost.c
 create mode 100644 drivers/vhost/vhost.h
 delete mode 100644 firmware/bnx2/bnx2-mips-06-5.0.0.j3.fw.ihex
 create mode 100644 firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex
 rename firmware/bnx2/{bnx2-mips-09-5.0.0.j3.fw.ihex => bnx2-mips-09-5.0.0.j9.fw.ihex} (63%)
 create mode 100644 firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex
 delete mode 100644 firmware/bnx2/bnx2-rv2p-09-5.0.0.j3.fw.ihex
 create mode 100644 firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex
 delete mode 100644 firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw.ihex
 create mode 100644 firmware/bnx2x-e1-5.2.13.0.fw.ihex
 create mode 100644 firmware/bnx2x-e1h-5.2.13.0.fw.ihex
 create mode 100644 include/linux/netfilter/xt_CT.h
 create mode 100644 include/linux/stmmac.h
 create mode 100644 include/linux/vhost.h
 create mode 100644 include/net/netfilter/nf_conntrack_zones.h
 create mode 100644 net/bridge/br_multicast.c
 create mode 100644 net/mac80211/offchannel.c
 create mode 100644 net/mac80211/work.c
 create mode 100644 net/netfilter/ipvs/ip_vs_proto_sctp.c
 create mode 100644 net/netfilter/xt_CT.c
 create mode 100644 net/netfilter/xt_repldata.h
 create mode 100644 net/wireless/.gitignore
 create mode 100644 net/wireless/db.txt
 create mode 100644 net/wireless/genregdb.awk
 create mode 100644 net/wireless/regdb.h

^ permalink raw reply

* Re: [RFC][PATCH] af_unix: Add peer inode to /proc/net/unix
From: Changli Gao @ 2010-03-01  7:05 UTC (permalink / raw)
  To: Kenan Kalajdzic; +Cc: netdev
In-Reply-To: <20100301045206.GB496@home.unix.ba>

On Mon, Mar 1, 2010 at 12:52 PM, Kenan Kalajdzic <kenan@unix.ba> wrote:
>  net/unix/af_unix.c |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index f255119..e778428 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -2157,7 +2157,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
>                seq_puts(seq, "Num       RefCount Protocol Flags    Type St "
>                         "Inode Path\n");
>        else {
> -               struct sock *s = v;
> +               struct sock *s = v, *peer;
>                struct unix_sock *u = unix_sk(s);
>                unix_state_lock(s);
>
> @@ -2186,6 +2186,13 @@ static int unix_seq_show(struct seq_file *seq, void *v)
>                        }
>                        for ( ; i < len; i++)
>                                seq_putc(seq, u->addr->name->sun_path[i]);
> +               } else {
> +                       peer = unix_peer(s);
> +                       if (peer) {
> +                               unix_state_lock(peer);
> +                               seq_printf(seq, " peer=%lu", sock_i_ino(peer));
> +                               unix_state_unlock(peer);
> +                       }
>                }
>                unix_state_unlock(s);
>                seq_putc(seq, '\n');

If there are two read requests, the system maybe locked up. please use
unix_state_double_lock()/unix_state_double_unlock(), instead. And the
file isn't consistent with the old one. You'd better use a column
title "Peer" instead of "peer=".

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* Re: [net-next-2.6 PATCH 3/3] ixgbe: Do not allocate too many netdev txqueues
From: Peter P Waskiewicz Jr @ 2010-03-01  7:21 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Kirsher, Jeffrey T, davem@davemloft.net, netdev@vger.kernel.org,
	gospo@redhat.com, Fastabend, John R
In-Reply-To: <1267329420.9082.28.camel@edumazet-laptop>

On Sat, 2010-02-27 at 20:57 -0700, Eric Dumazet wrote:
> Le samedi 27 février 2010 à 17:02 -0800, Peter P Waskiewicz Jr a écrit :
> > On Fri, 2010-02-26 at 06:04 -0800, Eric Dumazet wrote:
> > > Le vendredi 26 février 2010 à 01:15 -0800, Jeff Kirsher a écrit :
> > > > +	if (ii->mac == ixgbe_mac_82598EB)
> > > > +		indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
> > > > +	else
> > > > +		indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
> > > > +
> > > > +	indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
> > > > +#ifdef IXGBE_FCOE
> > > > +	indices += min_t(unsigned int, num_possible_cpus(),
> > > > +			 IXGBE_MAX_FCOE_INDICES);
> > > > +#endif
> > > > +	indices = min_t(unsigned int, indices, MAX_TX_QUEUES);
> > > > +	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
> > > >  	if (!netdev) {
> > > >  		err = -ENOMEM;
> > > >  		goto err_alloc_etherdev;
> > > > 
> > > 
> > > Thanks Jeff, but what is the reason for limiting to MAX_TX_QUEUES ?
> > > Is it a hardware issue ?
> > > 
> > 
> > MAX_TX_QUEUES is 128, which is the maximum the 82599 device supports in
> > hardware (82598 supports 32 Tx queues).  I'm not sure why you'd ever
> > want to have more Tx queues than what you have in the network device.
> 
> I was not sure MAX_TX_QUEUES capping was still necessary after the
> block :
> 
> if (ii->mac == ixgbe_mac_82598EB)
>           indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
> else
>           indices = min_t(unsigned int, indices,
> IXGBE_MAX_FDIR_INDICES);
> 
> indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
> #ifdef IXGBE_FCOE
> 	indices += min_t(unsigned int, num_possible_cpus(),
>                     IXGBE_MAX_FCOE_INDICES);
> #endif
> 
> So I asked to be sure that MAX_TX_QUEUES was not a leftover from the
> previous default allocation.
> 
> Thanks

I see what you're getting at now.  The most we could have from this
codepath is 72 indices for 82599, and 24 for 82598, so yeah, this is
probably unneeded.

We can get the patch cleaned up.

Cheers,
-PJ


^ permalink raw reply

* Re: [net-next-2.6 PATCH] infiniband: convert to use netdev_for_each_mc_addr
From: Or Gerlitz @ 2010-03-01  7:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Jiri Pirko, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, Moni Shoua
In-Reply-To: <20100227184410.GB13231-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Jason Gunthorpe wrote:
> Jiri Pirko wrote:
>> when bonding changes it's type, flush mc addresses and start over.

> There was a patch posted that tried to do something like what you are describing

Indeed, Jason, commit 75c785 "bonding: remap muticast addresses without using dev_close() and dev_open()" from Moni Shoua <monis-smomgflXvOZWk0Htik3J/w@public.gmane.org> does exactly that, isn't it?

Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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

* Re: [net-next-2.6 PATCH 3/3] ixgbe: Do not allocate too many netdev txqueues
From: John Fastabend @ 2010-03-01  7:53 UTC (permalink / raw)
  To: Waskiewicz Jr, Peter P
  Cc: Eric Dumazet, Kirsher, Jeffrey T, davem@davemloft.net,
	netdev@vger.kernel.org, gospo@redhat.com
In-Reply-To: <1267428097.2052.772.camel@localhost>

Waskiewicz Jr, Peter P wrote:
> On Sat, 2010-02-27 at 20:57 -0700, Eric Dumazet wrote:
>   
>> Le samedi 27 février 2010 à 17:02 -0800, Peter P Waskiewicz Jr a écrit :
>>     
>>> On Fri, 2010-02-26 at 06:04 -0800, Eric Dumazet wrote:
>>>       
>>>> Le vendredi 26 février 2010 à 01:15 -0800, Jeff Kirsher a écrit :
>>>>         
>>>>> +	if (ii->mac == ixgbe_mac_82598EB)
>>>>> +		indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
>>>>> +	else
>>>>> +		indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
>>>>> +
>>>>> +	indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
>>>>> +#ifdef IXGBE_FCOE
>>>>> +	indices += min_t(unsigned int, num_possible_cpus(),
>>>>> +			 IXGBE_MAX_FCOE_INDICES);
>>>>> +#endif
>>>>> +	indices = min_t(unsigned int, indices, MAX_TX_QUEUES);
>>>>> +	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
>>>>>  	if (!netdev) {
>>>>>  		err = -ENOMEM;
>>>>>  		goto err_alloc_etherdev;
>>>>>
>>>>>           
>>>> Thanks Jeff, but what is the reason for limiting to MAX_TX_QUEUES ?
>>>> Is it a hardware issue ?
>>>>
>>>>         
>>> MAX_TX_QUEUES is 128, which is the maximum the 82599 device supports in
>>> hardware (82598 supports 32 Tx queues).  I'm not sure why you'd ever
>>> want to have more Tx queues than what you have in the network device.
>>>       
>> I was not sure MAX_TX_QUEUES capping was still necessary after the
>> block :
>>
>> if (ii->mac == ixgbe_mac_82598EB)
>>           indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
>> else
>>           indices = min_t(unsigned int, indices,
>> IXGBE_MAX_FDIR_INDICES);
>>
>> indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
>> #ifdef IXGBE_FCOE
>> 	indices += min_t(unsigned int, num_possible_cpus(),
>>                     IXGBE_MAX_FCOE_INDICES);
>> #endif
>>
>> So I asked to be sure that MAX_TX_QUEUES was not a leftover from the
>> previous default allocation.
>>
>> Thanks
>>     
>
> I see what you're getting at now.  The most we could have from this
> codepath is 72 indices for 82599, and 24 for 82598, so yeah, this is
> probably unneeded.
>
> We can get the patch cleaned up.
>
> Cheers,
> -PJ
>
>   
Thanks for catching this.  I'll submit another patch to clean this up.  
Additionally, we can probably remove MAX_TX_QUEUES all together and use 
the above values instead.  No reason to have a tx_ring array larger then 
we are ever going to use.

thanks
john.


^ permalink raw reply

* Re: 2.6.33 dies on modprobe
From: M G Berberich @ 2010-03-01  9:07 UTC (permalink / raw)
  To: Américo Wang; +Cc: linux-kernel, Linux Kernel Network Developers
In-Reply-To: <2375c9f91002282022n29e83858jd8cadbb2e664b436@mail.gmail.com>

Hello,

Am Montag, den 01. März schrieb Américo Wang:
> On Mon, Mar 1, 2010 at 6:12 AM, M G Berberich
> <berberic@fmi.uni-passau.de> wrote:

> > I tried to build a 2.6.33 kernel but on boot it dies on modprobe
> > (kernel-Oops). This might be the result of faulty config, but I'm
> > totaly clueless what's the fault.
> >
> > The kernel starts up fine and mounts the root-filesystem, but then
> > dies on the first modprobe executed. I can boot it with init=/bin/bash
> > and get a working bash (until I do modprobe on any module).
> >
> > System is a Gigabyte M55S-S3 rev 2.0 (nForce 550) with an AMD Athlon64
> > X2 5000+ and amd64-kernel architecture. kernel-sources are from
> > kernel.org.

> It seems something is wrong with forcedeth code or PCI code.
> Adding some Cc's.

I don't think it's forcedeth. forcedeth just happens to be the first
module that get's loaded in startup. It crashes with any other module
too (I tried ohci_hcd). 

To repeat myself: This might be the result of faulty config

	MfG
	bmg

-- 
„Des is völlig wurscht, was heut beschlos- | M G Berberich
 sen wird: I bin sowieso dagegn!“          | berberic@fmi.uni-passau.de
(SPD-Stadtrat Kurt Schindler; Regensburg)  | www.fmi.uni-passau.de/~berberic

^ permalink raw reply

* NETIF_F_FRAGLIST and NETIF_F_SG difference
From: raj ravi @ 2010-03-01 11:02 UTC (permalink / raw)
  To: netdev

Hi,
http://lxr.linux.no/#linux+v2.6.33/include/linux/netdevice.h
In include/linux/netdevice.h I can see two definiton for "Scatter
Gather IO" namely NETIF_F_FRAGLIST  and NETIF_F_SG

Please let me know the difference between the two.... if there is no
difference why two Macros ??


#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
#define NETIF_F_IPV6_CSUM 16 /* Can checksum TCP/UDP over IPV6 */
#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */

Thx!
Kavi

^ permalink raw reply

* [net-next-2.6 PATCH] virtio_net: remove forgotten assignment
From: Jiri Pirko @ 2010-03-01 11:22 UTC (permalink / raw)
  To: netdev; +Cc: davem

This is no longer needed. I missed to remove this in
567ec874d15b478c8eda7e9a5d2dcb05f13f1fb5

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/virtio_net.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e6095f3..25dc77c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -775,7 +775,6 @@ static void virtnet_set_rx_mode(struct net_device *dev)
 	mac_data = (void *)&mac_data->macs[uc_count][0];
 
 	mac_data->entries = mc_count;
-	addr = dev->mc_list;
 	i = 0;
 	netdev_for_each_mc_addr(addr, dev)
 		memcpy(&mac_data->macs[i++][0], addr->da_addr, ETH_ALEN);
-- 
1.6.6


^ permalink raw reply related

* Re: [PATCH V2] net: add accounting for socket backlog
From: Eric Dumazet @ 2010-03-01 11:43 UTC (permalink / raw)
  To: Zhu Yi; +Cc: netdev, David Miller
In-Reply-To: <1267335071.9082.56.camel@edumazet-laptop>

Le dimanche 28 février 2010 à 06:31 +0100, Eric Dumazet a écrit :

> I am afraid sk_backlog_rcv() is not always called with lock held, and
> not always called to process backlog (see TCP ucopy.prequeue)
> 
> If you take a look at __release_sock() for example, we make the backlog
> private to the process before handling it (outside of lock_sock())
> 
> Therefore, I suggest doing the 'substraction' outside of
> sk_backlog_rcv().
> 
> diff --git a/net/core/sock.c b/net/core/sock.c
> index e1f6f22..57271cb 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -1520,6 +1520,7 @@ static void __release_sock(struct sock *sk)
>  
>         do {
>                 sk->sk_backlog.head = sk->sk_backlog.tail = NULL;
> +               sk->sk_backlog.len = 0;
>                 bh_unlock_sock(sk);
>  
>                 do {
> 
> 

Thinking again about this, doing this zero initialization at the very
end of __release_sock() solves the problem of potential infinite loop in
__release_sock(). Since producer will hit the backlog limit.

Thanks

diff --git a/net/core/sock.c b/net/core/sock.c
index 305cba4..544cf4a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1542,6 +1542,11 @@ static void __release_sock(struct sock *sk)
 
 		bh_lock_sock(sk);
 	} while ((skb = sk->sk_backlog.head) != NULL);
+	/*
+	 * Doing this zeroing at the end of this function guarantee we can not
+	 * loop forever while a wild producer attempts to flood us
+	 */
+	sk->sk_backlog.len = 0;
 }
 
 /**






^ permalink raw reply related

* sparse checking prevented by "net: fix kmemcheck annotations"
From: Stefan Richter @ 2010-03-01 12:09 UTC (permalink / raw)
  To: linux-kernel, Eric Dumazet; +Cc: David S. Miller, netdev

Hi all,

the post 2.6.32-rc5, pre 2.6.32-rc6 commit 14d18a81 causes a serious
regression for sparse checks:  make C=1 CF="-D__CHECK_ENDIAN__" now
causes sparse to log

    include/linux/skbuff.h:357:41: error: invalid bitfield specifier for
    type restricted __be16.


I reported this already shortly after this hit the mainline.  But back
then I didn't notice that this sparse error causes sparse to remain
silent on all subsequent warnings in a file!

We need to either change sparse to accept this bogus bit field that
occurs in skbuff.h (__be16 protocol:16;), silently or with a warning, or
revert this kmemcheck annotation.

("We" == preferably Eric :-)

skbuff.h is included by lots of drivers, even ones that are not even
networking drivers, notably DVB drivers.  None of these drivers can be
checked with sparse's __CHECK_ENDIAN__ at the moment.
-- 
Stefan Richter
-=====-==-=- --== ----=
http://arcgraph.de/sr/

^ permalink raw reply

* [PATCH net-next-2.6 v6 01/12] net-caif: add CAIF protocol definitions
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-1-git-send-email-sjur.brandeland@stericsson.com>

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

Add CAIF definitions to existing header files.
Files: if_arp.h, if_ether.h, socket.h.
Types: ARPHRD_CAIF, ETH_P_CAIF, AF_CAIF, PF_CAIF, SOL_CAIF, N_CAIF

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/linux/if_arp.h   |    1 +
 include/linux/if_ether.h |    1 +
 include/linux/socket.h   |    5 ++++-
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index e80b7f8..6d722f4 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -90,6 +90,7 @@
 
 #define ARPHRD_PHONET	820		/* PhoNet media type		*/
 #define ARPHRD_PHONET_PIPE 821		/* PhoNet pipe header		*/
+#define ARPHRD_CAIF	822		/* CAIF media type		*/
 
 #define ARPHRD_VOID	  0xFFFF	/* Void type, nothing is known */
 #define ARPHRD_NONE	  0xFFFE	/* zero header length */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 299b412..bed7a46 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -109,6 +109,7 @@
 #define ETH_P_TRAILER	0x001C		/* Trailer switch tagging	*/
 #define ETH_P_PHONET	0x00F5		/* Nokia Phonet frames          */
 #define ETH_P_IEEE802154 0x00F6		/* IEEE802.15.4 frame		*/
+#define ETH_P_CAIF	0x00F7		/* ST-Ericsson CAIF protocol	*/
 
 /*
  *	This is an Ethernet frame header.
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 7b3aae2..960659b 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -189,7 +189,8 @@ struct ucred {
 #define AF_ISDN		34	/* mISDN sockets 		*/
 #define AF_PHONET	35	/* Phonet sockets		*/
 #define AF_IEEE802154	36	/* IEEE802154 sockets		*/
-#define AF_MAX		37	/* For now.. */
+#define AF_CAIF		37	/* CAIF sockets			*/
+#define AF_MAX		38	/* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC	AF_UNSPEC
@@ -229,6 +230,7 @@ struct ucred {
 #define PF_ISDN		AF_ISDN
 #define PF_PHONET	AF_PHONET
 #define PF_IEEE802154	AF_IEEE802154
+#define PF_CAIF		AF_CAIF
 #define PF_MAX		AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
@@ -300,6 +302,7 @@ struct ucred {
 #define SOL_PNPIPE	275
 #define SOL_RDS		276
 #define SOL_IUCV	277
+#define SOL_CAIF	278
 
 /* IPX options */
 #define IPX_TYPE	1
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 04/12] net-caif: add CAIF Link layer device header files
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-4-git-send-email-sjur.brandeland@stericsson.com>

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

Header files for CAIF Link layer net-device,
and link-layer registration.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/net/caif/caif_dev.h    |   91 ++++++++++++++++++++++++++++++++++++++++
 include/net/caif/caif_device.h |   57 +++++++++++++++++++++++++
 2 files changed, 148 insertions(+), 0 deletions(-)

diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
new file mode 100644
index 0000000..65f289e
--- /dev/null
+++ b/include/net/caif/caif_dev.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/ sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CAIF_DEV_H_
+#define CAIF_DEV_H_
+
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfcnfg.h>
+#include <linux/caif/caif_socket.h>
+#include <linux/if.h>
+
+/**
+ * struct caif_param - CAIF parameters.
+ * @size:	Length of data
+ * @data:	Binary Data Blob
+ */
+struct caif_param {
+	u16  size;
+	u8   data[256];
+};
+
+/**
+ * caif_connect_request - Request data for CAIF channel setup.
+ * @sockaddr:		Socket address to connect.
+ * @priority:		Priority of the connection.
+ * @link_selector:	Link selector (high bandwidth or low latency)
+ * @link_name:		Name of the CAIF Link Layer to use.
+ *
+ * This struct is used when connecting a CAIF channel.
+ * It contains all CAIF channel configuration options.
+ */
+struct caif_connect_request {
+	int protocol;
+	struct sockaddr_caif sockaddr;
+	enum caif_channel_priority priority;
+	enum caif_link_selector link_selector;
+	char link_name[16];
+	struct caif_param param;
+};
+
+/**
+ * caif_connect_client - Connect a client to CAIF Core Stack.
+ * @config:		Channel setup parameters, specifying what address
+ *                      to connect on the Modem.
+ * @client_layer:	User implementation of client layer. This layer
+ *                      MUST have receive and control callback functions
+ *                      implemented.
+ *
+ * This function connects a CAIF channel. The Client must implement
+ * the struct cflayer. This layer represents the Client layer and holds
+ * receive functions and control callback functions. Control callback
+ * function will receive information about connect/disconnect responses,
+ * flow control etc (see enum caif_control).
+ * E.g. CAIF Socket will call this function for each socket it connects
+ * and have one client_layer instance for each socket.
+ */
+int caif_connect_client(struct caif_connect_request *config,
+			   struct cflayer *client_layer);
+
+/**
+ * caif_disconnect_client - Disconnects a client from the CAIF stack.
+ *
+ * @client_layer: Client layer to be removed.
+ */
+int caif_disconnect_client(struct cflayer *client_layer);
+
+
+/**
+ * connect_req_to_link_param - Translate configuration parameters
+ * 				from socket format to internal format.
+ * @cnfg: 	Pointer to configuration handler
+ * @con_req: 	Configuration parameters supplied in function
+ *		caif_connect_client
+ * @channel_setup_param: Parameters supplied to the CAIF Core stack for
+ *			 setting up channels.
+ *
+ */
+int connect_req_to_link_param(struct cfcnfg *cnfg,
+				struct caif_connect_request *con_req,
+				struct cfctrl_link_param *channel_setup_param);
+
+/**
+ * get_caif_conf() - Get the configuration handler.
+ */
+struct cfcnfg *get_caif_conf(void);
+
+
+#endif /* CAIF_DEV_H_ */
diff --git a/include/net/caif/caif_device.h b/include/net/caif/caif_device.h
new file mode 100644
index 0000000..ba22ee5
--- /dev/null
+++ b/include/net/caif/caif_device.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/ sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CAIF_DEVICE_H_
+#define CAIF_DEVICE_H_
+#include <linux/kernel.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/caif/caif_socket.h>
+#include <net/caif/caif_device.h>
+
+
+/**
+ * struct caif_dev_common - data shared between CAIF drivers and stack.
+ * @flowctrl:		Flow Control callback function. This function is
+ *                      supplied by CAIF Core Stack and is used by CAIF
+ *                      Link Layer to send flow-stop to CAIF Core.
+ *                      The flow information will be distributed to all
+ *                      clients of CAIF.
+ *
+ * @link_select:	Profile of device, either high-bandwidth or
+ *			low-latency. This member is set by CAIF Link
+ *			Layer Device in	order to indicate if this device
+ *			is a high bandwidth or low latency device.
+ *
+ * @use_frag:		CAIF Frames may be fragmented.
+ *			Is set by CAIF Link Layer in order to indicate if the
+ *			interface receives fragmented frames that must be
+ *			assembled by CAIF Core Layer.
+ *
+ * @use_fcs:		Indicate if Frame CheckSum (fcs) is used.
+ *			Is set if the physical interface is
+ *			using Frame Checksum on the CAIF Frames.
+ *
+ * @use_stx:		Indicate STart of frame eXtension (stx) in use.
+ *			Is set if the CAIF Link Layer expects
+ *			CAIF Frames to start with the STX byte.
+ *
+ * This structure is shared between the CAIF drivers and the CAIF stack.
+ * It is used by the device to register its behavior.
+ * CAIF Core layer must set the member flowctrl in order to supply
+ * CAIF Link Layer with the flow control function.
+ *
+ */
+ struct caif_dev_common {
+	void (*flowctrl)(struct net_device *net, int on);
+	enum caif_link_selector link_select;
+	int use_frag;
+	int use_fcs;
+	int use_stx;
+};
+
+#endif	/* CAIF_DEVICE_H_ */
+
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 03/12] net-caif: add CAIF core protocol stack header files
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-3-git-send-email-sjur.brandeland@stericsson.com>

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

Add include files for the CAIF Core protocol stack.

caif_layer.h - Defines the structure of the CAIF protocol layers
cfcnfg.h     - CAIF Configuration Module for services and link layers
cfctrl.h     - CAIF Control Protocol Layer
cffrml.h     - CAIF Framing Layer
cfmuxl.h     - CAIF Muxing Layer
cfpkt.h	     - CAIF Packet layer (skb helper functions)
cfserl.h     - CAIF Serial Layer
cfsrvl.h     - CAIF Service Layer

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/net/caif/caif_layer.h |  283 +++++++++++++++++++++++++++++++++++++++++
 include/net/caif/cfcnfg.h     |  134 +++++++++++++++++++
 include/net/caif/cfctrl.h     |  136 ++++++++++++++++++++
 include/net/caif/cffrml.h     |   17 +++
 include/net/caif/cfmuxl.h     |   22 +++
 include/net/caif/cfpkt.h      |  274 +++++++++++++++++++++++++++++++++++++++
 include/net/caif/cfserl.h     |   13 ++
 include/net/caif/cfsrvl.h     |   34 +++++
 8 files changed, 913 insertions(+), 0 deletions(-)

diff --git a/include/net/caif/caif_layer.h b/include/net/caif/caif_layer.h
new file mode 100644
index 0000000..2fc78d4
--- /dev/null
+++ b/include/net/caif/caif_layer.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CAIF_LAYER_H_
+#define CAIF_LAYER_H_
+
+#include <linux/list.h>
+
+struct cflayer;
+struct cfpkt;
+struct cfpktq;
+struct caif_payload_info;
+struct caif_packet_funcs;
+
+#define CAIF_MAX_FRAMESIZE 4096
+#define CAIF_MAX_PAYLOAD_SIZE (4096 - 64)
+#define CAIF_NEEDED_HEADROOM (10)
+#define CAIF_NEEDED_TAILROOM (2)
+
+
+#define CAIF_LAYER_NAME_SZ 16
+#define CAIF_SUCCESS    1
+#define CAIF_FAILURE    0
+
+/**
+ * caif_assert() - Assert function for CAIF.
+ * @assert: expression to evaluate.
+ *
+ * This function will print a error message and a do WARN_ON if the
+ * assertion failes. Normally this will do a stack up at the current location.
+ */
+#define caif_assert(assert)\
+do if (!(assert)) { \
+	pr_err("caif:Assert detected:'%s'\n", #assert); \
+	WARN_ON(!(assert));\
+} while (0)
+
+/**
+ * enum caif_ctrlcmd - CAIF Stack Control Signaling sent in layer.ctrlcmd().
+ *
+ * @CAIF_CTRLCMD_FLOW_OFF_IND:		Flow Control is OFF, transmit function
+ *					should stop sending data
+ *
+ * @CAIF_CTRLCMD_FLOW_ON_IND:		Flow Control is ON, transmit function
+ *					can start sending data
+ *
+ * @CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:  	Remote end modem has decided to close
+ *					down channel
+ *
+ * @CAIF_CTRLCMD_INIT_RSP:		Called initially when the layer below
+ *					has finished initialization
+ *
+ * @CAIF_CTRLCMD_DEINIT_RSP:		Called when de-initialization is
+ *					complete
+ *
+ * @CAIF_CTRLCMD_INIT_FAIL_RSP:		Called if initialization fails
+ *
+ * @_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: 	CAIF Link layer temporarily cannot
+ *					send more packets.
+ * @_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND:	Called if CAIF Link layer is able
+ *					to send	packets again.
+ * @_CAIF_CTRLCMD_PHYIF_DOWN_IND:	Called if CAIF Link layer is going
+ *					down.
+ *
+ * These commands are sent upwards in the CAIF stack to the CAIF Client.
+ * They are used for signaling originating from the modem or CAIF Link Layer.
+ * These are either responses (*_RSP) or events (*_IND).
+ */
+enum caif_ctrlcmd {
+	CAIF_CTRLCMD_FLOW_OFF_IND,
+	CAIF_CTRLCMD_FLOW_ON_IND,
+	CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
+	CAIF_CTRLCMD_INIT_RSP,
+	CAIF_CTRLCMD_DEINIT_RSP,
+	CAIF_CTRLCMD_INIT_FAIL_RSP,
+	_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
+	_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND,
+	_CAIF_CTRLCMD_PHYIF_DOWN_IND,
+};
+
+/**
+ * enum caif_modemcmd -  Modem Control Signaling, sent from CAIF Client
+ *                       to the CAIF Link Layer or modem.
+ *
+ * @CAIF_MODEMCMD_FLOW_ON_REQ:		Flow Control is ON, transmit function
+ *					can start sending data.
+ *
+ * @CAIF_MODEMCMD_FLOW_OFF_REQ:		Flow Control is OFF, transmit function
+ *					should stop sending data.
+ *
+ * @_CAIF_MODEMCMD_PHYIF_USEFULL:	Notify physical layer that it is in use
+ *
+ * @_CAIF_MODEMCMD_PHYIF_USELESS:	Notify physical layer that it is
+ *					no longer in use.
+ *
+ * These are requests sent 'downwards' in the stack.
+ * Flow ON, OFF can be indicated to the modem.
+ */
+enum caif_modemcmd {
+	CAIF_MODEMCMD_FLOW_ON_REQ = 0,
+	CAIF_MODEMCMD_FLOW_OFF_REQ = 1,
+	_CAIF_MODEMCMD_PHYIF_USEFULL = 3,
+	_CAIF_MODEMCMD_PHYIF_USELESS = 4
+};
+
+/**
+ * enum caif_direction - CAIF Packet Direction.
+ * Indicate if a packet is to be sent out or to be received in.
+ * @CAIF_DIR_IN:		Incoming packet received.
+ * @CAIF_DIR_OUT:		Outgoing packet to be transmitted.
+ */
+enum caif_direction {
+	CAIF_DIR_IN = 0,
+	CAIF_DIR_OUT = 1
+};
+
+/**
+ * struct cflayer - CAIF Stack layer.
+ * Defines the framework for the CAIF Core Stack.
+ * @up: 	Pointer up to the layer above.
+ * @dn:		Pointer down to the layer below.
+ * @node:	List node used when layer participate in a list.
+ * @receive:	Packet receive function.
+ * @transmit:	Packet transmit funciton.
+ * @ctrlcmd:	Used for control signalling upwards in the stack.
+ * @modemcmd:	Used for control signaling downwards in the stack.
+ * @prio:	Priority of this layer.
+ * @id:		The identity of this layer
+ * @type:	The type of this layer
+ * @name:	Name of the layer.
+ *
+ *  This structure defines the layered structure in CAIF.
+ *
+ *  It defines CAIF layering structure, used by all CAIF Layers and the
+ *  layers interfacing CAIF.
+ *
+ *  In order to integrate with CAIF an adaptation layer on top of the CAIF stack
+ *  and PHY layer below the CAIF stack
+ *  must be implemented. These layer must follow the design principles below.
+ *
+ *  Principles for layering of protocol layers:
+ *    -All layers must use this structure. If embedding it, then place this
+ *	     structure first in the layer specific structure.
+ *
+ *    - Each layer should not depend on any others layer private data.
+ *
+ *    - In order to send data upwards do
+ *	 layer->up->receive(layer->up, packet);
+ *
+ *    -In order to send data downwards do
+ *	 layer->dn->transmit(layer->dn, info, packet);
+ */
+struct cflayer {
+	struct cflayer *up;
+	struct cflayer *dn;
+	struct list_head node;
+
+	/*
+	 *  receive() - Receive Function.
+	 *  Contract: Each layer must implement a receive function passing the
+	 *  CAIF packets upwards in the stack.
+	 *	Packet handling rules:
+	 *	      -# The CAIF packet (cfpkt) cannot be accessed after
+	 *		     passing it to the next layer using up->receive().
+	 *	      -# If parsing of the packet fails, the packet must be
+	 *		     destroyed and -1 returned from the function.
+	 *	      -# If parsing succeeds (and above layers return OK) then
+	 *		      the function must return a value > 0.
+	 *
+	 *  Returns result < 0 indicates an error, 0 or positive value
+	 *	     indicates success.
+	 *
+	 *  @layr: Pointer to the current layer the receive function is
+	 *		implemented for (this pointer).
+	 *  @cfpkt: Pointer to CaifPacket to be handled.
+	 */
+	int (*receive)(struct cflayer *layr, struct cfpkt *cfpkt);
+
+	/*
+	 *  transmit() - Transmit Function.
+	 *  Contract: Each layer must implement a transmit function passing the
+	 *	CAIF packet downwards in the stack.
+	 *	Packet handling rules:
+	 *	      -# The CAIF packet (cfpkt) ownership is passed to the
+	 *		 transmit function. This means that the the packet
+	 *		 cannot be accessed after passing it to the below
+	 *		 layer using dn->transmit().
+	 *
+	 *	      -# If transmit fails, however, the ownership is returned
+	 *		 to thecaller. The caller of "dn->transmit()" must
+	 *		 destroy or resend packet.
+	 *
+	 *	      -# Return value less than zero means error, zero or
+	 *		 greater than zero means OK.
+	 *
+	 *       result < 0 indicates an error, 0 or positive value
+	 *	 indicate success.
+	 *
+	 *  @layr:  	Pointer to the current layer the receive function
+	 *		isimplemented for (this pointer).
+	 *  @cfpkt:	 Pointer to CaifPacket to be handled.
+	 */
+	int (*transmit) (struct cflayer *layr, struct cfpkt *cfpkt);
+
+	/*
+	 *  cttrlcmd() - Control Function upwards in CAIF Stack.
+	 *  Used for signaling responses (CAIF_CTRLCMD_*_RSP)
+	 *  and asynchronous events from the modem  (CAIF_CTRLCMD_*_IND)
+	 *
+	 *  @layr:  	Pointer to the current layer the receive function
+	 *		is implemented for (this pointer).
+	 *  @ctrl:	Control Command.
+	 */
+	void (*ctrlcmd) (struct cflayer *layr, enum caif_ctrlcmd ctrl,
+			 int phyid);
+
+	/*
+	 *  modemctrl() - Control Function used for controlling the modem.
+	 *  Used to signal down-wards in the CAIF stack.
+	 *  Returns 0 on success, < 0 upon failure.
+	 *
+	 *  @layr:	Pointer to the current layer the receive function
+	 *		is implemented for (this pointer).
+	 *  @ctrl:  Control Command.
+	 */
+	int (*modemcmd) (struct cflayer *layr, enum caif_modemcmd ctrl);
+
+	unsigned short prio;
+	unsigned int id;
+	unsigned int type;
+	char name[CAIF_LAYER_NAME_SZ];
+};
+
+/**
+ * layer_set_up() - Set the up pointer for a specified layer.
+ *  @layr: Layer where up pointer shall be set.
+ *  @above: Layer above.
+ */
+#define layer_set_up(layr, above) ((layr)->up = (struct cflayer *)(above))
+
+/**
+ *  layer_set_dn() - Set the down pointer for a specified layer.
+ *  @layr:  Layer where down pointer shall be set.
+ *  @below: Layer below.
+ */
+#define layer_set_dn(layr, below) ((layr)->dn = (struct cflayer *)(below))
+
+
+
+/**
+ * struct dev_info - Physical Device info information about physical layer.
+ * @dev:	Pointer to native physical device.
+ * @id:		Physical ID of the physical connection used by the
+ *	 	logical CAIF connection. Used by service layers to
+ *		identify their physical id to Caif MUX (CFMUXL)so
+ *		that the MUX can add the correct physical ID to the
+ *		packet.
+ */
+struct dev_info {
+	void *dev;
+	unsigned int id;
+};
+
+/**
+ * struct caif_payload_info - Payload information embedded in packet (sk_buff).
+ *
+ * @dev_info:	Information about the receiving device.
+ *
+ * @hdr_len:	Header length, used to align pay load on 32bit boundary.
+ *
+ * @channel_id: Channel ID of the logical CAIF connection.
+ * 		Used by mux to insert channel id into the caif packet.
+ */
+struct caif_payload_info {
+	struct dev_info *dev_info;
+	unsigned short hdr_len;
+	unsigned short channel_id;
+};
+
+#endif	/* CAIF_LAYER_H_ */
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h
new file mode 100644
index 0000000..55c3027
--- /dev/null
+++ b/include/net/caif/cfcnfg.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFCNFG_H_
+#define CFCNFG_H_
+#include <linux/spinlock.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfctrl.h>
+
+struct cfcnfg;
+
+/**
+ * enum cfcnfg_phy_type -  Types of physical layers defined in CAIF Stack
+ *
+ * @CFPHYTYPE_FRAG:	Fragmented frames physical interface.
+ * @CFPHYTYPE_CAIF:	Generic CAIF physical interface
+ */
+enum cfcnfg_phy_type {
+	CFPHYTYPE_FRAG = 1,
+	CFPHYTYPE_CAIF,
+	CFPHYTYPE_MAX
+};
+
+/**
+ * enum cfcnfg_phy_preference - Physical preference HW Abstraction
+ *
+ * @CFPHYPREF_UNSPECIFIED:	Default physical interface
+ *
+ * @CFPHYPREF_LOW_LAT:		Default physical interface for low-latency
+ *				traffic
+ * @CFPHYPREF_HIGH_BW:		Default physical interface for high-bandwidth
+ *				traffic
+ * @CFPHYPREF_LOOP:		TEST only Loopback interface simulating modem
+ *				responses.
+ *
+ */
+enum cfcnfg_phy_preference {
+	CFPHYPREF_UNSPECIFIED,
+	CFPHYPREF_LOW_LAT,
+	CFPHYPREF_HIGH_BW,
+	CFPHYPREF_LOOP
+};
+
+/**
+ * cfcnfg_create() - Create the CAIF configuration object.
+ */
+struct cfcnfg *cfcnfg_create(void);
+
+/**
+ * cfcnfg_remove() -  Remove the CFCNFG object
+ * @cfg: config object
+ */
+void cfcnfg_remove(struct cfcnfg *cfg);
+
+/**
+ * cfcnfg_add_phy_layer() - Adds a physical layer to the CAIF stack.
+ * @cnfg:	Pointer to a CAIF configuration object, created by
+ *		cfcnfg_create().
+ * @phy_type: 	Specifies the type of physical interface, e.g.
+ *		   	CFPHYTYPE_FRAG.
+ * @dev:	Pointer to link layer device
+ * @phy_layer:	Specify the physical layer. The transmit function
+ *		MUST be set in the structure.
+ * @phyid:	The assigned physical ID for this layer, used in
+ *		cfcnfg_add_adapt_layer to specify PHY for the link.
+ * @pref:	The phy (link layer) preference.
+ * @fcs:	Specify if checksum is used in CAIF Framing Layer.
+ * @stx:	Specify if Start Of Frame eXtention is used.
+ */
+
+void
+cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
+		     void *dev, struct cflayer *phy_layer, u16 *phyid,
+		     enum cfcnfg_phy_preference pref,
+		     bool fcs, bool stx);
+
+/**
+ * cfcnfg_del_phy_layer - Deletes an phy layer from the CAIF stack.
+ *
+ * @cnfg:	Pointer to a CAIF configuration object, created by
+ *		cfcnfg_create().
+ * @phy_layer:	Adaptation layer to be removed.
+ */
+int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer);
+
+
+/**
+ * cfcnfg_del_adapt_layer - Deletes an adaptation layer from the CAIF stack.
+ *
+ * @cnfg:	Pointer to a CAIF configuration object, created by
+ *		cfcnfg_create().
+ * @adap_layer: Adaptation layer to be removed.
+ */
+int cfcnfg_del_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer);
+
+
+/**
+ * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack.
+ *
+ * The adaptation Layer is where the interface to application or higher-level
+ * driver functionality is implemented.
+ *
+ * @cnfg:		Pointer to a CAIF configuration object, created by
+ *				cfcnfg_create().
+ * @param:		Link setup parameters.
+ * @adap_layer:		Specify the adaptation layer; the receive and
+ *			flow-control functions MUST be set in the structure.
+ *
+ */
+int
+cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
+			    struct cfctrl_link_param *param,
+			    struct cflayer *adap_layer);
+/**
+ * cfcnfg_get_phyid() - Get physical ID, given type.
+ * Returns one of the physical interfaces matching the given type.
+ * Zero if no match is found.
+ * @cnfg:	Configuration object
+ * @phy_pref:	Caif Link Layer preference
+ */
+struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
+		     enum cfcnfg_phy_preference phy_pref);
+
+/**
+ * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer
+ * @cnfg:	Configuration object
+ * @name:	Name of the Physical Layer (Caif Link Layer)
+ */
+int cfcnfg_get_named(struct cfcnfg *cnfg, char *name);
+
+#endif				/* CFCNFG_H_ */
diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h
new file mode 100644
index 0000000..d10d4eb
--- /dev/null
+++ b/include/net/caif/cfctrl.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFCTRL_H_
+#define CFCTRL_H_
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+
+/* CAIF Control packet commands */
+enum cfctrl_cmd {
+	CFCTRL_CMD_LINK_SETUP = 0,
+	CFCTRL_CMD_LINK_DESTROY = 1,
+	CFCTRL_CMD_LINK_ERR = 2,
+	CFCTRL_CMD_ENUM = 3,
+	CFCTRL_CMD_SLEEP = 4,
+	CFCTRL_CMD_WAKE = 5,
+	CFCTRL_CMD_LINK_RECONF = 6,
+	CFCTRL_CMD_START_REASON = 7,
+	CFCTRL_CMD_RADIO_SET = 8,
+	CFCTRL_CMD_MODEM_SET = 9,
+	CFCTRL_CMD_MASK = 0xf
+};
+
+/* Channel types */
+enum cfctrl_srv {
+	CFCTRL_SRV_DECM = 0,
+	CFCTRL_SRV_VEI = 1,
+	CFCTRL_SRV_VIDEO = 2,
+	CFCTRL_SRV_DBG = 3,
+	CFCTRL_SRV_DATAGRAM = 4,
+	CFCTRL_SRV_RFM = 5,
+	CFCTRL_SRV_UTIL = 6,
+	CFCTRL_SRV_MASK = 0xf
+};
+
+#define CFCTRL_RSP_BIT 0x20
+#define CFCTRL_ERR_BIT 0x10
+
+struct cfctrl_rsp {
+	void (*linksetup_rsp)(struct cflayer *layer, u8 linkid,
+			      enum cfctrl_srv serv, u8 phyid,
+			      struct cflayer *adapt_layer);
+	void (*linkdestroy_rsp)(struct cflayer *layer, u8 linkid,
+				struct cflayer *client_layer);
+	void (*linkerror_ind)(void);
+	void (*enum_rsp)(void);
+	void (*sleep_rsp)(void);
+	void (*wake_rsp)(void);
+	void (*restart_rsp)(void);
+	void (*radioset_rsp)(void);
+	void (*reject_rsp)(struct cflayer *layer, u8 linkid,
+				struct cflayer *client_layer);;
+};
+
+/* Link Setup Parameters for CAIF-Links. */
+struct cfctrl_link_param {
+	enum cfctrl_srv linktype;/* (T3,T0) Type of Channel */
+	u8 priority;		  /* (P4,P0) Priority of the channel */
+	u8 phyid;		  /* (U2-U0) Physical interface to connect */
+	u8 endpoint;		  /* (E1,E0) Endpoint for data channels */
+	u8 chtype;		  /* (H1,H0) Channel-Type, applies to
+				   *            VEI, DEBUG */
+	union {
+		struct {
+			u8 connid;	/*  (D7,D0) Video LinkId */
+		} video;
+
+		struct {
+			u32 connid;	/* (N31,Ngit0) Connection ID used
+					 *  for Datagram */
+		} datagram;
+
+		struct {
+			u32 connid;	/* Connection ID used for RFM */
+			char volume[20];	/* Volume to mount for RFM */
+		} rfm;		/* Configuration for RFM */
+
+		struct {
+			u16 fifosize_kb;	/* Psock FIFO size in KB */
+			u16 fifosize_bufs;	/* Psock # signal buffers */
+			char name[16];	/* Name of the PSOCK service */
+			u8 params[255];	/* Link setup Parameters> */
+			u16 paramlen;	/* Length of Link Setup
+						 *   Parameters */
+		} utility;	/* Configuration for Utility Links (Psock) */
+	} u;
+};
+
+/* This structure is used internally in CFCTRL */
+struct cfctrl_request_info {
+	int sequence_no;
+	enum cfctrl_cmd cmd;
+	u8 channel_id;
+	struct cfctrl_link_param param;
+	struct cfctrl_request_info *next;
+	struct cflayer *client_layer;
+};
+
+struct cfctrl {
+	struct cfsrvl serv;
+	struct cfctrl_rsp res;
+	atomic_t req_seq_no;
+	atomic_t rsp_seq_no;
+	struct cfctrl_request_info *first_req;
+	spinlock_t info_list_lock;
+#ifndef CAIF_NO_LOOP
+	u8 loop_linkid;
+	int loop_linkused[256];
+	spinlock_t loop_linkid_lock;
+#endif
+
+};
+
+void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid);
+void cfctrl_linkup_request(struct cflayer *cfctrl,
+			   struct cfctrl_link_param *param,
+			   struct cflayer *user_layer);
+int  cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid,
+			 struct cflayer *client);
+void cfctrl_sleep_req(struct cflayer *cfctrl);
+void cfctrl_wake_req(struct cflayer *cfctrl);
+void cfctrl_getstartreason_req(struct cflayer *cfctrl);
+struct cflayer *cfctrl_create(void);
+void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn);
+void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up);
+struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer);
+bool cfctrl_req_eq(struct cfctrl_request_info *r1,
+		   struct cfctrl_request_info *r2);
+void cfctrl_insert_req(struct cfctrl *ctrl,
+			      struct cfctrl_request_info *req);
+struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
+					      struct cfctrl_request_info *req);
+#endif				/* CFCTRL_H_ */
diff --git a/include/net/caif/cffrml.h b/include/net/caif/cffrml.h
new file mode 100644
index 0000000..2ee2fe3
--- /dev/null
+++ b/include/net/caif/cffrml.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFFRML_H_
+#define CFFRML_H_
+#include <net/caif/caif_layer.h>
+
+struct cffrml;
+struct cflayer *cffrml_create(u16 phyid, bool DoFCS);
+void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up);
+void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn);
+void cffrml_destroy(struct cflayer *layer);
+
+#endif /* CFFRML_H_ */
diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h
new file mode 100644
index 0000000..4e1b4f3
--- /dev/null
+++ b/include/net/caif/cfmuxl.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFMUXL_H_
+#define CFMUXL_H_
+#include <net/caif/caif_layer.h>
+
+struct cfsrvl;
+struct cffrml;
+
+struct cflayer *cfmuxl_create(void);
+int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid);
+struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid);
+int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid);
+struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid);
+bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid);
+u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id);
+
+#endif				/* CFMUXL_H_ */
diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h
new file mode 100644
index 0000000..fbc681b
--- /dev/null
+++ b/include/net/caif/cfpkt.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFPKT_H_
+#define CFPKT_H_
+#include <net/caif/caif_layer.h>
+#include <linux/types.h>
+struct cfpkt;
+
+/* Create a CAIF packet.
+ * len: Length of packet to be created
+ * @return New packet.
+ */
+struct cfpkt *cfpkt_create(u16 len);
+
+/* Create a CAIF packet.
+ * data Data to copy.
+ * len Length of packet to be created
+ * @return New packet.
+ */
+struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len);
+/*
+ * Destroy a CAIF Packet.
+ * pkt Packet to be destoyed.
+ */
+void cfpkt_destroy(struct cfpkt *pkt);
+
+/*
+ * Extract header from packet.
+ *
+ * pkt Packet to extract header data from.
+ * data Pointer to copy the header data into.
+ * len Length of head data to copy.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len);
+
+/*
+ * Peek header from packet.
+ * Reads data from packet without changing packet.
+ *
+ * pkt Packet to extract header data from.
+ * data Pointer to copy the header data into.
+ * len Length of head data to copy.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len);
+
+/*
+ * Extract header from trailer (end of packet).
+ *
+ * pkt Packet to extract header data from.
+ * data Pointer to copy the trailer data into.
+ * len Length of header data to copy.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_extr_trail(struct cfpkt *pkt, void *data, u16 len);
+
+/*
+ * Add header to packet.
+ *
+ *
+ * pkt Packet to add header data to.
+ * data Pointer to data to copy into the header.
+ * len Length of header data to copy.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_add_head(struct cfpkt *pkt, const void *data, u16 len);
+
+/*
+ * Add trailer to packet.
+ *
+ *
+ * pkt Packet to add trailer data to.
+ * data Pointer to data to copy into the trailer.
+ * len Length of trailer data to copy.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len);
+
+/*
+ * Pad trailer on packet.
+ * Moves data pointer in packet, no content copied.
+ *
+ * pkt Packet in which to pad trailer.
+ * len Length of padding to add.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_pad_trail(struct cfpkt *pkt, u16 len);
+
+/*
+ * Add a single byte to packet body (tail).
+ *
+ * pkt Packet in which to add byte.
+ * data Byte to add.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_addbdy(struct cfpkt *pkt, const u8 data);
+
+/*
+ * Add a data to packet body (tail).
+ *
+ * pkt Packet in which to add data.
+ * data Pointer to data to copy into the packet body.
+ * len Length of data to add.
+ * @return zero on success and error code upon failure
+ */
+int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len);
+
+/*
+ * Checks whether there are more data to process in packet.
+ * pkt Packet to check.
+ * @return true if more data are available in packet false otherwise
+ */
+bool cfpkt_more(struct cfpkt *pkt);
+
+/*
+ * Checks whether the packet is erroneous,
+ * i.e. if it has been attempted to extract more data than available in packet
+ * or writing more data than has been allocated in cfpkt_create().
+ * pkt Packet to check.
+ * @return true on error false otherwise
+ */
+bool cfpkt_erroneous(struct cfpkt *pkt);
+
+/*
+ * Get the packet length.
+ * pkt Packet to get length from.
+ * @return Number of bytes in packet.
+ */
+u16 cfpkt_getlen(struct cfpkt *pkt);
+
+/*
+ * Set the packet length, by adjusting the trailer pointer according to length.
+ * pkt Packet to set length.
+ * len Packet length.
+ * @return Number of bytes in packet.
+ */
+int cfpkt_setlen(struct cfpkt *pkt, u16 len);
+
+/*
+ * cfpkt_append - Appends a packet's data to another packet.
+ * dstpkt:    Packet to append data into, WILL BE FREED BY THIS FUNCTION
+ * addpkt:    Packet to be appended and automatically released,
+ *            WILL BE FREED BY THIS FUNCTION.
+ * expectlen: Packet's expected total length. This should be considered
+ *            as a hint.
+ * NB: Input packets will be destroyed after appending and cannot be used
+ * after calling this function.
+ * @return    The new appended packet.
+ */
+struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt,
+		      u16 expectlen);
+
+/*
+ * cfpkt_split - Split a packet into two packets at the specified split point.
+ * pkt: Packet to be split (will contain the first part of the data on exit)
+ * pos: Position to split packet in two parts.
+ * @return The new packet, containing the second part of the data.
+ */
+struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos);
+
+/*
+ * Iteration function, iterates the packet buffers from start to end.
+ *
+ * Checksum iteration function used to iterate buffers
+ * (we may have packets consisting of a chain of buffers)
+ * pkt:       Packet to calculate checksum for
+ * iter_func: Function pointer to iteration function
+ * chks:      Checksum calculated so far.
+ * buf:       Pointer to the buffer to checksum
+ * len:       Length of buf.
+ * data:      Initial checksum value.
+ * @return    Checksum of buffer.
+ */
+
+u16 cfpkt_iterate(struct cfpkt *pkt,
+		u16 (*iter_func)(u16 chks, void *buf, u16 len),
+		u16 data);
+
+/* Append by giving user access to packet buffer
+ * cfpkt Packet to append to
+ * buf Buffer inside pkt that user shall copy data into
+ * buflen Length of buffer and number of bytes added to packet
+ * @return 0 on error, 1 on success
+ */
+int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
+
+/* Extract by giving user access to packet buffer
+ * cfpkt Packet to extract from
+ * buf Buffer inside pkt that user shall copy data from
+ * buflen Length of buffer and number of bytes removed from packet
+ * @return 0 on error, 1 on success
+ */
+int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen);
+
+/* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet.
+ *  dir - Direction indicating whether this packet is to be sent or received.
+ *  nativepkt  - The native packet to be transformed to a CAIF packet
+ *  @return The mapped CAIF Packet CFPKT.
+ */
+struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt);
+
+/* Map from a CAIF packet to a "native" packet (e.g. Linux Socket Buffer).
+ *  pkt  - The CAIF packet to be transformed into a "native" packet.
+ *  @return The native packet transformed from a CAIF packet.
+ */
+void *cfpkt_tonative(struct cfpkt *pkt);
+
+/*
+ * Insert a packet in the packet queue.
+ * pktq Packet queue to insert into
+ * pkt Packet to be inserted in queue
+ * prio Priority of packet
+ */
+void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt,
+		 unsigned short prio);
+
+/*
+ * Remove a packet from the packet queue.
+ * pktq Packet queue to fetch packets from.
+ * @return Dequeued packet.
+ */
+struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq);
+
+/*
+ * Peek into a packet from the packet queue.
+ * pktq Packet queue to fetch packets from.
+ * @return Peeked packet.
+ */
+struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq);
+
+/*
+ * Initiates the packet queue.
+ * @return Pointer to new packet queue.
+ */
+struct cfpktq *cfpktq_create(void);
+
+/*
+ * Get the number of packets in the queue.
+ * pktq Packet queue to fetch count from.
+ * @return Number of packets in queue.
+ */
+int cfpkt_qcount(struct cfpktq *pktq);
+
+/*
+ * Put content of packet into buffer for debuging purposes.
+ * pkt Packet to copy data from
+ * buf Buffer to copy data into
+ * buflen Length of data to copy
+ * @return Pointer to copied data
+ */
+char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen);
+
+/*
+ * Clones a packet and releases the original packet.
+ * This is used for taking ownership of a packet e.g queueing.
+ * pkt Packet to clone and release.
+ * @return Cloned packet.
+ */
+struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt);
+
+
+/*
+ * Returns packet information for a packet.
+ * pkt Packet to get info from;
+ * @return Packet information
+ */
+struct caif_payload_info *cfpkt_info(struct cfpkt *pkt);
+/*! @} */
+#endif				/* CFPKT_H_ */
diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h
new file mode 100644
index 0000000..33644f4
--- /dev/null
+++ b/include/net/caif/cfserl.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFSERL_H_
+#define CFSERL_H_
+#include <net/caif/caif_layer.h>
+
+struct cflayer *cfserl_create(int type, int instance, bool use_stx);
+
+#endif				/* CFSERL_H_ */
diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h
new file mode 100644
index 0000000..b2a12db
--- /dev/null
+++ b/include/net/caif/cfsrvl.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CFSRVL_H_
+#define CFSRVL_H_
+#include <linux/list.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+struct cfsrvl {
+	struct cflayer layer;
+	bool open;
+	bool phy_flow_on;
+	bool modem_flow_on;
+	struct dev_info dev_info;
+};
+
+struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info);
+struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info);
+struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info);
+struct cflayer *cfvidl_create(u8 linkid, struct dev_info *dev_info);
+struct cflayer *cfrfml_create(u8 linkid, struct dev_info *dev_info);
+struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info);
+bool cfsrvl_phyid_match(struct cflayer *layer, int phyid);
+void cfservl_destroy(struct cflayer *layer);
+void cfsrvl_init(struct cfsrvl *service,
+		 u8 channel_id,
+		 struct dev_info *dev_info);
+bool cfsrvl_ready(struct cfsrvl *service, int *err);
+u8 cfsrvl_getphyid(struct cflayer *layer);
+
+#endif				/* CFSRVL_H_ */
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 00/12] net-caif: introducing CAIF protocol stack
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland

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

This patch-set introduces the CAIF protocol Stack.
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.

Changes since v5:
- Updated usage of standard types.

OVERVIEW:

* CAIF provides a socket interface which can be used to open virtual AT
  channels, create and configure GPRS Data connections.

* A CAIF Network device is also provided for GPRS access.
  This interface can be managed with RTNL.

* A kernel interface is provided allowing Kernel modules to use CAIF.

* A serial link layer layer implemented as a line discipline is currently 
  implemented. Other link interfaces may be contributed at a later stage.

  RTNL
   !
   !	 +------+   +------+   +------+
   !	+------+!  +------+!  +------+!
   !	! Sock !!  !Kernel!!  ! Net  !!
   !	! API  !+  ! API  !+  ! Dev  !+	  <- CAIF "Client" APIs
   !	+------+   +------!   +------+
   !	   !	      !		 !
   !	   +----------!----------+
   !		   +------+		  <- CAIF Core Protocol Implementation
   +------->	   ! CAIF !
		   ! Core !
		   +------+
	     +--------!--------+
	     !		       !
	  +------+	    +-----+
	  ! ldisc!	    ! ... !	  <- Link Layer (Net Devices)
	  +------+	    +-----+
	     !
	  +------+
	  ! tty	 !
	  +------+

Please see Documentation/networking/CAIF for more documentation.

Based on net-next-2.6



Sjur Braendeland (12):
  net-caif: add CAIF protocol definitions
  net-caif: add CAIF socket and configuration headers
  net-caif: add CAIF core protocol stack header files
  net-caif: add CAIF Link layer device header files
  net-caif: add CAIF core protocol stack
  net-caif: add CAIF generic caif support functions
  net-caif: add CAIF device registration functionality
  net-caif: add CAIF socket implementation
  net-caif: add CAIF netdevice
  net-caif: add CAIF Kconfig and Makefiles
  net-caif: add CAIF documentation
  net-caif-driver: add CAIF serial driver (ldisc)

 Documentation/networking/caif/Linux-CAIF.txt |  212 ++++
 Documentation/networking/caif/README         |  110 ++
 drivers/net/Kconfig                          |    2 +
 drivers/net/Makefile                         |    1 +
 drivers/net/caif/Kconfig                     |   24 +
 drivers/net/caif/Makefile                    |   14 +
 drivers/net/caif/caif_serial.c               |  463 +++++++++
 include/linux/caif/caif_socket.h             |  164 +++
 include/linux/caif/if_caif.h                 |   34 +
 include/linux/if_arp.h                       |    1 +
 include/linux/if_ether.h                     |    1 +
 include/linux/socket.h                       |    5 +-
 include/linux/tty.h                          |    4 +-
 include/net/caif/caif_dev.h                  |   91 ++
 include/net/caif/caif_device.h               |   57 +
 include/net/caif/caif_layer.h                |  283 +++++
 include/net/caif/cfcnfg.h                    |  134 +++
 include/net/caif/cfctrl.h                    |  136 +++
 include/net/caif/cffrml.h                    |   17 +
 include/net/caif/cfmuxl.h                    |   22 +
 include/net/caif/cfpkt.h                     |  274 +++++
 include/net/caif/cfserl.h                    |   13 +
 include/net/caif/cfsrvl.h                    |   34 +
 net/Kconfig                                  |    2 +
 net/Makefile                                 |    1 +
 net/caif/Kconfig                             |   48 +
 net/caif/Makefile                            |   27 +
 net/caif/caif_config_util.c                  |   88 ++
 net/caif/caif_dev.c                          |  394 +++++++
 net/caif/caif_socket.c                       | 1431 ++++++++++++++++++++++++++
 net/caif/cfcnfg.c                            |  529 ++++++++++
 net/caif/cfctrl.c                            |  711 +++++++++++++
 net/caif/cfdbgl.c                            |   40 +
 net/caif/cfdgml.c                            |  108 ++
 net/caif/cffrml.c                            |  151 +++
 net/caif/cfmuxl.c                            |  246 +++++
 net/caif/cfpkt_skbuff.c                      |  595 +++++++++++
 net/caif/cfrfml.c                            |  106 ++
 net/caif/cfserl.c                            |  199 ++++
 net/caif/cfsrvl.c                            |  185 ++++
 net/caif/cfutill.c                           |  115 ++
 net/caif/cfveil.c                            |  107 ++
 net/caif/cfvidl.c                            |   65 ++
 net/caif/chnl_net.c                          |  429 ++++++++
 44 files changed, 7670 insertions(+), 3 deletions(-)


^ permalink raw reply

* [PATCH net-next-2.6 v6 02/12] net-caif: add CAIF socket and configuration headers
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-2-git-send-email-sjur.brandeland@stericsson.com>

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

Add CAIF types for Socket Address, Socket Options,
and configuration parameters for the GPRS IP network interface.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/linux/caif/caif_socket.h |  164 ++++++++++++++++++++++++++++++++++++++
 include/linux/caif/if_caif.h     |   34 ++++++++
 2 files changed, 198 insertions(+), 0 deletions(-)

diff --git a/include/linux/caif/caif_socket.h b/include/linux/caif/caif_socket.h
new file mode 100644
index 0000000..8e5c844
--- /dev/null
+++ b/include/linux/caif/caif_socket.h
@@ -0,0 +1,164 @@
+/* linux/caif_socket.h
+ * CAIF Definitions for CAIF socket and network layer
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	 Sjur Brendeland/ sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef _LINUX_CAIF_SOCKET_H
+#define _LINUX_CAIF_SOCKET_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+#include <linux/socket.h>
+#else
+#include <sys/socket.h>
+#endif
+
+
+/**
+ * enum caif_link_selector -    Physical Link Selection.
+ * @CAIF_LINK_HIGH_BANDW:	Physical interface for high-bandwidth
+ *				traffic.
+ * @CAIF_LINK_LOW_LATENCY:	Physical interface for low-latency
+ *				traffic.
+ *
+ * CAIF Link Layers can register their link properties.
+ * This enum is used for choosing between CAIF Link Layers when
+ * setting up CAIF Channels when multiple CAIF Link Layers exists.
+ */
+enum caif_link_selector {
+	CAIF_LINK_HIGH_BANDW,
+	CAIF_LINK_LOW_LATENCY
+};
+
+/**
+ * enum caif_channel_priority - CAIF channel priorities.
+ *
+ * @CAIF_PRIO_MIN:	Min priority for a channel.
+ * @CAIF_PRIO_LOW:	Low-priority channel.
+ * @CAIF_PRIO_NORMAL:	Normal/default priority level.
+ * @CAIF_PRIO_HIGH:	High priority level
+ * @CAIF_PRIO_MAX:	Max priority for channel
+ *
+ * Priority can be set on CAIF Channels in order to
+ * prioritize between traffic on different CAIF Channels.
+ * These priority levels are recommended, but the priority value
+ * is not restricted to the values defined in this enum, any value
+ * between CAIF_PRIO_MIN and CAIF_PRIO_MAX could be used.
+ */
+enum caif_channel_priority {
+	CAIF_PRIO_MIN	 = 0x01,
+	CAIF_PRIO_LOW	 = 0x04,
+	CAIF_PRIO_NORMAL = 0x0f,
+	CAIF_PRIO_HIGH	 = 0x14,
+	CAIF_PRIO_MAX	 = 0x1F
+};
+
+/**
+ * enum caif_protocol_type  -	CAIF Channel type.
+ * @CAIFPROTO_AT:		Classic AT channel.
+ * @CAIFPROTO_DATAGRAM:		Datagram channel.
+ * @CAIFPROTO_DATAGRAM_LOOP:	Datagram loopback channel, used for testing.
+ * @CAIFPROTO_UTIL:		Utility (Psock) channel.
+ * @CAIFPROTO_RFM:		Remote File Manager
+ *
+ * This enum defines the CAIF Channel type to be used. This defines
+ * the service to connect to on the modem.
+ */
+enum caif_protocol_type {
+	CAIFPROTO_AT,
+	CAIFPROTO_DATAGRAM,
+	CAIFPROTO_DATAGRAM_LOOP,
+	CAIFPROTO_UTIL,
+	CAIFPROTO_RFM,
+	_CAIFPROTO_MAX
+};
+#define	CAIFPROTO_MAX _CAIFPROTO_MAX
+
+/**
+ * enum caif_at_type - AT Service Endpoint
+ * @CAIF_ATTYPE_PLAIN:	     Connects to a plain vanilla AT channel.
+ */
+enum caif_at_type {
+	CAIF_ATTYPE_PLAIN = 2
+};
+
+/**
+ * struct sockaddr_caif - the sockaddr structure for CAIF sockets.
+ * @u:			     Union of address data 'switched' by family.
+ * :
+ * @u.at:                    Applies when family = CAIFPROTO_AT.
+ *
+ * @u.at.type:               Type of AT link to set up (enum caif_at_type).
+ *
+ * @u.util:                  Applies when family = CAIFPROTO_UTIL
+ *
+ * @u.util.service:          Utility service name.
+ *
+ * @u.dgm:                   Applies when family = CAIFPROTO_DATAGRAM
+ *
+ * @u.dgm.connection_id:     Datagram connection id.
+ *
+ * @u.dgm.nsapi:             NSAPI of the PDP-Context.
+ *
+ * @u.rfm:                   Applies when family = CAIFPROTO_RFM
+ *
+ * @u.rfm.connection_id:     Connection ID for RFM.
+ *
+ * @u.rfm.volume:            Volume to mount.
+ *
+ * Description:
+ * This structure holds the connect parameters used for setting up a
+ * CAIF Channel. It defines the service to connect to on the modem.
+ */
+struct sockaddr_caif {
+	sa_family_t  family;
+	union {
+		struct {
+			__u8  type;		/* type: enum caif_at_type */
+		} at;				/* CAIFPROTO_AT */
+		struct {
+			char	  service[16];
+		} util;				/* CAIFPROTO_UTIL */
+		union {
+			__u32 connection_id;
+			__u8  nsapi;
+		} dgm;				/* CAIFPROTO_DATAGRAM(_LOOP)*/
+		struct {
+			__u32 connection_id;
+			char	  volume[16];
+		} rfm;				/* CAIFPROTO_RFM */
+	} u;
+};
+
+/**
+ * enum caif_socket_opts - CAIF option values for getsockopt and setsockopt.
+ *
+ * @CAIFSO_LINK_SELECT:		Selector used if multiple CAIF Link layers are
+ *				available. Either a high bandwidth
+ *				link can be selected (CAIF_LINK_HIGH_BANDW) or
+ *				or a low latency link (CAIF_LINK_LOW_LATENCY).
+ *                              This option is of type __u32.
+ *				Alternatively SO_BINDTODEVICE can be used.
+ *
+ * @CAIFSO_REQ_PARAM:		Used to set the request parameters for a
+ *				utility channel. (maximum 256 bytes). This
+ *				option must be set before connecting.
+ *
+ * @CAIFSO_RSP_PARAM:		Gets the response parameters for a utility
+ *				channel. (maximum 256 bytes). This option
+ *				is valid after a successful connect.
+ *
+ *
+ * This enum defines the CAIF Socket options to be used on a socket
+ *
+ */
+enum caif_socket_opts {
+	CAIFSO_LINK_SELECT	= 127,
+	CAIFSO_REQ_PARAM	= 128,
+	CAIFSO_RSP_PARAM	= 129,
+};
+
+#endif /* _LINUX_CAIF_SOCKET_H */
diff --git a/include/linux/caif/if_caif.h b/include/linux/caif/if_caif.h
new file mode 100644
index 0000000..5e7eed4
--- /dev/null
+++ b/include/linux/caif/if_caif.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/ sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef IF_CAIF_H_
+#define IF_CAIF_H_
+#include <linux/sockios.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/**
+ * enum ifla_caif - CAIF NetlinkRT parameters.
+ * @IFLA_CAIF_IPV4_CONNID:  Connection ID for IPv4 PDP Context.
+ *			    The type of attribute is NLA_U32.
+ * @IFLA_CAIF_IPV6_CONNID:  Connection ID for IPv6 PDP Context.
+ *			    The type of attribute is NLA_U32.
+ * @IFLA_CAIF_LOOPBACK:	    If different from zero, device is doing loopback
+ *			    The type of attribute is NLA_U8.
+ *
+ * When using RT Netlink to create, destroy or configure a CAIF IP interface,
+ * enum ifla_caif is used to specify the configuration attributes.
+ */
+enum ifla_caif {
+	__IFLA_CAIF_UNSPEC,
+	IFLA_CAIF_IPV4_CONNID,
+	IFLA_CAIF_IPV6_CONNID,
+	IFLA_CAIF_LOOPBACK,
+	__IFLA_CAIF_MAX
+};
+#define	IFLA_CAIF_MAX (__IFLA_CAIF_MAX-1)
+
+#endif /*IF_CAIF_H_*/
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 06/12] net-caif: add CAIF generic caif support functions
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-6-git-send-email-sjur.brandeland@stericsson.com>

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

Support functions for the caif protocol stack:
cfcnfg.c        - CAIF Configuration Module used for
                  adding and removing drivers and connection
cfpkt_skbuff.c  - CAIF Packet layer (SKB helper functions)

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 net/caif/cfcnfg.c       |  529 +++++++++++++++++++++++++++++++++++++++++
 net/caif/cfpkt_skbuff.c |  595 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1124 insertions(+), 0 deletions(-)

diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
new file mode 100644
index 0000000..58b16b8
--- /dev/null
+++ b/net/caif/cfcnfg.c
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/cfcnfg.h>
+#include <net/caif/cfctrl.h>
+#include <net/caif/cfmuxl.h>
+#include <net/caif/cffrml.h>
+#include <net/caif/cfserl.h>
+#include <net/caif/cfsrvl.h>
+
+#include <linux/module.h>
+#include <asm/atomic.h>
+
+#define MAX_PHY_LAYERS 7
+#define PHY_NAME_LEN 20
+
+#define container_obj(layr) container_of(layr, struct cfcnfg, layer)
+
+/* Information about CAIF physical interfaces held by Config Module in order
+ * to manage physical interfaces
+ */
+struct cfcnfg_phyinfo {
+	/* Pointer to the layer below the MUX (framing layer) */
+	struct cflayer *frm_layer;
+	/* Pointer to the lowest actual physical layer */
+	struct cflayer *phy_layer;
+	/* Unique identifier of the physical interface */
+	unsigned int id;
+	/* Preference of the physical in interface */
+	enum cfcnfg_phy_preference pref;
+
+	/* Reference count, number of channels using the device */
+	int phy_ref_count;
+
+	/* Information about the physical device */
+	struct dev_info dev_info;
+};
+
+struct cfcnfg {
+	struct cflayer layer;
+	struct cflayer *ctrl;
+	struct cflayer *mux;
+	u8 last_phyid;
+	struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS];
+};
+
+static void cncfg_linkup_rsp(struct cflayer *layer, u8 linkid,
+			     enum cfctrl_srv serv, u8 phyid,
+			     struct cflayer *adapt_layer);
+static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid,
+				  struct cflayer *client_layer);
+static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid,
+			     struct cflayer *adapt_layer);
+static void cfctrl_resp_func(void);
+static void cfctrl_enum_resp(void);
+
+struct cfcnfg *cfcnfg_create()
+{
+	struct cfcnfg *this;
+	struct cfctrl_rsp *resp;
+	/* Initiate this layer */
+	this = kmalloc(sizeof(struct cfcnfg), GFP_ATOMIC);
+	if (!this) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	memset(this, 0, sizeof(struct cfcnfg));
+	this->mux = cfmuxl_create();
+	if (!this->mux)
+		goto out_of_mem;
+	this->ctrl = cfctrl_create();
+	if (!this->ctrl)
+		goto out_of_mem;
+	/* Initiate response functions */
+	resp = cfctrl_get_respfuncs(this->ctrl);
+	resp->enum_rsp = cfctrl_enum_resp;
+	resp->linkerror_ind = cfctrl_resp_func;
+	resp->linkdestroy_rsp = cncfg_linkdestroy_rsp;
+	resp->sleep_rsp = cfctrl_resp_func;
+	resp->wake_rsp = cfctrl_resp_func;
+	resp->restart_rsp = cfctrl_resp_func;
+	resp->radioset_rsp = cfctrl_resp_func;
+	resp->linksetup_rsp = cncfg_linkup_rsp;
+	resp->reject_rsp = cncfg_reject_rsp;
+
+	this->last_phyid = 1;
+
+	cfmuxl_set_uplayer(this->mux, this->ctrl, 0);
+	layer_set_dn(this->ctrl, this->mux);
+	layer_set_up(this->ctrl, this);
+	return this;
+out_of_mem:
+	pr_warning("CAIF: %s(): Out of memory\n", __func__);
+	kfree(this->mux);
+	kfree(this->ctrl);
+	kfree(this);
+	return NULL;
+}
+EXPORT_SYMBOL(cfcnfg_create);
+
+void cfcnfg_remove(struct cfcnfg *cfg)
+{
+	if (cfg) {
+		kfree(cfg->mux);
+		kfree(cfg->ctrl);
+		kfree(cfg);
+	}
+}
+
+static void cfctrl_resp_func(void)
+{
+}
+
+static void cfctrl_enum_resp(void)
+{
+}
+
+struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
+				  enum cfcnfg_phy_preference phy_pref)
+{
+	int i;
+
+	/* Try to match with specified preference */
+	for (i = 1; i < MAX_PHY_LAYERS; i++) {
+		if (cnfg->phy_layers[i].id == i &&
+		     cnfg->phy_layers[i].pref == phy_pref &&
+		     cnfg->phy_layers[i].frm_layer != NULL) {
+			caif_assert(cnfg->phy_layers != NULL);
+			caif_assert(cnfg->phy_layers[i].id == i);
+			return &cnfg->phy_layers[i].dev_info;
+		}
+	}
+	/* Otherwise just return something */
+	for (i = 1; i < MAX_PHY_LAYERS; i++) {
+		if (cnfg->phy_layers[i].id == i) {
+			caif_assert(cnfg->phy_layers != NULL);
+			caif_assert(cnfg->phy_layers[i].id == i);
+			return &cnfg->phy_layers[i].dev_info;
+		}
+	}
+
+	return NULL;
+}
+
+static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg,
+							u8 phyid)
+{
+	int i;
+	/* Try to match with specified preference */
+	for (i = 0; i < MAX_PHY_LAYERS; i++)
+		if (cnfg->phy_layers[i].frm_layer != NULL &&
+		    cnfg->phy_layers[i].id == phyid)
+			return &cnfg->phy_layers[i];
+	return 0;
+}
+
+int cfcnfg_get_named(struct cfcnfg *cnfg, char *name)
+{
+	int i;
+
+	/* Try to match with specified name */
+	for (i = 0; i < MAX_PHY_LAYERS; i++) {
+		if (cnfg->phy_layers[i].frm_layer != NULL
+		    && strcmp(cnfg->phy_layers[i].phy_layer->name,
+			      name) == 0)
+			return cnfg->phy_layers[i].frm_layer->id;
+	}
+	return 0;
+}
+
+/*
+ * NOTE: What happens on destroy failure:
+ *	 1a) No response - Too early
+ *	      This will not happen because enumerate has already
+ *	      completed.
+ *	 1b) No response - FATAL
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ *	      Modem error, response is really expected -  this
+ *	      case is not really handled.
+ *	 2) O/E-bit indicate error
+ *	      Ignored - this link is destroyed anyway.
+ *	 3) Not able to match on request
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ *	 4) Link-Error - (no response)
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ */
+
+int cfcnfg_del_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
+{
+	u8 channel_id = 0;
+	int ret = 0;
+	struct cfcnfg_phyinfo *phyinfo = NULL;
+	u8 phyid = 0;
+
+	caif_assert(adap_layer != NULL);
+	channel_id = adap_layer->id;
+	if (channel_id == 0) {
+		pr_err("CAIF: %s():adap_layer->id is 0\n", __func__);
+		ret = -ENOTCONN;
+		goto end;
+	}
+
+	if (adap_layer->dn == NULL) {
+		pr_err("CAIF: %s():adap_layer->dn is NULL\n", __func__);
+		ret = -ENODEV;
+		goto end;
+	}
+
+	if (adap_layer->dn != NULL)
+		phyid = cfsrvl_getphyid(adap_layer->dn);
+
+	phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
+	if (phyinfo == NULL) {
+		pr_warning("CAIF: %s(): No interface to send disconnect to\n",
+			   __func__);
+		ret = -ENODEV;
+		goto end;
+	}
+
+	if (phyinfo->id != phyid
+		|| phyinfo->phy_layer->id != phyid
+		|| phyinfo->frm_layer->id != phyid) {
+
+		pr_err("CAIF: %s(): Inconsistency in phy registration\n",
+			__func__);
+		ret = -EINVAL;
+		goto end;
+	}
+
+	ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
+
+end:
+	if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 &&
+		phyinfo->phy_layer != NULL &&
+		phyinfo->phy_layer->modemcmd != NULL) {
+		phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
+					     _CAIF_MODEMCMD_PHYIF_USELESS);
+	}
+	return ret;
+
+}
+EXPORT_SYMBOL(cfcnfg_del_adapt_layer);
+
+static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid,
+				  struct cflayer *client_layer)
+{
+	struct cfcnfg *cnfg = container_obj(layer);
+	struct cflayer *servl;
+
+	/*
+	 * 1) Remove service from the MUX layer. The MUX must
+	 *    guarante that no more payload sent "upwards" (receive)
+	 */
+	servl = cfmuxl_remove_uplayer(cnfg->mux, linkid);
+
+	if (servl == NULL) {
+		pr_err("CAIF: %s(): PROTOCOL ERROR "
+		       "- Error removing service_layer Linkid(%d)",
+			__func__, linkid);
+		return;
+	}
+	caif_assert(linkid == servl->id);
+
+	if (servl != client_layer && servl->up != client_layer) {
+		pr_err("CAIF: %s(): Error removing service_layer "
+		       "Linkid(%d) %p %p",
+			__func__, linkid, (void *) servl,
+			(void *) client_layer);
+		return;
+	}
+
+	/*
+	 * 2) DEINIT_RSP must guarantee that no more packets are transmitted
+	 *    from client (adap_layer) when it returns.
+	 */
+
+	if (servl->ctrlcmd == NULL) {
+		pr_err("CAIF: %s(): Error servl->ctrlcmd == NULL", __func__);
+		return;
+	}
+
+	servl->ctrlcmd(servl, CAIF_CTRLCMD_DEINIT_RSP, 0);
+
+	/* 3) It is now safe to destroy the service layer. */
+	cfservl_destroy(servl);
+}
+
+/*
+ * NOTE: What happens on linksetup failure:
+ *	 1a) No response - Too early
+ *	      This will not happen because enumerate is secured
+ *	      before using interface.
+ *	 1b) No response - FATAL
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ *	      Modem error, response is really expected -  this case is
+ *	      not really handled.
+ *	 2) O/E-bit indicate error
+ *	      Handled in cnfg_reject_rsp
+ *	 3) Not able to match on request
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ *	 4) Link-Error - (no response)
+ *	      Not handled, but this should be a CAIF PROTOCOL ERROR
+ */
+
+int
+cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
+				struct cfctrl_link_param *param,
+				struct cflayer *adap_layer)
+{
+	struct cflayer *frml;
+	if (adap_layer == NULL) {
+		pr_err("CAIF: %s(): adap_layer is zero", __func__);
+		return -EINVAL;
+	}
+	if (adap_layer->receive == NULL) {
+		pr_err("CAIF: %s(): adap_layer->receive is NULL", __func__);
+		return -EINVAL;
+	}
+	if (adap_layer->ctrlcmd == NULL) {
+		pr_err("CAIF: %s(): adap_layer->ctrlcmd == NULL", __func__);
+		return -EINVAL;
+	}
+	frml = cnfg->phy_layers[param->phyid].frm_layer;
+	if (frml == NULL) {
+		pr_err("CAIF: %s(): Specified PHY type does not exist!",
+			__func__);
+		return -ENODEV;
+	}
+	caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id);
+	caif_assert(cnfg->phy_layers[param->phyid].frm_layer->id ==
+		     param->phyid);
+	caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id ==
+		     param->phyid);
+	/* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
+	cfctrl_enum_req(cnfg->ctrl, param->phyid);
+	cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
+	return 0;
+}
+EXPORT_SYMBOL(cfcnfg_add_adaptation_layer);
+
+static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid,
+			     struct cflayer *adapt_layer)
+{
+	if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL)
+		adapt_layer->ctrlcmd(adapt_layer,
+				     CAIF_CTRLCMD_INIT_FAIL_RSP, 0);
+}
+
+static void
+cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv,
+		 u8 phyid, struct cflayer *adapt_layer)
+{
+	struct cfcnfg *cnfg = container_obj(layer);
+	struct cflayer *servicel = NULL;
+	struct cfcnfg_phyinfo *phyinfo;
+	if (adapt_layer == NULL) {
+		pr_err("CAIF: %s(): PROTOCOL ERROR "
+			"- LinkUp Request/Response did not match\n", __func__);
+		return;
+	}
+
+	caif_assert(cnfg != NULL);
+	caif_assert(phyid != 0);
+	phyinfo = &cnfg->phy_layers[phyid];
+	caif_assert(phyinfo != NULL);
+	caif_assert(phyinfo->id == phyid);
+	caif_assert(phyinfo->phy_layer != NULL);
+	caif_assert(phyinfo->phy_layer->id == phyid);
+
+	if (phyinfo != NULL &&
+	    phyinfo->phy_ref_count++ == 0 &&
+	    phyinfo->phy_layer != NULL &&
+	    phyinfo->phy_layer->modemcmd != NULL) {
+		caif_assert(phyinfo->phy_layer->id == phyid);
+		phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
+					     _CAIF_MODEMCMD_PHYIF_USEFULL);
+
+	}
+	adapt_layer->id = linkid;
+
+	switch (serv) {
+	case CFCTRL_SRV_VEI:
+		servicel = cfvei_create(linkid, &phyinfo->dev_info);
+		break;
+	case CFCTRL_SRV_DATAGRAM:
+		servicel = cfdgml_create(linkid, &phyinfo->dev_info);
+		break;
+	case CFCTRL_SRV_RFM:
+		servicel = cfrfml_create(linkid, &phyinfo->dev_info);
+		break;
+	case CFCTRL_SRV_UTIL:
+		servicel = cfutill_create(linkid, &phyinfo->dev_info);
+		break;
+	case CFCTRL_SRV_VIDEO:
+		servicel = cfvidl_create(linkid, &phyinfo->dev_info);
+		break;
+	case CFCTRL_SRV_DBG:
+		servicel = cfdbgl_create(linkid, &phyinfo->dev_info);
+		break;
+	default:
+		pr_err("CAIF: %s(): Protocol error. "
+			"Link setup response - unknown channel type\n",
+			__func__);
+		return;
+	}
+	if (!servicel) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	layer_set_dn(servicel, cnfg->mux);
+	cfmuxl_set_uplayer(cnfg->mux, servicel, linkid);
+	layer_set_up(servicel, adapt_layer);
+	layer_set_dn(adapt_layer, servicel);
+	servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
+}
+
+void
+cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
+		     void *dev, struct cflayer *phy_layer, u16 *phyid,
+		     enum cfcnfg_phy_preference pref,
+		     bool fcs, bool stx)
+{
+	struct cflayer *frml;
+	struct cflayer *phy_driver = NULL;
+	int i;
+
+
+	if (cnfg->phy_layers[cnfg->last_phyid].frm_layer == NULL) {
+		*phyid = cnfg->last_phyid;
+
+		/* range: * 1..(MAX_PHY_LAYERS-1) */
+		cnfg->last_phyid =
+		    (cnfg->last_phyid % (MAX_PHY_LAYERS - 1)) + 1;
+	} else {
+		*phyid = 0;
+		for (i = 1; i < MAX_PHY_LAYERS; i++) {
+			if (cnfg->phy_layers[i].frm_layer == NULL) {
+				*phyid = i;
+				break;
+			}
+		}
+	}
+	if (*phyid == 0) {
+		pr_err("CAIF: %s(): No Available PHY ID\n", __func__);
+		return;
+	}
+
+	switch (phy_type) {
+	case CFPHYTYPE_FRAG:
+		phy_driver =
+		    cfserl_create(CFPHYTYPE_FRAG, *phyid, stx);
+		if (!phy_driver) {
+			pr_warning("CAIF: %s(): Out of memory\n", __func__);
+			return;
+		}
+
+		break;
+	case CFPHYTYPE_CAIF:
+		phy_driver = NULL;
+		break;
+	default:
+		pr_err("CAIF: %s(): %d", __func__, phy_type);
+		return;
+		break;
+	}
+
+	phy_layer->id = *phyid;
+	cnfg->phy_layers[*phyid].pref = pref;
+	cnfg->phy_layers[*phyid].id = *phyid;
+	cnfg->phy_layers[*phyid].dev_info.id = *phyid;
+	cnfg->phy_layers[*phyid].dev_info.dev = dev;
+	cnfg->phy_layers[*phyid].phy_layer = phy_layer;
+	cnfg->phy_layers[*phyid].phy_ref_count = 0;
+	phy_layer->type = phy_type;
+	frml = cffrml_create(*phyid, fcs);
+	if (!frml) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cnfg->phy_layers[*phyid].frm_layer = frml;
+	cfmuxl_set_dnlayer(cnfg->mux, frml, *phyid);
+	layer_set_up(frml, cnfg->mux);
+
+	if (phy_driver != NULL) {
+		phy_driver->id = *phyid;
+		layer_set_dn(frml, phy_driver);
+		layer_set_up(phy_driver, frml);
+		layer_set_dn(phy_driver, phy_layer);
+		layer_set_up(phy_layer, phy_driver);
+	} else {
+		layer_set_dn(frml, phy_layer);
+		layer_set_up(phy_layer, frml);
+	}
+}
+EXPORT_SYMBOL(cfcnfg_add_phy_layer);
+
+int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
+{
+	struct cflayer *frml, *frml_dn;
+	u16 phyid;
+	phyid = phy_layer->id;
+	caif_assert(phyid == cnfg->phy_layers[phyid].id);
+	caif_assert(phy_layer == cnfg->phy_layers[phyid].phy_layer);
+	caif_assert(phy_layer->id == phyid);
+	caif_assert(cnfg->phy_layers[phyid].frm_layer->id == phyid);
+
+	memset(&cnfg->phy_layers[phy_layer->id], 0,
+	       sizeof(struct cfcnfg_phyinfo));
+	frml = cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id);
+	frml_dn = frml->dn;
+	cffrml_set_uplayer(frml, NULL);
+	cffrml_set_dnlayer(frml, NULL);
+	cffrml_destroy(frml);
+
+	if (phy_layer != frml_dn) {
+		layer_set_up(frml_dn, NULL);
+		layer_set_dn(frml_dn, NULL);
+		kfree(frml_dn);
+	}
+	layer_set_up(phy_layer, NULL);
+	return 0;
+}
+EXPORT_SYMBOL(cfcnfg_del_phy_layer);
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
new file mode 100644
index 0000000..6c2a010
--- /dev/null
+++ b/net/caif/cfpkt_skbuff.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/hardirq.h>
+#include <net/caif/cfpkt.h>
+
+#define PKT_PREFIX CAIF_NEEDED_HEADROOM
+#define PKT_POSTFIX CAIF_NEEDED_TAILROOM
+#define PKT_LEN_WHEN_EXTENDING 128
+#define PKT_ERROR(pkt, errmsg) do {	   \
+    cfpkt_priv(pkt)->erronous = true;	   \
+    skb_reset_tail_pointer(&pkt->skb);	   \
+    pr_warning("CAIF: " errmsg);\
+  } while (0)
+
+struct cfpktq {
+	struct sk_buff_head head;
+	atomic_t count;
+	spinlock_t lock;
+};
+
+/*
+ * net/caif/ is generic and does not
+ * understand SKB, so we do this typecast
+ */
+struct cfpkt {
+	struct sk_buff skb;
+};
+
+/* Private data inside SKB */
+struct cfpkt_priv_data {
+	struct dev_info dev_info;
+	bool erronous;
+};
+
+inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
+{
+	return (struct cfpkt_priv_data *) pkt->skb.cb;
+}
+
+inline bool is_erronous(struct cfpkt *pkt)
+{
+	return cfpkt_priv(pkt)->erronous;
+}
+
+inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
+{
+	return &pkt->skb;
+}
+
+inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
+{
+	return (struct cfpkt *) skb;
+}
+
+atomic_t cfpkt_packet_count;
+EXPORT_SYMBOL(cfpkt_packet_count);
+
+struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt)
+{
+	struct cfpkt *pkt = skb_to_pkt(nativepkt);
+	cfpkt_priv(pkt)->erronous = false;
+	atomic_inc(&cfpkt_packet_count);
+	return pkt;
+}
+EXPORT_SYMBOL(cfpkt_fromnative);
+
+void *cfpkt_tonative(struct cfpkt *pkt)
+{
+	return (void *) pkt;
+}
+EXPORT_SYMBOL(cfpkt_tonative);
+
+struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
+{
+	struct sk_buff *skb;
+
+	if (likely(in_interrupt()))
+		skb = alloc_skb(len + pfx, GFP_ATOMIC);
+	else
+		skb = alloc_skb(len + pfx, GFP_KERNEL);
+
+	if (unlikely(skb == NULL))
+		return NULL;
+
+	skb_reserve(skb, pfx);
+	atomic_inc(&cfpkt_packet_count);
+	return skb_to_pkt(skb);
+}
+
+inline struct cfpkt *cfpkt_create(u16 len)
+{
+	return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
+}
+EXPORT_SYMBOL(cfpkt_create);
+
+void cfpkt_destroy(struct cfpkt *pkt)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	atomic_dec(&cfpkt_packet_count);
+	caif_assert(atomic_read(&cfpkt_packet_count) >= 0);
+	kfree_skb(skb);
+}
+EXPORT_SYMBOL(cfpkt_destroy);
+
+inline bool cfpkt_more(struct cfpkt *pkt)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	return skb->len > 0;
+}
+EXPORT_SYMBOL(cfpkt_more);
+
+int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	if (skb->tail - skb->data >= len) {
+		memcpy(data, skb->data, len);
+		return 0;
+	}
+	return !cfpkt_extr_head(pkt, data, len) &&
+	    !cfpkt_add_head(pkt, data, len);
+}
+EXPORT_SYMBOL(cfpkt_peek_head);
+
+int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	u8 *from;
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+
+	if (unlikely(len > skb->len)) {
+		PKT_ERROR(pkt, "cfpkt_extr_head read beyond end of packet\n");
+		return -EPROTO;
+	}
+
+	if (unlikely(len > skb_headlen(skb))) {
+		if (unlikely(skb_linearize(skb) != 0)) {
+			PKT_ERROR(pkt, "cfpkt_extr_head linearize failed\n");
+			return -EPROTO;
+		}
+	}
+	from = skb_pull(skb, len);
+	from -= len;
+	memcpy(data, from, len);
+	return 0;
+}
+EXPORT_SYMBOL(cfpkt_extr_head);
+
+int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	u8 *data = dta;
+	u8 *from;
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+
+	if (unlikely(skb_linearize(skb) != 0)) {
+		PKT_ERROR(pkt, "cfpkt_extr_trail linearize failed\n");
+		return -EPROTO;
+	}
+	if (unlikely(skb->data + len > skb_tail_pointer(skb))) {
+		PKT_ERROR(pkt, "cfpkt_extr_trail read beyond end of packet\n");
+		return -EPROTO;
+	}
+	from = skb_tail_pointer(skb) - len;
+	skb_trim(skb, skb->len - len);
+	memcpy(data, from, len);
+	return 0;
+}
+EXPORT_SYMBOL(cfpkt_extr_trail);
+
+int cfpkt_pad_trail(struct cfpkt *pkt, u16 len)
+{
+	return cfpkt_add_body(pkt, NULL, len);
+}
+EXPORT_SYMBOL(cfpkt_pad_trail);
+
+int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	struct sk_buff *lastskb;
+	u8 *to;
+	u16 addlen = 0;
+
+
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+
+	lastskb = skb;
+
+	/* Check whether we need to add space at the tail */
+	if (unlikely(skb_tailroom(skb) < len)) {
+		if (likely(len < PKT_LEN_WHEN_EXTENDING))
+			addlen = PKT_LEN_WHEN_EXTENDING;
+		else
+			addlen = len;
+	}
+
+	/* Check whether we need to change the SKB before writing to the tail */
+	if (unlikely((addlen > 0) || skb_cloned(skb) || skb_shared(skb))) {
+
+		/* Make sure data is writable */
+		if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) {
+			PKT_ERROR(pkt, "cfpkt_add_body: cow failed\n");
+			return -EPROTO;
+		}
+		/*
+		 * Is the SKB non-linear after skb_cow_data()? If so, we are
+		 * going to add data to the last SKB, so we need to adjust
+		 * lengths of the top SKB.
+		 */
+		if (lastskb != skb) {
+			pr_warning("CAIF: %s(): Packet is non-linear\n",
+				   __func__);
+			skb->len += len;
+			skb->data_len += len;
+		}
+	}
+
+	/* All set to put the last SKB and optionally write data there. */
+	to = skb_put(lastskb, len);
+	if (likely(data))
+		memcpy(to, data, len);
+	return 0;
+}
+EXPORT_SYMBOL(cfpkt_add_body);
+
+inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data)
+{
+	return cfpkt_add_body(pkt, &data, 1);
+}
+EXPORT_SYMBOL(cfpkt_addbdy);
+
+int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	struct sk_buff *lastskb;
+	u8 *to;
+	const u8 *data = data2;
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+	if (unlikely(skb_headroom(skb) < len)) {
+		PKT_ERROR(pkt, "cfpkt_add_head: no headroom\n");
+		return -EPROTO;
+	}
+
+	/* Make sure data is writable */
+	if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) {
+		PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n");
+		return -EPROTO;
+	}
+
+	to = skb_push(skb, len);
+	memcpy(to, data, len);
+	return 0;
+}
+EXPORT_SYMBOL(cfpkt_add_head);
+
+inline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len)
+{
+	return cfpkt_add_body(pkt, data, len);
+}
+EXPORT_SYMBOL(cfpkt_add_trail);
+
+inline u16 cfpkt_getlen(struct cfpkt *pkt)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	return skb->len;
+}
+EXPORT_SYMBOL(cfpkt_getlen);
+
+inline u16 cfpkt_iterate(struct cfpkt *pkt,
+			    u16 (*iter_func)(u16, void *, u16),
+			    u16 data)
+{
+	/*
+	 * Don't care about the performance hit of linearizing,
+	 * Checksum should not be used on high-speed interfaces anyway.
+	 */
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+	if (unlikely(skb_linearize(&pkt->skb) != 0)) {
+		PKT_ERROR(pkt, "cfpkt_iterate: linearize failed\n");
+		return -EPROTO;
+	}
+	return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
+}
+EXPORT_SYMBOL(cfpkt_iterate);
+
+int cfpkt_setlen(struct cfpkt *pkt, u16 len)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+
+
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+
+	if (likely(len <= skb->len)) {
+		if (unlikely(skb->data_len))
+			___pskb_trim(skb, len);
+		else
+			skb_trim(skb, len);
+
+			return cfpkt_getlen(pkt);
+	}
+
+	/* Need to expand SKB */
+	if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len)))
+		PKT_ERROR(pkt, "cfpkt_setlen: skb_pad_trail failed\n");
+
+	return cfpkt_getlen(pkt);
+}
+EXPORT_SYMBOL(cfpkt_setlen);
+
+struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len)
+{
+	struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
+	if (unlikely(data != NULL))
+		cfpkt_add_body(pkt, data, len);
+	return pkt;
+}
+EXPORT_SYMBOL(cfpkt_create_uplink);
+
+
+struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
+			     struct cfpkt *addpkt,
+			     u16 expectlen)
+{
+	struct sk_buff *dst = pkt_to_skb(dstpkt);
+	struct sk_buff *add = pkt_to_skb(addpkt);
+	u16 addlen = add->tail - add->data;
+	u16 neededtailspace;
+	struct sk_buff *tmp;
+	u16 dstlen;
+	u16 createlen;
+	if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
+		cfpkt_destroy(addpkt);
+		return dstpkt;
+	}
+	if (expectlen > addlen)
+		neededtailspace = expectlen;
+	else
+		neededtailspace = addlen;
+
+	if (dst->tail + neededtailspace > dst->end) {
+		/* Create a dumplicate of 'dst' with more tail space */
+		dstlen = dst->tail - dst->data;
+		createlen = dstlen + neededtailspace;
+		tmp = pkt_to_skb(
+			cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX));
+		if (!tmp)
+			return NULL;
+		tmp->tail = tmp->data + dstlen;
+		tmp->len = dstlen;
+		memcpy(tmp->data, dst->data, dstlen);
+		cfpkt_destroy(dstpkt);
+		dst = tmp;
+	}
+	memcpy(dst->tail, add->data, add->tail - add->data);
+	cfpkt_destroy(addpkt);
+	dst->tail += addlen;
+	dst->len += addlen;
+	return skb_to_pkt(dst);
+}
+EXPORT_SYMBOL(cfpkt_append);
+
+struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
+{
+	struct sk_buff *skb2;
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	u8 *split = skb->data + pos;
+	u16 len2nd = skb->tail - split;
+
+	if (unlikely(is_erronous(pkt)))
+		return NULL;
+
+	if (skb->data + pos > skb->tail) {
+		PKT_ERROR(pkt,
+			  "cfpkt_split: trying to split beyond end of packet");
+		return NULL;
+	}
+
+	/* Create a new packet for the second part of the data */
+	skb2 = pkt_to_skb(
+		cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
+				 PKT_PREFIX));
+
+	if (skb2 == NULL)
+		return NULL;
+
+	/* Reduce the length of the original packet */
+	skb->tail = split;
+	skb->len = pos;
+
+	memcpy(skb2->data, split, len2nd);
+	skb2->tail += len2nd;
+	skb2->len += len2nd;
+	return skb_to_pkt(skb2);
+}
+EXPORT_SYMBOL(cfpkt_split);
+
+
+char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	char *p = buf;
+	int i;
+
+	/*
+	 * Sanity check buffer length, it needs to be at least as large as
+	 * the header info: ~=50+ bytes
+	 */
+	if (buflen < 50)
+		return NULL;
+
+	snprintf(buf, buflen, "%s: pkt:%p len:%d(%d+%d) {%d,%d} data: [",
+		is_erronous(pkt) ? "ERRONOUS-SKB" :
+		 (skb->data_len != 0 ? "COMPLEX-SKB" : "SKB"),
+		skb,
+		skb->len,
+		skb->tail - skb->data,
+		skb->data_len,
+		skb->data - skb->head, skb->tail - skb->head);
+	p = buf + strlen(buf);
+
+	for (i = 0; i < skb->tail - skb->data && i < 300; i++) {
+		if (p > buf + buflen - 10) {
+			sprintf(p, "...");
+			p = buf + strlen(buf);
+			break;
+		}
+		sprintf(p, "%02x,", skb->data[i]);
+		p = buf + strlen(buf);
+	}
+	sprintf(p, "]\n");
+	return buf;
+}
+EXPORT_SYMBOL(cfpkt_log_pkt);
+
+int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+	struct sk_buff *lastskb;
+
+	caif_assert(buf != NULL);
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+	/* Make sure SKB is writable */
+	if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) {
+		PKT_ERROR(pkt, "cfpkt_raw_append: skb_cow_data failed\n");
+		return -EPROTO;
+	}
+
+	if (unlikely(skb_linearize(skb) != 0)) {
+		PKT_ERROR(pkt, "cfpkt_raw_append: linearize failed\n");
+		return -EPROTO;
+	}
+
+	if (unlikely(skb_tailroom(skb) < buflen)) {
+		PKT_ERROR(pkt, "cfpkt_raw_append: buffer too short - failed\n");
+		return -EPROTO;
+	}
+
+	*buf = skb_put(skb, buflen);
+	return 1;
+}
+EXPORT_SYMBOL(cfpkt_raw_append);
+
+int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen)
+{
+	struct sk_buff *skb = pkt_to_skb(pkt);
+
+	caif_assert(buf != NULL);
+	if (unlikely(is_erronous(pkt)))
+		return -EPROTO;
+
+	if (unlikely(buflen > skb->len)) {
+		PKT_ERROR(pkt, "cfpkt_raw_extract: buflen too large "
+				"- failed\n");
+		return -EPROTO;
+	}
+
+	if (unlikely(buflen > skb_headlen(skb))) {
+		if (unlikely(skb_linearize(skb) != 0)) {
+			PKT_ERROR(pkt, "cfpkt_raw_extract: linearize failed\n");
+			return -EPROTO;
+		}
+	}
+
+	*buf = skb->data;
+	skb_pull(skb, buflen);
+
+	return 1;
+}
+EXPORT_SYMBOL(cfpkt_raw_extract);
+
+inline bool cfpkt_erroneous(struct cfpkt *pkt)
+{
+	return cfpkt_priv(pkt)->erronous;
+}
+EXPORT_SYMBOL(cfpkt_erroneous);
+
+struct cfpkt *cfpkt_create_pkt(enum caif_direction dir,
+			  const unsigned char *data, unsigned int len)
+{
+	struct cfpkt *pkt;
+	if (dir == CAIF_DIR_OUT)
+		pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
+	else
+		pkt = cfpkt_create_pfx(len, 0);
+	if (unlikely(!pkt))
+		return NULL;
+	if (unlikely(data))
+		cfpkt_add_body(pkt, data, len);
+	cfpkt_priv(pkt)->erronous = false;
+	return pkt;
+}
+EXPORT_SYMBOL(cfpkt_create_pkt);
+
+struct cfpktq *cfpktq_create()
+{
+	struct cfpktq *q = kmalloc(sizeof(struct cfpktq), GFP_ATOMIC);
+	if (!q)
+		return NULL;
+	skb_queue_head_init(&q->head);
+	atomic_set(&q->count, 0);
+	spin_lock_init(&q->lock);
+	return q;
+}
+EXPORT_SYMBOL(cfpktq_create);
+
+void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio)
+{
+	atomic_inc(&pktq->count);
+	spin_lock(&pktq->lock);
+	skb_queue_tail(&pktq->head, pkt_to_skb(pkt));
+	spin_unlock(&pktq->lock);
+
+}
+EXPORT_SYMBOL(cfpkt_queue);
+
+struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq)
+{
+	struct cfpkt *tmp;
+	spin_lock(&pktq->lock);
+	tmp = skb_to_pkt(skb_peek(&pktq->head));
+	spin_unlock(&pktq->lock);
+	return tmp;
+}
+EXPORT_SYMBOL(cfpkt_qpeek);
+
+struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq)
+{
+	struct cfpkt *pkt;
+	spin_lock(&pktq->lock);
+	pkt = skb_to_pkt(skb_dequeue(&pktq->head));
+	if (pkt) {
+		atomic_dec(&pktq->count);
+		caif_assert(atomic_read(&pktq->count) >= 0);
+	}
+	spin_unlock(&pktq->lock);
+	return pkt;
+}
+EXPORT_SYMBOL(cfpkt_dequeue);
+
+int cfpkt_qcount(struct cfpktq *pktq)
+{
+	return atomic_read(&pktq->count);
+}
+EXPORT_SYMBOL(cfpkt_qcount);
+
+struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt)
+{
+	struct cfpkt *clone;
+	clone  = skb_to_pkt(skb_clone(pkt_to_skb(pkt), GFP_ATOMIC));
+	/* Free original packet. */
+	cfpkt_destroy(pkt);
+	if (!clone)
+		return NULL;
+	atomic_inc(&cfpkt_packet_count);
+	return clone;
+}
+EXPORT_SYMBOL(cfpkt_clone_release);
+
+struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
+{
+	return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
+}
+EXPORT_SYMBOL(cfpkt_info);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 07/12] net-caif: add CAIF device registration functionality
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-7-git-send-email-sjur.brandeland@stericsson.com>

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

Registration and deregistration of CAIF Link Layer.

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 net/caif/caif_config_util.c |   88 ++++++++++
 net/caif/caif_dev.c         |  394 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 482 insertions(+), 0 deletions(-)

diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c
new file mode 100644
index 0000000..af7daf8
--- /dev/null
+++ b/net/caif/caif_config_util.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <net/caif/cfctrl.h>
+#include <net/caif/cfcnfg.h>
+#include <net/caif/caif_dev.h>
+int connect_req_to_link_param(struct cfcnfg *cnfg,
+				struct caif_connect_request *s,
+				struct cfctrl_link_param *l)
+{
+	struct dev_info *dev_info;
+	enum cfcnfg_phy_preference pref;
+	memset(l, 0, sizeof(*l));
+	l->priority = s->priority;
+
+	if (s->link_name[0] != '\0')
+		l->phyid = cfcnfg_get_named(cnfg, s->link_name);
+	else {
+		switch (s->link_selector) {
+		case CAIF_LINK_HIGH_BANDW:
+			pref = CFPHYPREF_HIGH_BW;
+			break;
+		case CAIF_LINK_LOW_LATENCY:
+			pref = CFPHYPREF_LOW_LAT;
+			break;
+		default:
+			return -EINVAL;
+		}
+		dev_info = cfcnfg_get_phyid(cnfg, pref);
+		if (dev_info == NULL)
+			return -ENODEV;
+		l->phyid = dev_info->id;
+	}
+	switch (s->protocol) {
+	case CAIFPROTO_AT:
+		l->linktype = CFCTRL_SRV_VEI;
+		if (s->sockaddr.u.at.type == CAIF_ATTYPE_PLAIN)
+			l->chtype = 0x02;
+		else
+			l->chtype = s->sockaddr.u.at.type;
+		l->endpoint = 0x00;
+		break;
+	case CAIFPROTO_DATAGRAM:
+		l->linktype = CFCTRL_SRV_DATAGRAM;
+		l->chtype = 0x00;
+		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+		break;
+	case CAIFPROTO_DATAGRAM_LOOP:
+		l->linktype = CFCTRL_SRV_DATAGRAM;
+		l->chtype = 0x03;
+		l->endpoint = 0x00;
+		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
+		break;
+	case CAIFPROTO_RFM:
+		l->linktype = CFCTRL_SRV_RFM;
+		l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
+		strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
+			sizeof(l->u.rfm.volume)-1);
+		l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
+		break;
+	case CAIFPROTO_UTIL:
+		l->linktype = CFCTRL_SRV_UTIL;
+		l->endpoint = 0x00;
+		l->chtype = 0x00;
+		strncpy(l->u.utility.name, s->sockaddr.u.util.service,
+			sizeof(l->u.utility.name)-1);
+		l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
+		caif_assert(sizeof(l->u.utility.name) > 10);
+		l->u.utility.paramlen = s->param.size;
+		if (l->u.utility.paramlen > sizeof(l->u.utility.params))
+			l->u.utility.paramlen = sizeof(l->u.utility.params);
+
+		memcpy(l->u.utility.params, s->param.data,
+		       l->u.utility.paramlen);
+
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
new file mode 100644
index 0000000..2dd0b96
--- /dev/null
+++ b/net/caif/caif_dev.c
@@ -0,0 +1,394 @@
+/*
+ * CAIF Interface registration.
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Borrowed heavily from file: pn_dev.c. Thanks to
+ *  Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *  and Sakari Ailus <sakari.ailus@nokia.com>
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <net/netns/generic.h>
+#include <net/net_namespace.h>
+#include <net/pkt_sched.h>
+#include <net/caif/caif_device.h>
+#include <net/caif/caif_dev.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/cfcnfg.h>
+
+MODULE_LICENSE("GPL");
+#define TIMEOUT (HZ*1000)
+
+/* Used for local tracking of the CAIF net devices */
+struct caif_device_entry {
+	struct cflayer layer;
+	struct list_head list;
+	atomic_t in_use;
+	atomic_t state;
+	u16 phyid;
+	struct net_device *netdev;
+	wait_queue_head_t event;
+};
+
+struct caif_device_entry_list {
+	struct list_head list;
+	spinlock_t lock;
+};
+
+struct caif_net {
+	struct caif_device_entry_list caifdevs;
+};
+
+int caif_net_id;
+struct cfcnfg *cfg;
+
+struct caif_device_entry_list *caif_device_list(struct net *net)
+{
+	struct caif_net *caifn;
+	BUG_ON(!net);
+	caifn = net_generic(net, caif_net_id);
+	BUG_ON(!caifn);
+	return &caifn->caifdevs;
+}
+
+/* Allocate new CAIF device. */
+static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
+{
+	struct caif_device_entry_list *caifdevs;
+	struct caif_device_entry *caifd;
+	caifdevs = caif_device_list(dev_net(dev));
+	BUG_ON(!caifdevs);
+	caifd = kzalloc(sizeof(*caifd), GFP_ATOMIC);
+	if (!caifd)
+		return NULL;
+	caifd->netdev = dev;
+	list_add(&caifd->list, &caifdevs->list);
+	init_waitqueue_head(&caifd->event);
+	return caifd;
+}
+
+static struct caif_device_entry *caif_get(struct net_device *dev)
+{
+	struct caif_device_entry_list *caifdevs =
+	    caif_device_list(dev_net(dev));
+	struct caif_device_entry *caifd;
+	BUG_ON(!caifdevs);
+	list_for_each_entry(caifd, &caifdevs->list, list) {
+		if (caifd->netdev == dev)
+			return caifd;
+	}
+	return NULL;
+}
+
+static void caif_device_destroy(struct net_device *dev)
+{
+	struct caif_device_entry_list *caifdevs =
+	    caif_device_list(dev_net(dev));
+	struct caif_device_entry *caifd;
+	ASSERT_RTNL();
+	if (dev->type != ARPHRD_CAIF)
+		return;
+
+	spin_lock_bh(&caifdevs->lock);
+	caifd = caif_get(dev);
+	if (caifd == NULL) {
+		spin_unlock_bh(&caifdevs->lock);
+		return;
+	}
+
+	list_del(&caifd->list);
+	spin_unlock_bh(&caifdevs->lock);
+
+	kfree(caifd);
+	return;
+}
+
+static int transmit(struct cflayer *layer, struct cfpkt *pkt)
+{
+	struct caif_device_entry *caifd =
+	    container_of(layer, struct caif_device_entry, layer);
+	struct sk_buff *skb, *skb2;
+	int ret = -EINVAL;
+	skb = cfpkt_tonative(pkt);
+	skb->dev = caifd->netdev;
+	/*
+	 * Don't allow SKB to be destroyed upon error, but signal resend
+	 * notification to clients. We can't rely on the return value as
+	 * congestion (NET_XMIT_CN) sometimes drops the packet, sometimes don't.
+	 */
+	if (netif_queue_stopped(caifd->netdev))
+		return -EAGAIN;
+	skb2 = skb_get(skb);
+
+	ret = dev_queue_xmit(skb2);
+
+	if (!ret)
+		kfree_skb(skb);
+	else
+		return -EAGAIN;
+
+	return 0;
+}
+
+static int modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
+{
+	struct caif_device_entry *caifd;
+	struct caif_dev_common *caifdev;
+	caifd = container_of(layr, struct caif_device_entry, layer);
+	caifdev = netdev_priv(caifd->netdev);
+	if (ctrl == _CAIF_MODEMCMD_PHYIF_USEFULL) {
+		atomic_set(&caifd->in_use, 1);
+		wake_up_interruptible(&caifd->event);
+
+	} else if (ctrl == _CAIF_MODEMCMD_PHYIF_USELESS) {
+		atomic_set(&caifd->in_use, 0);
+		wake_up_interruptible(&caifd->event);
+	}
+	return 0;
+}
+
+/*
+ * Stuff received packets to associated sockets.
+ * On error, returns non-zero and releases the skb.
+ */
+static int receive(struct sk_buff *skb, struct net_device *dev,
+		   struct packet_type *pkttype, struct net_device *orig_dev)
+{
+	struct net *net;
+	struct cfpkt *pkt;
+	struct caif_device_entry *caifd;
+	net = dev_net(dev);
+	pkt = cfpkt_fromnative(CAIF_DIR_IN, skb);
+	caifd = caif_get(dev);
+	if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
+		return NET_RX_DROP;
+
+	if (caifd->layer.up->receive(caifd->layer.up, pkt))
+		return NET_RX_DROP;
+
+	return 0;
+}
+
+static struct packet_type caif_packet_type __read_mostly = {
+	.type = cpu_to_be16(ETH_P_CAIF),
+	.func = receive,
+};
+
+static void dev_flowctrl(struct net_device *dev, int on)
+{
+	struct caif_device_entry *caifd = caif_get(dev);
+	if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
+		return;
+
+	caifd->layer.up->ctrlcmd(caifd->layer.up,
+				 on ?
+				 _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND :
+				 _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
+				 caifd->layer.id);
+}
+
+/* notify Caif of device events */
+static int caif_device_notify(struct notifier_block *me, unsigned long what,
+			      void *arg)
+{
+	struct net_device *dev = arg;
+	struct caif_device_entry *caifd = NULL;
+	struct caif_dev_common *caifdev;
+	int res = -EINVAL;
+	enum cfcnfg_phy_type phy_type;
+
+	if (dev->type != ARPHRD_CAIF)
+		return 0;
+
+	switch (what) {
+	case NETDEV_REGISTER:
+		pr_info("CAIF: %s():register %s\n", __func__, dev->name);
+		caifd = caif_device_alloc(dev);
+		if (caifd == NULL)
+			break;
+		caifdev = netdev_priv(dev);
+		caifdev->flowctrl = dev_flowctrl;
+		atomic_set(&caifd->state, what);
+		res = 0;
+		break;
+
+	case NETDEV_UP:
+		pr_info("CAIF: %s(): up %s\n", __func__, dev->name);
+		caifd = caif_get(dev);
+		if (caifd == NULL)
+			break;
+		caifdev = netdev_priv(dev);
+		if (atomic_read(&caifd->state) == NETDEV_UP) {
+			pr_info("CAIF: %s():%s already up\n",
+				__func__, dev->name);
+			break;
+		}
+		atomic_set(&caifd->state, what);
+		caifd->layer.transmit = transmit;
+		caifd->layer.modemcmd = modemcmd;
+
+		if (caifdev->use_frag)
+			phy_type = CFPHYTYPE_FRAG;
+		else
+			phy_type = CFPHYTYPE_CAIF;
+
+		cfcnfg_add_phy_layer(get_caif_conf(),
+				     phy_type,
+				     dev,
+				     &caifd->layer,
+				     &caifd->phyid,
+				     caifdev->link_select,
+				     caifdev->use_fcs,
+				     caifdev->use_stx);
+		strncpy(caifd->layer.name, dev->name,
+			sizeof(caifd->layer.name) - 1);
+		caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0;
+		break;
+
+	case NETDEV_GOING_DOWN:
+		caifd = caif_get(dev);
+		if (caifd == NULL)
+			break;
+		pr_info("CAIF: %s():going down %s\n", __func__, dev->name);
+		atomic_set(&caifd->state, what);
+		if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd)
+			return -EINVAL;
+		caifd->layer.up->ctrlcmd(caifd->layer.up,
+					 _CAIF_CTRLCMD_PHYIF_DOWN_IND,
+					 caifd->layer.id);
+		res = wait_event_interruptible_timeout(caifd->event,
+					atomic_read(&caifd->in_use) == 0,
+					TIMEOUT);
+		break;
+
+	case NETDEV_DOWN:
+		caifd = caif_get(dev);
+		if (caifd == NULL)
+			break;
+		pr_info("CAIF: %s(): down %s\n", __func__, dev->name);
+		if (atomic_read(&caifd->in_use))
+			pr_warning("CAIF: %s(): "
+				   "Unregistering an active CAIF device: %s\n",
+				   __func__, dev->name);
+		cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer);
+		atomic_set(&caifd->state, what);
+		break;
+
+	case NETDEV_UNREGISTER:
+		caifd = caif_get(dev);
+		pr_info("CAIF: %s(): unregister %s\n", __func__, dev->name);
+		atomic_set(&caifd->state, what);
+		caif_device_destroy(dev);
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block caif_device_notifier = {
+	.notifier_call = caif_device_notify,
+	.priority = 0,
+};
+
+
+struct cfcnfg *get_caif_conf(void)
+{
+	return cfg;
+}
+EXPORT_SYMBOL(get_caif_conf);
+
+int caif_connect_client(struct caif_connect_request *conn_req,
+			   struct cflayer *client_layer)
+{
+	struct cfctrl_link_param param;
+	if (connect_req_to_link_param(get_caif_conf(), conn_req, &param) == 0)
+		/* Hook up the adaptation layer. */
+		return cfcnfg_add_adaptation_layer(get_caif_conf(),
+						&param, client_layer);
+
+	return -EINVAL;
+
+	caif_assert(0);
+}
+EXPORT_SYMBOL(caif_connect_client);
+
+int caif_disconnect_client(struct cflayer *adap_layer)
+{
+	return cfcnfg_del_adapt_layer(get_caif_conf(), adap_layer);
+}
+EXPORT_SYMBOL(caif_disconnect_client);
+
+/* Per-namespace Caif devices handling */
+static int caif_init_net(struct net *net)
+{
+	struct caif_net *caifn = net_generic(net, caif_net_id);
+	INIT_LIST_HEAD(&caifn->caifdevs.list);
+	spin_lock_init(&caifn->caifdevs.lock);
+	return 0;
+}
+
+static void caif_exit_net(struct net *net)
+{
+	struct net_device *dev;
+	int res;
+	rtnl_lock();
+	for_each_netdev(net, dev) {
+		if (dev->type != ARPHRD_CAIF)
+			continue;
+		res = dev_close(dev);
+		caif_device_destroy(dev);
+	}
+	rtnl_unlock();
+}
+
+static struct pernet_operations caif_net_ops = {
+	.init = caif_init_net,
+	.exit = caif_exit_net,
+	.id   = &caif_net_id,
+	.size = sizeof(struct caif_net),
+};
+
+/* Initialize Caif devices list */
+int __init caif_device_init(void)
+{
+	int result;
+	cfg = cfcnfg_create();
+	if (!cfg) {
+		pr_warning("CAIF: %s(): can't create cfcnfg.\n", __func__);
+		goto err_cfcnfg_create_failed;
+	}
+	result = register_pernet_device(&caif_net_ops);
+
+	if (result) {
+		kfree(cfg);
+		cfg = NULL;
+		return result;
+	}
+	dev_add_pack(&caif_packet_type);
+	register_netdevice_notifier(&caif_device_notifier);
+
+	return result;
+err_cfcnfg_create_failed:
+	return -ENODEV;
+}
+
+void __exit caif_device_exit(void)
+{
+	dev_remove_pack(&caif_packet_type);
+	unregister_pernet_device(&caif_net_ops);
+	unregister_netdevice_notifier(&caif_device_notifier);
+	cfcnfg_remove(cfg);
+}
+
+module_init(caif_device_init);
+module_exit(caif_device_exit);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 05/12] net-caif: add CAIF core protocol stack
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-5-git-send-email-sjur.brandeland@stericsson.com>

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

CAIF generic protocol implementation. This layer is
somewhat generic in order to be able to use and test it outside
the Linux Kernel.

cfctrl.c     - CAIF control protocol layer
cfdbgl.c     - CAIF debug protocol layer
cfdgml.c     - CAIF datagram protocol layer
cffrml.c     - CAIF framing protocol layer
cfmuxl.c     - CAIF mux protocol layer
cfrfml.c     - CAIF remote file manager protocol layer
cfserl.c     - CAIF serial (fragmentation) protocol layer
cfsrvl.c     - CAIF generic service layer functions
cfutill.c    - CAIF utility protocol layer
cfveil.c     - CAIF AT protocol layer
cfvidl.c     - CAIF video protocol layer

Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 net/caif/cfctrl.c  |  711 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/caif/cfdbgl.c  |   40 +++
 net/caif/cfdgml.c  |  108 ++++++++
 net/caif/cffrml.c  |  151 +++++++++++
 net/caif/cfmuxl.c  |  246 ++++++++++++++++++
 net/caif/cfrfml.c  |  106 ++++++++
 net/caif/cfserl.c  |  199 +++++++++++++++
 net/caif/cfsrvl.c  |  185 ++++++++++++++
 net/caif/cfutill.c |  115 +++++++++
 net/caif/cfveil.c  |  107 ++++++++
 net/caif/cfvidl.c  |   65 +++++
 11 files changed, 2033 insertions(+), 0 deletions(-)

diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
new file mode 100644
index 0000000..07c429c
--- /dev/null
+++ b/net/caif/cfctrl.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/cfctrl.h>
+
+#define container_obj(layr) container_of(layr, struct cfctrl, serv.layer)
+#define UTILITY_NAME_LENGTH 16
+#define CFPKT_CTRL_PKT_LEN 20
+
+
+#ifdef CAIF_NO_LOOP
+static inline int handle_loop(struct cfctrl *ctrl,
+			      int cmd, struct cfpkt *pkt){
+	return CAIF_FAILURE;
+}
+#else
+static int handle_loop(struct cfctrl *ctrl,
+		int cmd, struct cfpkt *pkt);
+#endif
+static int cfctrl_recv(struct cflayer *layr, struct cfpkt *pkt);
+static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+			   int phyid);
+
+
+struct cflayer *cfctrl_create()
+{
+	struct cfctrl *this =
+		kmalloc(sizeof(struct cfctrl), GFP_ATOMIC);
+	if (!this) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
+	memset(this, 0, sizeof(*this));
+	spin_lock_init(&this->info_list_lock);
+	atomic_set(&this->req_seq_no, 1);
+	atomic_set(&this->rsp_seq_no, 1);
+	this->serv.dev_info.id = 0xff;
+	this->serv.layer.id = 0;
+	this->serv.layer.receive = cfctrl_recv;
+	sprintf(this->serv.layer.name, "ctrl");
+	this->serv.layer.ctrlcmd = cfctrl_ctrlcmd;
+	spin_lock_init(&this->loop_linkid_lock);
+	this->loop_linkid = 1;
+	return &this->serv.layer;
+}
+
+bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2)
+{
+	bool eq =
+	    p1->linktype == p2->linktype &&
+	    p1->priority == p2->priority &&
+	    p1->phyid == p2->phyid &&
+	    p1->endpoint == p2->endpoint && p1->chtype == p2->chtype;
+
+	if (!eq)
+		return false;
+
+	switch (p1->linktype) {
+	case CFCTRL_SRV_VEI:
+		return true;
+	case CFCTRL_SRV_DATAGRAM:
+		return p1->u.datagram.connid == p2->u.datagram.connid;
+	case CFCTRL_SRV_RFM:
+		return
+		    p1->u.rfm.connid == p2->u.rfm.connid &&
+		    strcmp(p1->u.rfm.volume, p2->u.rfm.volume) == 0;
+	case CFCTRL_SRV_UTIL:
+		return
+		    p1->u.utility.fifosize_kb == p2->u.utility.fifosize_kb
+		    && p1->u.utility.fifosize_bufs ==
+		    p2->u.utility.fifosize_bufs
+		    && strcmp(p1->u.utility.name, p2->u.utility.name) == 0
+		    && p1->u.utility.paramlen == p2->u.utility.paramlen
+		    && memcmp(p1->u.utility.params, p2->u.utility.params,
+			      p1->u.utility.paramlen) == 0;
+
+	case CFCTRL_SRV_VIDEO:
+		return p1->u.video.connid == p2->u.video.connid;
+	case CFCTRL_SRV_DBG:
+		return true;
+	case CFCTRL_SRV_DECM:
+		return false;
+	default:
+		return false;
+	}
+	return false;
+}
+
+bool cfctrl_req_eq(struct cfctrl_request_info *r1,
+		   struct cfctrl_request_info *r2)
+{
+	if (r1->cmd != r2->cmd)
+		return false;
+	if (r1->cmd == CFCTRL_CMD_LINK_SETUP)
+		return param_eq(&r1->param, &r2->param);
+	else
+		return r1->channel_id == r2->channel_id;
+}
+
+/* Insert request at the end */
+void cfctrl_insert_req(struct cfctrl *ctrl,
+			      struct cfctrl_request_info *req)
+{
+	struct cfctrl_request_info *p;
+	spin_lock(&ctrl->info_list_lock);
+	req->next = NULL;
+	atomic_inc(&ctrl->req_seq_no);
+	req->sequence_no = atomic_read(&ctrl->req_seq_no);
+	if (ctrl->first_req == NULL) {
+		ctrl->first_req = req;
+		spin_unlock(&ctrl->info_list_lock);
+		return;
+	}
+	p = ctrl->first_req;
+	while (p->next != NULL)
+		p = p->next;
+	p->next = req;
+	spin_unlock(&ctrl->info_list_lock);
+}
+
+static void cfctrl_insert_req2(struct cfctrl *ctrl, enum cfctrl_cmd cmd,
+			       u8 linkid, struct cflayer *user_layer)
+{
+	struct cfctrl_request_info *req = kmalloc(sizeof(*req), GFP_KERNEL);
+	if (!req) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	req->client_layer = user_layer;
+	req->cmd = cmd;
+	req->channel_id = linkid;
+	cfctrl_insert_req(ctrl, req);
+}
+
+/* Compare and remove request */
+struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
+					      struct cfctrl_request_info *req)
+{
+	struct cfctrl_request_info *p;
+	struct cfctrl_request_info *ret;
+
+	spin_lock(&ctrl->info_list_lock);
+	if (ctrl->first_req == NULL) {
+		spin_unlock(&ctrl->info_list_lock);
+		return NULL;
+	}
+
+	if (cfctrl_req_eq(req, ctrl->first_req)) {
+		ret = ctrl->first_req;
+		atomic_set(&ctrl->rsp_seq_no,
+				 ctrl->first_req->sequence_no);
+		ctrl->first_req = ctrl->first_req->next;
+		spin_unlock(&ctrl->info_list_lock);
+		return ret;
+	}
+
+	pr_warning("CAIF: %s(): Requests are not received in order/matching\n",
+		   __func__);
+
+	p = ctrl->first_req;
+
+	while (p->next != NULL) {
+		if (cfctrl_req_eq(req, p->next)) {
+			ret = p->next;
+			atomic_set(&ctrl->rsp_seq_no,
+					 p->next->sequence_no);
+			p = p->next;
+			spin_unlock(&ctrl->info_list_lock);
+			return ret;
+		}
+		p = p->next;
+	}
+	spin_unlock(&ctrl->info_list_lock);
+	return NULL;
+}
+
+/* Compare and remove old requests based on sequence no. */
+void cfctrl_prune_req(struct cfctrl *ctrl)
+{
+	struct cfctrl_request_info *p;
+	struct cfctrl_request_info *del;
+
+	spin_lock(&ctrl->info_list_lock);
+	if (ctrl->first_req == NULL) {
+		spin_unlock(&ctrl->info_list_lock);
+		return;
+	}
+
+	if (ctrl->first_req->sequence_no <
+	    atomic_read(&ctrl->req_seq_no)) {
+		del = ctrl->first_req;
+		ctrl->first_req = ctrl->first_req->next;
+		kfree(del);
+	}
+	p = ctrl->first_req;
+	while (p->next != NULL) {
+		if (p->next->sequence_no <
+		    atomic_read(&ctrl->rsp_seq_no)) {
+			del = p->next;
+			p = p->next;
+			atomic_set(&ctrl->rsp_seq_no,
+					 ctrl->first_req->sequence_no);
+			kfree(del);
+		}
+		p = p->next;
+	}
+	spin_unlock(&ctrl->info_list_lock);
+}
+
+struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer)
+{
+	struct cfctrl *this = container_obj(layer);
+	return &this->res;
+}
+
+void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn)
+{
+	this->dn = dn;
+}
+
+void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up)
+{
+	this->up = up;
+}
+
+void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl)
+{
+	info->hdr_len = 0;
+	info->channel_id = cfctrl->serv.layer.id;
+	info->dev_info = &cfctrl->serv.dev_info;
+}
+
+void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
+{
+	struct cfctrl *cfctrl = container_obj(layer);
+	int ret;
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
+	init_info(cfpkt_info(pkt), cfctrl);
+	cfpkt_info(pkt)->dev_info->id = physlinkid;
+	cfctrl->serv.dev_info.id = physlinkid;
+	cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM);
+	cfpkt_addbdy(pkt, physlinkid);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0) {
+		pr_err("CAIF: %s(): Could not transmit enum message\n",
+			__func__);
+		cfpkt_destroy(pkt);
+	}
+}
+
+void cfctrl_linkup_request(struct cflayer *layer,
+			   struct cfctrl_link_param *param,
+			   struct cflayer *user_layer)
+{
+	struct cfctrl *cfctrl = container_obj(layer);
+	u32 tmp32;
+	u16 tmp16;
+	u8 tmp8;
+	struct cfctrl_request_info *req;
+	int ret;
+	char utility_name[16];
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP);
+	cfpkt_addbdy(pkt, (param->chtype << 4) + param->linktype);
+	cfpkt_addbdy(pkt, (param->priority << 3) + param->phyid);
+	cfpkt_addbdy(pkt, param->endpoint & 0x03);
+
+	switch (param->linktype) {
+	case CFCTRL_SRV_VEI:
+		break;
+	case CFCTRL_SRV_VIDEO:
+		cfpkt_addbdy(pkt, (u8) param->u.video.connid);
+		break;
+	case CFCTRL_SRV_DBG:
+		break;
+	case CFCTRL_SRV_DATAGRAM:
+		tmp32 = cpu_to_le32(param->u.datagram.connid);
+		cfpkt_add_body(pkt, &tmp32, 4);
+		break;
+	case CFCTRL_SRV_RFM:
+		/* Construct a frame, convert DatagramConnectionID to network
+		 * format long and copy it out...
+		 */
+		tmp32 = cpu_to_le32(param->u.rfm.connid);
+		cfpkt_add_body(pkt, &tmp32, 4);
+		/* Add volume name, including zero termination... */
+		cfpkt_add_body(pkt, param->u.rfm.volume,
+			       strlen(param->u.rfm.volume) + 1);
+		break;
+	case CFCTRL_SRV_UTIL:
+		tmp16 = cpu_to_le16(param->u.utility.fifosize_kb);
+		cfpkt_add_body(pkt, &tmp16, 2);
+		tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs);
+		cfpkt_add_body(pkt, &tmp16, 2);
+		memset(utility_name, 0, sizeof(utility_name));
+		strncpy(utility_name, param->u.utility.name,
+			UTILITY_NAME_LENGTH - 1);
+		cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH);
+		tmp8 = param->u.utility.paramlen;
+		cfpkt_add_body(pkt, &tmp8, 1);
+		cfpkt_add_body(pkt, param->u.utility.params,
+			       param->u.utility.paramlen);
+		break;
+	default:
+		pr_warning("CAIF: %s():Request setup of bad link type = %d\n",
+			   __func__, param->linktype);
+	}
+	req = kmalloc(sizeof(*req), GFP_KERNEL);
+	if (!req) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	memset(req, 0, sizeof(*req));
+	req->client_layer = user_layer;
+	req->cmd = CFCTRL_CMD_LINK_SETUP;
+	req->param = *param;
+	cfctrl_insert_req(cfctrl, req);
+	init_info(cfpkt_info(pkt), cfctrl);
+	cfpkt_info(pkt)->dev_info->id = param->phyid;
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0) {
+		pr_err("CAIF: %s(): Could not transmit linksetup request\n",
+			__func__);
+		cfpkt_destroy(pkt);
+	}
+}
+
+int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
+				struct cflayer *client)
+{
+	int ret;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return -ENOMEM;
+	}
+	cfctrl_insert_req2(cfctrl, CFCTRL_CMD_LINK_DESTROY, channelid, client);
+	cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
+	cfpkt_addbdy(pkt, channelid);
+	init_info(cfpkt_info(pkt), cfctrl);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0) {
+		pr_err("CAIF: %s(): Could not transmit link-down request\n",
+			__func__);
+		cfpkt_destroy(pkt);
+	}
+	return ret;
+}
+
+void cfctrl_sleep_req(struct cflayer *layer)
+{
+	int ret;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP);
+	init_info(cfpkt_info(pkt), cfctrl);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0)
+		cfpkt_destroy(pkt);
+}
+
+void cfctrl_wake_req(struct cflayer *layer)
+{
+	int ret;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE);
+	init_info(cfpkt_info(pkt), cfctrl);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0)
+		cfpkt_destroy(pkt);
+}
+
+void cfctrl_getstartreason_req(struct cflayer *layer)
+{
+	int ret;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON);
+	init_info(cfpkt_info(pkt), cfctrl);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0)
+		cfpkt_destroy(pkt);
+}
+
+void cfctrl_setmode_req(struct cflayer *layer, u8 mode)
+{
+	int ret;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return;
+	}
+	cfpkt_addbdy(pkt, CFCTRL_CMD_RADIO_SET);
+	cfpkt_addbdy(pkt, mode);
+	init_info(cfpkt_info(pkt), cfctrl);
+	ret =
+	    cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt);
+	if (ret < 0)
+		cfpkt_destroy(pkt);
+}
+
+static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
+{
+	u8 cmdrsp;
+	u8 cmd;
+	int ret = -1;
+	u16 tmp16;
+	u8 len;
+	u8 param[255];
+	u8 linkid;
+	struct cfctrl *cfctrl = container_obj(layer);
+	struct cfctrl_request_info rsp, *req;
+
+
+	cfpkt_extr_head(pkt, &cmdrsp, 1);
+	cmd = cmdrsp & CFCTRL_CMD_MASK;
+	if (cmd != CFCTRL_CMD_LINK_ERR
+	    && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) {
+		if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) {
+			pr_info("CAIF: %s() CAIF Protocol error:"
+				"Response bit not set\n", __func__);
+			goto error;
+		}
+	}
+
+	switch (cmd) {
+	case CFCTRL_CMD_LINK_SETUP:
+		{
+			enum cfctrl_srv serv;
+			enum cfctrl_srv servtype;
+			u8 endpoint;
+			u8 physlinkid;
+			u8 prio;
+			u8 tmp;
+			u32 tmp32;
+			u8 *cp;
+			int i;
+			struct cfctrl_link_param linkparam;
+			memset(&linkparam, 0, sizeof(linkparam));
+
+			cfpkt_extr_head(pkt, &tmp, 1);
+
+			serv = tmp & CFCTRL_SRV_MASK;
+			linkparam.linktype = serv;
+
+			servtype = tmp >> 4;
+			linkparam.chtype = servtype;
+
+			cfpkt_extr_head(pkt, &tmp, 1);
+			physlinkid = tmp & 0x07;
+			prio = tmp >> 3;
+
+			linkparam.priority = prio;
+			linkparam.phyid = physlinkid;
+			cfpkt_extr_head(pkt, &endpoint, 1);
+			linkparam.endpoint = endpoint & 0x03;
+
+			switch (serv) {
+			case CFCTRL_SRV_VEI:
+			case CFCTRL_SRV_DBG:
+				/* Link ID */
+				cfpkt_extr_head(pkt, &linkid, 1);
+				break;
+			case CFCTRL_SRV_VIDEO:
+				cfpkt_extr_head(pkt, &tmp, 1);
+				linkparam.u.video.connid = tmp;
+				/* Link ID */
+				cfpkt_extr_head(pkt, &linkid, 1);
+				break;
+
+			case CFCTRL_SRV_DATAGRAM:
+				cfpkt_extr_head(pkt, &tmp32, 4);
+				linkparam.u.datagram.connid =
+				    le32_to_cpu(tmp32);
+				/* Link ID */
+				cfpkt_extr_head(pkt, &linkid, 1);
+				break;
+			case CFCTRL_SRV_RFM:
+				/* Construct a frame, convert
+				 * DatagramConnectionID
+				 * to network format long and copy it out...
+				 */
+				cfpkt_extr_head(pkt, &tmp32, 4);
+				linkparam.u.rfm.connid =
+				  le32_to_cpu(tmp32);
+				cp = (u8 *) linkparam.u.rfm.volume;
+				for (cfpkt_extr_head(pkt, &tmp, 1);
+				     cfpkt_more(pkt) && tmp != '\0';
+				     cfpkt_extr_head(pkt, &tmp, 1))
+					*cp++ = tmp;
+				*cp = '\0';
+
+				/* Link ID */
+				cfpkt_extr_head(pkt, &linkid, 1);
+
+				break;
+			case CFCTRL_SRV_UTIL:
+				/* Construct a frame, convert
+				 * DatagramConnectionID
+				 * to network format long and copy it out...
+				 */
+				/* Fifosize KB */
+				cfpkt_extr_head(pkt, &tmp16, 2);
+				linkparam.u.utility.fifosize_kb =
+				    le16_to_cpu(tmp16);
+				/* Fifosize bufs */
+				cfpkt_extr_head(pkt, &tmp16, 2);
+				linkparam.u.utility.fifosize_bufs =
+				    le16_to_cpu(tmp16);
+				/* name */
+				cp = (u8 *) linkparam.u.utility.name;
+				caif_assert(sizeof(linkparam.u.utility.name)
+					     >= UTILITY_NAME_LENGTH);
+				for (i = 0;
+				     i < UTILITY_NAME_LENGTH
+				     && cfpkt_more(pkt); i++) {
+					cfpkt_extr_head(pkt, &tmp, 1);
+					*cp++ = tmp;
+				}
+				/* Length */
+				cfpkt_extr_head(pkt, &len, 1);
+				linkparam.u.utility.paramlen = len;
+				/* Param Data */
+				cp = linkparam.u.utility.params;
+				while (cfpkt_more(pkt) && len--) {
+					cfpkt_extr_head(pkt, &tmp, 1);
+					*cp++ = tmp;
+				}
+				/* Link ID */
+				cfpkt_extr_head(pkt, &linkid, 1);
+				/* Length */
+				cfpkt_extr_head(pkt, &len, 1);
+				/* Param Data */
+				cfpkt_extr_head(pkt, &param, len);
+				break;
+			default:
+				pr_warning("CAIF: %s(): Request setup "
+					   "- invalid link type (%d)",
+					   __func__, serv);
+				goto error;
+			}
+			if (cfpkt_erroneous(pkt)) {
+				pr_err("CAIF: %s(): Packet is erroneous!",
+					__func__);
+				goto error;
+			}
+			rsp.cmd = cmd;
+			rsp.param = linkparam;
+			req = cfctrl_remove_req(cfctrl, &rsp);
+
+			if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp)) {
+				pr_err("CAIF: %s(): Invalid O/E bit "
+				       "on CAIF control channel", __func__);
+				cfctrl->res.reject_rsp(cfctrl->serv.layer.up,
+						       0,
+						       req ? req->client_layer
+						       : NULL);
+			} else {
+				cfctrl->res.linksetup_rsp(cfctrl->serv.
+							  layer.up, linkid,
+							  serv, physlinkid,
+							  req ? req->
+							  client_layer : NULL);
+			}
+
+			if (req != NULL)
+				kfree(req);
+		}
+		break;
+	case CFCTRL_CMD_LINK_DESTROY:
+		cfpkt_extr_head(pkt, &linkid, 1);
+		rsp.cmd = cmd;
+		rsp.channel_id = linkid;
+		req = cfctrl_remove_req(cfctrl, &rsp);
+		cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid,
+					    req ? req->client_layer : NULL);
+		if (req != NULL)
+			kfree(req);
+		break;
+	case CFCTRL_CMD_LINK_ERR:
+		pr_err("CAIF: %s(): Frame Error Indication received \n",
+			__func__);
+		cfctrl->res.linkerror_ind();
+		break;
+	case CFCTRL_CMD_ENUM:
+		cfctrl->res.enum_rsp();
+		break;
+	case CFCTRL_CMD_SLEEP:
+		cfctrl->res.sleep_rsp();
+		break;
+	case CFCTRL_CMD_WAKE:
+		cfctrl->res.wake_rsp();
+		break;
+	case CFCTRL_CMD_LINK_RECONF:
+		cfctrl->res.restart_rsp();
+		break;
+	case CFCTRL_CMD_RADIO_SET:
+		cfctrl->res.radioset_rsp();
+		break;
+	default:
+		pr_err("CAIF: %s(): Unrecognized Control Frame\n", __func__);
+		goto error;
+		break;
+	}
+	ret = 0;
+error:
+	cfpkt_destroy(pkt);
+	return ret;
+}
+
+static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+			int phyid)
+{
+	struct cfctrl *this = container_obj(layr);
+	switch (ctrl) {
+	case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND:
+	case CAIF_CTRLCMD_FLOW_OFF_IND:
+		spin_lock(&this->info_list_lock);
+		if (this->first_req != NULL) {
+			pr_warning("CAIF: %s(): Received flow off in "
+				   "control layer", __func__);
+		}
+		spin_unlock(&this->info_list_lock);
+		break;
+	default:
+		break;
+	}
+}
+
+#ifndef CAIF_NO_LOOP
+int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt)
+{
+	static int last_linkid;
+	u8 linkid, linktype, tmp;
+	switch (cmd) {
+	case CFCTRL_CMD_LINK_SETUP:
+		spin_lock(&ctrl->loop_linkid_lock);
+		for (linkid = last_linkid + 1; linkid < 255; linkid++)
+			if (!ctrl->loop_linkused[linkid])
+				goto found;
+		for (linkid = last_linkid - 1; linkid > 0; linkid--)
+			if (!ctrl->loop_linkused[linkid])
+				goto found;
+		return -EINVAL;
+found:
+		if (!ctrl->loop_linkused[linkid])
+			ctrl->loop_linkused[linkid] = 1;
+
+		last_linkid = linkid;
+
+		cfpkt_add_trail(pkt, &linkid, 1);
+		spin_unlock(&ctrl->loop_linkid_lock);
+		cfpkt_peek_head(pkt, &linktype, 1);
+		if (linktype ==  CFCTRL_SRV_UTIL) {
+			tmp = 0x01;
+			cfpkt_add_trail(pkt, &tmp, 1);
+			cfpkt_add_trail(pkt, &tmp, 1);
+		}
+		break;
+
+	case CFCTRL_CMD_LINK_DESTROY:
+		spin_lock(&ctrl->loop_linkid_lock);
+		cfpkt_peek_head(pkt, &linkid, 1);
+		ctrl->loop_linkused[linkid] = 0;
+		spin_unlock(&ctrl->loop_linkid_lock);
+		break;
+	default:
+		break;
+	}
+	return CAIF_SUCCESS;
+}
+#endif
diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c
new file mode 100644
index 0000000..ab6b6dc
--- /dev/null
+++ b/net/caif/cfdbgl.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *dbg = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!dbg) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	memset(dbg, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(dbg, channel_id, dev_info);
+	dbg->layer.receive = cfdbgl_receive;
+	dbg->layer.transmit = cfdbgl_transmit;
+	snprintf(dbg->layer.name, CAIF_LAYER_NAME_SZ - 1, "dbg%d", channel_id);
+	return &dbg->layer;
+}
+
+static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	return layr->up->receive(layr->up, pkt);
+}
+
+static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	return layr->dn->transmit(layr->dn, pkt);
+}
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
new file mode 100644
index 0000000..5319484
--- /dev/null
+++ b/net/caif/cfdgml.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define container_obj(layr) ((struct cfsrvl *) layr)
+
+#define DGM_CMD_BIT  0x80
+#define DGM_FLOW_OFF 0x81
+#define DGM_FLOW_ON  0x80
+#define DGM_CTRL_PKT_SIZE 1
+
+static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *dgm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!dgm) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	memset(dgm, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(dgm, channel_id, dev_info);
+	dgm->layer.receive = cfdgml_receive;
+	dgm->layer.transmit = cfdgml_transmit;
+	snprintf(dgm->layer.name, CAIF_LAYER_NAME_SZ - 1, "dgm%d", channel_id);
+	dgm->layer.name[CAIF_LAYER_NAME_SZ - 1] = '\0';
+	return &dgm->layer;
+}
+
+static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 cmd = -1;
+	u8 dgmhdr[3];
+	int ret;
+	caif_assert(layr->up != NULL);
+	caif_assert(layr->receive != NULL);
+	caif_assert(layr->ctrlcmd != NULL);
+
+	if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+
+	if ((cmd & DGM_CMD_BIT) == 0) {
+		if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) {
+			pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+			cfpkt_destroy(pkt);
+			return -EPROTO;
+		}
+		ret = layr->up->receive(layr->up, pkt);
+		return ret;
+	}
+
+	switch (cmd) {
+	case DGM_FLOW_OFF:	/* FLOW OFF */
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	case DGM_FLOW_ON:	/* FLOW ON */
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	default:
+		cfpkt_destroy(pkt);
+		pr_info("CAIF: %s(): Unknown datagram control %d (0x%x)\n",
+			__func__, cmd, cmd);
+		return -EPROTO;
+	}
+}
+
+static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u32 zero = 0;
+	struct caif_payload_info *info;
+	struct cfsrvl *service = container_obj(layr);
+	int ret;
+	if (!cfsrvl_ready(service, &ret))
+		return ret;
+
+	cfpkt_add_head(pkt, &zero, 4);
+
+	/* Add info for MUX-layer to route the packet out. */
+	info = cfpkt_info(pkt);
+	info->channel_id = service->layer.id;
+	/* To optimize alignment, we add up the size of CAIF header
+	 * before payload.
+	 */
+	info->hdr_len = 4;
+	info->dev_info = &service->dev_info;
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0) {
+		u32 tmp32;
+		cfpkt_extr_head(pkt, &tmp32, 4);
+	}
+	return ret;
+}
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
new file mode 100644
index 0000000..d6f7280
--- /dev/null
+++ b/net/caif/cffrml.c
@@ -0,0 +1,151 @@
+/*
+ * CAIF Framing Layer.
+ *
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/crc-ccitt.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/cffrml.h>
+
+#define container_obj(layr) container_of(layr, struct cffrml, layer)
+
+struct cffrml {
+	struct cflayer layer;
+	bool dofcs;		/* !< FCS active */
+};
+
+static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt);
+static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid);
+
+u32 cffrml_rcv_error;
+u32 cffrml_rcv_checsum_error;
+struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
+{
+	struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC);
+	if (!this) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cffrml, layer) == 0);
+
+	memset(this, 0, sizeof(struct cflayer));
+	this->layer.receive = cffrml_receive;
+	this->layer.transmit = cffrml_transmit;
+	this->layer.ctrlcmd = cffrml_ctrlcmd;
+	snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "frm%d", phyid);
+	this->dofcs = use_fcs;
+	this->layer.id = phyid;
+	return (struct cflayer *) this;
+}
+
+void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up)
+{
+	this->up = up;
+}
+
+void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn)
+{
+	this->dn = dn;
+}
+
+static u16 cffrml_checksum(u16 chks, void *buf, u16 len)
+{
+	/* FIXME: FCS should be moved to glue in order to use OS-Specific
+	 * solutions
+	 */
+	return crc_ccitt(chks, buf, len);
+}
+
+static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u16 tmp;
+	u16 len;
+	u16 hdrchks;
+	u16 pktchks;
+	struct cffrml *this;
+	this = container_obj(layr);
+
+	cfpkt_extr_head(pkt, &tmp, 2);
+	len = le16_to_cpu(tmp);
+
+	/* Subtract for FCS on length if FCS is not used. */
+	if (!this->dofcs)
+		len -= 2;
+
+	if (cfpkt_setlen(pkt, len) < 0) {
+		++cffrml_rcv_error;
+		pr_err("CAIF: %s():Framing length error (%d)\n", __func__, len);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+	/*
+	 * Don't do extract if FCS is false, rather do setlen - then we don't
+	 * get a cache-miss.
+	 */
+	if (this->dofcs) {
+		cfpkt_extr_trail(pkt, &tmp, 2);
+		hdrchks = le16_to_cpu(tmp);
+		pktchks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
+		if (pktchks != hdrchks) {
+			cfpkt_add_trail(pkt, &tmp, 2);
+			++cffrml_rcv_error;
+			++cffrml_rcv_checsum_error;
+			pr_info("CAIF: %s(): Frame checksum error "
+				"(0x%x != 0x%x)\n", __func__, hdrchks, pktchks);
+			return -EILSEQ;
+		}
+	}
+	if (cfpkt_erroneous(pkt)) {
+		++cffrml_rcv_error;
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+	return layr->up->receive(layr->up, pkt);
+}
+
+static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	int tmp;
+	u16 chks;
+	u16 len;
+	int ret;
+	struct cffrml *this = container_obj(layr);
+	if (this->dofcs) {
+		chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
+		tmp = cpu_to_le16(chks);
+		cfpkt_add_trail(pkt, &tmp, 2);
+	} else {
+		cfpkt_pad_trail(pkt, 2);
+	}
+	len = cfpkt_getlen(pkt);
+	tmp = cpu_to_le16(len);
+	cfpkt_add_head(pkt, &tmp, 2);
+	cfpkt_info(pkt)->hdr_len += 2;
+	if (cfpkt_erroneous(pkt)) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		return -EPROTO;
+	}
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0) {
+		/* Remove header on faulty packet. */
+		cfpkt_extr_head(pkt, &tmp, 2);
+	}
+	return ret;
+}
+
+static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+					int phyid)
+{
+	if (layr->up->ctrlcmd)
+		layr->up->ctrlcmd(layr->up, ctrl, layr->id);
+}
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
new file mode 100644
index 0000000..71e3371
--- /dev/null
+++ b/net/caif/cfmuxl.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <net/caif/cfpkt.h>
+#include <net/caif/cfmuxl.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cffrml.h>
+
+#define container_obj(layr) container_of(layr, struct cfmuxl, layer)
+
+#define CAIF_CTRL_CHANNEL 0
+#define UP_CACHE_SIZE 8
+#define DN_CACHE_SIZE 8
+
+struct cfmuxl {
+	struct cflayer layer;
+	struct list_head srvl_list;
+	struct list_head frml_list;
+	struct cflayer *up_cache[UP_CACHE_SIZE];
+	struct cflayer *dn_cache[DN_CACHE_SIZE];
+	/*
+	 * Set when inserting or removing downwards layers.
+	 */
+	spinlock_t transmit_lock;
+
+	/*
+	 * Set when inserting or removing upwards layers.
+	 */
+	spinlock_t receive_lock;
+
+};
+
+static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt);
+static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid);
+static struct cflayer *get_up(struct cfmuxl *muxl, int id);
+
+struct cflayer *cfmuxl_create()
+{
+	struct cfmuxl *this = kmalloc(sizeof(struct cfmuxl), GFP_ATOMIC);
+	if (!this)
+		return NULL;
+	memset(this, 0, sizeof(*this));
+	this->layer.receive = cfmuxl_receive;
+	this->layer.transmit = cfmuxl_transmit;
+	this->layer.ctrlcmd = cfmuxl_ctrlcmd;
+	INIT_LIST_HEAD(&this->srvl_list);
+	INIT_LIST_HEAD(&this->frml_list);
+	spin_lock_init(&this->transmit_lock);
+	spin_lock_init(&this->receive_lock);
+	snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "mux");
+	return &this->layer;
+}
+
+int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
+{
+	struct cfmuxl *muxl = container_obj(layr);
+	spin_lock(&muxl->receive_lock);
+	list_add(&up->node, &muxl->srvl_list);
+	spin_unlock(&muxl->receive_lock);
+	return 0;
+}
+
+bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid)
+{
+	struct list_head *node;
+	struct cflayer *layer;
+	struct cfmuxl *muxl = container_obj(layr);
+	bool match = false;
+	spin_lock(&muxl->receive_lock);
+
+	list_for_each(node, &muxl->srvl_list) {
+		layer = list_entry(node, struct cflayer, node);
+		if (cfsrvl_phyid_match(layer, phyid)) {
+			match = true;
+			break;
+		}
+
+	}
+	spin_unlock(&muxl->receive_lock);
+	return match;
+}
+
+u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id)
+{
+	struct cflayer *up;
+	int phyid;
+	struct cfmuxl *muxl = container_obj(layr);
+	spin_lock(&muxl->receive_lock);
+	up = get_up(muxl, channel_id);
+	if (up != NULL)
+		phyid = cfsrvl_getphyid(up);
+	else
+		phyid = 0;
+	spin_unlock(&muxl->receive_lock);
+	return phyid;
+}
+
+int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
+{
+	struct cfmuxl *muxl = (struct cfmuxl *) layr;
+	spin_lock(&muxl->transmit_lock);
+	list_add(&dn->node, &muxl->frml_list);
+	spin_unlock(&muxl->transmit_lock);
+	return 0;
+}
+struct cflayer *get_from_id(struct list_head *list, int id)
+{
+	struct list_head *node;
+	struct cflayer *layer;
+	list_for_each(node, list) {
+		layer = list_entry(node, struct cflayer, node);
+		if (layer->id == id)
+			return layer;
+	}
+	return NULL;
+}
+
+struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
+{
+	struct cfmuxl *muxl = container_obj(layr);
+	struct cflayer *dn;
+	spin_lock(&muxl->transmit_lock);
+	memset(muxl->dn_cache, 0, sizeof(muxl->dn_cache));
+	dn = get_from_id(&muxl->frml_list, phyid);
+	if (dn == NULL)
+		return NULL;
+	list_del(&dn->node);
+	caif_assert(dn != NULL);
+	spin_unlock(&muxl->transmit_lock);
+	return dn;
+}
+
+
+/* Invariant: lock is taken */
+static struct cflayer *get_up(struct cfmuxl *muxl, int id)
+{
+	struct cflayer *up;
+	int idx = id % UP_CACHE_SIZE;
+	up = muxl->up_cache[idx];
+	if (up == NULL || up->id != id) {
+		up = get_from_id(&muxl->srvl_list, id);
+		muxl->up_cache[idx] = up;
+	}
+	return up;
+}
+
+/* Invariant: lock is taken */
+static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info)
+{
+	struct cflayer *dn;
+	int idx = dev_info->id % DN_CACHE_SIZE;
+	dn = muxl->dn_cache[idx];
+	if (dn == NULL || dn->id != dev_info->id) {
+		dn = get_from_id(&muxl->frml_list, dev_info->id);
+		muxl->dn_cache[idx] = dn;
+	}
+	return dn;
+}
+
+struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
+{
+	struct cflayer *up;
+	struct cfmuxl *muxl = container_obj(layr);
+	spin_lock(&muxl->receive_lock);
+	up = get_up(muxl, id);
+	memset(muxl->up_cache, 0, sizeof(muxl->up_cache));
+	list_del(&up->node);
+	spin_unlock(&muxl->receive_lock);
+	return up;
+}
+
+static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	int ret;
+	struct cfmuxl *muxl = container_obj(layr);
+	u8 id;
+	struct cflayer *up;
+	if (cfpkt_extr_head(pkt, &id, 1) < 0) {
+		pr_err("CAIF: %s(): erroneous Caif Packet\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+
+	spin_lock(&muxl->receive_lock);
+	up = get_up(muxl, id);
+	spin_unlock(&muxl->receive_lock);
+	if (up == NULL) {
+		pr_info("CAIF: %s():Received data on unknown link ID = %d "
+			"(0x%x)	 up == NULL", __func__, id, id);
+		cfpkt_destroy(pkt);
+		/*
+		 * Don't return ERROR, since modem misbehaves and sends out
+		 * flow on before linksetup response.
+		 */
+		return /* CFGLU_EPROT; */ 0;
+	}
+
+	ret = up->receive(up, pkt);
+
+
+	return ret;
+}
+
+static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	int ret;
+	struct cfmuxl *muxl = container_obj(layr);
+	u8 linkid;
+	struct cflayer *dn;
+	struct caif_payload_info *info = cfpkt_info(pkt);
+	dn = get_dn(muxl, cfpkt_info(pkt)->dev_info);
+	if (dn == NULL) {
+		pr_warning("CAIF: %s(): Send data on unknown phy "
+			   "ID = %d (0x%x)\n",
+			   __func__, info->dev_info->id, info->dev_info->id);
+		return -ENOTCONN;
+	}
+	info->hdr_len += 1;
+	linkid = info->channel_id;
+	cfpkt_add_head(pkt, &linkid, 1);
+	ret = dn->transmit(dn, pkt);
+	/* Remove MUX protocol header upon error. */
+	if (ret < 0)
+		cfpkt_extr_head(pkt, &linkid, 1);
+	return ret;
+}
+
+static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid)
+{
+	struct cfmuxl *muxl = container_obj(layr);
+	struct list_head *node;
+	struct cflayer *layer;
+	list_for_each(node, &muxl->srvl_list) {
+		layer = list_entry(node, struct cflayer, node);
+		if (cfsrvl_phyid_match(layer, phyid))
+			layer->ctrlcmd(layer, ctrl, phyid);
+	}
+}
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
new file mode 100644
index 0000000..f068231
--- /dev/null
+++ b/net/caif/cfrfml.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define container_obj(layr) container_of(layr, struct cfsrvl, layer)
+
+#define RFM_SEGMENTATION_BIT 0x01
+#define RFM_PAYLOAD  0x00
+#define RFM_CMD_BIT  0x80
+#define RFM_FLOW_OFF 0x81
+#define RFM_FLOW_ON  0x80
+#define RFM_SET_PIN  0x82
+#define RFM_CTRL_PKT_SIZE 1
+
+static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *rfm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!rfm) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	memset(rfm, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(rfm, channel_id, dev_info);
+	rfm->layer.receive = cfrfml_receive;
+	rfm->layer.transmit = cfrfml_transmit;
+	snprintf(rfm->layer.name, CAIF_LAYER_NAME_SZ, "rfm%d", channel_id);
+	return &rfm->layer;
+}
+
+void cffrml_destroy(struct cflayer *layer)
+{
+	kfree(layer);
+}
+
+static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 tmp;
+	bool segmented;
+	int ret;
+	caif_assert(layr->up != NULL);
+	caif_assert(layr->receive != NULL);
+
+	/*
+	 * RFM is taking care of segmentation and stripping of
+	 * segmentation bit.
+	 */
+	if (cfpkt_extr_head(pkt, &tmp, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+	segmented = tmp & RFM_SEGMENTATION_BIT;
+	caif_assert(!segmented);
+
+	ret = layr->up->receive(layr->up, pkt);
+	return ret;
+}
+
+static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 tmp = 0;
+	int ret;
+	struct cfsrvl *service = container_obj(layr);
+
+	caif_assert(layr->dn != NULL);
+	caif_assert(layr->dn->transmit != NULL);
+
+	if (!cfsrvl_ready(service, &ret))
+		return ret;
+
+	if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) {
+		pr_err("CAIF: %s():Packet too large - size=%d\n",
+			__func__, cfpkt_getlen(pkt));
+		return -EOVERFLOW;
+	}
+	if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		return -EPROTO;
+	}
+
+	/* Add info for MUX-layer to route the packet out. */
+	cfpkt_info(pkt)->channel_id = service->layer.id;
+	/*
+	 * To optimize alignment, we add up the size of CAIF header before
+	 * payload.
+	 */
+	cfpkt_info(pkt)->hdr_len = 1;
+	cfpkt_info(pkt)->dev_info = &service->dev_info;
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0)
+		cfpkt_extr_head(pkt, &tmp, 1);
+	return ret;
+}
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
new file mode 100644
index 0000000..69deeba
--- /dev/null
+++ b/net/caif/cfserl.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfpkt.h>
+#define container_obj(layr) ((struct cfserl *) layr)
+
+#define CFSERL_STX 0x02
+#define CAIF_MINIUM_PACKET_SIZE 4
+struct cfserl {
+	struct cflayer layer;
+	struct cfpkt *incomplete_frm;
+	spinlock_t sync;
+	bool usestx;
+};
+#define STXLEN(layr) (layr->usestx ? 1 : 0)
+
+static int cfserl_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt);
+static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid);
+
+struct cfserl *cfserl_create(int type, int instance, bool use_stx)
+{
+	struct cfserl *this = kmalloc(sizeof(struct cfserl), GFP_ATOMIC);
+	if (!this) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfserl, layer) == 0);
+	memset(this, 0, sizeof(struct cfserl));
+	this->layer.receive = cfserl_receive;
+	this->layer.transmit = cfserl_transmit;
+	this->layer.ctrlcmd = cfserl_ctrlcmd;
+	this->layer.type = type;
+	this->usestx = use_stx;
+	spin_lock_init(&this->sync);
+	snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "ser1");
+	return this;
+}
+
+void cfserl_set_uplayer(struct cfserl *this, struct cflayer *up)
+{
+	this->layer.up = up;
+}
+
+void cfserl_set_dnlayer(struct cfserl *this, struct cflayer *dn)
+{
+	this->layer.dn = dn;
+}
+
+static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
+{
+	struct cfserl *layr = container_obj(l);
+	u16 pkt_len;
+	struct cfpkt *pkt = NULL;
+	struct cfpkt *tail_pkt = NULL;
+	u8 tmp8;
+	u16 tmp;
+	u8 stx = CFSERL_STX;
+	int ret;
+	u16 expectlen = 0;
+	caif_assert(newpkt != NULL);
+	spin_lock(&layr->sync);
+
+	if (layr->incomplete_frm != NULL) {
+
+		layr->incomplete_frm =
+		    cfpkt_append(layr->incomplete_frm, newpkt, expectlen);
+		pkt = layr->incomplete_frm;
+	} else {
+		pkt = newpkt;
+	}
+	layr->incomplete_frm = NULL;
+
+	do {
+		/* Search for STX at start of pkt if STX is used */
+		if (layr->usestx) {
+			cfpkt_extr_head(pkt, &tmp8, 1);
+			if (tmp8 != CFSERL_STX) {
+				while (cfpkt_more(pkt)
+				       && tmp8 != CFSERL_STX) {
+					cfpkt_extr_head(pkt, &tmp8, 1);
+				}
+				if (!cfpkt_more(pkt)) {
+					cfpkt_destroy(pkt);
+					layr->incomplete_frm = NULL;
+					spin_unlock(&layr->sync);
+					return -EPROTO;
+				}
+			}
+		}
+
+		pkt_len = cfpkt_getlen(pkt);
+
+		/*
+		 *  pkt_len is the accumulated length of the packet data
+		 *  we have received so far.
+		 *  Exit if frame doesn't hold length.
+		 */
+
+		if (pkt_len < 2) {
+			if (layr->usestx)
+				cfpkt_add_head(pkt, &stx, 1);
+			layr->incomplete_frm = pkt;
+			spin_unlock(&layr->sync);
+			return 0;
+		}
+
+		/*
+		 *  Find length of frame.
+		 *  expectlen is the length we need for a full frame.
+		 */
+		cfpkt_peek_head(pkt, &tmp, 2);
+		expectlen = le16_to_cpu(tmp) + 2;
+		/*
+		 * Frame error handling
+		 */
+		if (expectlen < CAIF_MINIUM_PACKET_SIZE
+		    || expectlen > CAIF_MAX_FRAMESIZE) {
+			if (!layr->usestx) {
+				if (pkt != NULL)
+					cfpkt_destroy(pkt);
+				layr->incomplete_frm = NULL;
+				expectlen = 0;
+				spin_unlock(&layr->sync);
+				return -EPROTO;
+			}
+			continue;
+		}
+
+		if (pkt_len < expectlen) {
+			/* Too little received data */
+			if (layr->usestx)
+				cfpkt_add_head(pkt, &stx, 1);
+			layr->incomplete_frm = pkt;
+			spin_unlock(&layr->sync);
+			return 0;
+		}
+
+		/*
+		 * Enough data for at least one frame.
+		 * Split the frame, if too long
+		 */
+		if (pkt_len > expectlen)
+			tail_pkt = cfpkt_split(pkt, expectlen);
+		else
+			tail_pkt = NULL;
+
+		/* Send the first part of packet upwards.*/
+		spin_unlock(&layr->sync);
+		ret = layr->layer.up->receive(layr->layer.up, pkt);
+		spin_lock(&layr->sync);
+		if (ret == -EILSEQ) {
+			if (layr->usestx) {
+				if (tail_pkt != NULL)
+					pkt = cfpkt_append(pkt, tail_pkt, 0);
+
+				/* Start search for next STX if frame failed */
+				continue;
+			} else {
+				cfpkt_destroy(pkt);
+				pkt = NULL;
+			}
+		}
+
+		pkt = tail_pkt;
+
+	} while (pkt != NULL);
+
+	spin_unlock(&layr->sync);
+	return 0;
+}
+
+static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt)
+{
+	struct cfserl *layr = container_obj(layer);
+	int ret;
+	u8 tmp8 = CFSERL_STX;
+	if (layr->usestx)
+		cfpkt_add_head(newpkt, &tmp8, 1);
+	ret = layer->dn->transmit(layer->dn, newpkt);
+	if (ret < 0)
+		cfpkt_extr_head(newpkt, &tmp8, 1);
+
+	return ret;
+}
+
+static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid)
+{
+	layr->up->ctrlcmd(layr->up, ctrl, phyid);
+}
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c
new file mode 100644
index 0000000..d470c51
--- /dev/null
+++ b/net/caif/cfsrvl.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define SRVL_CTRL_PKT_SIZE 1
+#define SRVL_FLOW_OFF 0x81
+#define SRVL_FLOW_ON  0x80
+#define SRVL_SET_PIN  0x82
+#define SRVL_CTRL_PKT_SIZE 1
+
+#define container_obj(layr) container_of(layr, struct cfsrvl, layer)
+
+static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+				int phyid)
+{
+	struct cfsrvl *service = container_obj(layr);
+	caif_assert(layr->up != NULL);
+	caif_assert(layr->up->ctrlcmd != NULL);
+	switch (ctrl) {
+	case CAIF_CTRLCMD_INIT_RSP:
+		service->open = true;
+		layr->up->ctrlcmd(layr->up, ctrl, phyid);
+		break;
+	case CAIF_CTRLCMD_DEINIT_RSP:
+	case CAIF_CTRLCMD_INIT_FAIL_RSP:
+		service->open = false;
+		layr->up->ctrlcmd(layr->up, ctrl, phyid);
+		break;
+	case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND:
+		if (phyid != service->dev_info.id)
+			break;
+		if (service->modem_flow_on)
+			layr->up->ctrlcmd(layr->up,
+					  CAIF_CTRLCMD_FLOW_OFF_IND, phyid);
+		service->phy_flow_on = false;
+		break;
+	case _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND:
+		if (phyid != service->dev_info.id)
+			return;
+		if (service->modem_flow_on) {
+			layr->up->ctrlcmd(layr->up,
+					   CAIF_CTRLCMD_FLOW_ON_IND,
+					   phyid);
+		}
+		service->phy_flow_on = true;
+		break;
+	case CAIF_CTRLCMD_FLOW_OFF_IND:
+		if (service->phy_flow_on) {
+			layr->up->ctrlcmd(layr->up,
+					  CAIF_CTRLCMD_FLOW_OFF_IND, phyid);
+		}
+		service->modem_flow_on = false;
+		break;
+	case CAIF_CTRLCMD_FLOW_ON_IND:
+		if (service->phy_flow_on) {
+			layr->up->ctrlcmd(layr->up,
+					  CAIF_CTRLCMD_FLOW_ON_IND, phyid);
+		}
+		service->modem_flow_on = true;
+		break;
+	case _CAIF_CTRLCMD_PHYIF_DOWN_IND:
+		/* In case interface is down, let's fake a remove shutdown */
+		layr->up->ctrlcmd(layr->up,
+				CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, phyid);
+		break;
+	case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
+		layr->up->ctrlcmd(layr->up, ctrl, phyid);
+		break;
+	default:
+		pr_warning("CAIF: %s(): "
+			   "Unexpected ctrl in cfsrvl (%d)\n", __func__, ctrl);
+		/* We have both modem and phy flow on, send flow on */
+		layr->up->ctrlcmd(layr->up, ctrl, phyid);
+		service->phy_flow_on = true;
+		break;
+	}
+}
+
+static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
+{
+	struct cfsrvl *service = container_obj(layr);
+	caif_assert(layr != NULL);
+	caif_assert(layr->dn != NULL);
+	caif_assert(layr->dn->transmit != NULL);
+	switch (ctrl) {
+	case CAIF_MODEMCMD_FLOW_ON_REQ:
+		{
+			struct cfpkt *pkt;
+			struct caif_payload_info *info;
+			u8 flow_on = SRVL_FLOW_ON;
+			pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
+			if (!pkt) {
+				pr_warning("CAIF: %s(): Out of memory\n",
+					__func__);
+				return -ENOMEM;
+			}
+
+			if (cfpkt_add_head(pkt, &flow_on, 1) < 0) {
+				pr_err("CAIF: %s(): Packet is erroneous!\n",
+					__func__);
+				cfpkt_destroy(pkt);
+				return -EPROTO;
+			}
+			info = cfpkt_info(pkt);
+			info->channel_id = service->layer.id;
+			info->hdr_len = 1;
+			info->dev_info = &service->dev_info;
+			return layr->dn->transmit(layr->dn, pkt);
+		}
+	case CAIF_MODEMCMD_FLOW_OFF_REQ:
+		{
+			struct cfpkt *pkt;
+			struct caif_payload_info *info;
+			u8 flow_off = SRVL_FLOW_OFF;
+			pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE);
+			if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
+				pr_err("CAIF: %s(): Packet is erroneous!\n",
+					__func__);
+				cfpkt_destroy(pkt);
+				return -EPROTO;
+			}
+			info = cfpkt_info(pkt);
+			info->channel_id = service->layer.id;
+			info->hdr_len = 1;
+			info->dev_info = &service->dev_info;
+			return layr->dn->transmit(layr->dn, pkt);
+		}
+	default:
+	  break;
+	}
+	return -EINVAL;
+}
+
+void cfservl_destroy(struct cflayer *layer)
+{
+	kfree(layer);
+}
+
+void cfsrvl_init(struct cfsrvl *service,
+		 u8 channel_id,
+		 struct dev_info *dev_info)
+{
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	service->open = false;
+	service->modem_flow_on = true;
+	service->phy_flow_on = true;
+	service->layer.id = channel_id;
+	service->layer.ctrlcmd = cfservl_ctrlcmd;
+	service->layer.modemcmd = cfservl_modemcmd;
+	service->dev_info = *dev_info;
+}
+
+bool cfsrvl_ready(struct cfsrvl *service, int *err)
+{
+	if (service->open && service->modem_flow_on && service->phy_flow_on)
+		return true;
+	if (!service->open) {
+		*err = -ENOTCONN;
+		return false;
+	}
+	caif_assert(!(service->modem_flow_on && service->phy_flow_on));
+	*err = -EAGAIN;
+	return false;
+}
+u8 cfsrvl_getphyid(struct cflayer *layer)
+{
+	struct cfsrvl *servl = container_obj(layer);
+	return servl->dev_info.id;
+}
+
+bool cfsrvl_phyid_match(struct cflayer *layer, int phyid)
+{
+	struct cfsrvl *servl = container_obj(layer);
+	return servl->dev_info.id == phyid;
+}
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
new file mode 100644
index 0000000..5fd2c9e
--- /dev/null
+++ b/net/caif/cfutill.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define container_obj(layr) ((struct cfsrvl *) layr)
+#define UTIL_PAYLOAD  0x00
+#define UTIL_CMD_BIT  0x80
+#define UTIL_REMOTE_SHUTDOWN 0x82
+#define UTIL_FLOW_OFF 0x81
+#define UTIL_FLOW_ON  0x80
+#define UTIL_CTRL_PKT_SIZE 1
+static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *util = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!util) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	memset(util, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(util, channel_id, dev_info);
+	util->layer.receive = cfutill_receive;
+	util->layer.transmit = cfutill_transmit;
+	snprintf(util->layer.name, CAIF_LAYER_NAME_SZ - 1, "util1");
+	return &util->layer;
+}
+
+static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 cmd = -1;
+	struct cfsrvl *service = container_obj(layr);
+	caif_assert(layr != NULL);
+	caif_assert(layr->up != NULL);
+	caif_assert(layr->up->receive != NULL);
+	caif_assert(layr->up->ctrlcmd != NULL);
+	if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+
+	switch (cmd) {
+	case UTIL_PAYLOAD:
+		return layr->up->receive(layr->up, pkt);
+	case UTIL_FLOW_OFF:
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	case UTIL_FLOW_ON:
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	case UTIL_REMOTE_SHUTDOWN:	/* Remote Shutdown Request */
+		pr_err("CAIF: %s(): REMOTE SHUTDOWN REQUEST RECEIVED\n",
+			__func__);
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0);
+		service->open = false;
+		cfpkt_destroy(pkt);
+		return 0;
+	default:
+		cfpkt_destroy(pkt);
+		pr_warning("CAIF: %s(): Unknown service control %d (0x%x)\n",
+			   __func__, cmd, cmd);
+		return -EPROTO;
+	}
+}
+
+static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 zero = 0;
+	struct caif_payload_info *info;
+	int ret;
+	struct cfsrvl *service = container_obj(layr);
+	caif_assert(layr != NULL);
+	caif_assert(layr->dn != NULL);
+	caif_assert(layr->dn->transmit != NULL);
+	if (!cfsrvl_ready(service, &ret))
+		return ret;
+
+	if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) {
+		pr_err("CAIF: %s(): packet too large size=%d\n",
+			__func__, cfpkt_getlen(pkt));
+		return -EOVERFLOW;
+	}
+
+	cfpkt_add_head(pkt, &zero, 1);
+	/* Add info for MUX-layer to route the packet out. */
+	info = cfpkt_info(pkt);
+	info->channel_id = service->layer.id;
+	/*
+	 * To optimize alignment, we add up the size of CAIF header before
+	 * payload.
+	 */
+	info->hdr_len = 1;
+	info->dev_info = &service->dev_info;
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0) {
+		u32 tmp32;
+		cfpkt_extr_head(pkt, &tmp32, 4);
+	}
+	return ret;
+}
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
new file mode 100644
index 0000000..0fd827f
--- /dev/null
+++ b/net/caif/cfveil.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define VEI_PAYLOAD  0x00
+#define VEI_CMD_BIT  0x80
+#define VEI_FLOW_OFF 0x81
+#define VEI_FLOW_ON  0x80
+#define VEI_SET_PIN  0x82
+#define VEI_CTRL_PKT_SIZE 1
+#define container_obj(layr) container_of(layr, struct cfsrvl, layer)
+
+static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *vei = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!vei) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+	memset(vei, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(vei, channel_id, dev_info);
+	vei->layer.receive = cfvei_receive;
+	vei->layer.transmit = cfvei_transmit;
+	snprintf(vei->layer.name, CAIF_LAYER_NAME_SZ - 1, "vei%d", channel_id);
+	return &vei->layer;
+}
+
+static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 cmd;
+	int ret;
+	caif_assert(layr->up != NULL);
+	caif_assert(layr->receive != NULL);
+	caif_assert(layr->ctrlcmd != NULL);
+
+
+	if (cfpkt_extr_head(pkt, &cmd, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+	switch (cmd) {
+	case VEI_PAYLOAD:
+		ret = layr->up->receive(layr->up, pkt);
+		return ret;
+	case VEI_FLOW_OFF:
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	case VEI_FLOW_ON:
+		layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0);
+		cfpkt_destroy(pkt);
+		return 0;
+	case VEI_SET_PIN:	/* SET RS232 PIN */
+		cfpkt_destroy(pkt);
+		return 0;
+	default:		/* SET RS232 PIN */
+		pr_warning("CAIF: %s():Unknown VEI control packet %d (0x%x)!\n",
+			   __func__, cmd, cmd);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+}
+
+static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u8 tmp = 0;
+	struct caif_payload_info *info;
+	int ret;
+	struct cfsrvl *service = container_obj(layr);
+	if (!cfsrvl_ready(service, &ret))
+		return ret;
+	caif_assert(layr->dn != NULL);
+	caif_assert(layr->dn->transmit != NULL);
+	if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) {
+		pr_warning("CAIF: %s(): Packet too large - size=%d\n",
+			   __func__, cfpkt_getlen(pkt));
+		return -EOVERFLOW;
+	}
+
+	if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		return -EPROTO;
+	}
+
+	/* Add info-> for MUX-layer to route the packet out. */
+	info = cfpkt_info(pkt);
+	info->channel_id = service->layer.id;
+	info->hdr_len = 1;
+	info->dev_info = &service->dev_info;
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0)
+		cfpkt_extr_head(pkt, &tmp, 1);
+	return ret;
+}
diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
new file mode 100644
index 0000000..89ad4ea
--- /dev/null
+++ b/net/caif/cfvidl.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/cfsrvl.h>
+#include <net/caif/cfpkt.h>
+
+#define container_obj(layr) ((struct cfsrvl *) layr)
+
+static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt);
+static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt);
+
+struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info)
+{
+	struct cfsrvl *vid = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC);
+	if (!vid) {
+		pr_warning("CAIF: %s(): Out of memory\n", __func__);
+		return NULL;
+	}
+	caif_assert(offsetof(struct cfsrvl, layer) == 0);
+
+	memset(vid, 0, sizeof(struct cfsrvl));
+	cfsrvl_init(vid, channel_id, dev_info);
+	vid->layer.receive = cfvidl_receive;
+	vid->layer.transmit = cfvidl_transmit;
+	snprintf(vid->layer.name, CAIF_LAYER_NAME_SZ - 1, "vid1");
+	return &vid->layer;
+}
+
+static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt)
+{
+	u32 videoheader;
+	if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) {
+		pr_err("CAIF: %s(): Packet is erroneous!\n", __func__);
+		cfpkt_destroy(pkt);
+		return -EPROTO;
+	}
+	return layr->up->receive(layr->up, pkt);
+}
+
+static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt)
+{
+	struct cfsrvl *service = container_obj(layr);
+	struct caif_payload_info *info;
+	u32 videoheader = 0;
+	int ret;
+	if (!cfsrvl_ready(service, &ret))
+		return ret;
+	cfpkt_add_head(pkt, &videoheader, 4);
+	/* Add info for MUX-layer to route the packet out */
+	info = cfpkt_info(pkt);
+	info->channel_id = service->layer.id;
+	info->dev_info = &service->dev_info;
+	ret = layr->dn->transmit(layr->dn, pkt);
+	if (ret < 0)
+		cfpkt_extr_head(pkt, &videoheader, 4);
+	return ret;
+}
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 10/12] net-caif: add CAIF Kconfig and Makefiles
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-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 |   27 +++++++++++++++++++++++++++
 4 files changed, 78 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..65a926d
--- /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) that
+	uses CAIF as transport, if unsure say N.
+
+	If you select to build it as module then CAIF_SOCK and 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..031a4e0
--- /dev/null
+++ b/net/caif/Makefile
@@ -0,0 +1,27 @@
+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 v6 09/12] net-caif: add CAIF netdevice
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-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 |  429 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 429 insertions(+), 0 deletions(-)

diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
new file mode 100644
index 0000000..9df6fd3
--- /dev/null
+++ b/net/caif/chnl_net.c
@@ -0,0 +1,429 @@
+/*
+ * 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;
+};
+
+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_COMPLETE;
+
+	/* 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 void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
+				int phyid)
+{
+	struct chnl_net *priv  = NULL;
+	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);
+		wake_up_interruptible(&priv->netmgmt_wq);
+	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);
+
+	/* 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 delete_device(struct chnl_net *dev)
+{
+	ASSERT_RTNL();
+	if (dev->netdev)
+		unregister_netdevice(dev->netdev);
+	return 0;
+}
+
+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

* [PATCH net-next-2.6 v6 08/12] net-caif: add CAIF socket implementation
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-8-git-send-email-sjur.brandeland@stericsson.com>

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

Implementation of CAIF sockets for protocol and address family
PF_CAIF and AF_CAIF.
CAIF socket is connection oriented implementing SOCK_SEQPACKET
interface with supporting blocking and non-blocking mode.

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

diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
new file mode 100644
index 0000000..d499e19
--- /dev/null
+++ b/net/caif/caif_socket.c
@@ -0,0 +1,1431 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author:	Sjur Brendeland sjur.brandeland@stericsson.com
+ *		Per Sigmond per.sigmond@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/tcp.h>
+#include <linux/uaccess.h>
+#include <asm/atomic.h>
+
+#include <linux/caif/caif_socket.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/caif_dev.h>
+#include <net/caif/cfpkt.h>
+
+MODULE_LICENSE("GPL");
+
+
+#define CHNL_SKT_READ_QUEUE_HIGH 200
+#define CHNL_SKT_READ_QUEUE_LOW 100
+
+int caif_sockbuf_size = 40000;
+static struct kmem_cache *caif_sk_cachep;
+static atomic_t caif_nr_socks = ATOMIC_INIT(0);
+
+#define CONN_STATE_OPEN_BIT	      1
+#define CONN_STATE_PENDING_BIT	      2
+#define CONN_STATE_PEND_DESTROY_BIT   3
+#define CONN_REMOTE_SHUTDOWN_BIT      4
+
+#define TX_FLOW_ON_BIT		      1
+#define RX_FLOW_ON_BIT		      2
+
+#define STATE_IS_OPEN(cf_sk) test_bit(CONN_STATE_OPEN_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+#define STATE_IS_REMOTE_SHUTDOWN(cf_sk) test_bit(CONN_REMOTE_SHUTDOWN_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+#define STATE_IS_PENDING(cf_sk) test_bit(CONN_STATE_PENDING_BIT,\
+				       (void *) &(cf_sk)->conn_state)
+#define STATE_IS_PENDING_DESTROY(cf_sk) test_bit(CONN_STATE_PEND_DESTROY_BIT,\
+				       (void *) &(cf_sk)->conn_state)
+
+#define SET_STATE_PENDING_DESTROY(cf_sk) set_bit(CONN_STATE_PEND_DESTROY_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+#define SET_STATE_OPEN(cf_sk) set_bit(CONN_STATE_OPEN_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+#define SET_STATE_CLOSED(cf_sk) clear_bit(CONN_STATE_OPEN_BIT,\
+					(void *) &(cf_sk)->conn_state)
+#define SET_PENDING_ON(cf_sk) set_bit(CONN_STATE_PENDING_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+#define SET_PENDING_OFF(cf_sk) clear_bit(CONN_STATE_PENDING_BIT,\
+				       (void *) &(cf_sk)->conn_state)
+#define SET_REMOTE_SHUTDOWN(cf_sk) set_bit(CONN_REMOTE_SHUTDOWN_BIT,\
+				    (void *) &(cf_sk)->conn_state)
+
+#define SET_REMOTE_SHUTDOWN_OFF(dev) clear_bit(CONN_REMOTE_SHUTDOWN_BIT,\
+				    (void *) &(dev)->conn_state)
+#define RX_FLOW_IS_ON(cf_sk) test_bit(RX_FLOW_ON_BIT,\
+				    (void *) &(cf_sk)->flow_state)
+#define TX_FLOW_IS_ON(cf_sk) test_bit(TX_FLOW_ON_BIT,\
+				    (void *) &(cf_sk)->flow_state)
+
+#define SET_RX_FLOW_OFF(cf_sk) clear_bit(RX_FLOW_ON_BIT,\
+				       (void *) &(cf_sk)->flow_state)
+#define SET_RX_FLOW_ON(cf_sk) set_bit(RX_FLOW_ON_BIT,\
+				    (void *) &(cf_sk)->flow_state)
+#define SET_TX_FLOW_OFF(cf_sk) clear_bit(TX_FLOW_ON_BIT,\
+				       (void *) &(cf_sk)->flow_state)
+#define SET_TX_FLOW_ON(cf_sk) set_bit(TX_FLOW_ON_BIT,\
+				    (void *) &(cf_sk)->flow_state)
+
+#define SKT_READ_FLAG 0x01
+#define SKT_WRITE_FLAG 0x02
+static struct dentry *debugfsdir;
+#include <linux/debugfs.h>
+
+#ifdef CONFIG_DEBUG_FS
+struct debug_fs_counter {
+	atomic_t num_open;
+	atomic_t num_close;
+	atomic_t num_init;
+	atomic_t num_init_resp;
+	atomic_t num_init_fail_resp;
+	atomic_t num_deinit;
+	atomic_t num_deinit_resp;
+	atomic_t num_remote_shutdown_ind;
+	atomic_t num_tx_flow_off_ind;
+	atomic_t num_tx_flow_on_ind;
+	atomic_t num_rx_flow_off;
+	atomic_t num_rx_flow_on;
+	atomic_t skb_in_use;
+	atomic_t skb_alloc;
+	atomic_t skb_free;
+};
+struct debug_fs_counter cnt;
+#define	dbfs_atomic_inc(v) atomic_inc(v)
+#define	dbfs_atomic_dec(v) atomic_dec(v)
+#else
+#define	dbfs_atomic_inc(v)
+#define	dbfs_atomic_dec(v)
+#endif
+
+/* The AF_CAIF socket */
+struct caifsock {
+	/* NOTE: sk has to be the first member */
+	struct sock sk;
+	struct cflayer layer;
+	char name[CAIF_LAYER_NAME_SZ];
+	u32 conn_state;
+	u32 flow_state;
+	struct cfpktq *pktq;
+	int file_mode;
+	struct caif_connect_request conn_req;
+	int read_queue_len;
+	spinlock_t read_queue_len_lock;
+	struct dentry *debugfs_socket_dir;
+};
+
+static void drain_queue(struct caifsock *cf_sk);
+
+/* Packet Receive Callback function called from CAIF Stack */
+static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
+{
+	struct caifsock *cf_sk;
+	int read_queue_high;
+	cf_sk = container_of(layr, struct caifsock, layer);
+
+	if (!STATE_IS_OPEN(cf_sk)) {
+		/*FIXME: This should be allowed finally!*/
+		pr_debug("CAIF: %s(): called after close request\n", __func__);
+		cfpkt_destroy(pkt);
+		return 0;
+	}
+	/* NOTE: This function may be called in Tasklet context! */
+
+	/* The queue has its own lock */
+	cfpkt_queue(cf_sk->pktq, pkt, 0);
+
+	spin_lock(&cf_sk->read_queue_len_lock);
+	cf_sk->read_queue_len++;
+
+	read_queue_high = (cf_sk->read_queue_len > CHNL_SKT_READ_QUEUE_HIGH);
+	spin_unlock(&cf_sk->read_queue_len_lock);
+
+	if (RX_FLOW_IS_ON(cf_sk) && read_queue_high) {
+		dbfs_atomic_inc(&cnt.num_rx_flow_off);
+		SET_RX_FLOW_OFF(cf_sk);
+
+		/* Send flow off (NOTE: must not sleep) */
+		pr_debug("CAIF: %s():"
+			" sending flow OFF (queue len = %d)\n",
+			__func__,
+		     cf_sk->read_queue_len);
+		caif_assert(cf_sk->layer.dn);
+		caif_assert(cf_sk->layer.dn->ctrlcmd);
+
+		(void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn,
+					       CAIF_MODEMCMD_FLOW_OFF_REQ);
+	}
+
+	/* Signal reader that data is available. */
+
+	wake_up_interruptible(cf_sk->sk.sk_sleep);
+
+	return 0;
+}
+
+/* Packet Flow Control Callback function called from CAIF */
+static void caif_sktflowctrl_cb(struct cflayer *layr,
+				enum caif_ctrlcmd flow,
+				int phyid)
+{
+	struct caifsock *cf_sk;
+
+	/* NOTE: This function may be called in Tasklet context! */
+	pr_debug("CAIF: %s(): flowctrl func called: %s.\n",
+		      __func__,
+		      flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" :
+		      flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" :
+		      flow == CAIF_CTRLCMD_INIT_RSP ? "INIT_RSP" :
+		      flow == CAIF_CTRLCMD_DEINIT_RSP ? "DEINIT_RSP" :
+		      flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "INIT_FAIL_RSP" :
+		      flow ==
+		      CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? "REMOTE_SHUTDOWN" :
+		      "UKNOWN CTRL COMMAND");
+
+	cf_sk = container_of(layr, struct caifsock, layer);
+	switch (flow) {
+	case CAIF_CTRLCMD_FLOW_ON_IND:
+		dbfs_atomic_inc(&cnt.num_tx_flow_on_ind);
+		/* Signal reader that data is available. */
+		SET_TX_FLOW_ON(cf_sk);
+		wake_up_interruptible(cf_sk->sk.sk_sleep);
+		break;
+
+	case CAIF_CTRLCMD_FLOW_OFF_IND:
+		dbfs_atomic_inc(&cnt.num_tx_flow_off_ind);
+		SET_TX_FLOW_OFF(cf_sk);
+		break;
+
+	case CAIF_CTRLCMD_INIT_RSP:
+		dbfs_atomic_inc(&cnt.num_init_resp);
+		/* Signal reader that data is available. */
+		caif_assert(STATE_IS_OPEN(cf_sk));
+		SET_PENDING_OFF(cf_sk);
+		SET_TX_FLOW_ON(cf_sk);
+		wake_up_interruptible(cf_sk->sk.sk_sleep);
+		break;
+
+	case CAIF_CTRLCMD_DEINIT_RSP:
+		dbfs_atomic_inc(&cnt.num_deinit_resp);
+		caif_assert(!STATE_IS_OPEN(cf_sk));
+		SET_PENDING_OFF(cf_sk);
+		if (!STATE_IS_PENDING_DESTROY(cf_sk)) {
+			if (cf_sk->sk.sk_sleep != NULL)
+				wake_up_interruptible(cf_sk->sk.sk_sleep);
+		}
+		dbfs_atomic_inc(&cnt.num_deinit);
+		sock_put(&cf_sk->sk);
+		wake_up_interruptible(cf_sk->sk.sk_sleep);
+		break;
+
+	case CAIF_CTRLCMD_INIT_FAIL_RSP:
+		dbfs_atomic_inc(&cnt.num_init_fail_resp);
+		caif_assert(STATE_IS_OPEN(cf_sk));
+		SET_STATE_CLOSED(cf_sk);
+		SET_PENDING_OFF(cf_sk);
+		SET_TX_FLOW_OFF(cf_sk);
+		wake_up_interruptible(cf_sk->sk.sk_sleep);
+		break;
+
+	case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
+		dbfs_atomic_inc(&cnt.num_remote_shutdown_ind);
+		SET_REMOTE_SHUTDOWN(cf_sk);
+		SET_TX_FLOW_OFF(cf_sk);
+		drain_queue(cf_sk);
+		SET_RX_FLOW_ON(cf_sk);
+		cf_sk->file_mode = 0;
+		wake_up_interruptible(cf_sk->sk.sk_sleep);
+		break;
+
+	default:
+		pr_debug("CAIF: %s(): Unexpected flow command %d\n",
+			      __func__, flow);
+	}
+}
+
+static void skb_destructor(struct sk_buff *skb)
+{
+	dbfs_atomic_inc(&cnt.skb_free);
+	dbfs_atomic_dec(&cnt.skb_in_use);
+}
+
+
+static int caif_recvmsg(struct kiocb *iocb, struct socket *sock,
+				struct msghdr *m, size_t buf_len, int flags)
+
+{
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
+	struct cfpkt *pkt = NULL;
+	size_t len;
+	int result;
+	struct sk_buff *skb;
+	ssize_t ret = -EIO;
+	int read_queue_low;
+
+	if (cf_sk == NULL) {
+		pr_debug("CAIF: %s(): private_data not set!\n",
+			      __func__);
+		ret = -EBADFD;
+		goto read_error;
+	}
+
+	/* Don't do multiple iovec entries yet */
+	if (m->msg_iovlen != 1)
+		return -EOPNOTSUPP;
+
+	if (unlikely(!buf_len))
+		return -EINVAL;
+
+	lock_sock(&(cf_sk->sk));
+
+	caif_assert(cf_sk->pktq);
+
+	if (!STATE_IS_OPEN(cf_sk)) {
+		/* Socket is closed or closing. */
+		if (!STATE_IS_PENDING(cf_sk)) {
+			pr_debug("CAIF: %s(): socket is closed (by remote)\n",
+				 __func__);
+			ret = -EPIPE;
+		} else {
+			pr_debug("CAIF: %s(): socket is closing..\n", __func__);
+			ret = -EBADF;
+		}
+		goto read_error;
+	}
+	/* Socket is open or opening. */
+	if (STATE_IS_PENDING(cf_sk)) {
+		pr_debug("CAIF: %s(): socket is opening...\n", __func__);
+
+		if (flags & MSG_DONTWAIT) {
+			/* We can't block. */
+			pr_debug("CAIF: %s():state pending and MSG_DONTWAIT\n",
+				 __func__);
+			ret = -EAGAIN;
+			goto read_error;
+		}
+
+		/*
+		 * Blocking mode; state is pending and we need to wait
+		 * for its conclusion.
+		 */
+		release_sock(&cf_sk->sk);
+
+		result =
+		    wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					     !STATE_IS_PENDING(cf_sk));
+
+		lock_sock(&(cf_sk->sk));
+
+		if (result == -ERESTARTSYS) {
+			pr_debug("CAIF: %s(): wait_event_interruptible"
+				 " woken by a signal (1)", __func__);
+			ret = -ERESTARTSYS;
+			goto read_error;
+		}
+	}
+	if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) {
+		pr_debug("CAIF: %s(): received remote_shutdown indication\n",
+			 __func__);
+		ret = -ESHUTDOWN;
+		goto read_error;
+	}
+
+	/*
+	 * Block if we don't have any received buffers.
+	 * The queue has its own lock.
+	 */
+	while ((pkt = cfpkt_qpeek(cf_sk->pktq)) == NULL) {
+
+		if (flags & MSG_DONTWAIT) {
+			pr_debug("CAIF: %s(): MSG_DONTWAIT\n", __func__);
+			ret = -EAGAIN;
+			goto read_error;
+		}
+		trace_printk("CAIF: %s() wait_event\n", __func__);
+
+		/* Let writers in. */
+		release_sock(&cf_sk->sk);
+
+		/* Block reader until data arrives or socket is closed. */
+		if (wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					cfpkt_qpeek(cf_sk->pktq)
+					|| STATE_IS_REMOTE_SHUTDOWN(cf_sk)
+					|| !STATE_IS_OPEN(cf_sk)) ==
+		    -ERESTARTSYS) {
+			pr_debug("CAIF: %s():"
+				" wait_event_interruptible woken by "
+				"a signal, signal_pending(current) = %d\n",
+				__func__,
+				signal_pending(current));
+			return -ERESTARTSYS;
+		}
+
+		trace_printk("CAIF: %s() awake\n", __func__);
+		if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) {
+			pr_debug("CAIF: %s(): "
+				 "received remote_shutdown indication\n",
+				 __func__);
+			ret = -ESHUTDOWN;
+			goto read_error_no_unlock;
+		}
+
+		/* I want to be alone on cf_sk (except status and queue). */
+		lock_sock(&(cf_sk->sk));
+
+		if (!STATE_IS_OPEN(cf_sk)) {
+			/* Someone closed the link, report error. */
+			pr_debug("CAIF: %s(): remote end shutdown!\n",
+				      __func__);
+			ret = -EPIPE;
+			goto read_error;
+		}
+	}
+
+	/* The queue has its own lock. */
+	len = cfpkt_getlen(pkt);
+
+	/* Check max length that can be copied. */
+	if (len > buf_len) {
+		pr_debug("CAIF: %s(): user buffer too small\n", __func__);
+		ret = -EINVAL;
+		goto read_error;
+	}
+
+	/*
+	 * Get packet from queue.
+	 * The queue has its own lock.
+	 */
+	pkt = cfpkt_dequeue(cf_sk->pktq);
+
+	spin_lock(&cf_sk->read_queue_len_lock);
+	cf_sk->read_queue_len--;
+	read_queue_low = (cf_sk->read_queue_len < CHNL_SKT_READ_QUEUE_LOW);
+	spin_unlock(&cf_sk->read_queue_len_lock);
+
+	if (!RX_FLOW_IS_ON(cf_sk) && read_queue_low) {
+		dbfs_atomic_inc(&cnt.num_rx_flow_on);
+		SET_RX_FLOW_ON(cf_sk);
+
+		/* Send flow on. */
+		pr_debug("CAIF: %s(): sending flow ON (queue len = %d)\n",
+			 __func__, cf_sk->read_queue_len);
+		caif_assert(cf_sk->layer.dn);
+		caif_assert(cf_sk->layer.dn->ctrlcmd);
+		(void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn,
+					       CAIF_MODEMCMD_FLOW_ON_REQ);
+
+		caif_assert(cf_sk->read_queue_len >= 0);
+	}
+
+	skb = cfpkt_tonative(pkt);
+	result = skb_copy_datagram_iovec(skb, 0, m->msg_iov, len);
+	if (result) {
+		pr_debug("CAIF: %s(): cfpkt_raw_extract failed\n", __func__);
+		cfpkt_destroy(pkt);
+		ret = -EFAULT;
+		goto read_error;
+	}
+	if (unlikely(buf_len < len)) {
+		len = buf_len;
+		m->msg_flags |= MSG_TRUNC;
+	}
+
+	/* Free packet. */
+	skb_free_datagram(sk, skb);
+
+	/* Let the others in. */
+	release_sock(&cf_sk->sk);
+	return len;
+
+read_error:
+	release_sock(&cf_sk->sk);
+read_error_no_unlock:
+	return ret;
+}
+
+/* Send a signal as a consequence of sendmsg, sendto or caif_sendmsg. */
+static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock,
+			struct msghdr *msg, size_t len)
+{
+
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
+	void *payload;
+	size_t payload_size = msg->msg_iov->iov_len;
+	struct cfpkt *pkt = NULL;
+	struct caif_payload_info info;
+	unsigned char *txbuf;
+	ssize_t ret = -EIO;
+	int result;
+	struct sk_buff *skb;
+	caif_assert(msg->msg_iovlen == 1);
+
+	if (cf_sk == NULL) {
+		pr_debug("CAIF: %s(): private_data not set!\n",
+			      __func__);
+		ret = -EBADFD;
+		goto write_error_no_unlock;
+	}
+
+	if (unlikely(msg->msg_iov->iov_base == NULL)) {
+		pr_warning("CAIF: %s(): Buffer is NULL.\n", __func__);
+		ret = -EINVAL;
+		goto write_error_no_unlock;
+	}
+
+	payload = msg->msg_iov->iov_base;
+	if (payload_size > CAIF_MAX_PAYLOAD_SIZE) {
+		pr_debug("CAIF: %s(): buffer too long\n", __func__);
+		ret = -EINVAL;
+		goto write_error_no_unlock;
+	}
+	/* I want to be alone on cf_sk (except status and queue) */
+	lock_sock(&(cf_sk->sk));
+
+	caif_assert(cf_sk->pktq);
+
+	if (!STATE_IS_OPEN(cf_sk)) {
+		/* Socket is closed or closing */
+		if (!STATE_IS_PENDING(cf_sk)) {
+			pr_debug("CAIF: %s(): socket is closed (by remote)\n",
+				 __func__);
+			ret = -EPIPE;
+		} else {
+			pr_debug("CAIF: %s(): socket is closing...\n",
+				 __func__);
+			ret = -EBADF;
+		}
+		goto write_error;
+	}
+
+	/* Socket is open or opening */
+	if (STATE_IS_PENDING(cf_sk)) {
+		pr_debug("CAIF: %s(): socket is opening...\n", __func__);
+
+		if (msg->msg_flags & MSG_DONTWAIT) {
+			/* We can't block */
+			trace_printk("CAIF: %s():state pending:"
+				     "state=MSG_DONTWAIT\n", __func__);
+			ret = -EAGAIN;
+			goto write_error;
+		}
+
+		/* Let readers in */
+		release_sock(&cf_sk->sk);
+
+		/*
+		 * Blocking mode; state is pending and we need to wait
+		 * for its conclusion.
+		 */
+		result =
+		    wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					     !STATE_IS_PENDING(cf_sk));
+
+		/* I want to be alone on cf_sk (except status and queue) */
+		lock_sock(&(cf_sk->sk));
+
+		if (result == -ERESTARTSYS) {
+			pr_debug("CAIF: %s(): wait_event_interruptible"
+				 " woken by a signal (1)", __func__);
+			ret = -ERESTARTSYS;
+			goto write_error;
+		}
+	}
+
+	if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) {
+		pr_debug("CAIF: %s(): received remote_shutdown indication\n",
+			 __func__);
+		ret = -ESHUTDOWN;
+		goto write_error;
+	}
+
+	if (!TX_FLOW_IS_ON(cf_sk)) {
+
+		/* Flow is off. Check non-block flag */
+		if (msg->msg_flags & MSG_DONTWAIT) {
+			trace_printk("CAIF: %s(): MSG_DONTWAIT and tx flow off",
+				 __func__);
+			ret = -EAGAIN;
+			goto write_error;
+		}
+
+		/* release lock before waiting */
+		release_sock(&cf_sk->sk);
+
+		/* Wait until flow is on or socket is closed */
+		if (wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					TX_FLOW_IS_ON(cf_sk)
+					|| !STATE_IS_OPEN(cf_sk)
+					|| STATE_IS_REMOTE_SHUTDOWN(cf_sk)
+					) == -ERESTARTSYS) {
+			pr_debug("CAIF: %s():"
+				 " wait_event_interruptible woken by a signal",
+				 __func__);
+			ret = -ERESTARTSYS;
+			goto write_error_no_unlock;
+		}
+
+		/* I want to be alone on cf_sk (except status and queue) */
+		lock_sock(&(cf_sk->sk));
+
+		if (!STATE_IS_OPEN(cf_sk)) {
+			/* someone closed the link, report error */
+			pr_debug("CAIF: %s(): remote end shutdown!\n",
+				      __func__);
+			ret = -EPIPE;
+			goto write_error;
+		}
+
+		if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) {
+			pr_debug("CAIF: %s(): "
+				 "received remote_shutdown indication\n",
+				 __func__);
+			ret = -ESHUTDOWN;
+			goto write_error;
+		}
+	}
+
+	pkt = cfpkt_create(payload_size);
+	skb = (struct sk_buff *)pkt;
+	skb->destructor = skb_destructor;
+	skb->sk = sk;
+	dbfs_atomic_inc(&cnt.skb_alloc);
+	dbfs_atomic_inc(&cnt.skb_in_use);
+	if (cfpkt_raw_append(pkt, (void **) &txbuf, payload_size) < 0) {
+		pr_debug("CAIF: %s(): cfpkt_raw_append failed\n", __func__);
+		cfpkt_destroy(pkt);
+		ret = -EINVAL;
+		goto write_error;
+	}
+
+	/* Copy data into buffer. */
+	if (copy_from_user(txbuf, payload, payload_size)) {
+		pr_debug("CAIF: %s(): copy_from_user returned non zero.\n",
+			 __func__);
+		cfpkt_destroy(pkt);
+		ret = -EINVAL;
+		goto write_error;
+	}
+	memset(&info, 0, sizeof(info));
+
+	/* Send the packet down the stack. */
+	caif_assert(cf_sk->layer.dn);
+	caif_assert(cf_sk->layer.dn->transmit);
+
+	do {
+		ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
+
+		if (likely((ret >= 0) || (ret != -EAGAIN)))
+			break;
+
+		/* EAGAIN - retry */
+		if (msg->msg_flags & MSG_DONTWAIT) {
+			pr_debug("CAIF: %s(): NONBLOCK and transmit failed,"
+				 " error = %d\n", __func__, ret);
+			ret = -EAGAIN;
+			goto write_error;
+		}
+
+		/* Let readers in */
+		release_sock(&cf_sk->sk);
+
+		/* Wait until flow is on or socket is closed */
+		if (wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					TX_FLOW_IS_ON(cf_sk)
+					|| !STATE_IS_OPEN(cf_sk)
+					|| STATE_IS_REMOTE_SHUTDOWN(cf_sk)
+					) == -ERESTARTSYS) {
+			pr_debug("CAIF: %s(): wait_event_interruptible"
+				 " woken by a signal", __func__);
+			ret = -ERESTARTSYS;
+			goto write_error_no_unlock;
+		}
+
+		/* I want to be alone on cf_sk (except status and queue) */
+		lock_sock(&(cf_sk->sk));
+
+	} while (ret == -EAGAIN);
+
+	if (ret < 0) {
+		cfpkt_destroy(pkt);
+		pr_debug("CAIF: %s(): transmit failed, error = %d\n",
+			  __func__, ret);
+
+		goto write_error;
+	}
+
+	release_sock(&cf_sk->sk);
+	return payload_size;
+
+write_error:
+	release_sock(&cf_sk->sk);
+write_error_no_unlock:
+	return ret;
+}
+
+static unsigned int caif_poll(struct file *file, struct socket *sock,
+						poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
+	u32 mask = 0;
+
+	poll_wait(file, sk->sk_sleep, wait);
+	lock_sock(&(cf_sk->sk));
+	if (cfpkt_qpeek(cf_sk->pktq) != NULL)
+		mask |= (POLLIN | POLLRDNORM);
+	if (!STATE_IS_OPEN(cf_sk))
+		mask |= POLLHUP;
+	else if (TX_FLOW_IS_ON(cf_sk))
+		mask |= (POLLOUT | POLLWRNORM);
+	release_sock(&cf_sk->sk);
+	trace_printk("CAIF: %s(): poll mask=0x%04x...\n",
+		      __func__, mask);
+	return mask;
+}
+
+static void drain_queue(struct caifsock *cf_sk)
+{
+	struct cfpkt *pkt = NULL;
+
+	/* Empty the queue */
+	do {
+		/* The queue has its own lock */
+		pkt = cfpkt_dequeue(cf_sk->pktq);
+		if (!pkt)
+			break;
+		pr_debug("CAIF: %s(): freeing packet from read queue\n",
+			 __func__);
+		cfpkt_destroy(pkt);
+
+	} while (1);
+
+	spin_lock(&cf_sk->read_queue_len_lock);
+	cf_sk->read_queue_len = 0;
+	spin_unlock(&cf_sk->read_queue_len_lock);
+}
+
+
+static int setsockopt(struct socket *sock,
+			int lvl, int opt, char __user *ov, unsigned int ol)
+{
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
+	int prio, linksel;
+	struct ifreq ifreq;
+
+	if (STATE_IS_OPEN(cf_sk)) {
+		pr_debug("CAIF: %s(): setsockopt "
+			 "cannot be done on a connected socket\n",
+			 __func__);
+		return -ENOPROTOOPT;
+	}
+	switch (opt) {
+	case CAIFSO_LINK_SELECT:
+		if (ol < sizeof(int)) {
+			pr_debug("CAIF: %s(): setsockopt"
+				 " CAIFSO_CHANNEL_CONFIG bad size\n", __func__);
+			return -EINVAL;
+		}
+		if (lvl != SOL_CAIF)
+			goto bad_sol;
+		if (copy_from_user(&linksel, ov, sizeof(int)))
+			return -EINVAL;
+		lock_sock(&(cf_sk->sk));
+		cf_sk->conn_req.link_selector = linksel;
+		release_sock(&cf_sk->sk);
+		return 0;
+
+	case SO_PRIORITY:
+		if (lvl != SOL_SOCKET)
+			goto bad_sol;
+		if (ol < sizeof(int)) {
+			pr_debug("CAIF: %s(): setsockopt"
+				 " SO_PRIORITY bad size\n", __func__);
+			return -EINVAL;
+		}
+		if (copy_from_user(&prio, ov, sizeof(int)))
+			return -EINVAL;
+		lock_sock(&(cf_sk->sk));
+		cf_sk->conn_req.priority = prio;
+		pr_debug("CAIF: %s(): Setting sockopt priority=%d\n", __func__,
+			cf_sk->conn_req.priority);
+		release_sock(&cf_sk->sk);
+		return 0;
+
+	case SO_BINDTODEVICE:
+		if (lvl != SOL_SOCKET)
+			goto bad_sol;
+		if (ol < sizeof(struct ifreq)) {
+			pr_debug("CAIF: %s(): setsockopt"
+				 " SO_PRIORITY bad size\n", __func__);
+			return -EINVAL;
+		}
+		if (copy_from_user(&ifreq, ov, sizeof(ifreq)))
+			return -EFAULT;
+		lock_sock(&(cf_sk->sk));
+		strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name,
+			sizeof(cf_sk->conn_req.link_name));
+		cf_sk->conn_req.link_name
+			[sizeof(cf_sk->conn_req.link_name)-1] = 0;
+		release_sock(&cf_sk->sk);
+		return 0;
+
+	case CAIFSO_REQ_PARAM:
+		if (lvl != SOL_CAIF)
+			goto bad_sol;
+		if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL)
+			return -ENOPROTOOPT;
+		if (ol > sizeof(cf_sk->conn_req.param.data))
+			goto req_param_bad_size;
+
+		lock_sock(&(cf_sk->sk));
+		cf_sk->conn_req.param.size = ol;
+		if (copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) {
+			release_sock(&cf_sk->sk);
+req_param_bad_size:
+			pr_debug("CAIF: %s(): setsockopt"
+				 " CAIFSO_CHANNEL_CONFIG bad size\n", __func__);
+			return -EINVAL;
+		}
+
+		pr_debug("CAIF: %s(): Setting reqparam len=%d "
+				"data=0x%02x%02x%02x%02x\n",
+				__func__,
+				cf_sk->conn_req.param.size,
+				cf_sk->conn_req.param.data[0],
+				cf_sk->conn_req.param.data[1],
+				cf_sk->conn_req.param.data[2],
+				cf_sk->conn_req.param.data[3]);
+		release_sock(&cf_sk->sk);
+		return 0;
+
+	default:
+		pr_debug("CAIF: %s(): unhandled option %d\n", __func__, opt);
+		return -EINVAL;
+	}
+
+	return 0;
+bad_sol:
+	pr_debug("CAIF: %s(): setsockopt bad level\n", __func__);
+	return -ENOPROTOOPT;
+
+}
+
+static int getsockopt(struct socket *sock,
+			int lvl, int opt, char __user *ov, int __user *ol)
+{
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
+	int len;
+	u32 val;
+	if (lvl != SOL_CAIF)
+		return -ENOPROTOOPT;
+	if (get_user(len, ol))
+		return -EFAULT;
+	if (len < 0)
+		return -EINVAL;
+	if (!STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) {
+		pr_debug("CAIF: %s():"
+			"can only be done on a sconnected socket\n",
+			 __func__);
+		return -ENOPROTOOPT;
+	}
+
+	if (ov == NULL || len < sizeof(int))
+		return -EINVAL;
+	switch (opt) {
+	default:
+		pr_debug("CAIF: %s(): unhandled option %d\n", __func__, opt);
+		return -ENOPROTOOPT;
+	}
+	if (copy_to_user(ov, &val, sizeof(val)))
+		return -EINVAL;
+
+	if (put_user(len, ol))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+int caif_connect(struct socket *sock, struct sockaddr *uservaddr,
+	       int sockaddr_len, int flags)
+{
+	struct caifsock *cf_sk = NULL;
+	int result = -1;
+	int mode = 0;
+	int ret = -EIO;
+	struct sock *sk = sock->sk;
+	BUG_ON(sk == NULL);
+
+	cf_sk = container_of(sk, struct caifsock, sk);
+
+	trace_printk("CAIF: %s(): cf_sk=%p OPEN=%d, TX_FLOW=%d, RX_FLOW=%d\n",
+		 __func__, cf_sk,
+		STATE_IS_OPEN(cf_sk),
+		TX_FLOW_IS_ON(cf_sk), RX_FLOW_IS_ON(cf_sk));
+
+	sk->sk_state	= TCP_CLOSE;
+	sock->state	= SS_UNCONNECTED;
+
+	if (sock->type == SOCK_SEQPACKET) {
+		sock->state	= SS_CONNECTED;
+		sk->sk_state	= TCP_ESTABLISHED;
+	} else
+		goto out;
+
+	/* I want to be alone on cf_sk (except status and queue) */
+	lock_sock(&(cf_sk->sk));
+
+	if (sockaddr_len != sizeof(struct sockaddr_caif)) {
+		pr_debug("CAIF: %s(): Bad address len (%d,%d)\n",
+			 __func__, sockaddr_len, sizeof(struct sockaddr_caif));
+		ret = -EINVAL;
+		goto open_error;
+	}
+
+	if (uservaddr->sa_family != AF_CAIF) {
+		pr_debug("CAIF: %s(): Bad address family (%d)\n",
+			 __func__, uservaddr->sa_family);
+		ret = -EAFNOSUPPORT;
+		goto open_error;
+	}
+
+	memcpy(&cf_sk->conn_req.sockaddr, uservaddr,
+		sizeof(struct sockaddr_caif));
+
+	dbfs_atomic_inc(&cnt.num_open);
+	mode = SKT_READ_FLAG | SKT_WRITE_FLAG;
+
+	/* If socket is not open, make sure socket is in fully closed state */
+	if (!STATE_IS_OPEN(cf_sk)) {
+		/* Has link close response been received (if we ever sent it)?*/
+		if (STATE_IS_PENDING(cf_sk)) {
+			/*
+			 * Still waiting for close response from remote.
+			 * If opened non-blocking, report "would block"
+			 */
+			if (flags & MSG_DONTWAIT) {
+				pr_debug("CAIF: %s(): MSG_DONTWAIT"
+					" && close pending\n", __func__);
+				ret = -EAGAIN;
+				goto open_error;
+			}
+
+			pr_debug("CAIF: %s(): Wait for close response"
+				 " from remote...\n", __func__);
+
+			release_sock(&cf_sk->sk);
+
+			/*
+			 * Blocking mode; close is pending and we need to wait
+			 * for its conclusion.
+			 */
+			result =
+			    wait_event_interruptible(*cf_sk->sk.sk_sleep,
+						     !STATE_IS_PENDING(cf_sk));
+
+			lock_sock(&(cf_sk->sk));
+			if (result == -ERESTARTSYS) {
+				pr_debug("CAIF: %s(): wait_event_interruptible"
+					 "woken by a signal (1)", __func__);
+				ret = -ERESTARTSYS;
+				goto open_error;
+			}
+		}
+	}
+
+	/* socket is now either closed, pending open or open */
+	if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) {
+		/* Open */
+		pr_debug("CAIF: %s(): Socket is already opened (cf_sk=%p)"
+			" check access f_flags = 0x%x file_mode = 0x%x\n",
+			 __func__, cf_sk, mode, cf_sk->file_mode);
+
+		if (mode & cf_sk->file_mode) {
+			pr_debug("CAIF: %s(): Access mode already in use"
+				"0x%x\n",
+				__func__, mode);
+			ret = -EBUSY;
+			goto open_error;
+		}
+	} else {
+		/* We are closed or pending open.
+		 * If closed:	    send link setup
+		 * If pending open: link setup already sent (we could have been
+		 *		    interrupted by a signal last time)
+		 */
+		if (!STATE_IS_OPEN(cf_sk)) {
+			/* First opening of file; connect lower layers: */
+			/* Drain queue (very unlikely) */
+			drain_queue(cf_sk);
+
+			cf_sk->layer.receive = caif_sktrecv_cb;
+
+			SET_STATE_OPEN(cf_sk);
+			SET_PENDING_ON(cf_sk);
+
+			/* Register this channel. */
+			result =
+				caif_connect_client(&cf_sk->conn_req,
+							&cf_sk->layer);
+			if (result < 0) {
+				pr_debug("CAIF: %s(): can't register channel\n",
+					__func__);
+				ret = -EIO;
+				SET_STATE_CLOSED(cf_sk);
+				SET_PENDING_OFF(cf_sk);
+				goto open_error;
+			}
+			dbfs_atomic_inc(&cnt.num_init);
+		}
+
+		/* If opened non-blocking, report "success".
+		 */
+		if (flags & MSG_DONTWAIT) {
+			pr_debug("CAIF: %s(): MSG_DONTWAIT success\n",
+				 __func__);
+			ret = 0;
+			goto open_success;
+		}
+
+		trace_printk("CAIF: %s(): Wait for connect response\n",
+			     __func__);
+
+		/* release lock before waiting */
+		release_sock(&cf_sk->sk);
+
+		result =
+		    wait_event_interruptible(*cf_sk->sk.sk_sleep,
+					     !STATE_IS_PENDING(cf_sk));
+
+		lock_sock(&(cf_sk->sk));
+
+		if (result == -ERESTARTSYS) {
+			pr_debug("CAIF: %s(): wait_event_interruptible"
+				 "woken by a signal (2)", __func__);
+			ret = -ERESTARTSYS;
+			goto open_error;
+		}
+
+		if (!STATE_IS_OPEN(cf_sk)) {
+			/* Lower layers said "no" */
+			pr_debug("CAIF: %s(): Closed received\n", __func__);
+			ret = -EPIPE;
+			goto open_error;
+		}
+
+		trace_printk("CAIF: %s(): Connect received\n", __func__);
+	}
+open_success:
+	/* Open is ok */
+	cf_sk->file_mode |= mode;
+
+	trace_printk("CAIF: %s(): Connected - file mode = %x\n",
+		  __func__, cf_sk->file_mode);
+
+	release_sock(&cf_sk->sk);
+	return 0;
+open_error:
+	release_sock(&cf_sk->sk);
+out:
+	return ret;
+}
+
+
+static int caif_shutdown(struct socket *sock, int how)
+{
+	struct caifsock *cf_sk = NULL;
+	int result;
+	int tx_flow_state_was_on;
+	struct sock *sk = sock->sk;
+	if (how != SHUT_RDWR)
+		return -EOPNOTSUPP; /* FIXME: ENOTSUP in userland for POSIX */
+	cf_sk = container_of(sk, struct caifsock, sk);
+	if (cf_sk == NULL) {
+		pr_debug("CAIF: %s(): COULD NOT FIND SOCKET\n", __func__);
+		return -EBADF;
+	}
+	/* I want to be alone on cf_sk (except status queue) */
+	lock_sock(&(cf_sk->sk));
+	sock_hold(&cf_sk->sk);
+
+	/* IS_CLOSED have double meaning:
+	 * 1) Spontanous Remote Shutdown Request.
+	 * 2) Ack on a channel teardown(disconnect)
+	 * Must clear bit in case we previously received
+	 * remote shudown request.
+	 */
+	if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) {
+
+		SET_STATE_CLOSED(cf_sk);
+		SET_PENDING_ON(cf_sk);
+		sock->state = SS_DISCONNECTING;
+		tx_flow_state_was_on = TX_FLOW_IS_ON(cf_sk);
+		SET_TX_FLOW_OFF(cf_sk);
+
+		/* Hold the socket until DEINIT_RSP is received */
+		sock_hold(&cf_sk->sk);
+		result = caif_disconnect_client(&cf_sk->layer);
+
+		if (result < 0) {
+			pr_debug("CAIF: %s(): "
+					"caif_disconnect_client() failed\n",
+					 __func__);
+			SET_STATE_CLOSED(cf_sk);
+			SET_PENDING_OFF(cf_sk);
+			SET_TX_FLOW_OFF(cf_sk);
+			release_sock(&cf_sk->sk);
+			sock_put(&cf_sk->sk);
+			return -EIO;
+		}
+
+	}
+	if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) {
+		SET_PENDING_OFF(cf_sk);
+		SET_REMOTE_SHUTDOWN_OFF(cf_sk);
+	}
+	result =
+	    wait_event_interruptible(*cf_sk->sk.sk_sleep,
+				     !STATE_IS_PENDING(cf_sk));
+
+	if (result == -ERESTARTSYS) {
+		pr_debug("CAIF: %s(): wait_event_interruptible"
+			 "woken by a signal (1)", __func__);
+	}
+
+	/*
+	 * Socket is no longer in state pending close,
+	 * and we can release the reference.
+	 */
+
+	dbfs_atomic_inc(&cnt.num_close);
+	drain_queue(cf_sk);
+	SET_RX_FLOW_ON(cf_sk);
+	cf_sk->file_mode = 0;
+	sock_put(&cf_sk->sk);
+	release_sock(&cf_sk->sk);
+	return result;
+}
+
+static ssize_t caif_sock_no_sendpage(struct socket *sock,
+				     struct page *page,
+				     int offset, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+/* This function is called as part of close. */
+static int caif_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	struct caifsock *cf_sk = NULL;
+	int res;
+
+	caif_assert(sk != NULL);
+	cf_sk = container_of(sk, struct caifsock, sk);
+
+	res = caif_shutdown(sock, SHUT_RDWR);
+	if (res)
+		return res;
+	lock_sock(&(cf_sk->sk));
+
+	sock->sk = NULL;
+
+	/* Detach the socket from its process context by making it orphan. */
+	sock_orphan(sk);
+
+	/*
+	 * Setting SHUTDOWN_MASK means that both send and receive are shutdown
+	 * for the socket.
+	 */
+	sk->sk_shutdown = SHUTDOWN_MASK;
+
+	/*
+	 * Set the socket state to closed, the TCP_CLOSE macro is used when
+	 * closing any socket.
+	 */
+	sk->sk_state = TCP_CLOSE;
+
+	/* Flush out this sockets receive queue. */
+	drain_queue(cf_sk);
+
+	/* Finally release the socket. */
+	STATE_IS_PENDING_DESTROY(cf_sk);
+	release_sock(&cf_sk->sk);
+
+	sock_put(sk);
+
+	/*
+	 * The rest of the cleanup will be handled from the
+	 * caif_sock_destructor
+	 */
+	return 0;
+}
+
+static struct proto_ops caif_ops = {
+	.family = PF_CAIF,
+	.owner = THIS_MODULE,
+	.release = caif_release,
+	.bind = sock_no_bind,
+	.connect = caif_connect,
+	.socketpair = sock_no_socketpair,
+	.accept = sock_no_accept,
+	.getname = sock_no_getname,
+	.poll = caif_poll,
+	.ioctl = sock_no_ioctl,
+	.listen = sock_no_listen,
+	.shutdown = caif_shutdown,
+	.setsockopt = setsockopt,
+	.getsockopt = getsockopt,
+	.sendmsg = caif_sendmsg,
+	.recvmsg = caif_recvmsg,
+	.mmap = sock_no_mmap,
+	.sendpage = caif_sock_no_sendpage,
+};
+
+/* This function is called when a socket is finally destroyed. */
+static void caif_sock_destructor(struct sock *sk)
+{
+	struct caifsock *cf_sk = NULL;
+	cf_sk = container_of(sk, struct caifsock, sk);
+
+	/* Error checks. */
+	caif_assert(!atomic_read(&sk->sk_wmem_alloc));
+	caif_assert(sk_unhashed(sk));
+	caif_assert(!sk->sk_socket);
+
+	if (!sock_flag(sk, SOCK_DEAD)) {
+		pr_debug("CAIF: %s(): 0x%p", __func__, sk);
+		return;
+	}
+
+	lock_sock(&(cf_sk->sk));
+
+	if (STATE_IS_OPEN(cf_sk)) {
+		pr_debug("CAIF: %s(): socket is opened (cf_sk=%p)"
+			 " file_mode = 0x%x\n", __func__,
+			 cf_sk, cf_sk->file_mode);
+		release_sock(&cf_sk->sk);
+		return;
+	}
+	drain_queue(cf_sk);
+	kfree(cf_sk->pktq);
+
+	if (cf_sk->debugfs_socket_dir != NULL)
+		debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
+
+	release_sock(&cf_sk->sk);
+	trace_printk("CAIF: %s(): caif_sock_destructor: Removing socket %s\n",
+		__func__, cf_sk->name);
+	atomic_dec(&caif_nr_socks);
+}
+
+static int caif_create(struct net *net, struct socket *sock, int protocol,
+		       int kern)
+{
+	struct sock *sk = NULL;
+	struct caifsock *cf_sk = NULL;
+	int result = 0;
+	static struct proto prot = {.name = "PF_CAIF",
+		.owner = THIS_MODULE,
+		.obj_size = sizeof(struct caifsock),
+	};
+
+	/*
+	 * The sock->type specifies the socket type to use. The CAIF socket is
+	 * a packet stream in the sence that it is packet based.
+	 * CAIF trusts the reliability of the link, no resending is implemented.
+	 */
+	if (sock->type != SOCK_SEQPACKET)
+		return -ESOCKTNOSUPPORT;
+	prot.slab = caif_sk_cachep;
+
+	if (net != &init_net)
+		return -EAFNOSUPPORT;
+
+	if (protocol < 0 || protocol >= CAIFPROTO_MAX)
+		return -EPROTONOSUPPORT;
+	/*
+	 * Set the socket state to unconnected.	 The socket state is really
+	 * not used at all in the net/core or socket.c but the
+	 * initialization makes sure that sock->state is not uninitialized.
+	 */
+	sock->state = SS_UNCONNECTED;
+
+	sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot);
+	if (!sk)
+		return -ENOMEM;
+
+	cf_sk = container_of(sk, struct caifsock, sk);
+
+	/* Store the protocol */
+	sk->sk_protocol = (unsigned char) protocol;
+
+	spin_lock_init(&cf_sk->read_queue_len_lock);
+
+	/* Fill in some information concerning the misc socket. */
+	snprintf(cf_sk->name, sizeof(cf_sk->name), "cf_sk%d",
+		atomic_read(&caif_nr_socks));
+
+	/*
+	 * Lock in order to try to stop someone from opening the socket
+	 * too early.
+	 */
+	lock_sock(&(cf_sk->sk));
+
+	/* Initialize the nozero default sock structure data. */
+	sock_init_data(sock, sk);
+	sock->ops = &caif_ops;
+	sk->sk_destruct = caif_sock_destructor;
+	sk->sk_sndbuf = caif_sockbuf_size;
+	sk->sk_rcvbuf = caif_sockbuf_size;
+
+	cf_sk->pktq = cfpktq_create();
+
+	if (!cf_sk->pktq) {
+		pr_err("CAIF: %s(): queue create failed.\n", __func__);
+		result = -ENOMEM;
+		release_sock(&cf_sk->sk);
+		goto err_failed;
+	}
+	cf_sk->layer.ctrlcmd = caif_sktflowctrl_cb;
+	SET_STATE_CLOSED(cf_sk);
+	SET_PENDING_OFF(cf_sk);
+	SET_TX_FLOW_OFF(cf_sk);
+	SET_RX_FLOW_ON(cf_sk);
+
+	/* Set default options on configuration */
+	cf_sk->conn_req.priority = CAIF_PRIO_NORMAL;
+	cf_sk->conn_req.link_selector = CAIF_LINK_HIGH_BANDW;
+	cf_sk->conn_req.protocol = protocol;
+	/* Increase the number of sockets created. */
+	atomic_inc(&caif_nr_socks);
+	if (!IS_ERR(debugfsdir)) {
+		cf_sk->debugfs_socket_dir =
+			debugfs_create_dir(cf_sk->name, debugfsdir);
+		debugfs_create_u32("conn_state", S_IRUSR | S_IWUSR,
+				cf_sk->debugfs_socket_dir, &cf_sk->conn_state);
+		debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR,
+				cf_sk->debugfs_socket_dir, &cf_sk->flow_state);
+		debugfs_create_u32("read_queue_len", S_IRUSR | S_IWUSR,
+				cf_sk->debugfs_socket_dir,
+				(u32 *) &cf_sk->read_queue_len);
+		debugfs_create_u32("identity", S_IRUSR | S_IWUSR,
+				cf_sk->debugfs_socket_dir,
+				(u32 *) &cf_sk->layer.id);
+	}
+	release_sock(&cf_sk->sk);
+	return 0;
+err_failed:
+	sk_free(sk);
+	return result;
+}
+
+
+static struct net_proto_family caif_family_ops = {
+	.family = PF_CAIF,
+	.create = caif_create,
+	.owner = THIS_MODULE,
+};
+
+int af_caif_init(void)
+{
+	int err;
+	err = sock_register(&caif_family_ops);
+
+	if (!err)
+		return err;
+
+	return 0;
+}
+
+static int __init caif_sktinit_module(void)
+{
+	int stat;
+#ifdef CONFIG_DEBUG_FS
+	debugfsdir = debugfs_create_dir("chnl_skt", NULL);
+	if (!IS_ERR(debugfsdir)) {
+		debugfs_create_u32("skb_inuse", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.skb_in_use);
+		debugfs_create_u32("skb_alloc", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.skb_alloc);
+		debugfs_create_u32("skb_free", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.skb_free);
+		debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &caif_nr_socks);
+		debugfs_create_u32("num_open", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_open);
+		debugfs_create_u32("num_close", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_close);
+		debugfs_create_u32("num_init", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_init);
+		debugfs_create_u32("num_init_resp", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_init_resp);
+		debugfs_create_u32("num_init_fail_resp", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_init_fail_resp);
+		debugfs_create_u32("num_deinit", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_deinit);
+		debugfs_create_u32("num_deinit_resp", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_deinit_resp);
+		debugfs_create_u32("num_remote_shutdown_ind",
+				S_IRUSR | S_IWUSR, debugfsdir,
+				(u32 *) &cnt.num_remote_shutdown_ind);
+		debugfs_create_u32("num_tx_flow_off_ind", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_tx_flow_off_ind);
+		debugfs_create_u32("num_tx_flow_on_ind", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_tx_flow_on_ind);
+		debugfs_create_u32("num_rx_flow_off", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_rx_flow_off);
+		debugfs_create_u32("num_rx_flow_on", S_IRUSR | S_IWUSR,
+				debugfsdir,
+				(u32 *) &cnt.num_rx_flow_on);
+	}
+#endif
+	stat = af_caif_init();
+	if (stat) {
+		pr_err("CAIF: %s(): Failed to initialize CAIF socket layer.",
+		       __func__);
+		return stat;
+	}
+	return 0;
+}
+
+static void __exit caif_sktexit_module(void)
+{
+	sock_unregister(PF_CAIF);
+	if (debugfsdir != NULL)
+		debugfs_remove_recursive(debugfsdir);
+}
+
+module_init(caif_sktinit_module);
+module_exit(caif_sktexit_module);
+
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH net-next-2.6 v6 11/12] net-caif: add CAIF documentation
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-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         |  110 +++++++++++++
 2 files changed, 322 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..f11cea3
--- /dev/null
+++ b/Documentation/networking/caif/README
@@ -0,0 +1,110 @@
+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.
+  - 0x04 means TX_COMPLETE, i.e. a frame has been sent by the tty
+  - 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 v6 12/12] net-caif-driver: add CAIF serial driver (ldisc)
From: sjur.brandeland @ 2010-03-01 12:12 UTC (permalink / raw)
  To: netdev, davem, marcel
  Cc: daniel.martensson, kaber, stefano.babic, randy.dunlap,
	Sjur Braendeland
In-Reply-To: <1267445559-1911-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       |   24 ++
 drivers/net/caif/Makefile      |   14 ++
 drivers/net/caif/caif_serial.c |  463 ++++++++++++++++++++++++++++++++++++++++
 include/linux/tty.h            |    4 +-
 6 files changed, 506 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..504b90a
--- /dev/null
+++ b/drivers/net/caif/Kconfig
@@ -0,0 +1,24 @@
+#
+# 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.
+
+if CAIF_TTY
+config CAIF_TTY_NOFCS
+	bool "Don't use checksum for CAIF TTY transport driver"
+	default n
+	---help---
+	If the CAIF transport driver is reliable checksumming is
+	not needed.
+endif # CAIF_TTY
+
+endif # CAIF
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
new file mode 100644
index 0000000..01784a0
--- /dev/null
+++ b/drivers/net/caif/Makefile
@@ -0,0 +1,14 @@
+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..e5b19fa
--- /dev/null
+++ b/drivers/net/caif/caif_serial.c
@@ -0,0 +1,463 @@
+/*
+ * 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 CAIF_SENDING	1 /* Bit 1 = 0x02*/
+#define CAIF_UART_TX_COMPLETED	2 /* Bit 2 = 0x04 */
+#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 int ser_phy_tx(struct ser_device *ser, struct sk_buff *skb);
+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;
+
+	/*
+	 * Workaround for garbage at start of transmission,
+	 * only enable if STX handling is not enables
+	 */
+	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(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;
+	char *buf;
+	int tty_wr, len, room, pktlen;
+	tty = ser->tty;
+
+	/*
+	 * NOTE: This workaround is not really needed when STX is enabled.
+	 * Remove?
+	 */
+	if (ser->tx_started == false)
+		ser->tx_started = true;
+
+	if (test_and_set_bit(CAIF_SENDING, &ser->state)) {
+		set_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+		return 0;
+	}
+
+	do {
+		skb = skb_peek(&ser->head);
+		if (skb != NULL && skb->len == 0) {
+			struct sk_buff *tmp;
+			tmp = skb_dequeue(&ser->head);
+			BUG_ON(tmp != skb);
+			kfree_skb(skb);
+			skb = skb_peek(&ser->head);
+		}
+
+		if (skb == NULL) {
+			if (test_and_clear_bit(
+				    CAIF_FLOW_OFF_SENT,
+				    &ser->state)) {
+				if (ser->common.flowctrl != NULL)
+					ser->common.flowctrl(ser->dev, ON);
+			}
+			break;
+		}
+
+
+		buf = skb->data;
+		pktlen = len = skb->len;
+
+		clear_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+		room = tty_write_room(tty);
+		if (room > ser_write_chunk)
+			room = ser_write_chunk;
+
+		if (len > room)
+			len = room;
+		debugfs_tx(ser, buf, len);
+		if (!ser_loop) {
+			tty_wr = tty->ops->write(tty, buf, len);
+		} else {
+			tty_wr = len;
+			ldisc_receive(tty, buf, 0, len);
+		}
+		ser->dev->stats.tx_packets++;
+		ser->dev->stats.tx_bytes += tty_wr;
+		if (tty_wr > 0)
+			skb_pull(skb, tty_wr);
+
+		if (ser_loop)
+			ldisc_tx_wakeup(tty);
+		update_tty_status(ser);
+
+	} while (test_bit(CAIF_UART_TX_COMPLETED, &(ser->state)));
+
+	clear_bit(CAIF_SENDING, &ser->state);
+	return 0;
+}
+
+static int ser_phy_tx(struct ser_device *ser, struct sk_buff *skb)
+{
+	if (skb_peek(&ser->head) !=  NULL) {
+		if (!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);
+	if (!test_bit(CAIF_SENDING, &ser->state))
+		handle_tx(ser);
+	update_tty_status(ser);
+	return 0;
+}
+
+static int caif_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ser_device *ser;
+	if (!dev)
+		return -EINVAL;
+	ser = netdev_priv(dev);
+	return ser_phy_tx(ser, skb);
+}
+
+
+static void ldisc_tx_wakeup(struct tty_struct *tty)
+{
+	struct ser_device *ser;
+	ser = tty->disc_data;
+	if (ser == NULL)
+		return;
+	set_bit(CAIF_UART_TX_COMPLETED, &ser->state);
+	if (ser->tty != tty)
+		return;
+	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, "caif_%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 | IFF_POINTOPOINT;
+	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


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