* (unknown),
From: Leslie Rhorer @ 2010-03-01 5:19 UTC (permalink / raw)
To: netdev
I was doing some ping testing today, and I ran across some test in
ping's output I have never noticed before. Several of the responses
returned by `ping -q -c 50 -i 12 xxxxx` had lines like the following:
rtt min/avg/max/mdev = 501.663/12212.524/60863.587/15003.409 ms, pipe 6
I searched the web using Google, and I came up with several queries
concerning a response of "pipe n", but none of them were ever answered
specifically. One did mention something about pinging across a VPN
connection, and I was indeed pinging across an openvpn connection, if that
has any relevance.
Please respond e-mail direct, if you have an answer. I haven't
joined the mail list just to get an answer to this one minor question.
^ permalink raw reply
* 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, ¶m) == 0)
+ /* Hook up the adaptation layer. */
+ return cfcnfg_add_adaptation_layer(get_caif_conf(),
+ ¶m, 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, ¶m, 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox