* [PATCH net-deletions] caif: remove CAIF NETWORK LAYER
@ 2026-04-16 18:28 Jakub Kicinski
2026-04-17 9:06 ` Michael S. Tsirkin
2026-04-18 8:48 ` Greg KH
0 siblings, 2 replies; 3+ messages in thread
From: Jakub Kicinski @ 2026-04-16 18:28 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
corbet, skhan, alexs, si.yanteng, dzm91, linux, mst, jasowang,
xuanzhuo, eperezma, xu.xin16, wang.yaxin, jiang.kun2, linusw,
jihed.chaibi.dev, arnd, tytso, jiayuan.chen, gregkh
Remove CAIF (Communication CPU to Application CPU Interface), the
ST-Ericsson modem protocol. The subsystem has been orphaned since 2013.
The last meaningful changes from the maintainers were in March 2013:
a8c7687bf216 ("caif_virtio: Check that vringh_config is not null")
b2273be8d2df ("caif_virtio: Use vringh_notify_enable correctly")
0d2e1a2926b1 ("caif_virtio: Introduce caif over virtio")
Not-so-coincidentally, according to "the Internet" ST-Ericsson officially
shut down its modem joint venture in Aug 2013.
If anyone is using this code please yell!
In the 13 years since, the code has accumulated 200 non-merge commits,
of which 71 were cross-tree API changes, 21 carried Fixes: tags, and
the remaining ~110 were cleanups, doc conversions, treewide refactors,
and one partial removal (caif_hsi, ca75bcf0a83b).
We are still getting fixes to this code, in the last 10 days there were
3 reports on security@ about CAIF that I have been CCed on.
UAPI constants (AF_CAIF, ARPHRD_CAIF, N_CAIF, VIRTIO_ID_CAIF) and the
SELinux classmap entry are intentionally kept for ABI stability.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
I think we should accumulate such patches over the coming days on a separate
branch. CAIF is a no-brainer IMO but other removals may be more controversial.
CC: corbet@lwn.net
CC: skhan@linuxfoundation.org
CC: alexs@kernel.org
CC: si.yanteng@linux.dev
CC: dzm91@hust.edu.cn
CC: linux@armlinux.org.uk
CC: mst@redhat.com
CC: jasowang@redhat.com
CC: xuanzhuo@linux.alibaba.com
CC: eperezma@redhat.com
CC: xu.xin16@zte.com.cn
CC: wang.yaxin@zte.com.cn
CC: jiang.kun2@zte.com.cn
CC: linusw@kernel.org
CC: jihed.chaibi.dev@gmail.com
CC: arnd@arndb.de
CC: tytso@mit.edu
CC: jiayuan.chen@shopee.com
CC: gregkh@linuxfoundation.org
---
MAINTAINERS | 9 -
Documentation/networking/caif/caif.rst | 138 --
Documentation/networking/caif/index.rst | 12 -
Documentation/networking/caif/linux_caif.rst | 195 ---
Documentation/networking/index.rst | 1 -
.../translations/zh_CN/networking/index.rst | 1 -
drivers/net/Kconfig | 2 -
drivers/net/caif/Kconfig | 33 -
net/Kconfig | 1 -
net/caif/Kconfig | 54 -
drivers/net/Makefile | 1 -
drivers/net/caif/Makefile | 8 -
net/Makefile | 1 -
net/caif/Makefile | 16 -
include/linux/virtio_caif.h | 24 -
include/net/caif/caif_dev.h | 128 --
include/net/caif/caif_device.h | 55 -
include/net/caif/caif_layer.h | 277 ----
include/net/caif/cfcnfg.h | 90 --
include/net/caif/cfctrl.h | 130 --
include/net/caif/cffrml.h | 21 -
include/net/caif/cfmuxl.h | 20 -
include/net/caif/cfpkt.h | 232 ----
include/net/caif/cfserl.h | 13 -
include/net/caif/cfsrvl.h | 61 -
include/uapi/linux/caif/caif_socket.h | 195 ---
include/uapi/linux/caif/if_caif.h | 35 -
drivers/net/caif/caif_serial.c | 443 -------
drivers/net/caif/caif_virtio.c | 791 ------------
net/caif/caif_dev.c | 586 ---------
net/caif/caif_socket.c | 1114 -----------------
net/caif/caif_usb.c | 216 ----
net/caif/cfcnfg.c | 612 ---------
net/caif/cfctrl.c | 631 ----------
net/caif/cfdbgl.c | 55 -
net/caif/cfdgml.c | 113 --
net/caif/cffrml.c | 204 ---
net/caif/cfmuxl.c | 267 ----
net/caif/cfpkt_skbuff.c | 373 ------
net/caif/cfrfml.c | 299 -----
net/caif/cfserl.c | 192 ---
net/caif/cfsrvl.c | 224 ----
net/caif/cfutill.c | 104 --
net/caif/cfveil.c | 101 --
net/caif/cfvidl.c | 65 -
net/caif/chnl_net.c | 531 --------
arch/arm/configs/u8500_defconfig | 1 -
47 files changed, 8675 deletions(-)
delete mode 100644 Documentation/networking/caif/caif.rst
delete mode 100644 Documentation/networking/caif/index.rst
delete mode 100644 Documentation/networking/caif/linux_caif.rst
delete mode 100644 drivers/net/caif/Kconfig
delete mode 100644 net/caif/Kconfig
delete mode 100644 drivers/net/caif/Makefile
delete mode 100644 net/caif/Makefile
delete mode 100644 include/linux/virtio_caif.h
delete mode 100644 include/net/caif/caif_dev.h
delete mode 100644 include/net/caif/caif_device.h
delete mode 100644 include/net/caif/caif_layer.h
delete mode 100644 include/net/caif/cfcnfg.h
delete mode 100644 include/net/caif/cfctrl.h
delete mode 100644 include/net/caif/cffrml.h
delete mode 100644 include/net/caif/cfmuxl.h
delete mode 100644 include/net/caif/cfpkt.h
delete mode 100644 include/net/caif/cfserl.h
delete mode 100644 include/net/caif/cfsrvl.h
delete mode 100644 include/uapi/linux/caif/caif_socket.h
delete mode 100644 include/uapi/linux/caif/if_caif.h
delete mode 100644 drivers/net/caif/caif_serial.c
delete mode 100644 drivers/net/caif/caif_virtio.c
delete mode 100644 net/caif/caif_dev.c
delete mode 100644 net/caif/caif_socket.c
delete mode 100644 net/caif/caif_usb.c
delete mode 100644 net/caif/cfcnfg.c
delete mode 100644 net/caif/cfctrl.c
delete mode 100644 net/caif/cfdbgl.c
delete mode 100644 net/caif/cfdgml.c
delete mode 100644 net/caif/cffrml.c
delete mode 100644 net/caif/cfmuxl.c
delete mode 100644 net/caif/cfpkt_skbuff.c
delete mode 100644 net/caif/cfrfml.c
delete mode 100644 net/caif/cfserl.c
delete mode 100644 net/caif/cfsrvl.c
delete mode 100644 net/caif/cfutill.c
delete mode 100644 net/caif/cfveil.c
delete mode 100644 net/caif/cfvidl.c
delete mode 100644 net/caif/chnl_net.c
diff --git a/MAINTAINERS b/MAINTAINERS
index e7dc9e6fad2e..2b1b5e93c272 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5674,15 +5674,6 @@ T: git git://linuxtv.org/media.git
F: Documentation/admin-guide/media/cafe_ccic*
F: drivers/media/platform/marvell/
-CAIF NETWORK LAYER
-L: netdev@vger.kernel.org
-S: Orphan
-F: Documentation/networking/caif/
-F: drivers/net/caif/
-F: include/net/caif/
-F: include/uapi/linux/caif/
-F: net/caif/
-
CAKE QDISC
M: Toke Høiland-Jørgensen <toke@toke.dk>
L: cake@lists.bufferbloat.net (moderated for non-subscribers)
diff --git a/Documentation/networking/caif/caif.rst b/Documentation/networking/caif/caif.rst
deleted file mode 100644
index d922d419c513..000000000000
--- a/Documentation/networking/caif/caif.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-
-================
-Using Linux CAIF
-================
-
-
-:Copyright: |copy| ST-Ericsson AB 2010
-
-:Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
-
-Start
-=====
-
-If you have compiled CAIF for modules do::
-
- $modprobe crc_ccitt
- $modprobe caif
- $modprobe caif_socket
- $modprobe chnl_net
-
-
-Preparing the setup with a STE modem
-====================================
-
-If you are working on integration of CAIF you should make sure
-that the kernel is built with module support.
-
-There are some things that need to be tweaked to get the host TTY correctly
-set up to talk to the modem.
-Since the CAIF stack is running in the kernel and we want to use the existing
-TTY, we are installing our physical serial driver as a line discipline above
-the TTY device.
-
-To achieve this we need to install the N_CAIF ldisc from user space.
-The benefit is that we can hook up to any TTY.
-
-The use of Start-of-frame-extension (STX) must also be set as
-module parameter "ser_use_stx".
-
-Normally Frame Checksum is always used on UART, but this is also provided as a
-module parameter "ser_use_fcs".
-
-::
-
- $ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
- $ ifconfig caif_ttyS0 up
-
-PLEASE NOTE:
- There is a limitation in Android shell.
- It only accepts one argument to insmod/modprobe!
-
-Trouble shooting
-================
-
-There are debugfs parameters provided for serial communication.
-/sys/kernel/debug/caif_serial/<tty-name>/
-
-* ser_state: Prints the bit-mask status where
-
- - 0x02 means SENDING, this is a transient state.
- - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
- and is blocking further send operation. Flow OFF has been propagated
- to all CAIF Channels using this TTY.
-
-* tty_status: Prints the bit-mask tty status information
-
- - 0x01 - tty->warned is on.
- - 0x04 - tty->packed is on.
- - 0x08 - tty->flow.tco_stopped is on.
- - 0x10 - tty->hw_stopped is on.
- - 0x20 - tty->flow.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.
diff --git a/Documentation/networking/caif/index.rst b/Documentation/networking/caif/index.rst
deleted file mode 100644
index ec29b6f4bdb4..000000000000
--- a/Documentation/networking/caif/index.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-CAIF
-====
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- linux_caif
- caif
diff --git a/Documentation/networking/caif/linux_caif.rst b/Documentation/networking/caif/linux_caif.rst
deleted file mode 100644
index a0480862ab8c..000000000000
--- a/Documentation/networking/caif/linux_caif.rst
+++ /dev/null
@@ -1,195 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-==========
-Linux CAIF
-==========
-
-Copyright |copy| 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 and GPRS IP Interface.
-* CAIF Core Protocol Implementation
-* CAIF Link Layer, implemented as NET devices.
-
-::
-
- RTNL
- !
- ! +------+ +------+
- ! +------+! +------+!
- ! ! IP !! !Socket!!
- +-------> !interf!+ ! API !+ <- CAIF Client APIs
- ! +------+ +------!
- ! ! !
- ! +-----------+
- ! !
- ! +------+ <- CAIF Core Protocol
- ! ! CAIF !
- ! ! Core !
- ! +------+
- ! +----------!---------+
- ! ! ! !
- ! +------+ +-----+ +------+
- +--> ! HSI ! ! TTY ! ! USB ! <- Link Layer (Net Devices)
- +------+ +-----+ +------+
-
-
-
-Implementation
-==============
-
-
-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 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 function)
-
-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.
-
-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 appropriate 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);
-
-
-CAIF Socket and IP interface
-============================
-
-The IP interface and CAIF socket API are implemented on top of the
-CAIF Core protocol. The IP Interface 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.
-
-Configuration of Link Layer
----------------------------
-The Link Layer is implemented as Linux network 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/index.rst b/Documentation/networking/index.rst
index c2406bd8ae0b..2e946924ad3f 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -17,7 +17,6 @@ Refer to :ref:`netdev-FAQ` for a guide on netdev development process specifics.
diagnostic/index
dsa/index
devlink/index
- caif/index
ethtool-netlink
ieee802154
iso15765-2
diff --git a/Documentation/translations/zh_CN/networking/index.rst b/Documentation/translations/zh_CN/networking/index.rst
index c276c0993c51..333e9f6cafff 100644
--- a/Documentation/translations/zh_CN/networking/index.rst
+++ b/Documentation/translations/zh_CN/networking/index.rst
@@ -42,7 +42,6 @@ 目录:
* diagnostic/index
* dsa/index
* devlink/index
-* caif/index
* ethtool-netlink
* ieee802154
* iso15765-2
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index edaab759dc50..8ec98f6dfef9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -503,8 +503,6 @@ source "drivers/net/arcnet/Kconfig"
source "drivers/atm/Kconfig"
-source "drivers/net/caif/Kconfig"
-
source "drivers/net/dsa/Kconfig"
source "drivers/net/ethernet/Kconfig"
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
deleted file mode 100644
index 709660cb38f8..000000000000
--- a/drivers/net/caif/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# CAIF physical drivers
-#
-
-menuconfig CAIF_DRIVERS
- bool "CAIF transport drivers"
- depends on CAIF
- help
- Enable this to see CAIF physical drivers.
-
-if CAIF_DRIVERS
-
-config CAIF_TTY
- tristate "CAIF TTY transport driver"
- depends on CAIF && TTY
- default n
- help
- The CAIF TTY transport driver is a Line Discipline (ldisc)
- identified as N_CAIF. When this ldisc is opened from user space
- it will redirect the TTY's traffic into the CAIF stack.
-
-config CAIF_VIRTIO
- tristate "CAIF virtio transport driver"
- depends on CAIF && HAS_DMA
- select VHOST_RING
- select VIRTIO
- select GENERIC_ALLOCATOR
- default n
- help
- The CAIF driver for CAIF over Virtio.
-
-endif # CAIF_DRIVERS
diff --git a/net/Kconfig b/net/Kconfig
index 62266eaf0e95..5c588dbcbdbd 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -439,7 +439,6 @@ endif # WIRELESS
source "net/rfkill/Kconfig"
source "net/9p/Kconfig"
-source "net/caif/Kconfig"
source "net/ceph/Kconfig"
source "net/nfc/Kconfig"
source "net/psample/Kconfig"
diff --git a/net/caif/Kconfig b/net/caif/Kconfig
deleted file mode 100644
index 87205251cc25..000000000000
--- a/net/caif/Kconfig
+++ /dev/null
@@ -1,54 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# CAIF net configurations
-#
-
-menuconfig CAIF
- tristate "CAIF support"
- select CRC_CCITT
- default n
- help
- The "Communication CPU to Application CPU Interface" (CAIF) is a packet
- based connection-oriented MUX protocol developed by ST-Ericsson for use
- with its modems. It is accessed from user space as sockets (PF_CAIF).
-
- Say Y (or M) here if you build for a phone product (e.g. Android or
- MeeGo) that uses CAIF as transport. If unsure say N.
-
- If you select to build it as module then CAIF_NETDEV also needs to be
- built as a module. You will also need to say Y (or M) to any CAIF
- physical devices that your platform requires.
-
- See Documentation/networking/caif for a further explanation on how to
- use and configure CAIF.
-
-config CAIF_DEBUG
- bool "Enable Debug"
- depends on CAIF
- 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"
- depends on CAIF
- 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.
-
-config CAIF_USB
- tristate "CAIF USB support"
- depends on CAIF
- default n
- help
- Say Y if you are using CAIF over USB CDC NCM.
- 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 N.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5b01215f6829..3b2d28127634 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -48,7 +48,6 @@ obj-$(CONFIG_MHI_NET) += mhi_net.o
# Networking Drivers
#
obj-$(CONFIG_ARCNET) += arcnet/
-obj-$(CONFIG_CAIF) += caif/
obj-$(CONFIG_CAN) += can/
ifdef CONFIG_NET_DSA
obj-y += dsa/
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
deleted file mode 100644
index 97f664f8016c..000000000000
--- a/drivers/net/caif/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
-
-# Serial interface
-obj-$(CONFIG_CAIF_TTY) += caif_serial.o
-
-# Virtio interface
-obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
diff --git a/net/Makefile b/net/Makefile
index 90e3d72bf58b..98e182829eff 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -53,7 +53,6 @@ obj-$(CONFIG_IUCV) += iucv/
obj-$(CONFIG_SMC) += smc/
obj-$(CONFIG_RFKILL) += rfkill/
obj-$(CONFIG_NET_9P) += 9p/
-obj-$(CONFIG_CAIF) += caif/
obj-$(CONFIG_DCB) += dcb/
obj-$(CONFIG_6LOWPAN) += 6lowpan/
obj-$(CONFIG_IEEE802154) += ieee802154/
diff --git a/net/caif/Makefile b/net/caif/Makefile
deleted file mode 100644
index 4f6c0517cdfb..000000000000
--- a/net/caif/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
-
-caif-y := 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
-
-obj-$(CONFIG_CAIF) += caif.o
-obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
-obj-$(CONFIG_CAIF) += caif_socket.o
-obj-$(CONFIG_CAIF_USB) += caif_usb.o
-
-export-y := caif.o
diff --git a/include/linux/virtio_caif.h b/include/linux/virtio_caif.h
deleted file mode 100644
index ea722479510c..000000000000
--- a/include/linux/virtio_caif.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson AB 2012
- * Author: Sjur Brændeland <sjur.brandeland@stericsson.com>
- *
- * This header is BSD licensed so
- * anyone can use the definitions to implement compatible remote processors
- */
-
-#ifndef VIRTIO_CAIF_H
-#define VIRTIO_CAIF_H
-
-#include <linux/types.h>
-struct virtio_caif_transf_config {
- __virtio16 headroom;
- __virtio16 tailroom;
- __virtio32 mtu;
- u8 reserved[4];
-};
-
-struct virtio_caif_config {
- struct virtio_caif_transf_config uplink, downlink;
- u8 reserved[8];
-};
-#endif
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
deleted file mode 100644
index b655d8666f55..000000000000
--- a/include/net/caif/caif_dev.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CAIF_DEV_H_
-#define CAIF_DEV_H_
-
-#include <net/caif/caif_layer.h>
-#include <net/caif/cfcnfg.h>
-#include <net/caif/caif_device.h>
-#include <linux/caif/caif_socket.h>
-#include <linux/if.h>
-#include <linux/net.h>
-
-/**
- * struct caif_param - CAIF parameters.
- * @size: Length of data
- * @data: Binary Data Blob
- */
-struct caif_param {
- u16 size;
- u8 data[256];
-};
-
-/**
- * struct caif_connect_request - Request data for CAIF channel setup.
- * @protocol: Type of CAIF protocol to use (at, datagram etc)
- * @sockaddr: Socket address to connect.
- * @priority: Priority of the connection.
- * @link_selector: Link selector (high bandwidth or low latency)
- * @ifindex: kernel index of the interface.
- * @param: Connect Request parameters (CAIF_SO_REQ_PARAM).
- *
- * This struct is used when connecting a CAIF channel.
- * It contains all CAIF channel configuration options.
- */
-struct caif_connect_request {
- enum caif_protocol_type protocol;
- struct sockaddr_caif sockaddr;
- enum caif_channel_priority priority;
- enum caif_link_selector link_selector;
- int ifindex;
- 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.
- * @ifindex: Link layer interface index used for this connection.
- * @headroom: Head room needed by CAIF protocol.
- * @tailroom: Tail room needed by CAIF protocol.
- *
- * 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 net *net,
- struct caif_connect_request *conn_req,
- struct cflayer *client_layer, int *ifindex,
- int *headroom, int *tailroom);
-
-/**
- * caif_disconnect_client - Disconnects a client from the CAIF stack.
- *
- * @client_layer: Client layer to be disconnected.
- */
-int caif_disconnect_client(struct net *net, struct cflayer *client_layer);
-
-
-/**
- * caif_client_register_refcnt - register ref-count functions provided by client.
- *
- * @adapt_layer: Client layer using CAIF Stack.
- * @hold: Function provided by client layer increasing ref-count
- * @put: Function provided by client layer decreasing ref-count
- *
- * Client of the CAIF Stack must register functions for reference counting.
- * These functions are called by the CAIF Stack for every upstream packet,
- * and must therefore be implemented efficiently.
- *
- * Client should call caif_free_client when reference count degrease to zero.
- */
-
-void caif_client_register_refcnt(struct cflayer *adapt_layer,
- void (*hold)(struct cflayer *lyr),
- void (*put)(struct cflayer *lyr));
-/**
- * caif_free_client - Free memory used to manage the client in the CAIF Stack.
- *
- * @client_layer: Client layer to be removed.
- *
- * This function must be called from client layer in order to free memory.
- * Caller must guarantee that no packets are in flight upstream when calling
- * this function.
- */
-void caif_free_client(struct cflayer *adap_layer);
-
-/**
- * struct caif_enroll_dev - Enroll a net-device as a CAIF Link layer
- * @dev: Network device to enroll.
- * @caifdev: Configuration information from CAIF Link Layer
- * @link_support: Link layer support layer
- * @head_room: Head room needed by link support layer
- * @layer: Lowest layer in CAIF stack
- * @rcv_fun: Receive function for CAIF stack.
- *
- * This function enroll a CAIF link layer into CAIF Stack and
- * expects the interface to be able to handle CAIF payload.
- * The link_support layer is used to add any Link Layer specific
- * framing.
- */
-int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
- struct cflayer *link_support, int head_room,
- struct cflayer **layer, int (**rcv_func)(
- struct sk_buff *, struct net_device *,
- struct packet_type *, struct net_device *));
-
-#endif /* CAIF_DEV_H_ */
diff --git a/include/net/caif/caif_device.h b/include/net/caif/caif_device.h
deleted file mode 100644
index 91d1fd5b44a4..000000000000
--- a/include/net/caif/caif_device.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#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_ */
diff --git a/include/net/caif/caif_layer.h b/include/net/caif/caif_layer.h
deleted file mode 100644
index 053e7c6a6a66..000000000000
--- a/include/net/caif/caif_layer.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CAIF_LAYER_H_
-#define CAIF_LAYER_H_
-
-#include <linux/list.h>
-
-struct cflayer;
-struct cfpkt;
-struct caif_payload_info;
-
-#define CAIF_LAYER_NAME_SZ 16
-
-/**
- * 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 fails. 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 function.
- * @ctrlcmd: Used for control signalling upwards in the stack.
- * @modemcmd: Used for control signaling downwards in the stack.
- * @id: The identity 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's 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 (non-blocking).
- * Contract: Each layer must implement a receive function passing the
- * CAIF packets upwards in the stack.
- * Packet handling rules:
- * - The CAIF packet (cfpkt) ownership is passed to the
- * called receive function. This means that the
- * packet cannot be accessed after passing it to the
- * above layer using up->receive().
- *
- * - If parsing of the packet fails, the packet must be
- * destroyed and negative error code returned
- * from the function.
- * EXCEPTION: If the framing layer (cffrml) returns
- * -EILSEQ, the packet is not freed.
- *
- * - 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 (non-blocking).
- * 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 packet
- * cannot be accessed after passing it to the below
- * layer using dn->transmit().
- *
- * - Upon error the packet ownership is still passed on,
- * so the packet shall be freed where error is detected.
- * Callers of the transmit function shall not free packets,
- * but errors shall be returned.
- *
- * - Return value less than zero means error, zero or
- * greater than zero means OK.
- *
- * Returns result < 0 indicates an error, 0 or positive value
- * indicates 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 (non-blocking).
- * 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 int id;
- 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
deleted file mode 100644
index 8819ff4db35a..000000000000
--- a/include/net/caif/cfcnfg.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CFCNFG_H_
-#define CFCNFG_H_
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <net/caif/caif_layer.h>
-#include <net/caif/cfctrl.h>
-
-struct cfcnfg;
-
-/**
- * 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() - Get the CAIF configuration object given network.
- * @net: Network for the CAIF configuration object.
- */
-struct cfcnfg *get_cfcnfg(struct net *net);
-
-/**
- * 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().
- * @dev: Pointer to link layer device
- * @phy_layer: Specify the physical layer. The transmit function
- * MUST be set in the structure.
- * @pref: The phy (link layer) preference.
- * @link_support: Protocol implementation for link layer specific protocol.
- * @fcs: Specify if checksum is used in CAIF Framing Layer.
- * @head_room: Head space needed by link specific protocol.
- */
-int
-cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
- struct net_device *dev, struct cflayer *phy_layer,
- enum cfcnfg_phy_preference pref,
- struct cflayer *link_support,
- bool fcs, int head_room);
-
-/**
- * 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_set_phy_state() - Set the state of the physical interface device.
- * @cnfg: Configuration object
- * @phy_layer: Physical Layer representation
- * @up: State of device
- */
-int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
- bool up);
-
-#endif /* CFCNFG_H_ */
diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h
deleted file mode 100644
index 86d17315c8a1..000000000000
--- a/include/net/caif/cfctrl.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#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);
- 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 cflayer *client_layer;
- struct list_head list;
-};
-
-struct cfctrl {
- struct cfsrvl serv;
- struct cfctrl_rsp res;
- atomic_t req_seq_no;
- atomic_t rsp_seq_no;
- struct list_head list;
- /* Protects from simultaneous access to first_req list */
- spinlock_t info_list_lock;
-#ifndef CAIF_NO_LOOP
- u8 loop_linkid;
- int loop_linkused[256];
- /* Protects simultaneous access to loop_linkid and loop_linkused */
- spinlock_t loop_linkid_lock;
-#endif
-
-};
-
-void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid);
-int 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);
-
-struct cflayer *cfctrl_create(void);
-struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer);
-int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
-void cfctrl_remove(struct cflayer *layr);
-
-#endif /* CFCTRL_H_ */
diff --git a/include/net/caif/cffrml.h b/include/net/caif/cffrml.h
deleted file mode 100644
index 1ab8a80ede4d..000000000000
--- a/include/net/caif/cffrml.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CFFRML_H_
-#define CFFRML_H_
-#include <net/caif/caif_layer.h>
-#include <linux/netdevice.h>
-
-struct cffrml;
-struct cflayer *cffrml_create(u16 phyid, bool use_fcs);
-void cffrml_free(struct cflayer *layr);
-void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up);
-void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn);
-void cffrml_put(struct cflayer *layr);
-void cffrml_hold(struct cflayer *layr);
-int cffrml_refcnt_read(struct cflayer *layr);
-
-#endif /* CFFRML_H_ */
diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h
deleted file mode 100644
index 92ccb2648309..000000000000
--- a/include/net/caif/cfmuxl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#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);
-
-#endif /* CFMUXL_H_ */
diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h
deleted file mode 100644
index acf664227d96..000000000000
--- a/include/net/caif/cfpkt.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#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);
-
-/*
- * Destroy a CAIF Packet.
- * pkt Packet to be destroyed.
- */
-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);
-
-static inline u8 cfpkt_extr_head_u8(struct cfpkt *pkt)
-{
- u8 tmp;
-
- cfpkt_extr_head(pkt, &tmp, 1);
-
- return tmp;
-}
-
-static inline u16 cfpkt_extr_head_u16(struct cfpkt *pkt)
-{
- __le16 tmp;
-
- cfpkt_extr_head(pkt, &tmp, 2);
-
- return le16_to_cpu(tmp);
-}
-
-static inline u32 cfpkt_extr_head_u32(struct cfpkt *pkt)
-{
- __le32 tmp;
-
- cfpkt_extr_head(pkt, &tmp, 4);
-
- return le32_to_cpu(tmp);
-}
-
-/*
- * 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.
- */
-
-int cfpkt_iterate(struct cfpkt *pkt,
- u16 (*iter_func)(u16 chks, void *buf, u16 len),
- u16 data);
-
-/* 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);
-
-/*
- * Returns packet information for a packet.
- * pkt Packet to get info from;
- * @return Packet information
- */
-struct caif_payload_info *cfpkt_info(struct cfpkt *pkt);
-
-/** cfpkt_set_prio - set priority for a CAIF packet.
- *
- * @pkt: The CAIF packet to be adjusted.
- * @prio: one of TC_PRIO_ constants.
- */
-void cfpkt_set_prio(struct cfpkt *pkt, int prio);
-
-#endif /* CFPKT_H_ */
diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h
deleted file mode 100644
index 67cce8757175..000000000000
--- a/include/net/caif/cfserl.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CFSERL_H_
-#define CFSERL_H_
-#include <net/caif/caif_layer.h>
-
-struct cflayer *cfserl_create(int instance, bool use_stx);
-void cfserl_release(struct cflayer *layer);
-#endif
diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h
deleted file mode 100644
index a000dc45f966..000000000000
--- a/include/net/caif/cfsrvl.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#ifndef CFSRVL_H_
-#define CFSRVL_H_
-#include <linux/list.h>
-#include <linux/stddef.h>
-#include <linux/types.h>
-#include <linux/kref.h>
-#include <linux/rculist.h>
-
-struct cfsrvl {
- struct cflayer layer;
- bool open;
- bool phy_flow_on;
- bool modem_flow_on;
- bool supports_flowctrl;
- void (*release)(struct cflayer *layer);
- struct dev_info dev_info;
- void (*hold)(struct cflayer *lyr);
- void (*put)(struct cflayer *lyr);
- struct rcu_head rcu;
-};
-
-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,
- int mtu_size);
-struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info);
-
-bool cfsrvl_phyid_match(struct cflayer *layer, int phyid);
-
-void cfsrvl_init(struct cfsrvl *service,
- u8 channel_id,
- struct dev_info *dev_info,
- bool supports_flowctrl);
-bool cfsrvl_ready(struct cfsrvl *service, int *err);
-
-static inline void cfsrvl_get(struct cflayer *layr)
-{
- struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
- if (layr == NULL || layr->up == NULL || s->hold == NULL)
- return;
-
- s->hold(layr->up);
-}
-
-static inline void cfsrvl_put(struct cflayer *layr)
-{
- struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
- if (layr == NULL || layr->up == NULL || s->hold == NULL)
- return;
-
- s->put(layr->up);
-}
-#endif /* CFSRVL_H_ */
diff --git a/include/uapi/linux/caif/caif_socket.h b/include/uapi/linux/caif/caif_socket.h
deleted file mode 100644
index d9970bbaa156..000000000000
--- a/include/uapi/linux/caif/caif_socket.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/* linux/caif_socket.h
- * CAIF Definitions for CAIF socket and network layer
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef _LINUX_CAIF_SOCKET_H
-#define _LINUX_CAIF_SOCKET_H
-
-#include <linux/types.h>
-#include <linux/socket.h>
-
-/**
- * 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
- * @CAIFPROTO_DEBUG: Debug link
- *
- * 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_DEBUG,
- _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
-};
- /**
- * enum caif_debug_type - Content selection for debug connection
- * @CAIF_DEBUG_TRACE_INTERACTIVE: Connection will contain
- * both trace and interactive debug.
- * @CAIF_DEBUG_TRACE: Connection contains trace only.
- * @CAIF_DEBUG_INTERACTIVE: Connection to interactive debug.
- */
-enum caif_debug_type {
- CAIF_DEBUG_TRACE_INTERACTIVE = 0,
- CAIF_DEBUG_TRACE,
- CAIF_DEBUG_INTERACTIVE,
-};
-
-/**
- * enum caif_debug_service - Debug Service Endpoint
- * @CAIF_RADIO_DEBUG_SERVICE: Debug service on the Radio sub-system
- * @CAIF_APP_DEBUG_SERVICE: Debug for the applications sub-system
- */
-enum caif_debug_service {
- CAIF_RADIO_DEBUG_SERVICE = 1,
- CAIF_APP_DEBUG_SERVICE
-};
-
-/**
- * struct sockaddr_caif - the sockaddr structure for CAIF sockets.
- * @family: Address family number, must be AF_CAIF.
- * @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.
- *
- * @u.dbg: Applies when family = CAIFPROTO_DEBUG.
- *
- * @u.dbg.type: Type of debug connection to set up
- * (caif_debug_type).
- *
- * @u.dbg.service: Service sub-system to connect (caif_debug_service
- * 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 {
- __kernel_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 */
- struct {
- __u8 type; /* type:enum caif_debug_type */
- __u8 service; /* service:caif_debug_service */
- } dbg; /* CAIFPROTO_DEBUG */
- } 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
- * 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
- * of type PF_CAIF.
- *
- */
-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/uapi/linux/caif/if_caif.h b/include/uapi/linux/caif/if_caif.h
deleted file mode 100644
index 74bca19403fa..000000000000
--- a/include/uapi/linux/caif/if_caif.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- * 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_*/
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
deleted file mode 100644
index 1873d8287bb9..000000000000
--- a/drivers/net/caif/caif_serial.c
+++ /dev/null
@@ -1,443 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#include <linux/hardirq.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/tty.h>
-#include <linux/file.h>
-#include <linux/if_arp.h>
-#include <net/caif/caif_device.h>
-#include <net/caif/cfcnfg.h>
-#include <linux/err.h>
-#include <linux/debugfs.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sjur Brendeland");
-MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_CAIF);
-
-#define SEND_QUEUE_LOW 10
-#define SEND_QUEUE_HIGH 100
-#define CAIF_SENDING 1 /* Bit 1 = 0x02*/
-#define CAIF_FLOW_OFF_SENT 4 /* Bit 4 = 0x10 */
-#define MAX_WRITE_CHUNK 4096
-#define ON 1
-#define OFF 0
-#define CAIF_MAX_MTU 4096
-
-static DEFINE_SPINLOCK(ser_lock);
-static LIST_HEAD(ser_list);
-static LIST_HEAD(ser_release_list);
-
-static bool ser_loop;
-module_param(ser_loop, bool, 0444);
-MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
-
-static bool ser_use_stx = true;
-module_param(ser_use_stx, bool, 0444);
-MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
-
-static bool ser_use_fcs = true;
-
-module_param(ser_use_fcs, bool, 0444);
-MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
-
-static int ser_write_chunk = MAX_WRITE_CHUNK;
-module_param(ser_write_chunk, int, 0444);
-
-MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
-
-static struct dentry *debugfsdir;
-
-static int caif_net_open(struct net_device *dev);
-static int caif_net_close(struct net_device *dev);
-
-struct ser_device {
- struct caif_dev_common common;
- struct list_head node;
- struct net_device *dev;
- struct sk_buff_head head;
- struct tty_struct *tty;
- bool tx_started;
- unsigned long state;
-#ifdef CONFIG_DEBUG_FS
- struct dentry *debugfs_tty_dir;
- struct debugfs_blob_wrapper tx_blob;
- struct debugfs_blob_wrapper rx_blob;
- u8 rx_data[128];
- u8 tx_data[128];
- u8 tty_status;
-
-#endif
-};
-
-static void caifdev_setup(struct net_device *dev);
-static void ldisc_tx_wakeup(struct tty_struct *tty);
-#ifdef CONFIG_DEBUG_FS
-static inline void update_tty_status(struct ser_device *ser)
-{
- ser->tty_status =
- ser->tty->flow.stopped << 5 |
- ser->tty->flow.tco_stopped << 3 |
- ser->tty->ctrl.packet << 2;
-}
-static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
-{
- ser->debugfs_tty_dir = debugfs_create_dir(tty->name, debugfsdir);
-
- debugfs_create_blob("last_tx_msg", 0400, ser->debugfs_tty_dir,
- &ser->tx_blob);
-
- debugfs_create_blob("last_rx_msg", 0400, ser->debugfs_tty_dir,
- &ser->rx_blob);
-
- debugfs_create_xul("ser_state", 0400, ser->debugfs_tty_dir,
- &ser->state);
-
- debugfs_create_x8("tty_status", 0400, ser->debugfs_tty_dir,
- &ser->tty_status);
-
- ser->tx_blob.data = ser->tx_data;
- ser->tx_blob.size = 0;
- ser->rx_blob.data = ser->rx_data;
- ser->rx_blob.size = 0;
-}
-
-static inline void debugfs_deinit(struct ser_device *ser)
-{
- debugfs_remove_recursive(ser->debugfs_tty_dir);
-}
-
-static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
-{
- if (size > sizeof(ser->rx_data))
- size = sizeof(ser->rx_data);
- memcpy(ser->rx_data, data, size);
- ser->rx_blob.data = ser->rx_data;
- ser->rx_blob.size = size;
-}
-#else
-static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
-{
-}
-
-static inline void debugfs_deinit(struct ser_device *ser)
-{
-}
-
-static inline void update_tty_status(struct ser_device *ser)
-{
-}
-
-static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
-{
-}
-#endif
-
-static void ldisc_receive(struct tty_struct *tty, const u8 *data,
- const u8 *flags, size_t count)
-{
- struct sk_buff *skb = NULL;
- struct ser_device *ser;
- int ret;
-
- ser = tty->disc_data;
-
- /*
- * NOTE: flags may contain information about break or overrun.
- * This is not yet handled.
- */
-
-
- /*
- * Workaround for garbage at start of transmission,
- * only enable if STX handling is not enabled.
- */
- if (!ser->common.use_stx && !ser->tx_started) {
- dev_info(&ser->dev->dev,
- "Bytes received before initial transmission -"
- "bytes discarded.\n");
- return;
- }
-
- BUG_ON(ser->dev == NULL);
-
- /* Get a suitable caif packet and copy in data. */
- skb = netdev_alloc_skb(ser->dev, count+1);
- if (skb == NULL)
- return;
- skb_put_data(skb, data, count);
-
- skb->protocol = htons(ETH_P_CAIF);
- skb_reset_mac_header(skb);
- debugfs_rx(ser, data, count);
- /* Push received packet up the stack. */
- ret = netif_rx(skb);
- if (!ret) {
- ser->dev->stats.rx_packets++;
- ser->dev->stats.rx_bytes += count;
- } else
- ++ser->dev->stats.rx_dropped;
- update_tty_status(ser);
-}
-
-static int handle_tx(struct ser_device *ser)
-{
- struct tty_struct *tty;
- struct sk_buff *skb;
- int tty_wr, len, room;
-
- tty = ser->tty;
- ser->tx_started = true;
-
- /* Enter critical section */
- if (test_and_set_bit(CAIF_SENDING, &ser->state))
- return 0;
-
- /* skb_peek is safe because handle_tx is called after skb_queue_tail */
- while ((skb = skb_peek(&ser->head)) != NULL) {
-
- /* Make sure you don't write too much */
- len = skb->len;
- room = tty_write_room(tty);
- if (!room)
- break;
- if (room > ser_write_chunk)
- room = ser_write_chunk;
- if (len > room)
- len = room;
-
- /* Write to tty or loopback */
- if (!ser_loop) {
- tty_wr = tty->ops->write(tty, skb->data, len);
- update_tty_status(ser);
- } else {
- tty_wr = len;
- ldisc_receive(tty, skb->data, NULL, len);
- }
- ser->dev->stats.tx_packets++;
- ser->dev->stats.tx_bytes += tty_wr;
-
- /* Error on TTY ?! */
- if (tty_wr < 0)
- goto error;
- /* Reduce buffer written, and discard if empty */
- skb_pull(skb, tty_wr);
- if (skb->len == 0) {
- struct sk_buff *tmp = skb_dequeue(&ser->head);
- WARN_ON(tmp != skb);
- dev_consume_skb_any(skb);
- }
- }
- /* Send flow off if queue is empty */
- if (ser->head.qlen <= SEND_QUEUE_LOW &&
- test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
- ser->common.flowctrl != NULL)
- ser->common.flowctrl(ser->dev, ON);
- clear_bit(CAIF_SENDING, &ser->state);
- return 0;
-error:
- clear_bit(CAIF_SENDING, &ser->state);
- return tty_wr;
-}
-
-static netdev_tx_t caif_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ser_device *ser;
-
- ser = netdev_priv(dev);
-
- /* Send flow off once, on high water mark */
- if (ser->head.qlen > SEND_QUEUE_HIGH &&
- !test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
- ser->common.flowctrl != NULL)
-
- ser->common.flowctrl(ser->dev, OFF);
-
- skb_queue_tail(&ser->head, skb);
- return handle_tx(ser);
-}
-
-
-static void ldisc_tx_wakeup(struct tty_struct *tty)
-{
- struct ser_device *ser;
-
- ser = tty->disc_data;
- BUG_ON(ser == NULL);
- WARN_ON(ser->tty != tty);
- handle_tx(ser);
-}
-
-
-static void ser_release(struct work_struct *work)
-{
- struct list_head list;
- struct ser_device *ser, *tmp;
- struct tty_struct *tty;
-
- spin_lock(&ser_lock);
- list_replace_init(&ser_release_list, &list);
- spin_unlock(&ser_lock);
-
- if (!list_empty(&list)) {
- rtnl_lock();
- list_for_each_entry_safe(ser, tmp, &list, node) {
- tty = ser->tty;
- dev_close(ser->dev);
- unregister_netdevice(ser->dev);
- debugfs_deinit(ser);
- tty_kref_put(tty->link);
- tty_kref_put(tty);
- }
- rtnl_unlock();
- }
-}
-
-static DECLARE_WORK(ser_release_work, ser_release);
-
-static int ldisc_open(struct tty_struct *tty)
-{
- struct ser_device *ser;
- struct net_device *dev;
- char name[64];
- int result;
-
- /* No write no play */
- if (tty->ops->write == NULL)
- return -EOPNOTSUPP;
- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG))
- return -EPERM;
-
- /* release devices to avoid name collision */
- ser_release(NULL);
-
- result = snprintf(name, sizeof(name), "cf%s", tty->name);
- if (result >= IFNAMSIZ)
- return -EINVAL;
- dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN,
- caifdev_setup);
- if (!dev)
- return -ENOMEM;
-
- ser = netdev_priv(dev);
- ser->tty = tty_kref_get(tty);
- tty_kref_get(tty->link);
- ser->dev = dev;
- debugfs_init(ser, tty);
- tty->receive_room = 4096;
- tty->disc_data = ser;
- set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
- rtnl_lock();
- result = register_netdevice(dev);
- if (result) {
- tty_kref_put(tty->link);
- tty_kref_put(tty);
- rtnl_unlock();
- free_netdev(dev);
- return -ENODEV;
- }
-
- spin_lock(&ser_lock);
- list_add(&ser->node, &ser_list);
- spin_unlock(&ser_lock);
- rtnl_unlock();
- netif_stop_queue(dev);
- update_tty_status(ser);
- return 0;
-}
-
-static void ldisc_close(struct tty_struct *tty)
-{
- struct ser_device *ser = tty->disc_data;
-
- spin_lock(&ser_lock);
- list_move(&ser->node, &ser_release_list);
- spin_unlock(&ser_lock);
- schedule_work(&ser_release_work);
-}
-
-/* The line discipline structure. */
-static struct tty_ldisc_ops caif_ldisc = {
- .owner = THIS_MODULE,
- .num = N_CAIF,
- .name = "n_caif",
- .open = ldisc_open,
- .close = ldisc_close,
- .receive_buf = ldisc_receive,
- .write_wakeup = ldisc_tx_wakeup
-};
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = caif_net_open,
- .ndo_stop = caif_net_close,
- .ndo_start_xmit = caif_xmit
-};
-
-static void caifdev_setup(struct net_device *dev)
-{
- struct ser_device *serdev = netdev_priv(dev);
-
- dev->features = 0;
- dev->netdev_ops = &netdev_ops;
- dev->type = ARPHRD_CAIF;
- dev->flags = IFF_POINTOPOINT | IFF_NOARP;
- dev->mtu = CAIF_MAX_MTU;
- dev->priv_flags |= IFF_NO_QUEUE;
- dev->needs_free_netdev = true;
- skb_queue_head_init(&serdev->head);
- serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
- serdev->common.use_frag = true;
- serdev->common.use_stx = ser_use_stx;
- serdev->common.use_fcs = ser_use_fcs;
- serdev->dev = dev;
-}
-
-
-static int caif_net_open(struct net_device *dev)
-{
- netif_wake_queue(dev);
- return 0;
-}
-
-static int caif_net_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- return 0;
-}
-
-static int __init caif_ser_init(void)
-{
- int ret;
-
- ret = tty_register_ldisc(&caif_ldisc);
- if (ret < 0)
- pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret);
-
- debugfsdir = debugfs_create_dir("caif_serial", NULL);
- return ret;
-}
-
-static void __exit caif_ser_exit(void)
-{
- spin_lock(&ser_lock);
- list_splice(&ser_list, &ser_release_list);
- spin_unlock(&ser_lock);
- ser_release(NULL);
- cancel_work_sync(&ser_release_work);
- tty_unregister_ldisc(&caif_ldisc);
- debugfs_remove_recursive(debugfsdir);
-}
-
-module_init(caif_ser_init);
-module_exit(caif_ser_exit);
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
deleted file mode 100644
index 8ac1a4b8e055..000000000000
--- a/drivers/net/caif/caif_virtio.c
+++ /dev/null
@@ -1,791 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2013
- * Authors: Vicram Arv
- * Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
- * Sjur Brendeland
- */
-#include <linux/module.h>
-#include <linux/if_arp.h>
-#include <linux/virtio.h>
-#include <linux/vringh.h>
-#include <linux/debugfs.h>
-#include <linux/spinlock.h>
-#include <linux/genalloc.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/virtio_ids.h>
-#include <linux/virtio_caif.h>
-#include <linux/virtio_ring.h>
-#include <linux/dma-mapping.h>
-#include <net/caif/caif_dev.h>
-#include <linux/virtio_config.h>
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Vicram Arv");
-MODULE_AUTHOR("Sjur Brendeland");
-MODULE_DESCRIPTION("Virtio CAIF Driver");
-
-/* NAPI schedule quota */
-#define CFV_DEFAULT_QUOTA 32
-
-/* Defaults used if virtio config space is unavailable */
-#define CFV_DEF_MTU_SIZE 4096
-#define CFV_DEF_HEADROOM 32
-#define CFV_DEF_TAILROOM 32
-
-/* Required IP header alignment */
-#define IP_HDR_ALIGN 4
-
-/* struct cfv_napi_contxt - NAPI context info
- * @riov: IOV holding data read from the ring. Note that riov may
- * still hold data when cfv_rx_poll() returns.
- * @head: Last descriptor ID we received from vringh_getdesc_kern.
- * We use this to put descriptor back on the used ring. USHRT_MAX is
- * used to indicate invalid head-id.
- */
-struct cfv_napi_context {
- struct vringh_kiov riov;
- unsigned short head;
-};
-
-/* struct cfv_stats - statistics for debugfs
- * @rx_napi_complete: Number of NAPI completions (RX)
- * @rx_napi_resched: Number of calls where the full quota was used (RX)
- * @rx_nomem: Number of SKB alloc failures (RX)
- * @rx_kicks: Number of RX kicks
- * @tx_full_ring: Number times TX ring was full
- * @tx_no_mem: Number of times TX went out of memory
- * @tx_flow_on: Number of flow on (TX)
- * @tx_kicks: Number of TX kicks
- */
-struct cfv_stats {
- u32 rx_napi_complete;
- u32 rx_napi_resched;
- u32 rx_nomem;
- u32 rx_kicks;
- u32 tx_full_ring;
- u32 tx_no_mem;
- u32 tx_flow_on;
- u32 tx_kicks;
-};
-
-/* struct cfv_info - Caif Virtio control structure
- * @cfdev: caif common header
- * @vdev: Associated virtio device
- * @vr_rx: rx/downlink host vring
- * @vq_tx: tx/uplink virtqueue
- * @ndev: CAIF link layer device
- * @watermark_tx: indicates number of free descriptors we need
- * to reopen the tx-queues after overload.
- * @tx_lock: protects vq_tx from concurrent use
- * @tx_release_tasklet: Tasklet for freeing consumed TX buffers
- * @napi: Napi context used in cfv_rx_poll()
- * @ctx: Context data used in cfv_rx_poll()
- * @tx_hr: transmit headroom
- * @rx_hr: receive headroom
- * @tx_tr: transmit tail room
- * @rx_tr: receive tail room
- * @mtu: transmit max size
- * @mru: receive max size
- * @allocsz: size of dma memory reserved for TX buffers
- * @alloc_addr: virtual address to dma memory for TX buffers
- * @alloc_dma: dma address to dma memory for TX buffers
- * @genpool: Gen Pool used for allocating TX buffers
- * @reserved_mem: Pointer to memory reserve allocated from genpool
- * @reserved_size: Size of memory reserve allocated from genpool
- * @stats: Statistics exposed in sysfs
- * @debugfs: Debugfs dentry for statistic counters
- */
-struct cfv_info {
- struct caif_dev_common cfdev;
- struct virtio_device *vdev;
- struct vringh *vr_rx;
- struct virtqueue *vq_tx;
- struct net_device *ndev;
- unsigned int watermark_tx;
- /* Protect access to vq_tx */
- spinlock_t tx_lock;
- struct tasklet_struct tx_release_tasklet;
- struct napi_struct napi;
- struct cfv_napi_context ctx;
- u16 tx_hr;
- u16 rx_hr;
- u16 tx_tr;
- u16 rx_tr;
- u32 mtu;
- u32 mru;
- size_t allocsz;
- void *alloc_addr;
- dma_addr_t alloc_dma;
- struct gen_pool *genpool;
- unsigned long reserved_mem;
- size_t reserved_size;
- struct cfv_stats stats;
- struct dentry *debugfs;
-};
-
-/* struct buf_info - maintains transmit buffer data handle
- * @size: size of transmit buffer
- * @dma_handle: handle to allocated dma device memory area
- * @vaddr: virtual address mapping to allocated memory area
- */
-struct buf_info {
- size_t size;
- u8 *vaddr;
-};
-
-/* Called from virtio device, in IRQ context */
-static void cfv_release_cb(struct virtqueue *vq_tx)
-{
- struct cfv_info *cfv = vq_tx->vdev->priv;
-
- ++cfv->stats.tx_kicks;
- tasklet_schedule(&cfv->tx_release_tasklet);
-}
-
-static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info)
-{
- if (!buf_info)
- return;
- gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr,
- buf_info->size);
- kfree(buf_info);
-}
-
-/* This is invoked whenever the remote processor completed processing
- * a TX msg we just sent, and the buffer is put back to the used ring.
- */
-static void cfv_release_used_buf(struct virtqueue *vq_tx)
-{
- struct cfv_info *cfv = vq_tx->vdev->priv;
- unsigned long flags;
-
- BUG_ON(vq_tx != cfv->vq_tx);
-
- for (;;) {
- unsigned int len;
- struct buf_info *buf_info;
-
- /* Get used buffer from used ring to recycle used descriptors */
- spin_lock_irqsave(&cfv->tx_lock, flags);
- buf_info = virtqueue_get_buf(vq_tx, &len);
- spin_unlock_irqrestore(&cfv->tx_lock, flags);
-
- /* Stop looping if there are no more buffers to free */
- if (!buf_info)
- break;
-
- free_buf_info(cfv, buf_info);
-
- /* watermark_tx indicates if we previously stopped the tx
- * queues. If we have enough free stots in the virtio ring,
- * re-establish memory reserved and open up tx queues.
- */
- if (cfv->vq_tx->num_free <= cfv->watermark_tx)
- continue;
-
- /* Re-establish memory reserve */
- if (cfv->reserved_mem == 0 && cfv->genpool)
- cfv->reserved_mem =
- gen_pool_alloc(cfv->genpool,
- cfv->reserved_size);
-
- /* Open up the tx queues */
- if (cfv->reserved_mem) {
- cfv->watermark_tx =
- virtqueue_get_vring_size(cfv->vq_tx);
- netif_tx_wake_all_queues(cfv->ndev);
- /* Buffers are recycled in cfv_netdev_tx, so
- * disable notifications when queues are opened.
- */
- virtqueue_disable_cb(cfv->vq_tx);
- ++cfv->stats.tx_flow_on;
- } else {
- /* if no memory reserve, wait for more free slots */
- WARN_ON(cfv->watermark_tx >
- virtqueue_get_vring_size(cfv->vq_tx));
- cfv->watermark_tx +=
- virtqueue_get_vring_size(cfv->vq_tx) / 4;
- }
- }
-}
-
-/* Allocate a SKB and copy packet data to it */
-static struct sk_buff *cfv_alloc_and_copy_skb(int *err,
- struct cfv_info *cfv,
- u8 *frm, u32 frm_len)
-{
- struct sk_buff *skb;
- u32 cfpkt_len, pad_len;
-
- *err = 0;
- /* Verify that packet size with down-link header and mtu size */
- if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) {
- netdev_err(cfv->ndev,
- "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n",
- frm_len, cfv->mru, cfv->rx_hr,
- cfv->rx_tr);
- *err = -EPROTO;
- return NULL;
- }
-
- cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr);
- pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1);
-
- skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len);
- if (!skb) {
- *err = -ENOMEM;
- return NULL;
- }
-
- skb_reserve(skb, cfv->rx_hr + pad_len);
-
- skb_put_data(skb, frm + cfv->rx_hr, cfpkt_len);
- return skb;
-}
-
-/* Get packets from the host vring */
-static int cfv_rx_poll(struct napi_struct *napi, int quota)
-{
- struct cfv_info *cfv = container_of(napi, struct cfv_info, napi);
- int rxcnt = 0;
- int err = 0;
- void *buf;
- struct sk_buff *skb;
- struct vringh_kiov *riov = &cfv->ctx.riov;
- unsigned int skb_len;
-
- do {
- skb = NULL;
-
- /* Put the previous iovec back on the used ring and
- * fetch a new iovec if we have processed all elements.
- */
- if (riov->i == riov->used) {
- if (cfv->ctx.head != USHRT_MAX) {
- vringh_complete_kern(cfv->vr_rx,
- cfv->ctx.head,
- 0);
- cfv->ctx.head = USHRT_MAX;
- }
-
- err = vringh_getdesc_kern(
- cfv->vr_rx,
- riov,
- NULL,
- &cfv->ctx.head,
- GFP_ATOMIC);
-
- if (err <= 0)
- goto exit;
- }
-
- buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base);
- /* TODO: Add check on valid buffer address */
-
- skb = cfv_alloc_and_copy_skb(&err, cfv, buf,
- riov->iov[riov->i].iov_len);
- if (unlikely(err))
- goto exit;
-
- /* Push received packet up the stack. */
- skb_len = skb->len;
- skb->protocol = htons(ETH_P_CAIF);
- skb_reset_mac_header(skb);
- skb->dev = cfv->ndev;
- err = netif_receive_skb(skb);
- if (unlikely(err)) {
- ++cfv->ndev->stats.rx_dropped;
- } else {
- ++cfv->ndev->stats.rx_packets;
- cfv->ndev->stats.rx_bytes += skb_len;
- }
-
- ++riov->i;
- ++rxcnt;
- } while (rxcnt < quota);
-
- ++cfv->stats.rx_napi_resched;
- goto out;
-
-exit:
- switch (err) {
- case 0:
- ++cfv->stats.rx_napi_complete;
-
- /* Really out of packets? (stolen from virtio_net)*/
- napi_complete(napi);
- if (unlikely(!vringh_notify_enable_kern(cfv->vr_rx)) &&
- napi_schedule_prep(napi)) {
- vringh_notify_disable_kern(cfv->vr_rx);
- __napi_schedule(napi);
- }
- break;
-
- case -ENOMEM:
- ++cfv->stats.rx_nomem;
- dev_kfree_skb(skb);
- /* Stop NAPI poll on OOM, we hope to be polled later */
- napi_complete(napi);
- vringh_notify_enable_kern(cfv->vr_rx);
- break;
-
- default:
- /* We're doomed, any modem fault is fatal */
- netdev_warn(cfv->ndev, "Bad ring, disable device\n");
- cfv->ndev->stats.rx_dropped = riov->used - riov->i;
- napi_complete(napi);
- vringh_notify_disable_kern(cfv->vr_rx);
- netif_carrier_off(cfv->ndev);
- break;
- }
-out:
- if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0)
- vringh_notify(cfv->vr_rx);
- return rxcnt;
-}
-
-static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx)
-{
- struct cfv_info *cfv = vdev->priv;
-
- ++cfv->stats.rx_kicks;
- vringh_notify_disable_kern(cfv->vr_rx);
- napi_schedule(&cfv->napi);
-}
-
-static void cfv_destroy_genpool(struct cfv_info *cfv)
-{
- if (cfv->alloc_addr)
- dma_free_coherent(cfv->vdev->dev.parent->parent,
- cfv->allocsz, cfv->alloc_addr,
- cfv->alloc_dma);
-
- if (!cfv->genpool)
- return;
- gen_pool_free(cfv->genpool, cfv->reserved_mem,
- cfv->reserved_size);
- gen_pool_destroy(cfv->genpool);
- cfv->genpool = NULL;
-}
-
-static int cfv_create_genpool(struct cfv_info *cfv)
-{
- int err;
-
- /* dma_alloc can only allocate whole pages, and we need a more
- * fine graned allocation so we use genpool. We ask for space needed
- * by IP and a full ring. If the dma allcoation fails we retry with a
- * smaller allocation size.
- */
- err = -ENOMEM;
- cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) *
- (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10;
- if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu)
- return -EINVAL;
-
- for (;;) {
- if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) {
- netdev_info(cfv->ndev, "Not enough device memory\n");
- return -ENOMEM;
- }
-
- cfv->alloc_addr = dma_alloc_coherent(
- cfv->vdev->dev.parent->parent,
- cfv->allocsz, &cfv->alloc_dma,
- GFP_ATOMIC);
- if (cfv->alloc_addr)
- break;
-
- cfv->allocsz = (cfv->allocsz * 3) >> 2;
- }
-
- netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n",
- cfv->allocsz);
-
- /* Allocate on 128 bytes boundaries (1 << 7)*/
- cfv->genpool = gen_pool_create(7, -1);
- if (!cfv->genpool)
- goto err;
-
- err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr,
- (phys_addr_t)virt_to_phys(cfv->alloc_addr),
- cfv->allocsz, -1);
- if (err)
- goto err;
-
- /* Reserve some memory for low memory situations. If we hit the roof
- * in the memory pool, we stop TX flow and release the reserve.
- */
- cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu;
- cfv->reserved_mem = gen_pool_alloc(cfv->genpool,
- cfv->reserved_size);
- if (!cfv->reserved_mem) {
- err = -ENOMEM;
- goto err;
- }
-
- cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx);
- return 0;
-err:
- cfv_destroy_genpool(cfv);
- return err;
-}
-
-/* Enable the CAIF interface and allocate the memory-pool */
-static int cfv_netdev_open(struct net_device *netdev)
-{
- struct cfv_info *cfv = netdev_priv(netdev);
-
- if (cfv_create_genpool(cfv))
- return -ENOMEM;
-
- netif_carrier_on(netdev);
- napi_enable(&cfv->napi);
-
- /* Schedule NAPI to read any pending packets */
- napi_schedule(&cfv->napi);
- return 0;
-}
-
-/* Disable the CAIF interface and free the memory-pool */
-static int cfv_netdev_close(struct net_device *netdev)
-{
- struct cfv_info *cfv = netdev_priv(netdev);
- unsigned long flags;
- struct buf_info *buf_info;
-
- /* Disable interrupts, queues and NAPI polling */
- netif_carrier_off(netdev);
- virtqueue_disable_cb(cfv->vq_tx);
- vringh_notify_disable_kern(cfv->vr_rx);
- napi_disable(&cfv->napi);
-
- /* Release any TX buffers on both used and available rings */
- cfv_release_used_buf(cfv->vq_tx);
- spin_lock_irqsave(&cfv->tx_lock, flags);
- while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx)))
- free_buf_info(cfv, buf_info);
- spin_unlock_irqrestore(&cfv->tx_lock, flags);
-
- /* Release all dma allocated memory and destroy the pool */
- cfv_destroy_genpool(cfv);
- return 0;
-}
-
-/* Allocate a buffer in dma-memory and copy skb to it */
-static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv,
- struct sk_buff *skb,
- struct scatterlist *sg)
-{
- struct caif_payload_info *info = (void *)&skb->cb;
- struct buf_info *buf_info = NULL;
- u8 pad_len, hdr_ofs;
-
- if (!cfv->genpool)
- goto err;
-
- if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) {
- netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n",
- cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu);
- goto err;
- }
-
- buf_info = kmalloc_obj(struct buf_info, GFP_ATOMIC);
- if (unlikely(!buf_info))
- goto err;
-
- /* Make the IP header aligned in the buffer */
- hdr_ofs = cfv->tx_hr + info->hdr_len;
- pad_len = hdr_ofs & (IP_HDR_ALIGN - 1);
- buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len;
-
- /* allocate dma memory buffer */
- buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size);
- if (unlikely(!buf_info->vaddr))
- goto err;
-
- /* copy skbuf contents to send buffer */
- skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len);
- sg_init_one(sg, buf_info->vaddr + pad_len,
- skb->len + cfv->tx_hr + cfv->rx_hr);
-
- return buf_info;
-err:
- kfree(buf_info);
- return NULL;
-}
-
-/* Put the CAIF packet on the virtio ring and kick the receiver */
-static netdev_tx_t cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
-{
- struct cfv_info *cfv = netdev_priv(netdev);
- struct buf_info *buf_info;
- struct scatterlist sg;
- unsigned long flags;
- bool flow_off = false;
- int ret;
-
- /* garbage collect released buffers */
- cfv_release_used_buf(cfv->vq_tx);
- spin_lock_irqsave(&cfv->tx_lock, flags);
-
- /* Flow-off check takes into account number of cpus to make sure
- * virtqueue will not be overfilled in any possible smp conditions.
- *
- * Flow-on is triggered when sufficient buffers are freed
- */
- if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) {
- flow_off = true;
- cfv->stats.tx_full_ring++;
- }
-
- /* If we run out of memory, we release the memory reserve and retry
- * allocation.
- */
- buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
- if (unlikely(!buf_info)) {
- cfv->stats.tx_no_mem++;
- flow_off = true;
-
- if (cfv->reserved_mem && cfv->genpool) {
- gen_pool_free(cfv->genpool, cfv->reserved_mem,
- cfv->reserved_size);
- cfv->reserved_mem = 0;
- buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
- }
- }
-
- if (unlikely(flow_off)) {
- /* Turn flow on when a 1/4 of the descriptors are released */
- cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4;
- /* Enable notifications of recycled TX buffers */
- virtqueue_enable_cb(cfv->vq_tx);
- netif_tx_stop_all_queues(netdev);
- }
-
- if (unlikely(!buf_info)) {
- /* If the memory reserve does it's job, this shouldn't happen */
- netdev_warn(cfv->ndev, "Out of gen_pool memory\n");
- goto err;
- }
-
- ret = virtqueue_add_outbuf(cfv->vq_tx, &sg, 1, buf_info, GFP_ATOMIC);
- if (unlikely((ret < 0))) {
- /* If flow control works, this shouldn't happen */
- netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n",
- ret);
- goto err;
- }
-
- /* update netdev statistics */
- cfv->ndev->stats.tx_packets++;
- cfv->ndev->stats.tx_bytes += skb->len;
- spin_unlock_irqrestore(&cfv->tx_lock, flags);
-
- /* tell the remote processor it has a pending message to read */
- virtqueue_kick(cfv->vq_tx);
-
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-err:
- spin_unlock_irqrestore(&cfv->tx_lock, flags);
- cfv->ndev->stats.tx_dropped++;
- free_buf_info(cfv, buf_info);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-static void cfv_tx_release_tasklet(struct tasklet_struct *t)
-{
- struct cfv_info *cfv = from_tasklet(cfv, t, tx_release_tasklet);
- cfv_release_used_buf(cfv->vq_tx);
-}
-
-static const struct net_device_ops cfv_netdev_ops = {
- .ndo_open = cfv_netdev_open,
- .ndo_stop = cfv_netdev_close,
- .ndo_start_xmit = cfv_netdev_tx,
-};
-
-static void cfv_netdev_setup(struct net_device *netdev)
-{
- netdev->netdev_ops = &cfv_netdev_ops;
- netdev->type = ARPHRD_CAIF;
- netdev->tx_queue_len = 100;
- netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
- netdev->mtu = CFV_DEF_MTU_SIZE;
- netdev->needs_free_netdev = true;
-}
-
-/* Create debugfs counters for the device */
-static inline void debugfs_init(struct cfv_info *cfv)
-{
- cfv->debugfs = debugfs_create_dir(netdev_name(cfv->ndev), NULL);
-
- debugfs_create_u32("rx-napi-complete", 0400, cfv->debugfs,
- &cfv->stats.rx_napi_complete);
- debugfs_create_u32("rx-napi-resched", 0400, cfv->debugfs,
- &cfv->stats.rx_napi_resched);
- debugfs_create_u32("rx-nomem", 0400, cfv->debugfs,
- &cfv->stats.rx_nomem);
- debugfs_create_u32("rx-kicks", 0400, cfv->debugfs,
- &cfv->stats.rx_kicks);
- debugfs_create_u32("tx-full-ring", 0400, cfv->debugfs,
- &cfv->stats.tx_full_ring);
- debugfs_create_u32("tx-no-mem", 0400, cfv->debugfs,
- &cfv->stats.tx_no_mem);
- debugfs_create_u32("tx-kicks", 0400, cfv->debugfs,
- &cfv->stats.tx_kicks);
- debugfs_create_u32("tx-flow-on", 0400, cfv->debugfs,
- &cfv->stats.tx_flow_on);
-}
-
-/* Setup CAIF for the a virtio device */
-static int cfv_probe(struct virtio_device *vdev)
-{
- vrh_callback_t *vrh_cbs = cfv_recv;
- const char *cfv_netdev_name = "cfvrt";
- struct net_device *netdev;
- struct cfv_info *cfv;
- int err;
-
- netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
- NET_NAME_UNKNOWN, cfv_netdev_setup);
- if (!netdev)
- return -ENOMEM;
-
- cfv = netdev_priv(netdev);
- cfv->vdev = vdev;
- cfv->ndev = netdev;
-
- spin_lock_init(&cfv->tx_lock);
-
- /* Get the RX virtio ring. This is a "host side vring". */
- err = -ENODEV;
- if (!vdev->vringh_config || !vdev->vringh_config->find_vrhs)
- goto err;
-
- err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs);
- if (err)
- goto err;
-
- /* Get the TX virtio ring. This is a "guest side vring". */
- cfv->vq_tx = virtio_find_single_vq(vdev, cfv_release_cb, "output");
- if (IS_ERR(cfv->vq_tx)) {
- err = PTR_ERR(cfv->vq_tx);
- goto err;
- }
-
- /* Get the CAIF configuration from virtio config space, if available */
- if (vdev->config->get) {
- virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
- &cfv->tx_hr);
- virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
- &cfv->rx_hr);
- virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
- &cfv->tx_tr);
- virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
- &cfv->rx_tr);
- virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
- &cfv->mtu);
- virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
- &cfv->mru);
- } else {
- cfv->tx_hr = CFV_DEF_HEADROOM;
- cfv->rx_hr = CFV_DEF_HEADROOM;
- cfv->tx_tr = CFV_DEF_TAILROOM;
- cfv->rx_tr = CFV_DEF_TAILROOM;
- cfv->mtu = CFV_DEF_MTU_SIZE;
- cfv->mru = CFV_DEF_MTU_SIZE;
- }
-
- netdev->needed_headroom = cfv->tx_hr;
- netdev->needed_tailroom = cfv->tx_tr;
-
- /* Disable buffer release interrupts unless we have stopped TX queues */
- virtqueue_disable_cb(cfv->vq_tx);
-
- netdev->mtu = cfv->mtu - cfv->tx_tr;
- vdev->priv = cfv;
-
- /* Initialize NAPI poll context data */
- vringh_kiov_init(&cfv->ctx.riov, NULL, 0);
- cfv->ctx.head = USHRT_MAX;
- netif_napi_add_weight(netdev, &cfv->napi, cfv_rx_poll,
- CFV_DEFAULT_QUOTA);
-
- tasklet_setup(&cfv->tx_release_tasklet, cfv_tx_release_tasklet);
-
- /* Carrier is off until netdevice is opened */
- netif_carrier_off(netdev);
-
- /* serialize netdev register + virtio_device_ready() with ndo_open() */
- rtnl_lock();
-
- /* register Netdev */
- err = register_netdevice(netdev);
- if (err) {
- rtnl_unlock();
- dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
- goto err;
- }
-
- virtio_device_ready(vdev);
-
- rtnl_unlock();
-
- debugfs_init(cfv);
-
- return 0;
-err:
- netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err);
-
- if (cfv->vr_rx)
- vdev->vringh_config->del_vrhs(cfv->vdev);
- if (cfv->vq_tx)
- vdev->config->del_vqs(cfv->vdev);
- free_netdev(netdev);
- return err;
-}
-
-static void cfv_remove(struct virtio_device *vdev)
-{
- struct cfv_info *cfv = vdev->priv;
-
- rtnl_lock();
- dev_close(cfv->ndev);
- rtnl_unlock();
-
- tasklet_kill(&cfv->tx_release_tasklet);
- debugfs_remove_recursive(cfv->debugfs);
-
- vringh_kiov_cleanup(&cfv->ctx.riov);
- virtio_reset_device(vdev);
- vdev->vringh_config->del_vrhs(cfv->vdev);
- cfv->vr_rx = NULL;
- vdev->config->del_vqs(cfv->vdev);
- unregister_netdev(cfv->ndev);
-}
-
-static struct virtio_device_id id_table[] = {
- { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID },
- { 0 },
-};
-
-static unsigned int features[] = {
-};
-
-static struct virtio_driver caif_virtio_driver = {
- .feature_table = features,
- .feature_table_size = ARRAY_SIZE(features),
- .driver.name = KBUILD_MODNAME,
- .id_table = id_table,
- .probe = cfv_probe,
- .remove = cfv_remove,
-};
-
-module_virtio_driver(caif_virtio_driver);
-MODULE_DEVICE_TABLE(virtio, id_table);
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
deleted file mode 100644
index 922de3d611c0..000000000000
--- a/net/caif/caif_dev.c
+++ /dev/null
@@ -1,586 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * CAIF Interface registration.
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- *
- * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont
- * and Sakari Ailus <sakari.ailus@nokia.com>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/if_arp.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/spinlock.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_layer.h>
-#include <net/caif/caif_dev.h>
-#include <net/caif/cfpkt.h>
-#include <net/caif/cfcnfg.h>
-#include <net/caif/cfserl.h>
-
-MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol support");
-MODULE_LICENSE("GPL");
-
-/* Used for local tracking of the CAIF net devices */
-struct caif_device_entry {
- struct cflayer layer;
- struct list_head list;
- struct net_device *netdev;
- int __percpu *pcpu_refcnt;
- spinlock_t flow_lock;
- struct sk_buff *xoff_skb;
- void (*xoff_skb_dtor)(struct sk_buff *skb);
- bool xoff;
-};
-
-struct caif_device_entry_list {
- struct list_head list;
- /* Protects simulanous deletes in list */
- struct mutex lock;
-};
-
-struct caif_net {
- struct cfcnfg *cfg;
- struct caif_device_entry_list caifdevs;
-};
-
-static unsigned int caif_net_id;
-static int q_high = 50; /* Percent */
-
-struct cfcnfg *get_cfcnfg(struct net *net)
-{
- struct caif_net *caifn;
- caifn = net_generic(net, caif_net_id);
- return caifn->cfg;
-}
-EXPORT_SYMBOL(get_cfcnfg);
-
-static struct caif_device_entry_list *caif_device_list(struct net *net)
-{
- struct caif_net *caifn;
- caifn = net_generic(net, caif_net_id);
- return &caifn->caifdevs;
-}
-
-static void caifd_put(struct caif_device_entry *e)
-{
- this_cpu_dec(*e->pcpu_refcnt);
-}
-
-static void caifd_hold(struct caif_device_entry *e)
-{
- this_cpu_inc(*e->pcpu_refcnt);
-}
-
-static int caifd_refcnt_read(struct caif_device_entry *e)
-{
- int i, refcnt = 0;
- for_each_possible_cpu(i)
- refcnt += *per_cpu_ptr(e->pcpu_refcnt, i);
- return refcnt;
-}
-
-/* Allocate new CAIF device. */
-static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
-{
- struct caif_device_entry *caifd;
-
- caifd = kzalloc_obj(*caifd);
- if (!caifd)
- return NULL;
- caifd->pcpu_refcnt = alloc_percpu(int);
- if (!caifd->pcpu_refcnt) {
- kfree(caifd);
- return NULL;
- }
- caifd->netdev = dev;
- dev_hold(dev);
- 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;
-
- list_for_each_entry_rcu(caifd, &caifdevs->list, list,
- lockdep_rtnl_is_held()) {
- if (caifd->netdev == dev)
- return caifd;
- }
- return NULL;
-}
-
-static void caif_flow_cb(struct sk_buff *skb)
-{
- struct caif_device_entry *caifd;
- void (*dtor)(struct sk_buff *skb) = NULL;
- bool send_xoff;
-
- WARN_ON(skb->dev == NULL);
-
- rcu_read_lock();
- caifd = caif_get(skb->dev);
-
- WARN_ON(caifd == NULL);
- if (!caifd) {
- rcu_read_unlock();
- return;
- }
-
- caifd_hold(caifd);
- rcu_read_unlock();
-
- spin_lock_bh(&caifd->flow_lock);
- send_xoff = caifd->xoff;
- caifd->xoff = false;
- dtor = caifd->xoff_skb_dtor;
-
- if (WARN_ON(caifd->xoff_skb != skb))
- skb = NULL;
-
- caifd->xoff_skb = NULL;
- caifd->xoff_skb_dtor = NULL;
-
- spin_unlock_bh(&caifd->flow_lock);
-
- if (dtor && skb)
- dtor(skb);
-
- if (send_xoff)
- caifd->layer.up->
- ctrlcmd(caifd->layer.up,
- _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND,
- caifd->layer.id);
- caifd_put(caifd);
-}
-
-static int transmit(struct cflayer *layer, struct cfpkt *pkt)
-{
- int err, high = 0, qlen = 0;
- struct caif_device_entry *caifd =
- container_of(layer, struct caif_device_entry, layer);
- struct sk_buff *skb;
- struct netdev_queue *txq;
-
- rcu_read_lock_bh();
-
- skb = cfpkt_tonative(pkt);
- skb->dev = caifd->netdev;
- skb_reset_network_header(skb);
- skb->protocol = htons(ETH_P_CAIF);
-
- /* Check if we need to handle xoff */
- if (likely(caifd->netdev->priv_flags & IFF_NO_QUEUE))
- goto noxoff;
-
- if (unlikely(caifd->xoff))
- goto noxoff;
-
- if (likely(!netif_queue_stopped(caifd->netdev))) {
- struct Qdisc *sch;
-
- /* If we run with a TX queue, check if the queue is too long*/
- txq = netdev_get_tx_queue(skb->dev, 0);
- sch = rcu_dereference_bh(txq->qdisc);
- if (likely(qdisc_is_empty(sch)))
- goto noxoff;
-
- /* can check for explicit qdisc len value only !NOLOCK,
- * always set flow off otherwise
- */
- high = (caifd->netdev->tx_queue_len * q_high) / 100;
- if (!(sch->flags & TCQ_F_NOLOCK) && likely(sch->q.qlen < high))
- goto noxoff;
- }
-
- /* Hold lock while accessing xoff */
- spin_lock_bh(&caifd->flow_lock);
- if (caifd->xoff) {
- spin_unlock_bh(&caifd->flow_lock);
- goto noxoff;
- }
-
- /*
- * Handle flow off, we do this by temporary hi-jacking this
- * skb's destructor function, and replace it with our own
- * flow-on callback. The callback will set flow-on and call
- * the original destructor.
- */
-
- pr_debug("queue has stopped(%d) or is full (%d > %d)\n",
- netif_queue_stopped(caifd->netdev),
- qlen, high);
- caifd->xoff = true;
- caifd->xoff_skb = skb;
- caifd->xoff_skb_dtor = skb->destructor;
- skb->destructor = caif_flow_cb;
- spin_unlock_bh(&caifd->flow_lock);
-
- caifd->layer.up->ctrlcmd(caifd->layer.up,
- _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
- caifd->layer.id);
-noxoff:
- rcu_read_unlock_bh();
-
- err = dev_queue_xmit(skb);
- if (err > 0)
- err = -EIO;
-
- return err;
-}
-
-/*
- * Stuff received packets into the CAIF stack.
- * 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 cfpkt *pkt;
- struct caif_device_entry *caifd;
- int err;
-
- pkt = cfpkt_fromnative(CAIF_DIR_IN, skb);
-
- rcu_read_lock();
- caifd = caif_get(dev);
-
- if (!caifd || !caifd->layer.up || !caifd->layer.up->receive ||
- !netif_oper_up(caifd->netdev)) {
- rcu_read_unlock();
- kfree_skb(skb);
- return NET_RX_DROP;
- }
-
- /* Hold reference to netdevice while using CAIF stack */
- caifd_hold(caifd);
- rcu_read_unlock();
-
- err = caifd->layer.up->receive(caifd->layer.up, pkt);
-
- /* For -EILSEQ the packet is not freed so free it now */
- if (err == -EILSEQ)
- cfpkt_destroy(pkt);
-
- /* Release reference to stack upwards */
- caifd_put(caifd);
-
- if (err != 0)
- err = NET_RX_DROP;
- return err;
-}
-
-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;
-
- rcu_read_lock();
-
- caifd = caif_get(dev);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
- rcu_read_unlock();
- return;
- }
-
- caifd_hold(caifd);
- rcu_read_unlock();
-
- caifd->layer.up->ctrlcmd(caifd->layer.up,
- on ?
- _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND :
- _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
- caifd->layer.id);
- caifd_put(caifd);
-}
-
-int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
- struct cflayer *link_support, int head_room,
- struct cflayer **layer,
- int (**rcv_func)(struct sk_buff *, struct net_device *,
- struct packet_type *,
- struct net_device *))
-{
- struct caif_device_entry *caifd;
- enum cfcnfg_phy_preference pref;
- struct cfcnfg *cfg = get_cfcnfg(dev_net(dev));
- struct caif_device_entry_list *caifdevs;
- int res;
-
- caifdevs = caif_device_list(dev_net(dev));
- caifd = caif_device_alloc(dev);
- if (!caifd)
- return -ENOMEM;
- *layer = &caifd->layer;
- spin_lock_init(&caifd->flow_lock);
-
- switch (caifdev->link_select) {
- case CAIF_LINK_HIGH_BANDW:
- pref = CFPHYPREF_HIGH_BW;
- break;
- case CAIF_LINK_LOW_LATENCY:
- pref = CFPHYPREF_LOW_LAT;
- break;
- default:
- pref = CFPHYPREF_HIGH_BW;
- break;
- }
- mutex_lock(&caifdevs->lock);
- list_add_rcu(&caifd->list, &caifdevs->list);
-
- strscpy(caifd->layer.name, dev->name,
- sizeof(caifd->layer.name));
- caifd->layer.transmit = transmit;
- res = cfcnfg_add_phy_layer(cfg,
- dev,
- &caifd->layer,
- pref,
- link_support,
- caifdev->use_fcs,
- head_room);
- mutex_unlock(&caifdevs->lock);
- if (rcv_func)
- *rcv_func = receive;
- return res;
-}
-EXPORT_SYMBOL(caif_enroll_dev);
-
-/* notify Caif of device events */
-static int caif_device_notify(struct notifier_block *me, unsigned long what,
- void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct caif_device_entry *caifd = NULL;
- struct caif_dev_common *caifdev;
- struct cfcnfg *cfg;
- struct cflayer *layer, *link_support;
- int head_room = 0;
- struct caif_device_entry_list *caifdevs;
- int res;
-
- cfg = get_cfcnfg(dev_net(dev));
- caifdevs = caif_device_list(dev_net(dev));
-
- caifd = caif_get(dev);
- if (caifd == NULL && dev->type != ARPHRD_CAIF)
- return 0;
-
- switch (what) {
- case NETDEV_REGISTER:
- if (caifd != NULL)
- break;
-
- caifdev = netdev_priv(dev);
-
- link_support = NULL;
- if (caifdev->use_frag) {
- head_room = 1;
- link_support = cfserl_create(dev->ifindex,
- caifdev->use_stx);
- if (!link_support) {
- pr_warn("Out of memory\n");
- break;
- }
- }
- res = caif_enroll_dev(dev, caifdev, link_support, head_room,
- &layer, NULL);
- if (res)
- cfserl_release(link_support);
- caifdev->flowctrl = dev_flowctrl;
- break;
-
- case NETDEV_UP:
- rcu_read_lock();
-
- caifd = caif_get(dev);
- if (caifd == NULL) {
- rcu_read_unlock();
- break;
- }
-
- caifd->xoff = false;
- cfcnfg_set_phy_state(cfg, &caifd->layer, true);
- rcu_read_unlock();
-
- break;
-
- case NETDEV_DOWN:
- rcu_read_lock();
-
- caifd = caif_get(dev);
- if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
- rcu_read_unlock();
- return -EINVAL;
- }
-
- cfcnfg_set_phy_state(cfg, &caifd->layer, false);
- caifd_hold(caifd);
- rcu_read_unlock();
-
- caifd->layer.up->ctrlcmd(caifd->layer.up,
- _CAIF_CTRLCMD_PHYIF_DOWN_IND,
- caifd->layer.id);
-
- spin_lock_bh(&caifd->flow_lock);
-
- /*
- * Replace our xoff-destructor with original destructor.
- * We trust that skb->destructor *always* is called before
- * the skb reference is invalid. The hijacked SKB destructor
- * takes the flow_lock so manipulating the skb->destructor here
- * should be safe.
- */
- if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL)
- caifd->xoff_skb->destructor = caifd->xoff_skb_dtor;
-
- caifd->xoff = false;
- caifd->xoff_skb_dtor = NULL;
- caifd->xoff_skb = NULL;
-
- spin_unlock_bh(&caifd->flow_lock);
- caifd_put(caifd);
- break;
-
- case NETDEV_UNREGISTER:
- mutex_lock(&caifdevs->lock);
-
- caifd = caif_get(dev);
- if (caifd == NULL) {
- mutex_unlock(&caifdevs->lock);
- break;
- }
- list_del_rcu(&caifd->list);
-
- /*
- * NETDEV_UNREGISTER is called repeatedly until all reference
- * counts for the net-device are released. If references to
- * caifd is taken, simply ignore NETDEV_UNREGISTER and wait for
- * the next call to NETDEV_UNREGISTER.
- *
- * If any packets are in flight down the CAIF Stack,
- * cfcnfg_del_phy_layer will return nonzero.
- * If no packets are in flight, the CAIF Stack associated
- * with the net-device un-registering is freed.
- */
-
- if (caifd_refcnt_read(caifd) != 0 ||
- cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0) {
-
- pr_info("Wait for device inuse\n");
- /* Enrole device if CAIF Stack is still in use */
- list_add_rcu(&caifd->list, &caifdevs->list);
- mutex_unlock(&caifdevs->lock);
- break;
- }
-
- synchronize_rcu();
- dev_put(caifd->netdev);
- free_percpu(caifd->pcpu_refcnt);
- kfree(caifd);
-
- mutex_unlock(&caifdevs->lock);
- break;
- }
- return 0;
-}
-
-static struct notifier_block caif_device_notifier = {
- .notifier_call = caif_device_notify,
- .priority = 0,
-};
-
-/* 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);
- mutex_init(&caifn->caifdevs.lock);
-
- caifn->cfg = cfcnfg_create();
- if (!caifn->cfg)
- return -ENOMEM;
-
- return 0;
-}
-
-static void caif_exit_net(struct net *net)
-{
- struct caif_device_entry *caifd, *tmp;
- struct caif_device_entry_list *caifdevs =
- caif_device_list(net);
- struct cfcnfg *cfg = get_cfcnfg(net);
-
- rtnl_lock();
- mutex_lock(&caifdevs->lock);
-
- list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
- int i = 0;
- list_del_rcu(&caifd->list);
- cfcnfg_set_phy_state(cfg, &caifd->layer, false);
-
- while (i < 10 &&
- (caifd_refcnt_read(caifd) != 0 ||
- cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0)) {
-
- pr_info("Wait for device inuse\n");
- msleep(250);
- i++;
- }
- synchronize_rcu();
- dev_put(caifd->netdev);
- free_percpu(caifd->pcpu_refcnt);
- kfree(caifd);
- }
- cfcnfg_remove(cfg);
-
- mutex_unlock(&caifdevs->lock);
- 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 */
-static int __init caif_device_init(void)
-{
- int result;
-
- result = register_pernet_subsys(&caif_net_ops);
-
- if (result)
- return result;
-
- register_netdevice_notifier(&caif_device_notifier);
- dev_add_pack(&caif_packet_type);
-
- return result;
-}
-
-static void __exit caif_device_exit(void)
-{
- unregister_netdevice_notifier(&caif_device_notifier);
- dev_remove_pack(&caif_packet_type);
- unregister_pernet_subsys(&caif_net_ops);
-}
-
-module_init(caif_device_init);
-module_exit(caif_device_exit);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
deleted file mode 100644
index af218742af5a..000000000000
--- a/net/caif/caif_socket.c
+++ /dev/null
@@ -1,1114 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/filter.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched/signal.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 <linux/debugfs.h>
-#include <linux/caif/caif_socket.h>
-#include <linux/pkt_sched.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <net/caif/caif_layer.h>
-#include <net/caif/caif_dev.h>
-#include <net/caif/cfpkt.h>
-
-MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol socket support (AF_CAIF)");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(AF_CAIF);
-
-/*
- * CAIF state is re-using the TCP socket states.
- * caif_states stored in sk_state reflect the state as reported by
- * the CAIF stack, while sk_socket->state is the state of the socket.
- */
-enum caif_states {
- CAIF_CONNECTED = TCP_ESTABLISHED,
- CAIF_CONNECTING = TCP_SYN_SENT,
- CAIF_DISCONNECTED = TCP_CLOSE
-};
-
-#define TX_FLOW_ON_BIT 1
-#define RX_FLOW_ON_BIT 2
-
-struct caifsock {
- struct sock sk; /* must be first member */
- struct cflayer layer;
- unsigned long flow_state;
- struct caif_connect_request conn_req;
- struct mutex readlock;
- struct dentry *debugfs_socket_dir;
- int headroom, tailroom, maxframe;
-};
-
-static int rx_flow_is_on(struct caifsock *cf_sk)
-{
- return test_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static int tx_flow_is_on(struct caifsock *cf_sk)
-{
- return test_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static void set_rx_flow_off(struct caifsock *cf_sk)
-{
- clear_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static void set_rx_flow_on(struct caifsock *cf_sk)
-{
- set_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static void set_tx_flow_off(struct caifsock *cf_sk)
-{
- clear_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static void set_tx_flow_on(struct caifsock *cf_sk)
-{
- set_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
-}
-
-static void caif_read_lock(struct sock *sk)
-{
- struct caifsock *cf_sk;
- cf_sk = container_of(sk, struct caifsock, sk);
- mutex_lock(&cf_sk->readlock);
-}
-
-static void caif_read_unlock(struct sock *sk)
-{
- struct caifsock *cf_sk;
- cf_sk = container_of(sk, struct caifsock, sk);
- mutex_unlock(&cf_sk->readlock);
-}
-
-static int sk_rcvbuf_lowwater(struct caifsock *cf_sk)
-{
- /* A quarter of full buffer is used a low water mark */
- return cf_sk->sk.sk_rcvbuf / 4;
-}
-
-static void caif_flow_ctrl(struct sock *sk, int mode)
-{
- struct caifsock *cf_sk;
- cf_sk = container_of(sk, struct caifsock, sk);
- if (cf_sk->layer.dn && cf_sk->layer.dn->modemcmd)
- cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode);
-}
-
-/*
- * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are
- * not dropped, but CAIF is sending flow off instead.
- */
-static void caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
-{
- int err;
- unsigned long flags;
- struct sk_buff_head *list = &sk->sk_receive_queue;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- bool queued = false;
-
- if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
- (unsigned int)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) {
- net_dbg_ratelimited("sending flow OFF (queue len = %d %d)\n",
- atomic_read(&cf_sk->sk.sk_rmem_alloc),
- sk_rcvbuf_lowwater(cf_sk));
- set_rx_flow_off(cf_sk);
- caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
- }
-
- err = sk_filter(sk, skb);
- if (err)
- goto out;
-
- if (!sk_rmem_schedule(sk, skb, skb->truesize) && rx_flow_is_on(cf_sk)) {
- set_rx_flow_off(cf_sk);
- net_dbg_ratelimited("sending flow OFF due to rmem_schedule\n");
- caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
- }
- skb->dev = NULL;
- skb_set_owner_r(skb, sk);
- spin_lock_irqsave(&list->lock, flags);
- queued = !sock_flag(sk, SOCK_DEAD);
- if (queued)
- __skb_queue_tail(list, skb);
- spin_unlock_irqrestore(&list->lock, flags);
-out:
- if (queued)
- sk->sk_data_ready(sk);
- else
- kfree_skb(skb);
-}
-
-/* Packet Receive Callback function called from CAIF Stack */
-static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
-{
- struct caifsock *cf_sk;
- struct sk_buff *skb;
-
- cf_sk = container_of(layr, struct caifsock, layer);
- skb = cfpkt_tonative(pkt);
-
- if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) {
- kfree_skb(skb);
- return 0;
- }
- caif_queue_rcv_skb(&cf_sk->sk, skb);
- return 0;
-}
-
-static void cfsk_hold(struct cflayer *layr)
-{
- struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
- sock_hold(&cf_sk->sk);
-}
-
-static void cfsk_put(struct cflayer *layr)
-{
- struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
- sock_put(&cf_sk->sk);
-}
-
-/* Packet Control Callback function called from CAIF */
-static void caif_ctrl_cb(struct cflayer *layr,
- enum caif_ctrlcmd flow,
- int phyid)
-{
- struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
- switch (flow) {
- case CAIF_CTRLCMD_FLOW_ON_IND:
- /* OK from modem to start sending again */
- set_tx_flow_on(cf_sk);
- cf_sk->sk.sk_state_change(&cf_sk->sk);
- break;
-
- case CAIF_CTRLCMD_FLOW_OFF_IND:
- /* Modem asks us to shut up */
- set_tx_flow_off(cf_sk);
- cf_sk->sk.sk_state_change(&cf_sk->sk);
- break;
-
- case CAIF_CTRLCMD_INIT_RSP:
- /* We're now connected */
- caif_client_register_refcnt(&cf_sk->layer,
- cfsk_hold, cfsk_put);
- cf_sk->sk.sk_state = CAIF_CONNECTED;
- set_tx_flow_on(cf_sk);
- cf_sk->sk.sk_shutdown = 0;
- cf_sk->sk.sk_state_change(&cf_sk->sk);
- break;
-
- case CAIF_CTRLCMD_DEINIT_RSP:
- /* We're now disconnected */
- cf_sk->sk.sk_state = CAIF_DISCONNECTED;
- cf_sk->sk.sk_state_change(&cf_sk->sk);
- break;
-
- case CAIF_CTRLCMD_INIT_FAIL_RSP:
- /* Connect request failed */
- cf_sk->sk.sk_err = ECONNREFUSED;
- cf_sk->sk.sk_state = CAIF_DISCONNECTED;
- cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
- /*
- * Socket "standards" seems to require POLLOUT to
- * be set at connect failure.
- */
- set_tx_flow_on(cf_sk);
- cf_sk->sk.sk_state_change(&cf_sk->sk);
- break;
-
- case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
- /* Modem has closed this connection, or device is down. */
- cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
- cf_sk->sk.sk_err = ECONNRESET;
- set_rx_flow_on(cf_sk);
- sk_error_report(&cf_sk->sk);
- break;
-
- default:
- pr_debug("Unexpected flow command %d\n", flow);
- }
-}
-
-static void caif_check_flow_release(struct sock *sk)
-{
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
-
- if (rx_flow_is_on(cf_sk))
- return;
-
- if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) {
- set_rx_flow_on(cf_sk);
- caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ);
- }
-}
-
-/*
- * Copied from unix_dgram_recvmsg, but removed credit checks,
- * changed locking, address handling and added MSG_TRUNC.
- */
-static int caif_seqpkt_recvmsg(struct socket *sock, struct msghdr *m,
- size_t len, int flags)
-
-{
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int ret;
- int copylen;
-
- ret = -EOPNOTSUPP;
- if (flags & MSG_OOB)
- goto read_error;
-
- skb = skb_recv_datagram(sk, flags, &ret);
- if (!skb)
- goto read_error;
- copylen = skb->len;
- if (len < copylen) {
- m->msg_flags |= MSG_TRUNC;
- copylen = len;
- }
-
- ret = skb_copy_datagram_msg(skb, 0, m, copylen);
- if (ret)
- goto out_free;
-
- ret = (flags & MSG_TRUNC) ? skb->len : copylen;
-out_free:
- skb_free_datagram(sk, skb);
- caif_check_flow_release(sk);
- return ret;
-
-read_error:
- return ret;
-}
-
-
-/* Copied from unix_stream_wait_data, identical except for lock call. */
-static long caif_stream_data_wait(struct sock *sk, long timeo)
-{
- DEFINE_WAIT(wait);
- lock_sock(sk);
-
- for (;;) {
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- sk->sk_err ||
- sk->sk_state != CAIF_CONNECTED ||
- sock_flag(sk, SOCK_DEAD) ||
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
- signal_pending(current) ||
- !timeo)
- break;
-
- sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
-
- if (sock_flag(sk, SOCK_DEAD))
- break;
-
- sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
- }
-
- finish_wait(sk_sleep(sk), &wait);
- release_sock(sk);
- return timeo;
-}
-
-
-/*
- * Copied from unix_stream_recvmsg, but removed credit checks,
- * changed locking calls, changed address handling.
- */
-static int caif_stream_recvmsg(struct socket *sock, struct msghdr *msg,
- size_t size, int flags)
-{
- struct sock *sk = sock->sk;
- int copied = 0;
- int target;
- int err = 0;
- long timeo;
-
- err = -EOPNOTSUPP;
- if (flags&MSG_OOB)
- goto out;
-
- /*
- * Lock the socket to prevent queue disordering
- * while sleeps in memcpy_tomsg
- */
- err = -EAGAIN;
- if (sk->sk_state == CAIF_CONNECTING)
- goto out;
-
- caif_read_lock(sk);
- target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
-
- do {
- int chunk;
- struct sk_buff *skb;
-
- lock_sock(sk);
- if (sock_flag(sk, SOCK_DEAD)) {
- err = -ECONNRESET;
- goto unlock;
- }
- skb = skb_dequeue(&sk->sk_receive_queue);
- caif_check_flow_release(sk);
-
- if (skb == NULL) {
- if (copied >= target)
- goto unlock;
- /*
- * POSIX 1003.1g mandates this order.
- */
- err = sock_error(sk);
- if (err)
- goto unlock;
- err = -ECONNRESET;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- goto unlock;
-
- err = -EPIPE;
- if (sk->sk_state != CAIF_CONNECTED)
- goto unlock;
- if (sock_flag(sk, SOCK_DEAD))
- goto unlock;
-
- release_sock(sk);
-
- err = -EAGAIN;
- if (!timeo)
- break;
-
- caif_read_unlock(sk);
-
- timeo = caif_stream_data_wait(sk, timeo);
-
- if (signal_pending(current)) {
- err = sock_intr_errno(timeo);
- goto out;
- }
- caif_read_lock(sk);
- continue;
-unlock:
- release_sock(sk);
- break;
- }
- release_sock(sk);
- chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_to_msg(msg, skb->data, chunk)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (copied == 0)
- copied = -EFAULT;
- break;
- }
- copied += chunk;
- size -= chunk;
-
- /* Mark read part of skb as used */
- if (!(flags & MSG_PEEK)) {
- skb_pull(skb, chunk);
-
- /* put the skb back if we didn't use it up. */
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- kfree_skb(skb);
-
- } else {
- /*
- * It is questionable, see note in unix_dgram_recvmsg.
- */
- /* put message back and return */
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- } while (size);
- caif_read_unlock(sk);
-
-out:
- return copied ? : err;
-}
-
-/*
- * Copied from sock.c:sock_wait_for_wmem, but change to wait for
- * CAIF flow-on and sock_writable.
- */
-static long caif_wait_for_flow_on(struct caifsock *cf_sk,
- int wait_writeable, long timeo, int *err)
-{
- struct sock *sk = &cf_sk->sk;
- DEFINE_WAIT(wait);
- for (;;) {
- *err = 0;
- if (tx_flow_is_on(cf_sk) &&
- (!wait_writeable || sock_writeable(&cf_sk->sk)))
- break;
- *err = -ETIMEDOUT;
- if (!timeo)
- break;
- *err = -ERESTARTSYS;
- if (signal_pending(current))
- break;
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
- *err = -ECONNRESET;
- if (sk->sk_shutdown & SHUTDOWN_MASK)
- break;
- *err = -sk->sk_err;
- if (sk->sk_err)
- break;
- *err = -EPIPE;
- if (cf_sk->sk.sk_state != CAIF_CONNECTED)
- break;
- timeo = schedule_timeout(timeo);
- }
- finish_wait(sk_sleep(sk), &wait);
- return timeo;
-}
-
-/*
- * Transmit a SKB. The device may temporarily request re-transmission
- * by returning EAGAIN.
- */
-static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
- int noblock, long timeo)
-{
- struct cfpkt *pkt;
-
- pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
- memset(skb->cb, 0, sizeof(struct caif_payload_info));
- cfpkt_set_prio(pkt, cf_sk->sk.sk_priority);
-
- if (cf_sk->layer.dn == NULL) {
- kfree_skb(skb);
- return -EINVAL;
- }
-
- return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
-}
-
-/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */
-static int caif_seqpkt_sendmsg(struct socket *sock, struct msghdr *msg,
- size_t len)
-{
- struct sock *sk = sock->sk;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- int buffer_size;
- int ret = 0;
- struct sk_buff *skb = NULL;
- int noblock;
- long timeo;
- caif_assert(cf_sk);
- ret = sock_error(sk);
- if (ret)
- goto err;
-
- ret = -EOPNOTSUPP;
- if (msg->msg_flags&MSG_OOB)
- goto err;
-
- ret = -EOPNOTSUPP;
- if (msg->msg_namelen)
- goto err;
-
- noblock = msg->msg_flags & MSG_DONTWAIT;
-
- timeo = sock_sndtimeo(sk, noblock);
- timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk),
- 1, timeo, &ret);
-
- if (ret)
- goto err;
- ret = -EPIPE;
- if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
- sock_flag(sk, SOCK_DEAD) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
- goto err;
-
- /* Error if trying to write more than maximum frame size. */
- ret = -EMSGSIZE;
- if (len > cf_sk->maxframe && cf_sk->sk.sk_protocol != CAIFPROTO_RFM)
- goto err;
-
- buffer_size = len + cf_sk->headroom + cf_sk->tailroom;
-
- ret = -ENOMEM;
- skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret);
-
- if (!skb || skb_tailroom(skb) < buffer_size)
- goto err;
-
- skb_reserve(skb, cf_sk->headroom);
-
- ret = memcpy_from_msg(skb_put(skb, len), msg, len);
-
- if (ret)
- goto err;
- ret = transmit_skb(skb, cf_sk, noblock, timeo);
- if (ret < 0)
- /* skb is already freed */
- return ret;
-
- return len;
-err:
- kfree_skb(skb);
- return ret;
-}
-
-/*
- * Copied from unix_stream_sendmsg and adapted to CAIF:
- * Changed removed permission handling and added waiting for flow on
- * and other minor adaptations.
- */
-static int caif_stream_sendmsg(struct socket *sock, struct msghdr *msg,
- size_t len)
-{
- struct sock *sk = sock->sk;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- int err, size;
- struct sk_buff *skb;
- int sent = 0;
- long timeo;
-
- err = -EOPNOTSUPP;
- if (unlikely(msg->msg_flags&MSG_OOB))
- goto out_err;
-
- if (unlikely(msg->msg_namelen))
- goto out_err;
-
- timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
- timeo = caif_wait_for_flow_on(cf_sk, 1, timeo, &err);
-
- if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN))
- goto pipe_err;
-
- while (sent < len) {
-
- size = len-sent;
-
- if (size > cf_sk->maxframe)
- size = cf_sk->maxframe;
-
- /* If size is more than half of sndbuf, chop up message */
- if (size > ((sk->sk_sndbuf >> 1) - 64))
- size = (sk->sk_sndbuf >> 1) - 64;
-
- if (size > SKB_MAX_ALLOC)
- size = SKB_MAX_ALLOC;
-
- skb = sock_alloc_send_skb(sk,
- size + cf_sk->headroom +
- cf_sk->tailroom,
- msg->msg_flags&MSG_DONTWAIT,
- &err);
- if (skb == NULL)
- goto out_err;
-
- skb_reserve(skb, cf_sk->headroom);
- /*
- * If you pass two values to the sock_alloc_send_skb
- * it tries to grab the large buffer with GFP_NOFS
- * (which can fail easily), and if it fails grab the
- * fallback size buffer which is under a page and will
- * succeed. [Alan]
- */
- size = min_t(int, size, skb_tailroom(skb));
-
- err = memcpy_from_msg(skb_put(skb, size), msg, size);
- if (err) {
- kfree_skb(skb);
- goto out_err;
- }
- err = transmit_skb(skb, cf_sk,
- msg->msg_flags&MSG_DONTWAIT, timeo);
- if (err < 0)
- /* skb is already freed */
- goto pipe_err;
-
- sent += size;
- }
-
- return sent;
-
-pipe_err:
- if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
- send_sig(SIGPIPE, current, 0);
- err = -EPIPE;
-out_err:
- return sent ? : err;
-}
-
-static int setsockopt(struct socket *sock, int lvl, int opt, sockptr_t ov,
- unsigned int ol)
-{
- struct sock *sk = sock->sk;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- int linksel;
-
- if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED)
- return -ENOPROTOOPT;
-
- switch (opt) {
- case CAIFSO_LINK_SELECT:
- if (ol < sizeof(int))
- return -EINVAL;
- if (lvl != SOL_CAIF)
- goto bad_sol;
- if (copy_from_sockptr(&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 CAIFSO_REQ_PARAM:
- if (lvl != SOL_CAIF)
- goto bad_sol;
- if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL)
- return -ENOPROTOOPT;
- lock_sock(&(cf_sk->sk));
- if (ol > sizeof(cf_sk->conn_req.param.data) ||
- copy_from_sockptr(&cf_sk->conn_req.param.data, ov, ol)) {
- release_sock(&cf_sk->sk);
- return -EINVAL;
- }
- cf_sk->conn_req.param.size = ol;
- release_sock(&cf_sk->sk);
- return 0;
-
- default:
- return -ENOPROTOOPT;
- }
-
- return 0;
-bad_sol:
- return -ENOPROTOOPT;
-
-}
-
-/*
- * caif_connect() - Connect a CAIF Socket
- * Copied and modified af_irda.c:irda_connect().
- *
- * Note : by consulting "errno", the user space caller may learn the cause
- * of the failure. Most of them are visible in the function, others may come
- * from subroutines called and are listed here :
- * o -EAFNOSUPPORT: bad socket family or type.
- * o -ESOCKTNOSUPPORT: bad socket type or protocol
- * o -EINVAL: bad socket address, or CAIF link type
- * o -ECONNREFUSED: remote end refused the connection.
- * o -EINPROGRESS: connect request sent but timed out (or non-blocking)
- * o -EISCONN: already connected.
- * o -ETIMEDOUT: Connection timed out (send timeout)
- * o -ENODEV: No link layer to send request
- * o -ECONNRESET: Received Shutdown indication or lost link layer
- * o -ENOMEM: Out of memory
- *
- * State Strategy:
- * o sk_state: holds the CAIF_* protocol state, it's updated by
- * caif_ctrl_cb.
- * o sock->state: holds the SS_* socket state and is updated by connect and
- * disconnect.
- */
-static int caif_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
- int addr_len, int flags)
-{
- struct sock *sk = sock->sk;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- long timeo;
- int err;
- int ifindex, headroom, tailroom;
- unsigned int mtu;
- struct net_device *dev;
-
- lock_sock(sk);
-
- err = -EINVAL;
- if (addr_len < offsetofend(struct sockaddr, sa_family))
- goto out;
-
- err = -EAFNOSUPPORT;
- if (uaddr->sa_family != AF_CAIF)
- goto out;
-
- switch (sock->state) {
- case SS_UNCONNECTED:
- /* Normal case, a fresh connect */
- caif_assert(sk->sk_state == CAIF_DISCONNECTED);
- break;
- case SS_CONNECTING:
- switch (sk->sk_state) {
- case CAIF_CONNECTED:
- sock->state = SS_CONNECTED;
- err = -EISCONN;
- goto out;
- case CAIF_DISCONNECTED:
- /* Reconnect allowed */
- break;
- case CAIF_CONNECTING:
- err = -EALREADY;
- if (flags & O_NONBLOCK)
- goto out;
- goto wait_connect;
- }
- break;
- case SS_CONNECTED:
- caif_assert(sk->sk_state == CAIF_CONNECTED ||
- sk->sk_state == CAIF_DISCONNECTED);
- if (sk->sk_shutdown & SHUTDOWN_MASK) {
- /* Allow re-connect after SHUTDOWN_IND */
- caif_disconnect_client(sock_net(sk), &cf_sk->layer);
- caif_free_client(&cf_sk->layer);
- break;
- }
- /* No reconnect on a seqpacket socket */
- err = -EISCONN;
- goto out;
- case SS_DISCONNECTING:
- case SS_FREE:
- caif_assert(1); /*Should never happen */
- break;
- }
- sk->sk_state = CAIF_DISCONNECTED;
- sock->state = SS_UNCONNECTED;
- sk_stream_kill_queues(&cf_sk->sk);
-
- err = -EINVAL;
- if (addr_len != sizeof(struct sockaddr_caif))
- goto out;
-
- memcpy(&cf_sk->conn_req.sockaddr, uaddr,
- sizeof(struct sockaddr_caif));
-
- /* Move to connecting socket, start sending Connect Requests */
- sock->state = SS_CONNECTING;
- sk->sk_state = CAIF_CONNECTING;
-
- /* Check priority value comming from socket */
- /* if priority value is out of range it will be ajusted */
- if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
- cf_sk->conn_req.priority = CAIF_PRIO_MAX;
- else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN)
- cf_sk->conn_req.priority = CAIF_PRIO_MIN;
- else
- cf_sk->conn_req.priority = cf_sk->sk.sk_priority;
-
- /*ifindex = id of the interface.*/
- cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
-
- cf_sk->layer.receive = caif_sktrecv_cb;
-
- err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
- &cf_sk->layer, &ifindex, &headroom, &tailroom);
-
- if (err < 0) {
- cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
- cf_sk->sk.sk_state = CAIF_DISCONNECTED;
- goto out;
- }
-
- err = -ENODEV;
- rcu_read_lock();
- dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
- if (!dev) {
- rcu_read_unlock();
- goto out;
- }
- cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom);
- mtu = dev->mtu;
- rcu_read_unlock();
-
- cf_sk->tailroom = tailroom;
- cf_sk->maxframe = mtu - (headroom + tailroom);
- if (cf_sk->maxframe < 1) {
- pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu);
- err = -ENODEV;
- goto out;
- }
-
- err = -EINPROGRESS;
-wait_connect:
-
- if (sk->sk_state != CAIF_CONNECTED && (flags & O_NONBLOCK))
- goto out;
-
- timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-
- release_sock(sk);
- err = -ERESTARTSYS;
- timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
- sk->sk_state != CAIF_CONNECTING,
- timeo);
- lock_sock(sk);
- if (timeo < 0)
- goto out; /* -ERESTARTSYS */
-
- err = -ETIMEDOUT;
- if (timeo == 0 && sk->sk_state != CAIF_CONNECTED)
- goto out;
- if (sk->sk_state != CAIF_CONNECTED) {
- sock->state = SS_UNCONNECTED;
- err = sock_error(sk);
- if (!err)
- err = -ECONNREFUSED;
- goto out;
- }
- sock->state = SS_CONNECTED;
- err = 0;
-out:
- release_sock(sk);
- return err;
-}
-
-/*
- * caif_release() - Disconnect a CAIF Socket
- * Copied and modified af_irda.c:irda_release().
- */
-static int caif_release(struct socket *sock)
-{
- struct sock *sk = sock->sk;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
-
- if (!sk)
- return 0;
-
- set_tx_flow_off(cf_sk);
-
- /*
- * Ensure that packets are not queued after this point in time.
- * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock,
- * this ensures no packets when sock is dead.
- */
- spin_lock_bh(&sk->sk_receive_queue.lock);
- sock_set_flag(sk, SOCK_DEAD);
- spin_unlock_bh(&sk->sk_receive_queue.lock);
- sock->sk = NULL;
-
- WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
- debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
-
- lock_sock(&(cf_sk->sk));
- sk->sk_state = CAIF_DISCONNECTED;
- sk->sk_shutdown = SHUTDOWN_MASK;
-
- caif_disconnect_client(sock_net(sk), &cf_sk->layer);
- cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
- wake_up_interruptible_poll(sk_sleep(sk), EPOLLERR|EPOLLHUP);
-
- sock_orphan(sk);
- sk_stream_kill_queues(&cf_sk->sk);
- release_sock(sk);
- sock_put(sk);
- return 0;
-}
-
-/* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */
-static __poll_t caif_poll(struct file *file,
- struct socket *sock, poll_table *wait)
-{
- struct sock *sk = sock->sk;
- __poll_t mask;
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
-
- sock_poll_wait(file, sock, wait);
- mask = 0;
-
- /* exceptional events? */
- if (sk->sk_err)
- mask |= EPOLLERR;
- if (sk->sk_shutdown == SHUTDOWN_MASK)
- mask |= EPOLLHUP;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= EPOLLRDHUP;
-
- /* readable? */
- if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
- (sk->sk_shutdown & RCV_SHUTDOWN))
- mask |= EPOLLIN | EPOLLRDNORM;
-
- /*
- * we set writable also when the other side has shut down the
- * connection. This prevents stuck sockets.
- */
- if (sock_writeable(sk) && tx_flow_is_on(cf_sk))
- mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
-
- return mask;
-}
-
-static const struct proto_ops caif_seqpacket_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 = sock_no_shutdown,
- .setsockopt = setsockopt,
- .sendmsg = caif_seqpkt_sendmsg,
- .recvmsg = caif_seqpkt_recvmsg,
- .mmap = sock_no_mmap,
-};
-
-static const struct proto_ops caif_stream_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 = sock_no_shutdown,
- .setsockopt = setsockopt,
- .sendmsg = caif_stream_sendmsg,
- .recvmsg = caif_stream_recvmsg,
- .mmap = sock_no_mmap,
-};
-
-/* This function is called when a socket is finally destroyed. */
-static void caif_sock_destructor(struct sock *sk)
-{
- struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
- caif_assert(!refcount_read(&sk->sk_wmem_alloc));
- caif_assert(sk_unhashed(sk));
- caif_assert(!sk->sk_socket);
- if (!sock_flag(sk, SOCK_DEAD)) {
- pr_debug("Attempt to release alive CAIF socket: %p\n", sk);
- return;
- }
- sk_stream_kill_queues(&cf_sk->sk);
- WARN_ON_ONCE(sk->sk_forward_alloc);
- caif_free_client(&cf_sk->layer);
-}
-
-static int caif_create(struct net *net, struct socket *sock, int protocol,
- int kern)
-{
- struct sock *sk = NULL;
- struct caifsock *cf_sk = NULL;
- static struct proto prot = {.name = "PF_CAIF",
- .owner = THIS_MODULE,
- .obj_size = sizeof(struct caifsock),
- .useroffset = offsetof(struct caifsock, conn_req.param),
- .usersize = sizeof_field(struct caifsock, conn_req.param)
- };
-
- if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN))
- return -EPERM;
- /*
- * The sock->type specifies the socket type to use.
- * The CAIF socket is a packet stream in the sense
- * that it is packet based. CAIF trusts the reliability
- * of the link, no resending is implemented.
- */
- if (sock->type == SOCK_SEQPACKET)
- sock->ops = &caif_seqpacket_ops;
- else if (sock->type == SOCK_STREAM)
- sock->ops = &caif_stream_ops;
- else
- return -ESOCKTNOSUPPORT;
-
- 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.
- */
- sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot, kern);
- if (!sk)
- return -ENOMEM;
-
- cf_sk = container_of(sk, struct caifsock, sk);
-
- /* Store the protocol */
- sk->sk_protocol = (unsigned char) protocol;
-
- /* Initialize default priority for well-known cases */
- switch (protocol) {
- case CAIFPROTO_AT:
- sk->sk_priority = TC_PRIO_CONTROL;
- break;
- case CAIFPROTO_RFM:
- sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
- break;
- default:
- sk->sk_priority = TC_PRIO_BESTEFFORT;
- }
-
- /*
- * 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);
- sk->sk_destruct = caif_sock_destructor;
-
- mutex_init(&cf_sk->readlock); /* single task reading lock */
- cf_sk->layer.ctrlcmd = caif_ctrl_cb;
- cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
- cf_sk->sk.sk_state = CAIF_DISCONNECTED;
-
- set_tx_flow_off(cf_sk);
- set_rx_flow_on(cf_sk);
-
- /* Set default options on configuration */
- cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
- cf_sk->conn_req.protocol = protocol;
- release_sock(&cf_sk->sk);
- return 0;
-}
-
-
-static const struct net_proto_family caif_family_ops = {
- .family = PF_CAIF,
- .create = caif_create,
- .owner = THIS_MODULE,
-};
-
-static int __init caif_sktinit_module(void)
-{
- return sock_register(&caif_family_ops);
-}
-
-static void __exit caif_sktexit_module(void)
-{
- sock_unregister(PF_CAIF);
-}
-module_init(caif_sktinit_module);
-module_exit(caif_sktexit_module);
diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c
deleted file mode 100644
index 4d44960d4c2f..000000000000
--- a/net/caif/caif_usb.c
+++ /dev/null
@@ -1,216 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * CAIF USB handler
- * Copyright (C) ST-Ericsson AB 2011
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/usbnet.h>
-#include <linux/etherdevice.h>
-#include <net/netns/generic.h>
-#include <net/caif/caif_dev.h>
-#include <net/caif/caif_layer.h>
-#include <net/caif/cfpkt.h>
-#include <net/caif/cfcnfg.h>
-
-MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol USB support");
-MODULE_LICENSE("GPL");
-
-#define CFUSB_PAD_DESCR_SZ 1 /* Alignment descriptor length */
-#define CFUSB_ALIGNMENT 4 /* Number of bytes to align. */
-#define CFUSB_MAX_HEADLEN (CFUSB_PAD_DESCR_SZ + CFUSB_ALIGNMENT-1)
-#define STE_USB_VID 0x04cc /* USB Product ID for ST-Ericsson */
-#define STE_USB_PID_CAIF 0x230f /* Product id for CAIF Modems */
-
-struct cfusbl {
- struct cflayer layer;
- u8 tx_eth_hdr[ETH_HLEN];
-};
-
-static bool pack_added;
-
-static int cfusbl_receive(struct cflayer *layr, struct cfpkt *pkt)
-{
- u8 hpad;
-
- /* Remove padding. */
- cfpkt_extr_head(pkt, &hpad, 1);
- cfpkt_extr_head(pkt, NULL, hpad);
- return layr->up->receive(layr->up, pkt);
-}
-
-static int cfusbl_transmit(struct cflayer *layr, struct cfpkt *pkt)
-{
- struct caif_payload_info *info;
- u8 hpad;
- u8 zeros[CFUSB_ALIGNMENT];
- struct sk_buff *skb;
- struct cfusbl *usbl = container_of(layr, struct cfusbl, layer);
-
- skb = cfpkt_tonative(pkt);
-
- skb_reset_network_header(skb);
- skb->protocol = htons(ETH_P_IP);
-
- info = cfpkt_info(pkt);
- hpad = (info->hdr_len + CFUSB_PAD_DESCR_SZ) & (CFUSB_ALIGNMENT - 1);
-
- if (skb_headroom(skb) < ETH_HLEN + CFUSB_PAD_DESCR_SZ + hpad) {
- pr_warn("Headroom too small\n");
- kfree_skb(skb);
- return -EIO;
- }
- memset(zeros, 0, hpad);
-
- cfpkt_add_head(pkt, zeros, hpad);
- cfpkt_add_head(pkt, &hpad, 1);
- cfpkt_add_head(pkt, usbl->tx_eth_hdr, sizeof(usbl->tx_eth_hdr));
- return layr->dn->transmit(layr->dn, pkt);
-}
-
-static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
- int phyid)
-{
- if (layr->up && layr->up->ctrlcmd)
- layr->up->ctrlcmd(layr->up, ctrl, layr->id);
-}
-
-static struct cflayer *cfusbl_create(int phyid, const u8 ethaddr[ETH_ALEN],
- u8 braddr[ETH_ALEN])
-{
- struct cfusbl *this = kmalloc_obj(struct cfusbl, GFP_ATOMIC);
-
- if (!this)
- return NULL;
-
- caif_assert(offsetof(struct cfusbl, layer) == 0);
-
- memset(&this->layer, 0, sizeof(this->layer));
- this->layer.receive = cfusbl_receive;
- this->layer.transmit = cfusbl_transmit;
- this->layer.ctrlcmd = cfusbl_ctrlcmd;
- snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "usb%d", phyid);
- this->layer.id = phyid;
-
- /*
- * Construct TX ethernet header:
- * 0-5 destination address
- * 5-11 source address
- * 12-13 protocol type
- */
- ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], braddr);
- ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], ethaddr);
- this->tx_eth_hdr[12] = cpu_to_be16(ETH_P_802_EX1) & 0xff;
- this->tx_eth_hdr[13] = (cpu_to_be16(ETH_P_802_EX1) >> 8) & 0xff;
- pr_debug("caif ethernet TX-header dst:%pM src:%pM type:%02x%02x\n",
- this->tx_eth_hdr, this->tx_eth_hdr + ETH_ALEN,
- this->tx_eth_hdr[12], this->tx_eth_hdr[13]);
-
- return (struct cflayer *) this;
-}
-
-static void cfusbl_release(struct cflayer *layer)
-{
- kfree(layer);
-}
-
-static struct packet_type caif_usb_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_802_EX1),
-};
-
-static int cfusbl_device_notify(struct notifier_block *me, unsigned long what,
- void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct caif_dev_common common;
- struct cflayer *layer, *link_support;
- struct usbnet *usbnet;
- struct usb_device *usbdev;
- int res;
-
- if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED)
- return 0;
-
- /* Check whether we have a NCM device, and find its VID/PID. */
- if (!(dev->dev.parent && dev->dev.parent->driver &&
- strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0))
- return 0;
-
- usbnet = netdev_priv(dev);
- usbdev = usbnet->udev;
-
- pr_debug("USB CDC NCM device VID:0x%4x PID:0x%4x\n",
- le16_to_cpu(usbdev->descriptor.idVendor),
- le16_to_cpu(usbdev->descriptor.idProduct));
-
- /* Check for VID/PID that supports CAIF */
- if (!(le16_to_cpu(usbdev->descriptor.idVendor) == STE_USB_VID &&
- le16_to_cpu(usbdev->descriptor.idProduct) == STE_USB_PID_CAIF))
- return 0;
-
- if (what == NETDEV_UNREGISTER)
- module_put(THIS_MODULE);
-
- if (what != NETDEV_REGISTER)
- return 0;
-
- __module_get(THIS_MODULE);
-
- memset(&common, 0, sizeof(common));
- common.use_frag = false;
- common.use_fcs = false;
- common.use_stx = false;
- common.link_select = CAIF_LINK_HIGH_BANDW;
- common.flowctrl = NULL;
-
- link_support = cfusbl_create(dev->ifindex, dev->dev_addr,
- dev->broadcast);
-
- if (!link_support)
- return -ENOMEM;
-
- if (dev->num_tx_queues > 1)
- pr_warn("USB device uses more than one tx queue\n");
-
- res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
- &layer, &caif_usb_type.func);
- if (res)
- goto err;
-
- if (!pack_added)
- dev_add_pack(&caif_usb_type);
- pack_added = true;
-
- strscpy(layer->name, dev->name, sizeof(layer->name));
-
- return 0;
-err:
- cfusbl_release(link_support);
- return res;
-}
-
-static struct notifier_block caif_device_notifier = {
- .notifier_call = cfusbl_device_notify,
- .priority = 0,
-};
-
-static int __init cfusbl_init(void)
-{
- return register_netdevice_notifier(&caif_device_notifier);
-}
-
-static void __exit cfusbl_exit(void)
-{
- unregister_netdevice_notifier(&caif_device_notifier);
- dev_remove_pack(&caif_usb_type);
-}
-
-module_init(cfusbl_init);
-module_exit(cfusbl_exit);
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
deleted file mode 100644
index 8a80914783e8..000000000000
--- a/net/caif/cfcnfg.c
+++ /dev/null
@@ -1,612 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/module.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 <net/caif/caif_dev.h>
-
-#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 {
- struct list_head node;
- bool up;
-
- /* 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;
-
- /* Information about the physical device */
- struct dev_info dev_info;
-
- /* Interface index */
- int ifindex;
-
- /* Protocol head room added for CAIF link layer */
- int head_room;
-
- /* Use Start of frame checksum */
- bool use_fcs;
-};
-
-struct cfcnfg {
- struct cflayer layer;
- struct cflayer *ctrl;
- struct cflayer *mux;
- struct list_head phys;
- struct mutex lock;
-};
-
-static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id,
- enum cfctrl_srv serv, u8 phyid,
- struct cflayer *adapt_layer);
-static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id);
-static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
- struct cflayer *adapt_layer);
-static void cfctrl_resp_func(void);
-static void cfctrl_enum_resp(void);
-
-struct cfcnfg *cfcnfg_create(void)
-{
- struct cfcnfg *this;
- struct cfctrl_rsp *resp;
-
- might_sleep();
-
- /* Initiate this layer */
- this = kzalloc_obj(struct cfcnfg, GFP_ATOMIC);
- if (!this)
- return NULL;
- 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 = cfcnfg_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 = cfcnfg_linkup_rsp;
- resp->reject_rsp = cfcnfg_reject_rsp;
- INIT_LIST_HEAD(&this->phys);
-
- cfmuxl_set_uplayer(this->mux, this->ctrl, 0);
- layer_set_dn(this->ctrl, this->mux);
- layer_set_up(this->ctrl, this);
- mutex_init(&this->lock);
-
- return this;
-out_of_mem:
- synchronize_rcu();
-
- kfree(this->mux);
- kfree(this->ctrl);
- kfree(this);
- return NULL;
-}
-
-void cfcnfg_remove(struct cfcnfg *cfg)
-{
- might_sleep();
- if (cfg) {
- synchronize_rcu();
-
- kfree(cfg->mux);
- cfctrl_remove(cfg->ctrl);
- kfree(cfg);
- }
-}
-
-static void cfctrl_resp_func(void)
-{
-}
-
-static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo_rcu(struct cfcnfg *cnfg,
- u8 phyid)
-{
- struct cfcnfg_phyinfo *phy;
-
- list_for_each_entry_rcu(phy, &cnfg->phys, node)
- if (phy->id == phyid)
- return phy;
- return NULL;
-}
-
-static void cfctrl_enum_resp(void)
-{
-}
-
-static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
- enum cfcnfg_phy_preference phy_pref)
-{
- /* Try to match with specified preference */
- struct cfcnfg_phyinfo *phy;
-
- list_for_each_entry_rcu(phy, &cnfg->phys, node) {
- if (phy->up && phy->pref == phy_pref &&
- phy->frm_layer != NULL)
-
- return &phy->dev_info;
- }
-
- /* Otherwise just return something */
- list_for_each_entry_rcu(phy, &cnfg->phys, node)
- if (phy->up)
- return &phy->dev_info;
-
- return NULL;
-}
-
-static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
-{
- struct cfcnfg_phyinfo *phy;
-
- list_for_each_entry_rcu(phy, &cnfg->phys, node)
- if (phy->ifindex == ifi && phy->up)
- return phy->id;
- return -ENODEV;
-}
-
-int caif_disconnect_client(struct net *net, struct cflayer *adap_layer)
-{
- u8 channel_id;
- struct cfcnfg *cfg = get_cfcnfg(net);
-
- caif_assert(adap_layer != NULL);
- cfctrl_cancel_req(cfg->ctrl, adap_layer);
- channel_id = adap_layer->id;
- if (channel_id != 0) {
- struct cflayer *servl;
- servl = cfmuxl_remove_uplayer(cfg->mux, channel_id);
- cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer);
- if (servl != NULL)
- layer_set_up(servl, NULL);
- } else
- pr_debug("nothing to disconnect\n");
-
- /* Do RCU sync before initiating cleanup */
- synchronize_rcu();
- if (adap_layer->ctrlcmd != NULL)
- adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0);
- return 0;
-
-}
-EXPORT_SYMBOL(caif_disconnect_client);
-
-static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
-{
-}
-
-static const int protohead[CFCTRL_SRV_MASK] = {
- [CFCTRL_SRV_VEI] = 4,
- [CFCTRL_SRV_DATAGRAM] = 7,
- [CFCTRL_SRV_UTIL] = 4,
- [CFCTRL_SRV_RFM] = 3,
- [CFCTRL_SRV_DBG] = 3,
-};
-
-
-static int caif_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;
- int res;
-
- memset(l, 0, sizeof(*l));
- /* In caif protocol low value is high priority */
- l->priority = CAIF_PRIO_MAX - s->priority + 1;
-
- if (s->ifindex != 0) {
- res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
- if (res < 0)
- return res;
- l->phyid = res;
- } 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;
- l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3;
- l->chtype = s->sockaddr.u.at.type & 0x3;
- 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;
- strscpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
- sizeof(l->u.rfm.volume));
- break;
- case CAIFPROTO_UTIL:
- l->linktype = CFCTRL_SRV_UTIL;
- l->endpoint = 0x00;
- l->chtype = 0x00;
- strscpy(l->u.utility.name, s->sockaddr.u.util.service,
- sizeof(l->u.utility.name));
- 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;
- case CAIFPROTO_DEBUG:
- l->linktype = CFCTRL_SRV_DBG;
- l->endpoint = s->sockaddr.u.dbg.service;
- l->chtype = s->sockaddr.u.dbg.type;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
- struct cflayer *adap_layer, int *ifindex,
- int *proto_head, int *proto_tail)
-{
- struct cflayer *frml;
- struct cfcnfg_phyinfo *phy;
- int err;
- struct cfctrl_link_param param;
- struct cfcnfg *cfg = get_cfcnfg(net);
-
- rcu_read_lock();
- err = caif_connect_req_to_link_param(cfg, conn_req, ¶m);
- if (err)
- goto unlock;
-
- phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid);
- if (!phy) {
- err = -ENODEV;
- goto unlock;
- }
- err = -EINVAL;
-
- if (adap_layer == NULL) {
- pr_err("adap_layer is zero\n");
- goto unlock;
- }
- if (adap_layer->receive == NULL) {
- pr_err("adap_layer->receive is NULL\n");
- goto unlock;
- }
- if (adap_layer->ctrlcmd == NULL) {
- pr_err("adap_layer->ctrlcmd == NULL\n");
- goto unlock;
- }
-
- err = -ENODEV;
- frml = phy->frm_layer;
- if (frml == NULL) {
- pr_err("Specified PHY type does not exist!\n");
- goto unlock;
- }
- caif_assert(param.phyid == phy->id);
- caif_assert(phy->frm_layer->id ==
- param.phyid);
- caif_assert(phy->phy_layer->id ==
- param.phyid);
-
- *ifindex = phy->ifindex;
- *proto_tail = 2;
- *proto_head = protohead[param.linktype] + phy->head_room;
-
- rcu_read_unlock();
-
- /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
- cfctrl_enum_req(cfg->ctrl, param.phyid);
- return cfctrl_linkup_request(cfg->ctrl, ¶m, adap_layer);
-
-unlock:
- rcu_read_unlock();
- return err;
-}
-EXPORT_SYMBOL(caif_connect_client);
-
-static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
- 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
-cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
- u8 phyid, struct cflayer *adapt_layer)
-{
- struct cfcnfg *cnfg = container_obj(layer);
- struct cflayer *servicel = NULL;
- struct cfcnfg_phyinfo *phyinfo;
- struct net_device *netdev;
-
- if (channel_id == 0) {
- pr_warn("received channel_id zero\n");
- if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL)
- adapt_layer->ctrlcmd(adapt_layer,
- CAIF_CTRLCMD_INIT_FAIL_RSP, 0);
- return;
- }
-
- rcu_read_lock();
-
- if (adapt_layer == NULL) {
- pr_debug("link setup response but no client exist, send linkdown back\n");
- cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
- goto unlock;
- }
-
- caif_assert(cnfg != NULL);
- caif_assert(phyid != 0);
-
- phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
- if (phyinfo == NULL) {
- pr_err("ERROR: Link Layer Device disappeared while connecting\n");
- goto unlock;
- }
-
- caif_assert(phyinfo != NULL);
- caif_assert(phyinfo->id == phyid);
- caif_assert(phyinfo->phy_layer != NULL);
- caif_assert(phyinfo->phy_layer->id == phyid);
-
- adapt_layer->id = channel_id;
-
- switch (serv) {
- case CFCTRL_SRV_VEI:
- servicel = cfvei_create(channel_id, &phyinfo->dev_info);
- break;
- case CFCTRL_SRV_DATAGRAM:
- servicel = cfdgml_create(channel_id,
- &phyinfo->dev_info);
- break;
- case CFCTRL_SRV_RFM:
- netdev = phyinfo->dev_info.dev;
- servicel = cfrfml_create(channel_id, &phyinfo->dev_info,
- netdev->mtu);
- break;
- case CFCTRL_SRV_UTIL:
- servicel = cfutill_create(channel_id, &phyinfo->dev_info);
- break;
- case CFCTRL_SRV_VIDEO:
- servicel = cfvidl_create(channel_id, &phyinfo->dev_info);
- break;
- case CFCTRL_SRV_DBG:
- servicel = cfdbgl_create(channel_id, &phyinfo->dev_info);
- break;
- default:
- pr_err("Protocol error. Link setup response - unknown channel type\n");
- goto unlock;
- }
- if (!servicel)
- goto unlock;
- layer_set_dn(servicel, cnfg->mux);
- cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id);
- layer_set_up(servicel, adapt_layer);
- layer_set_dn(adapt_layer, servicel);
-
- rcu_read_unlock();
-
- servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
- return;
-unlock:
- rcu_read_unlock();
-}
-
-int
-cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
- struct net_device *dev, struct cflayer *phy_layer,
- enum cfcnfg_phy_preference pref,
- struct cflayer *link_support,
- bool fcs, int head_room)
-{
- struct cflayer *frml;
- struct cfcnfg_phyinfo *phyinfo = NULL;
- int i, res = 0;
- u8 phyid;
-
- mutex_lock(&cnfg->lock);
-
- /* CAIF protocol allow maximum 6 link-layers */
- for (i = 0; i < 7; i++) {
- phyid = (dev->ifindex + i) & 0x7;
- if (phyid == 0)
- continue;
- if (cfcnfg_get_phyinfo_rcu(cnfg, phyid) == NULL)
- goto got_phyid;
- }
- pr_warn("Too many CAIF Link Layers (max 6)\n");
- res = -EEXIST;
- goto out;
-
-got_phyid:
- phyinfo = kzalloc_obj(struct cfcnfg_phyinfo, GFP_ATOMIC);
- if (!phyinfo) {
- res = -ENOMEM;
- goto out;
- }
-
- phy_layer->id = phyid;
- phyinfo->pref = pref;
- phyinfo->id = phyid;
- phyinfo->dev_info.id = phyid;
- phyinfo->dev_info.dev = dev;
- phyinfo->phy_layer = phy_layer;
- phyinfo->ifindex = dev->ifindex;
- phyinfo->head_room = head_room;
- phyinfo->use_fcs = fcs;
-
- frml = cffrml_create(phyid, fcs);
-
- if (!frml) {
- res = -ENOMEM;
- goto out_err;
- }
- phyinfo->frm_layer = frml;
- layer_set_up(frml, cnfg->mux);
-
- if (link_support != NULL) {
- link_support->id = phyid;
- layer_set_dn(frml, link_support);
- layer_set_up(link_support, frml);
- layer_set_dn(link_support, phy_layer);
- layer_set_up(phy_layer, link_support);
- } else {
- layer_set_dn(frml, phy_layer);
- layer_set_up(phy_layer, frml);
- }
-
- list_add_rcu(&phyinfo->node, &cnfg->phys);
-out:
- mutex_unlock(&cnfg->lock);
- return res;
-
-out_err:
- kfree(phyinfo);
- mutex_unlock(&cnfg->lock);
- return res;
-}
-EXPORT_SYMBOL(cfcnfg_add_phy_layer);
-
-int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
- bool up)
-{
- struct cfcnfg_phyinfo *phyinfo;
-
- rcu_read_lock();
- phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phy_layer->id);
- if (phyinfo == NULL) {
- rcu_read_unlock();
- return -ENODEV;
- }
-
- if (phyinfo->up == up) {
- rcu_read_unlock();
- return 0;
- }
- phyinfo->up = up;
-
- if (up) {
- cffrml_hold(phyinfo->frm_layer);
- cfmuxl_set_dnlayer(cnfg->mux, phyinfo->frm_layer,
- phy_layer->id);
- } else {
- cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id);
- cffrml_put(phyinfo->frm_layer);
- }
-
- rcu_read_unlock();
- return 0;
-}
-EXPORT_SYMBOL(cfcnfg_set_phy_state);
-
-int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
-{
- struct cflayer *frml, *frml_dn;
- u16 phyid;
- struct cfcnfg_phyinfo *phyinfo;
-
- might_sleep();
-
- mutex_lock(&cnfg->lock);
-
- phyid = phy_layer->id;
- phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
-
- if (phyinfo == NULL) {
- mutex_unlock(&cnfg->lock);
- return 0;
- }
- caif_assert(phyid == phyinfo->id);
- caif_assert(phy_layer == phyinfo->phy_layer);
- caif_assert(phy_layer->id == phyid);
- caif_assert(phyinfo->frm_layer->id == phyid);
-
- list_del_rcu(&phyinfo->node);
- synchronize_rcu();
-
- /* Fail if reference count is not zero */
- if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) {
- pr_info("Wait for device inuse\n");
- list_add_rcu(&phyinfo->node, &cnfg->phys);
- mutex_unlock(&cnfg->lock);
- return -EAGAIN;
- }
-
- frml = phyinfo->frm_layer;
- frml_dn = frml->dn;
- cffrml_set_uplayer(frml, NULL);
- cffrml_set_dnlayer(frml, NULL);
- if (phy_layer != frml_dn) {
- layer_set_up(frml_dn, NULL);
- layer_set_dn(frml_dn, NULL);
- }
- layer_set_up(phy_layer, NULL);
-
- if (phyinfo->phy_layer != frml_dn)
- kfree(frml_dn);
-
- cffrml_free(frml);
- kfree(phyinfo);
- mutex_unlock(&cnfg->lock);
-
- return 0;
-}
-EXPORT_SYMBOL(cfcnfg_del_phy_layer);
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
deleted file mode 100644
index c6cc2bfed65d..000000000000
--- a/net/caif/cfctrl.c
+++ /dev/null
@@ -1,631 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/pkt_sched.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 int handle_loop(struct cfctrl *ctrl,
- int cmd, struct cfpkt *pkt){
- return -1;
-}
-#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(void)
-{
- struct dev_info dev_info;
- struct cfctrl *this =
- kzalloc_obj(struct cfctrl, GFP_ATOMIC);
- if (!this)
- return NULL;
- caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
- memset(&dev_info, 0, sizeof(dev_info));
- dev_info.id = 0xff;
- cfsrvl_init(&this->serv, 0, &dev_info, false);
- atomic_set(&this->req_seq_no, 1);
- atomic_set(&this->rsp_seq_no, 1);
- this->serv.layer.receive = cfctrl_recv;
- sprintf(this->serv.layer.name, "ctrl");
- this->serv.layer.ctrlcmd = cfctrl_ctrlcmd;
-#ifndef CAIF_NO_LOOP
- spin_lock_init(&this->loop_linkid_lock);
- this->loop_linkid = 1;
-#endif
- spin_lock_init(&this->info_list_lock);
- INIT_LIST_HEAD(&this->list);
- return &this->serv.layer;
-}
-
-void cfctrl_remove(struct cflayer *layer)
-{
- struct cfctrl_request_info *p, *tmp;
- struct cfctrl *ctrl = container_obj(layer);
-
- spin_lock_bh(&ctrl->info_list_lock);
- list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
- list_del(&p->list);
- kfree(p);
- }
- spin_unlock_bh(&ctrl->info_list_lock);
- kfree(layer);
-}
-
-static bool param_eq(const struct cfctrl_link_param *p1,
- const 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;
-}
-
-static bool cfctrl_req_eq(const struct cfctrl_request_info *r1,
- const 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 */
-static void cfctrl_insert_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req)
-{
- spin_lock_bh(&ctrl->info_list_lock);
- atomic_inc(&ctrl->req_seq_no);
- req->sequence_no = atomic_read(&ctrl->req_seq_no);
- list_add_tail(&req->list, &ctrl->list);
- spin_unlock_bh(&ctrl->info_list_lock);
-}
-
-/* Compare and remove request */
-static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
- struct cfctrl_request_info *req)
-{
- struct cfctrl_request_info *p, *tmp, *first;
-
- first = list_first_entry(&ctrl->list, struct cfctrl_request_info, list);
-
- list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
- if (cfctrl_req_eq(req, p)) {
- if (p != first)
- pr_warn("Requests are not received in order\n");
-
- atomic_set(&ctrl->rsp_seq_no,
- p->sequence_no);
- list_del(&p->list);
- goto out;
- }
- }
- p = NULL;
-out:
- return p;
-}
-
-struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer)
-{
- struct cfctrl *this = container_obj(layer);
- return &this->res;
-}
-
-static 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 cfpkt *pkt;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cflayer *dn = cfctrl->serv.layer.dn;
-
- if (!dn) {
- pr_debug("not able to send enum request\n");
- return;
- }
- pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt)
- 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);
- cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
- dn->transmit(dn, pkt);
-}
-
-int cfctrl_linkup_request(struct cflayer *layer,
- struct cfctrl_link_param *param,
- struct cflayer *user_layer)
-{
- struct cfctrl *cfctrl = container_obj(layer);
- struct cflayer *dn = cfctrl->serv.layer.dn;
- char utility_name[UTILITY_NAME_LENGTH];
- struct cfctrl_request_info *req;
- struct cfpkt *pkt;
- u32 tmp32;
- u16 tmp16;
- u8 tmp8;
- int ret;
-
- if (!dn) {
- pr_debug("not able to send linkup request\n");
- return -ENODEV;
- }
-
- if (cfctrl_cancel_req(layer, user_layer) > 0) {
- /* Slight Paranoia, check if already connecting */
- pr_err("Duplicate connect request for same client\n");
- WARN_ON(1);
- return -EALREADY;
- }
-
- pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt)
- return -ENOMEM;
- 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);
- strscpy_pad(utility_name, param->u.utility.name);
- 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_warn("Request setup of bad link type = %d\n",
- param->linktype);
- cfpkt_destroy(pkt);
- return -EINVAL;
- }
- req = kzalloc_obj(*req);
- if (!req) {
- cfpkt_destroy(pkt);
- return -ENOMEM;
- }
-
- 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);
- /*
- * NOTE:Always send linkup and linkdown request on the same
- * device as the payload. Otherwise old queued up payload
- * might arrive with the newly allocated channel ID.
- */
- cfpkt_info(pkt)->dev_info->id = param->phyid;
- cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
- ret =
- dn->transmit(dn, pkt);
- if (ret < 0) {
- int count;
-
- count = cfctrl_cancel_req(&cfctrl->serv.layer,
- user_layer);
- if (count != 1) {
- pr_err("Could not remove request (%d)", count);
- return -ENODEV;
- }
- }
- return 0;
-}
-
-int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
- struct cflayer *client)
-{
- int ret;
- struct cfpkt *pkt;
- struct cfctrl *cfctrl = container_obj(layer);
- struct cflayer *dn = cfctrl->serv.layer.dn;
-
- if (!dn) {
- pr_debug("not able to send link-down request\n");
- return -ENODEV;
- }
- pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
- if (!pkt)
- return -ENOMEM;
- cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
- cfpkt_addbdy(pkt, channelid);
- init_info(cfpkt_info(pkt), cfctrl);
- cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
- ret =
- dn->transmit(dn, pkt);
-#ifndef CAIF_NO_LOOP
- cfctrl->loop_linkused[channelid] = 0;
-#endif
- return ret;
-}
-
-int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
-{
- struct cfctrl_request_info *p, *tmp;
- struct cfctrl *ctrl = container_obj(layr);
- int found = 0;
- spin_lock_bh(&ctrl->info_list_lock);
-
- list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
- if (p->client_layer == adap_layer) {
- list_del(&p->list);
- kfree(p);
- found++;
- }
- }
-
- spin_unlock_bh(&ctrl->info_list_lock);
- return found;
-}
-
-static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp)
-{
- u8 len;
- u8 linkid = 0;
- enum cfctrl_srv serv;
- enum cfctrl_srv servtype;
- u8 endpoint;
- u8 physlinkid;
- u8 prio;
- u8 tmp;
- u8 *cp;
- int i;
- struct cfctrl_link_param linkparam;
- struct cfctrl_request_info rsp, *req;
-
- memset(&linkparam, 0, sizeof(linkparam));
-
- tmp = cfpkt_extr_head_u8(pkt);
-
- serv = tmp & CFCTRL_SRV_MASK;
- linkparam.linktype = serv;
-
- servtype = tmp >> 4;
- linkparam.chtype = servtype;
-
- tmp = cfpkt_extr_head_u8(pkt);
- physlinkid = tmp & 0x07;
- prio = tmp >> 3;
-
- linkparam.priority = prio;
- linkparam.phyid = physlinkid;
- endpoint = cfpkt_extr_head_u8(pkt);
- linkparam.endpoint = endpoint & 0x03;
-
- switch (serv) {
- case CFCTRL_SRV_VEI:
- case CFCTRL_SRV_DBG:
- if (CFCTRL_ERR_BIT & cmdrsp)
- break;
- /* Link ID */
- linkid = cfpkt_extr_head_u8(pkt);
- break;
- case CFCTRL_SRV_VIDEO:
- tmp = cfpkt_extr_head_u8(pkt);
- linkparam.u.video.connid = tmp;
- if (CFCTRL_ERR_BIT & cmdrsp)
- break;
- /* Link ID */
- linkid = cfpkt_extr_head_u8(pkt);
- break;
-
- case CFCTRL_SRV_DATAGRAM:
- linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt);
- if (CFCTRL_ERR_BIT & cmdrsp)
- break;
- /* Link ID */
- linkid = cfpkt_extr_head_u8(pkt);
- break;
- case CFCTRL_SRV_RFM:
- /* Construct a frame, convert
- * DatagramConnectionID
- * to network format long and copy it out...
- */
- linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt);
- cp = (u8 *) linkparam.u.rfm.volume;
- for (tmp = cfpkt_extr_head_u8(pkt);
- cfpkt_more(pkt) && tmp != '\0';
- tmp = cfpkt_extr_head_u8(pkt))
- *cp++ = tmp;
- *cp = '\0';
-
- if (CFCTRL_ERR_BIT & cmdrsp)
- break;
- /* Link ID */
- linkid = cfpkt_extr_head_u8(pkt);
-
- break;
- case CFCTRL_SRV_UTIL:
- /* Construct a frame, convert
- * DatagramConnectionID
- * to network format long and copy it out...
- */
- /* Fifosize KB */
- linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt);
- /* Fifosize bufs */
- linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt);
- /* 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++) {
- tmp = cfpkt_extr_head_u8(pkt);
- *cp++ = tmp;
- }
- /* Length */
- len = cfpkt_extr_head_u8(pkt);
- linkparam.u.utility.paramlen = len;
- /* Param Data */
- cp = linkparam.u.utility.params;
- while (cfpkt_more(pkt) && len--) {
- tmp = cfpkt_extr_head_u8(pkt);
- *cp++ = tmp;
- }
- if (CFCTRL_ERR_BIT & cmdrsp)
- break;
- /* Link ID */
- linkid = cfpkt_extr_head_u8(pkt);
- /* Length */
- len = cfpkt_extr_head_u8(pkt);
- /* Param Data */
- cfpkt_extr_head(pkt, NULL, len);
- break;
- default:
- pr_warn("Request setup, invalid type (%d)\n", serv);
- return -1;
- }
-
- rsp.cmd = CFCTRL_CMD_LINK_SETUP;
- rsp.param = linkparam;
- spin_lock_bh(&cfctrl->info_list_lock);
- req = cfctrl_remove_req(cfctrl, &rsp);
-
- if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
- cfpkt_erroneous(pkt)) {
- pr_err("Invalid O/E bit or parse error "
- "on CAIF control channel\n");
- 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);
- }
-
- kfree(req);
-
- spin_unlock_bh(&cfctrl->info_list_lock);
-
- return 0;
-}
-
-static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
-{
- u8 cmdrsp;
- u8 cmd;
- int ret = 0;
- u8 linkid = 0;
- struct cfctrl *cfctrl = container_obj(layer);
-
- cmdrsp = cfpkt_extr_head_u8(pkt);
- cmd = cmdrsp & CFCTRL_CMD_MASK;
- if (cmd != CFCTRL_CMD_LINK_ERR
- && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)
- && CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) {
- if (handle_loop(cfctrl, cmd, pkt) != 0)
- cmdrsp |= CFCTRL_ERR_BIT;
- }
-
- switch (cmd) {
- case CFCTRL_CMD_LINK_SETUP:
- ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp);
- break;
- case CFCTRL_CMD_LINK_DESTROY:
- linkid = cfpkt_extr_head_u8(pkt);
- cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid);
- break;
- case CFCTRL_CMD_LINK_ERR:
- pr_err("Frame Error Indication received\n");
- 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("Unrecognized Control Frame\n");
- ret = -1;
- goto error;
- }
-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_bh(&this->info_list_lock);
- if (!list_empty(&this->list))
- pr_debug("Received flow off in control layer\n");
- spin_unlock_bh(&this->info_list_lock);
- break;
- case _CAIF_CTRLCMD_PHYIF_DOWN_IND: {
- struct cfctrl_request_info *p, *tmp;
-
- /* Find all connect request and report failure */
- spin_lock_bh(&this->info_list_lock);
- list_for_each_entry_safe(p, tmp, &this->list, list) {
- if (p->param.phyid == phyid) {
- list_del(&p->list);
- p->client_layer->ctrlcmd(p->client_layer,
- CAIF_CTRLCMD_INIT_FAIL_RSP,
- phyid);
- kfree(p);
- }
- }
- spin_unlock_bh(&this->info_list_lock);
- break;
- }
- default:
- break;
- }
-}
-
-#ifndef CAIF_NO_LOOP
-static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt)
-{
- static int last_linkid;
- static int dec;
- u8 linkid, linktype, tmp;
- switch (cmd) {
- case CFCTRL_CMD_LINK_SETUP:
- spin_lock_bh(&ctrl->loop_linkid_lock);
- if (!dec) {
- for (linkid = last_linkid + 1; linkid < 254; linkid++)
- if (!ctrl->loop_linkused[linkid])
- goto found;
- }
- dec = 1;
- for (linkid = last_linkid - 1; linkid > 1; linkid--)
- if (!ctrl->loop_linkused[linkid])
- goto found;
- spin_unlock_bh(&ctrl->loop_linkid_lock);
- return -1;
-found:
- if (linkid < 10)
- dec = 0;
-
- if (!ctrl->loop_linkused[linkid])
- ctrl->loop_linkused[linkid] = 1;
-
- last_linkid = linkid;
-
- cfpkt_add_trail(pkt, &linkid, 1);
- spin_unlock_bh(&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_bh(&ctrl->loop_linkid_lock);
- cfpkt_peek_head(pkt, &linkid, 1);
- ctrl->loop_linkused[linkid] = 0;
- spin_unlock_bh(&ctrl->loop_linkid_lock);
- break;
- default:
- break;
- }
- return 0;
-}
-#endif
diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c
deleted file mode 100644
index 57ad3f82e004..000000000000
--- a/net/caif/cfdbgl.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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 container_obj(layr) ((struct cfsrvl *) layr)
-
-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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
- if (!dbg)
- return NULL;
- caif_assert(offsetof(struct cfsrvl, layer) == 0);
- cfsrvl_init(dbg, channel_id, dev_info, false);
- dbg->layer.receive = cfdbgl_receive;
- dbg->layer.transmit = cfdbgl_transmit;
- snprintf(dbg->layer.name, CAIF_LAYER_NAME_SZ, "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)
-{
- struct cfsrvl *service = container_obj(layr);
- struct caif_payload_info *info;
- int ret;
-
- if (!cfsrvl_ready(service, &ret)) {
- cfpkt_destroy(pkt);
- return ret;
- }
-
- /* 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;
-
- return layr->dn->transmit(layr->dn, pkt);
-}
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
deleted file mode 100644
index c451ddd155a7..000000000000
--- a/net/caif/cfdgml.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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_MTU 1500
-
-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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
- if (!dgm)
- return NULL;
- caif_assert(offsetof(struct cfsrvl, layer) == 0);
- cfsrvl_init(dgm, channel_id, dev_info, true);
- dgm->layer.receive = cfdgml_receive;
- dgm->layer.transmit = cfdgml_transmit;
- snprintf(dgm->layer.name, CAIF_LAYER_NAME_SZ, "dgm%d", channel_id);
- 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("Packet is erroneous!\n");
- cfpkt_destroy(pkt);
- return -EPROTO;
- }
-
- if ((cmd & DGM_CMD_BIT) == 0) {
- if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) {
- pr_err("Packet is erroneous!\n");
- 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("Unknown datagram control %d (0x%x)\n", cmd, cmd);
- return -EPROTO;
- }
-}
-
-static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
-{
- u8 packet_type;
- u32 zero = 0;
- struct caif_payload_info *info;
- struct cfsrvl *service = container_obj(layr);
- int ret;
-
- if (!cfsrvl_ready(service, &ret)) {
- cfpkt_destroy(pkt);
- return ret;
- }
-
- /* STE Modem cannot handle more than 1500 bytes datagrams */
- if (cfpkt_getlen(pkt) > DGM_MTU) {
- cfpkt_destroy(pkt);
- return -EMSGSIZE;
- }
-
- cfpkt_add_head(pkt, &zero, 3);
- packet_type = 0x08; /* B9 set - UNCLASSIFIED */
- cfpkt_add_head(pkt, &packet_type, 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 = 4;
- info->dev_info = &service->dev_info;
- return layr->dn->transmit(layr->dn, pkt);
-}
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
deleted file mode 100644
index 0f4979d89fcb..000000000000
--- a/net/caif/cffrml.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * CAIF Framing Layer.
- *
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/crc-ccitt.h>
-#include <linux/netdevice.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 */
- int __percpu *pcpu_refcnt;
-};
-
-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);
-
-static u32 cffrml_rcv_error;
-static u32 cffrml_rcv_checsum_error;
-struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
-{
- struct cffrml *this = kzalloc_obj(struct cffrml, GFP_ATOMIC);
- if (!this)
- return NULL;
- this->pcpu_refcnt = alloc_percpu(int);
- if (this->pcpu_refcnt == NULL) {
- kfree(this);
- return NULL;
- }
-
- caif_assert(offsetof(struct cffrml, layer) == 0);
-
- 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_free(struct cflayer *layer)
-{
- struct cffrml *this = container_obj(layer);
- free_percpu(this->pcpu_refcnt);
- kfree(layer);
-}
-
-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;
- int 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) {
- if (len < 2) {
- ++cffrml_rcv_error;
- pr_err("Invalid frame length (%d)\n", len);
- cfpkt_destroy(pkt);
- return -EPROTO;
- }
- len -= 2;
- }
-
- if (cfpkt_setlen(pkt, len) < 0) {
- ++cffrml_rcv_error;
- pr_err("Framing length error (%d)\n", 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("Frame checksum error (0x%x != 0x%x)\n",
- hdrchks, pktchks);
- return -EILSEQ;
- }
- }
- if (cfpkt_erroneous(pkt)) {
- ++cffrml_rcv_error;
- pr_err("Packet is erroneous!\n");
- cfpkt_destroy(pkt);
- return -EPROTO;
- }
-
- if (layr->up == NULL) {
- pr_err("Layr up is missing!\n");
- cfpkt_destroy(pkt);
- return -EINVAL;
- }
-
- return layr->up->receive(layr->up, pkt);
-}
-
-static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
-{
- u16 chks;
- u16 len;
- __le16 data;
-
- struct cffrml *this = container_obj(layr);
- if (this->dofcs) {
- chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
- data = cpu_to_le16(chks);
- cfpkt_add_trail(pkt, &data, 2);
- } else {
- cfpkt_pad_trail(pkt, 2);
- }
- len = cfpkt_getlen(pkt);
- data = cpu_to_le16(len);
- cfpkt_add_head(pkt, &data, 2);
- cfpkt_info(pkt)->hdr_len += 2;
- if (cfpkt_erroneous(pkt)) {
- pr_err("Packet is erroneous!\n");
- cfpkt_destroy(pkt);
- return -EPROTO;
- }
-
- if (layr->dn == NULL) {
- cfpkt_destroy(pkt);
- return -ENODEV;
-
- }
- return layr->dn->transmit(layr->dn, pkt);
-}
-
-static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
- int phyid)
-{
- if (layr->up && layr->up->ctrlcmd)
- layr->up->ctrlcmd(layr->up, ctrl, layr->id);
-}
-
-void cffrml_put(struct cflayer *layr)
-{
- struct cffrml *this = container_obj(layr);
- if (layr != NULL && this->pcpu_refcnt != NULL)
- this_cpu_dec(*this->pcpu_refcnt);
-}
-
-void cffrml_hold(struct cflayer *layr)
-{
- struct cffrml *this = container_obj(layr);
- if (layr != NULL && this->pcpu_refcnt != NULL)
- this_cpu_inc(*this->pcpu_refcnt);
-}
-
-int cffrml_refcnt_read(struct cflayer *layr)
-{
- int i, refcnt = 0;
- struct cffrml *this = container_obj(layr);
- for_each_possible_cpu(i)
- refcnt += *per_cpu_ptr(this->pcpu_refcnt, i);
- return refcnt;
-}
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
deleted file mode 100644
index 77a1f31639b7..000000000000
--- a/net/caif/cfmuxl.c
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/rculist.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, u16 id);
-
-struct cflayer *cfmuxl_create(void)
-{
- struct cfmuxl *this = kzalloc_obj(struct cfmuxl, GFP_ATOMIC);
-
- if (!this)
- return NULL;
- 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_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
-{
- struct cfmuxl *muxl = (struct cfmuxl *) layr;
-
- spin_lock_bh(&muxl->transmit_lock);
- list_add_rcu(&dn->node, &muxl->frml_list);
- spin_unlock_bh(&muxl->transmit_lock);
- return 0;
-}
-
-static struct cflayer *get_from_id(struct list_head *list, u16 id)
-{
- struct cflayer *lyr;
- list_for_each_entry_rcu(lyr, list, node) {
- if (lyr->id == id)
- return lyr;
- }
-
- return NULL;
-}
-
-int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
-{
- struct cfmuxl *muxl = container_obj(layr);
- struct cflayer *old;
-
- spin_lock_bh(&muxl->receive_lock);
-
- /* Two entries with same id is wrong, so remove old layer from mux */
- old = get_from_id(&muxl->srvl_list, linkid);
- if (old != NULL)
- list_del_rcu(&old->node);
-
- list_add_rcu(&up->node, &muxl->srvl_list);
- spin_unlock_bh(&muxl->receive_lock);
-
- return 0;
-}
-
-struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
-{
- struct cfmuxl *muxl = container_obj(layr);
- struct cflayer *dn;
- int idx = phyid % DN_CACHE_SIZE;
-
- spin_lock_bh(&muxl->transmit_lock);
- RCU_INIT_POINTER(muxl->dn_cache[idx], NULL);
- dn = get_from_id(&muxl->frml_list, phyid);
- if (dn == NULL)
- goto out;
-
- list_del_rcu(&dn->node);
- caif_assert(dn != NULL);
-out:
- spin_unlock_bh(&muxl->transmit_lock);
- return dn;
-}
-
-static struct cflayer *get_up(struct cfmuxl *muxl, u16 id)
-{
- struct cflayer *up;
- int idx = id % UP_CACHE_SIZE;
- up = rcu_dereference(muxl->up_cache[idx]);
- if (up == NULL || up->id != id) {
- spin_lock_bh(&muxl->receive_lock);
- up = get_from_id(&muxl->srvl_list, id);
- rcu_assign_pointer(muxl->up_cache[idx], up);
- spin_unlock_bh(&muxl->receive_lock);
- }
- return up;
-}
-
-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 = rcu_dereference(muxl->dn_cache[idx]);
- if (dn == NULL || dn->id != dev_info->id) {
- spin_lock_bh(&muxl->transmit_lock);
- dn = get_from_id(&muxl->frml_list, dev_info->id);
- rcu_assign_pointer(muxl->dn_cache[idx], dn);
- spin_unlock_bh(&muxl->transmit_lock);
- }
- return dn;
-}
-
-struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
-{
- struct cflayer *up;
- struct cfmuxl *muxl = container_obj(layr);
- int idx = id % UP_CACHE_SIZE;
-
- if (id == 0) {
- pr_warn("Trying to remove control layer\n");
- return NULL;
- }
-
- spin_lock_bh(&muxl->receive_lock);
- up = get_from_id(&muxl->srvl_list, id);
- if (up == NULL)
- goto out;
-
- RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
- list_del_rcu(&up->node);
-out:
- spin_unlock_bh(&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("erroneous Caif Packet\n");
- cfpkt_destroy(pkt);
- return -EPROTO;
- }
- rcu_read_lock();
- up = get_up(muxl, id);
-
- if (up == NULL) {
- pr_debug("Received data on unknown link ID = %d (0x%x)"
- " up == NULL", id, id);
- cfpkt_destroy(pkt);
- /*
- * Don't return ERROR, since modem misbehaves and sends out
- * flow on before linksetup response.
- */
-
- rcu_read_unlock();
- return /* CFGLU_EPROT; */ 0;
- }
-
- /* We can't hold rcu_lock during receive, so take a ref count instead */
- cfsrvl_get(up);
- rcu_read_unlock();
-
- ret = up->receive(up, pkt);
-
- cfsrvl_put(up);
- return ret;
-}
-
-static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
-{
- struct cfmuxl *muxl = container_obj(layr);
- int err;
- u8 linkid;
- struct cflayer *dn;
- struct caif_payload_info *info = cfpkt_info(pkt);
- BUG_ON(!info);
-
- rcu_read_lock();
-
- dn = get_dn(muxl, info->dev_info);
- if (dn == NULL) {
- pr_debug("Send data on unknown phy ID = %d (0x%x)\n",
- info->dev_info->id, info->dev_info->id);
- rcu_read_unlock();
- cfpkt_destroy(pkt);
- return -ENOTCONN;
- }
-
- info->hdr_len += 1;
- linkid = info->channel_id;
- cfpkt_add_head(pkt, &linkid, 1);
-
- /* We can't hold rcu_lock during receive, so take a ref count instead */
- cffrml_hold(dn);
-
- rcu_read_unlock();
-
- err = dn->transmit(dn, pkt);
-
- cffrml_put(dn);
- return err;
-}
-
-static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
- int phyid)
-{
- struct cfmuxl *muxl = container_obj(layr);
- struct cflayer *layer;
-
- rcu_read_lock();
- list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
-
- if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) {
-
- if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
- ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
- layer->id != 0)
- cfmuxl_remove_uplayer(layr, layer->id);
-
- /* NOTE: ctrlcmd is not allowed to block */
- layer->ctrlcmd(layer, ctrl, phyid);
- }
- }
- rcu_read_unlock();
-}
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
deleted file mode 100644
index 96236d21b18e..000000000000
--- a/net/caif/cfpkt_skbuff.c
+++ /dev/null
@@ -1,373 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <linux/export.h>
-#include <net/caif/cfpkt.h>
-
-#define PKT_PREFIX 48
-#define PKT_POSTFIX 2
-#define PKT_LEN_WHEN_EXTENDING 128
-#define PKT_ERROR(pkt, errmsg) \
-do { \
- cfpkt_priv(pkt)->erronous = true; \
- skb_reset_tail_pointer(&pkt->skb); \
- pr_warn(errmsg); \
-} while (0)
-
-/*
- * 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;
-};
-
-static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
-{
- return (struct cfpkt_priv_data *) pkt->skb.cb;
-}
-
-static inline bool is_erronous(struct cfpkt *pkt)
-{
- return cfpkt_priv(pkt)->erronous;
-}
-
-static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
-{
- return &pkt->skb;
-}
-
-static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
-{
- return (struct cfpkt *) skb;
-}
-
-struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt)
-{
- struct cfpkt *pkt = skb_to_pkt(nativepkt);
- cfpkt_priv(pkt)->erronous = false;
- return pkt;
-}
-EXPORT_SYMBOL(cfpkt_fromnative);
-
-void *cfpkt_tonative(struct cfpkt *pkt)
-{
- return (void *) pkt;
-}
-EXPORT_SYMBOL(cfpkt_tonative);
-
-static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(len + pfx, GFP_ATOMIC);
- if (unlikely(skb == NULL))
- return NULL;
-
- skb_reserve(skb, pfx);
- return skb_to_pkt(skb);
-}
-
-inline struct cfpkt *cfpkt_create(u16 len)
-{
- return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
-}
-
-void cfpkt_destroy(struct cfpkt *pkt)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- kfree_skb(skb);
-}
-
-inline bool cfpkt_more(struct cfpkt *pkt)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- return skb->len > 0;
-}
-
-int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- if (skb_headlen(skb) >= len) {
- memcpy(data, skb->data, len);
- return 0;
- }
- return !cfpkt_extr_head(pkt, data, len) &&
- !cfpkt_add_head(pkt, data, len);
-}
-
-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, "read beyond end of packet\n");
- return -EPROTO;
- }
-
- if (unlikely(len > skb_headlen(skb))) {
- if (unlikely(skb_linearize(skb) != 0)) {
- PKT_ERROR(pkt, "linearize failed\n");
- return -EPROTO;
- }
- }
- from = skb_pull(skb, len);
- from -= len;
- if (data)
- 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, "linearize failed\n");
- return -EPROTO;
- }
- if (unlikely(skb->data + len > skb_tail_pointer(skb))) {
- PKT_ERROR(pkt, "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;
-}
-
-int cfpkt_pad_trail(struct cfpkt *pkt, u16 len)
-{
- return cfpkt_add_body(pkt, NULL, len);
-}
-
-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, "cow failed\n");
- return -EPROTO;
- }
- }
-
- /* All set to put the last SKB and optionally write data there. */
- to = pskb_put(skb, lastskb, len);
- if (likely(data))
- memcpy(to, data, len);
- return 0;
-}
-
-inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data)
-{
- return cfpkt_add_body(pkt, &data, 1);
-}
-
-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;
- int ret;
- if (unlikely(is_erronous(pkt)))
- return -EPROTO;
- if (unlikely(skb_headroom(skb) < len)) {
- PKT_ERROR(pkt, "no headroom\n");
- return -EPROTO;
- }
-
- /* Make sure data is writable */
- ret = skb_cow_data(skb, 0, &lastskb);
- if (unlikely(ret < 0)) {
- PKT_ERROR(pkt, "cow failed\n");
- return ret;
- }
-
- 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);
-}
-
-inline u16 cfpkt_getlen(struct cfpkt *pkt)
-{
- struct sk_buff *skb = pkt_to_skb(pkt);
- return skb->len;
-}
-
-int 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, "linearize failed\n");
- return -EPROTO;
- }
- return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
-}
-
-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, "skb_pad_trail failed\n");
-
- return cfpkt_getlen(pkt);
-}
-
-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 = skb_headlen(add);
- u16 neededtailspace;
- struct sk_buff *tmp;
- u16 dstlen;
- u16 createlen;
- if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
- return dstpkt;
- }
-
- neededtailspace = max(expectlen, addlen);
-
- if (dst->tail + neededtailspace > dst->end) {
- /* Create a dumplicate of 'dst' with more tail space */
- struct cfpkt *tmppkt;
- dstlen = skb_headlen(dst);
- createlen = dstlen + neededtailspace;
- tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
- if (tmppkt == NULL)
- return NULL;
- tmp = pkt_to_skb(tmppkt);
- skb_put_data(tmp, dst->data, dstlen);
- cfpkt_destroy(dstpkt);
- dst = tmp;
- }
- skb_put_data(dst, add->data, skb_headlen(add));
- cfpkt_destroy(addpkt);
- return skb_to_pkt(dst);
-}
-
-struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
-{
- struct sk_buff *skb2;
- struct sk_buff *skb = pkt_to_skb(pkt);
- struct cfpkt *tmppkt;
- u8 *split = skb->data + pos;
- u16 len2nd = skb_tail_pointer(skb) - split;
-
- if (unlikely(is_erronous(pkt)))
- return NULL;
-
- if (skb->data + pos > skb_tail_pointer(skb)) {
- PKT_ERROR(pkt, "trying to split beyond end of packet\n");
- return NULL;
- }
-
- /* Create a new packet for the second part of the data */
- tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
- PKT_PREFIX);
- if (tmppkt == NULL)
- return NULL;
- skb2 = pkt_to_skb(tmppkt);
-
-
- if (skb2 == NULL)
- return NULL;
-
- skb_put_data(skb2, split, len2nd);
-
- /* Reduce the length of the original packet */
- skb_trim(skb, pos);
-
- skb2->priority = skb->priority;
- return skb_to_pkt(skb2);
-}
-
-bool cfpkt_erroneous(struct cfpkt *pkt)
-{
- return cfpkt_priv(pkt)->erronous;
-}
-
-struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
-{
- return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
-}
-EXPORT_SYMBOL(cfpkt_info);
-
-void cfpkt_set_prio(struct cfpkt *pkt, int prio)
-{
- pkt_to_skb(pkt)->priority = prio;
-}
-EXPORT_SYMBOL(cfpkt_set_prio);
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
deleted file mode 100644
index 93732ebbd1e2..000000000000
--- a/net/caif/cfrfml.c
+++ /dev/null
@@ -1,299 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/stddef.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/unaligned.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 cfrfml, serv.layer)
-#define RFM_SEGMENTATION_BIT 0x01
-#define RFM_HEAD_SIZE 7
-
-static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt);
-static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt);
-
-struct cfrfml {
- struct cfsrvl serv;
- struct cfpkt *incomplete_frm;
- int fragment_size;
- u8 seghead[6];
- u16 pdu_size;
- /* Protects serialized processing of packets */
- spinlock_t sync;
-};
-
-static void cfrfml_release(struct cflayer *layer)
-{
- struct cfsrvl *srvl = container_of(layer, struct cfsrvl, layer);
- struct cfrfml *rfml = container_obj(&srvl->layer);
-
- if (rfml->incomplete_frm)
- cfpkt_destroy(rfml->incomplete_frm);
-
- kfree(srvl);
-}
-
-struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info,
- int mtu_size)
-{
- int tmp;
- struct cfrfml *this = kzalloc_obj(struct cfrfml, GFP_ATOMIC);
-
- if (!this)
- return NULL;
-
- cfsrvl_init(&this->serv, channel_id, dev_info, false);
- this->serv.release = cfrfml_release;
- this->serv.layer.receive = cfrfml_receive;
- this->serv.layer.transmit = cfrfml_transmit;
-
- /* Round down to closest multiple of 16 */
- tmp = (mtu_size - RFM_HEAD_SIZE - 6) / 16;
- tmp *= 16;
-
- this->fragment_size = tmp;
- spin_lock_init(&this->sync);
- snprintf(this->serv.layer.name, CAIF_LAYER_NAME_SZ,
- "rfm%d", channel_id);
-
- return &this->serv.layer;
-}
-
-static struct cfpkt *rfm_append(struct cfrfml *rfml, char *seghead,
- struct cfpkt *pkt, int *err)
-{
- struct cfpkt *tmppkt;
- *err = -EPROTO;
- /* n-th but not last segment */
-
- if (cfpkt_extr_head(pkt, seghead, 6) < 0)
- return NULL;
-
- /* Verify correct header */
- if (memcmp(seghead, rfml->seghead, 6) != 0)
- return NULL;
-
- tmppkt = cfpkt_append(rfml->incomplete_frm, pkt,
- rfml->pdu_size + RFM_HEAD_SIZE);
-
- /* If cfpkt_append failes input pkts are not freed */
- *err = -ENOMEM;
- if (tmppkt == NULL)
- return NULL;
-
- *err = 0;
- return tmppkt;
-}
-
-static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt)
-{
- u8 tmp;
- bool segmented;
- int err;
- u8 seghead[6];
- struct cfrfml *rfml;
- struct cfpkt *tmppkt = NULL;
-
- caif_assert(layr->up != NULL);
- caif_assert(layr->receive != NULL);
- rfml = container_obj(layr);
- spin_lock(&rfml->sync);
-
- err = -EPROTO;
- if (cfpkt_extr_head(pkt, &tmp, 1) < 0)
- goto out;
- segmented = tmp & RFM_SEGMENTATION_BIT;
-
- if (segmented) {
- if (rfml->incomplete_frm == NULL) {
- /* Initial Segment */
- if (cfpkt_peek_head(pkt, rfml->seghead, 6) != 0)
- goto out;
-
- rfml->pdu_size = get_unaligned_le16(rfml->seghead+4);
-
- if (cfpkt_erroneous(pkt))
- goto out;
- rfml->incomplete_frm = pkt;
- pkt = NULL;
- } else {
-
- tmppkt = rfm_append(rfml, seghead, pkt, &err);
- if (tmppkt == NULL)
- goto out;
-
- if (cfpkt_erroneous(tmppkt))
- goto out;
-
- rfml->incomplete_frm = tmppkt;
-
-
- if (cfpkt_erroneous(tmppkt))
- goto out;
- }
- err = 0;
- goto out;
- }
-
- if (rfml->incomplete_frm) {
-
- /* Last Segment */
- tmppkt = rfm_append(rfml, seghead, pkt, &err);
- if (tmppkt == NULL)
- goto out;
-
- if (cfpkt_erroneous(tmppkt))
- goto out;
-
- rfml->incomplete_frm = NULL;
- pkt = tmppkt;
- tmppkt = NULL;
-
- /* Verify that length is correct */
- err = -EPROTO;
- if (rfml->pdu_size != cfpkt_getlen(pkt) - RFM_HEAD_SIZE + 1)
- goto out;
- }
-
- err = rfml->serv.layer.up->receive(rfml->serv.layer.up, pkt);
-
-out:
-
- if (err != 0) {
- if (tmppkt)
- cfpkt_destroy(tmppkt);
- if (pkt)
- cfpkt_destroy(pkt);
- if (rfml->incomplete_frm)
- cfpkt_destroy(rfml->incomplete_frm);
- rfml->incomplete_frm = NULL;
-
- pr_info("Connection error %d triggered on RFM link\n", err);
-
- /* Trigger connection error upon failure.*/
- layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
- rfml->serv.dev_info.id);
- }
- spin_unlock(&rfml->sync);
-
- if (unlikely(err == -EAGAIN))
- /* It is not possible to recover after drop of a fragment */
- err = -EIO;
-
- return err;
-}
-
-
-static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt)
-{
- caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size + RFM_HEAD_SIZE);
-
- /* Add info for MUX-layer to route the packet out. */
- cfpkt_info(pkt)->channel_id = rfml->serv.layer.id;
-
- /*
- * To optimize alignment, we add up the size of CAIF header before
- * payload.
- */
- cfpkt_info(pkt)->hdr_len = RFM_HEAD_SIZE;
- cfpkt_info(pkt)->dev_info = &rfml->serv.dev_info;
-
- return rfml->serv.layer.dn->transmit(rfml->serv.layer.dn, pkt);
-}
-
-static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
-{
- int err;
- u8 seg;
- u8 head[6];
- struct cfpkt *rearpkt = NULL;
- struct cfpkt *frontpkt = pkt;
- struct cfrfml *rfml = container_obj(layr);
-
- caif_assert(layr->dn != NULL);
- caif_assert(layr->dn->transmit != NULL);
-
- if (!cfsrvl_ready(&rfml->serv, &err))
- goto out;
-
- err = -EPROTO;
- if (cfpkt_getlen(pkt) <= RFM_HEAD_SIZE-1)
- goto out;
-
- err = 0;
- if (cfpkt_getlen(pkt) > rfml->fragment_size + RFM_HEAD_SIZE)
- err = cfpkt_peek_head(pkt, head, 6);
-
- if (err != 0)
- goto out;
-
- while (cfpkt_getlen(frontpkt) > rfml->fragment_size + RFM_HEAD_SIZE) {
-
- seg = 1;
- err = -EPROTO;
-
- if (cfpkt_add_head(frontpkt, &seg, 1) < 0)
- goto out;
- /*
- * On OOM error cfpkt_split returns NULL.
- *
- * NOTE: Segmented pdu is not correctly aligned.
- * This has negative performance impact.
- */
-
- rearpkt = cfpkt_split(frontpkt, rfml->fragment_size);
- if (rearpkt == NULL)
- goto out;
-
- err = cfrfml_transmit_segment(rfml, frontpkt);
-
- if (err != 0) {
- frontpkt = NULL;
- goto out;
- }
-
- frontpkt = rearpkt;
- rearpkt = NULL;
-
- err = -EPROTO;
- if (cfpkt_add_head(frontpkt, head, 6) < 0)
- goto out;
-
- }
-
- seg = 0;
- err = -EPROTO;
-
- if (cfpkt_add_head(frontpkt, &seg, 1) < 0)
- goto out;
-
- err = cfrfml_transmit_segment(rfml, frontpkt);
-
- frontpkt = NULL;
-out:
-
- if (err != 0) {
- pr_info("Connection error %d triggered on RFM link\n", err);
- /* Trigger connection error upon failure.*/
-
- layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
- rfml->serv.dev_info.id);
-
- if (rearpkt)
- cfpkt_destroy(rearpkt);
-
- if (frontpkt)
- cfpkt_destroy(frontpkt);
- }
-
- return err;
-}
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
deleted file mode 100644
index faf78fb754e2..000000000000
--- a/net/caif/cfserl.c
+++ /dev/null
@@ -1,192 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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/cfserl.h>
-
-#define container_obj(layr) ((struct cfserl *) layr)
-
-#define CFSERL_STX 0x02
-#define SERIAL_MINIUM_PACKET_SIZE 4
-#define SERIAL_MAX_FRAMESIZE 4096
-struct cfserl {
- struct cflayer layer;
- struct cfpkt *incomplete_frm;
- /* Protects parallel processing of incoming packets */
- spinlock_t sync;
- bool usestx;
-};
-
-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);
-
-void cfserl_release(struct cflayer *layer)
-{
- kfree(layer);
-}
-
-struct cflayer *cfserl_create(int instance, bool use_stx)
-{
- struct cfserl *this = kzalloc_obj(struct cfserl, GFP_ATOMIC);
- if (!this)
- return NULL;
- caif_assert(offsetof(struct cfserl, layer) == 0);
- this->layer.receive = cfserl_receive;
- this->layer.transmit = cfserl_transmit;
- this->layer.ctrlcmd = cfserl_ctrlcmd;
- this->usestx = use_stx;
- spin_lock_init(&this->sync);
- snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "ser1");
- return &this->layer;
-}
-
-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;
- if (pkt == NULL) {
- spin_unlock(&layr->sync);
- return -ENOMEM;
- }
- } 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 < SERIAL_MINIUM_PACKET_SIZE
- || expectlen > SERIAL_MAX_FRAMESIZE) {
- if (!layr->usestx) {
- if (pkt != NULL)
- cfpkt_destroy(pkt);
- layr->incomplete_frm = NULL;
- 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);
- u8 tmp8 = CFSERL_STX;
- if (layr->usestx)
- cfpkt_add_head(newpkt, &tmp8, 1);
- return layer->dn->transmit(layer->dn, newpkt);
-}
-
-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
deleted file mode 100644
index d687fd0b4ed3..000000000000
--- a/net/caif/cfsrvl.c
+++ /dev/null
@@ -1,224 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/pkt_sched.h>
-#include <net/caif/caif_layer.h>
-#include <net/caif/cfsrvl.h>
-#include <net/caif/cfpkt.h>
-#include <net/caif/caif_dev.h>
-
-#define SRVL_CTRL_PKT_SIZE 1
-#define SRVL_FLOW_OFF 0x81
-#define SRVL_FLOW_ON 0x80
-#define SRVL_SET_PIN 0x82
-
-#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);
-
- if (layr->up == NULL || layr->up->ctrlcmd == NULL)
- return;
-
- 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_warn("Unexpected ctrl in cfsrvl (%d)\n", 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);
-
- if (!service->supports_flowctrl)
- return 0;
-
- 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)
- return -ENOMEM;
-
- if (cfpkt_add_head(pkt, &flow_on, 1) < 0) {
- pr_err("Packet is erroneous!\n");
- 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;
- cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
- 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 (!pkt)
- return -ENOMEM;
-
- if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
- pr_err("Packet is erroneous!\n");
- 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;
- cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
- return layr->dn->transmit(layr->dn, pkt);
- }
- default:
- break;
- }
- return -EINVAL;
-}
-
-static void cfsrvl_release(struct cflayer *layer)
-{
- struct cfsrvl *service = container_of(layer, struct cfsrvl, layer);
- kfree(service);
-}
-
-void cfsrvl_init(struct cfsrvl *service,
- u8 channel_id,
- struct dev_info *dev_info,
- bool supports_flowctrl)
-{
- 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;
- service->supports_flowctrl = supports_flowctrl;
- service->release = cfsrvl_release;
-}
-
-bool cfsrvl_ready(struct cfsrvl *service, int *err)
-{
- if (!service->open) {
- *err = -ENOTCONN;
- return false;
- }
- return true;
-}
-
-bool cfsrvl_phyid_match(struct cflayer *layer, int phyid)
-{
- struct cfsrvl *servl = container_obj(layer);
- return servl->dev_info.id == phyid;
-}
-
-void caif_free_client(struct cflayer *adap_layer)
-{
- struct cflayer *serv_layer;
- struct cfsrvl *servl;
-
- if (!adap_layer)
- return;
-
- serv_layer = adap_layer->dn;
- if (!serv_layer)
- return;
-
- layer_set_dn(adap_layer, NULL);
- layer_set_up(serv_layer, NULL);
-
- servl = container_obj(serv_layer);
- servl->release(&servl->layer);
-}
-EXPORT_SYMBOL(caif_free_client);
-
-void caif_client_register_refcnt(struct cflayer *adapt_layer,
- void (*hold)(struct cflayer *lyr),
- void (*put)(struct cflayer *lyr))
-{
- struct cfsrvl *service;
-
- if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL))
- return;
- service = container_of(adapt_layer->dn, struct cfsrvl, layer);
- service->hold = hold;
- service->put = put;
-}
-EXPORT_SYMBOL(caif_client_register_refcnt);
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
deleted file mode 100644
index 5111090bb2c0..000000000000
--- a/net/caif/cfutill.c
+++ /dev/null
@@ -1,104 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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
-
-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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
- if (!util)
- return NULL;
- caif_assert(offsetof(struct cfsrvl, layer) == 0);
- cfsrvl_init(util, channel_id, dev_info, true);
- util->layer.receive = cfutill_receive;
- util->layer.transmit = cfutill_transmit;
- snprintf(util->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
- 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("REMOTE SHUTDOWN REQUEST RECEIVED\n");
- layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0);
- service->open = false;
- cfpkt_destroy(pkt);
- return 0;
- default:
- cfpkt_destroy(pkt);
- pr_warn("Unknown service control %d (0x%x)\n", 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)) {
- cfpkt_destroy(pkt);
- return ret;
- }
-
- 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;
- return layr->dn->transmit(layr->dn, pkt);
-}
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
deleted file mode 100644
index 53f844c49bbb..000000000000
--- a/net/caif/cfveil.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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 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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
- if (!vei)
- return NULL;
- caif_assert(offsetof(struct cfsrvl, layer) == 0);
- cfsrvl_init(vei, channel_id, dev_info, true);
- vei->layer.receive = cfvei_receive;
- vei->layer.transmit = cfvei_transmit;
- snprintf(vei->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
- 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_warn("Unknown VEI control packet %d (0x%x)!\n", 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))
- goto err;
- caif_assert(layr->dn != NULL);
- caif_assert(layr->dn->transmit != NULL);
-
- if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
- pr_err("Packet is erroneous!\n");
- ret = -EPROTO;
- goto err;
- }
-
- /* 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;
- return layr->dn->transmit(layr->dn, pkt);
-err:
- cfpkt_destroy(pkt);
- return ret;
-}
diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
deleted file mode 100644
index 39e075b0a259..000000000000
--- a/net/caif/cfvidl.c
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author: Sjur Brendeland
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
- if (!vid)
- return NULL;
- caif_assert(offsetof(struct cfsrvl, layer) == 0);
-
- cfsrvl_init(vid, channel_id, dev_info, false);
- vid->layer.receive = cfvidl_receive;
- vid->layer.transmit = cfvidl_transmit;
- snprintf(vid->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
- 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)) {
- cfpkt_destroy(pkt);
- 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;
- return layr->dn->transmit(layr->dn, pkt);
-}
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
deleted file mode 100644
index fa6a3c2634a8..000000000000
--- a/net/caif/chnl_net.c
+++ /dev/null
@@ -1,531 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Authors: Sjur Brendeland
- * Daniel Martensson
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
-
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.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/cfpkt.h>
-#include <net/caif/caif_dev.h>
-
-/* GPRS PDP connection has MTU to 1500 */
-#define GPRS_PDP_MTU 1500
-/* 5 sec. connect timeout */
-#define CONNECT_TIMEOUT (5 * HZ)
-#define CAIF_NET_DEFAULT_QUEUE_LEN 500
-#define UNDEF_CONNID 0xffffffff
-
-/*This list is protected by the rtnl lock. */
-static LIST_HEAD(chnl_net_list);
-
-MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol GPRS network device");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_RTNL_LINK("caif");
-
-enum caif_states {
- CAIF_CONNECTED = 1,
- CAIF_CONNECTING,
- CAIF_DISCONNECTED,
- CAIF_SHUTDOWN
-};
-
-struct chnl_net {
- struct cflayer chnl;
- struct caif_connect_request conn_req;
- struct list_head list_field;
- struct net_device *netdev;
- wait_queue_head_t netmgmt_wq;
- /* Flow status to remember and control the transmission. */
- bool flowenabled;
- enum caif_states state;
-};
-
-static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
-{
- struct sk_buff *skb;
- struct chnl_net *priv;
- int pktlen;
- const u8 *ip_version;
- u8 buf;
-
- priv = container_of(layr, struct chnl_net, chnl);
-
- skb = (struct sk_buff *) cfpkt_tonative(pkt);
-
- /* Get length of CAIF packet. */
- pktlen = skb->len;
-
- /* Pass some minimum information and
- * send the packet to the net stack.
- */
- skb->dev = priv->netdev;
-
- /* check the version of IP */
- ip_version = skb_header_pointer(skb, 0, 1, &buf);
- if (!ip_version) {
- kfree_skb(skb);
- return -EINVAL;
- }
-
- switch (*ip_version >> 4) {
- case 4:
- skb->protocol = htons(ETH_P_IP);
- break;
- case 6:
- skb->protocol = htons(ETH_P_IPV6);
- break;
- default:
- kfree_skb(skb);
- priv->netdev->stats.rx_errors++;
- return -EINVAL;
- }
-
- /* If we change the header in loop mode, the checksum is corrupted. */
- if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
-
- netif_rx(skb);
-
- /* Update statistics. */
- priv->netdev->stats.rx_packets++;
- priv->netdev->stats.rx_bytes += pktlen;
-
- return 0;
-}
-
-static int delete_device(struct chnl_net *dev)
-{
- ASSERT_RTNL();
- if (dev->netdev)
- unregister_netdevice(dev->netdev);
- return 0;
-}
-
-static void close_work(struct work_struct *work)
-{
- struct chnl_net *dev = NULL;
- struct list_head *list_node;
- struct list_head *_tmp;
-
- rtnl_lock();
- list_for_each_safe(list_node, _tmp, &chnl_net_list) {
- dev = list_entry(list_node, struct chnl_net, list_field);
- if (dev->state == CAIF_SHUTDOWN)
- dev_close(dev->netdev);
- }
- rtnl_unlock();
-}
-static DECLARE_WORK(close_worker, close_work);
-
-static void chnl_hold(struct cflayer *lyr)
-{
- struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
- dev_hold(priv->netdev);
-}
-
-static void chnl_put(struct cflayer *lyr)
-{
- struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
- dev_put(priv->netdev);
-}
-
-static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
- int phyid)
-{
- struct chnl_net *priv = container_of(layr, struct chnl_net, chnl);
- pr_debug("NET flowctrl func called flow: %s\n",
- 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" : "UNKNOWN CTRL COMMAND");
-
-
-
- switch (flow) {
- case CAIF_CTRLCMD_FLOW_OFF_IND:
- priv->flowenabled = false;
- netif_stop_queue(priv->netdev);
- break;
- case CAIF_CTRLCMD_DEINIT_RSP:
- priv->state = CAIF_DISCONNECTED;
- break;
- case CAIF_CTRLCMD_INIT_FAIL_RSP:
- priv->state = CAIF_DISCONNECTED;
- wake_up_interruptible(&priv->netmgmt_wq);
- break;
- case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
- priv->state = CAIF_SHUTDOWN;
- netif_tx_disable(priv->netdev);
- schedule_work(&close_worker);
- break;
- case CAIF_CTRLCMD_FLOW_ON_IND:
- priv->flowenabled = true;
- netif_wake_queue(priv->netdev);
- break;
- case CAIF_CTRLCMD_INIT_RSP:
- caif_client_register_refcnt(&priv->chnl, chnl_hold, chnl_put);
- priv->state = CAIF_CONNECTED;
- priv->flowenabled = true;
- netif_wake_queue(priv->netdev);
- wake_up_interruptible(&priv->netmgmt_wq);
- break;
- default:
- break;
- }
-}
-
-static netdev_tx_t 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_warn("Size of skb exceeded MTU\n");
- kfree_skb(skb);
- dev->stats.tx_errors++;
- return NETDEV_TX_OK;
- }
-
- if (!priv->flowenabled) {
- pr_debug("dropping packets flow off\n");
- kfree_skb(skb);
- dev->stats.tx_dropped++;
- return NETDEV_TX_OK;
- }
-
- 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) {
- dev->stats.tx_dropped++;
- return NETDEV_TX_OK;
- }
-
- /* 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;
- int llifindex, headroom, tailroom, mtu;
- struct net_device *lldev;
- ASSERT_RTNL();
- priv = netdev_priv(dev);
- if (!priv) {
- pr_debug("chnl_net_open: no priv\n");
- return -ENODEV;
- }
-
- if (priv->state != CAIF_CONNECTING) {
- priv->state = CAIF_CONNECTING;
- result = caif_connect_client(dev_net(dev), &priv->conn_req,
- &priv->chnl, &llifindex,
- &headroom, &tailroom);
- if (result != 0) {
- pr_debug("err: "
- "Unable to register and open device,"
- " Err:%d\n",
- result);
- goto error;
- }
-
- lldev = __dev_get_by_index(dev_net(dev), llifindex);
-
- if (lldev == NULL) {
- pr_debug("no interface?\n");
- result = -ENODEV;
- goto error;
- }
-
- dev->needed_tailroom = tailroom + lldev->needed_tailroom;
- dev->hard_header_len = headroom + lldev->hard_header_len +
- lldev->needed_tailroom;
-
- /*
- * MTU, head-room etc is not know before we have a
- * CAIF link layer device available. MTU calculation may
- * override initial RTNL configuration.
- * MTU is minimum of current mtu, link layer mtu pluss
- * CAIF head and tail, and PDP GPRS contexts max MTU.
- */
- mtu = min_t(int, dev->mtu, lldev->mtu - (headroom + tailroom));
- mtu = min_t(int, GPRS_PDP_MTU, mtu);
- dev_set_mtu(dev, mtu);
-
- if (mtu < 100) {
- pr_warn("CAIF Interface MTU too small (%d)\n", mtu);
- result = -ENODEV;
- goto error;
- }
- }
-
- rtnl_unlock(); /* Release RTNL lock during connect wait */
-
- result = wait_event_interruptible_timeout(priv->netmgmt_wq,
- priv->state != CAIF_CONNECTING,
- CONNECT_TIMEOUT);
-
- rtnl_lock();
-
- if (result == -ERESTARTSYS) {
- pr_debug("wait_event_interruptible woken by a signal\n");
- result = -ERESTARTSYS;
- goto error;
- }
-
- if (result == 0) {
- pr_debug("connect timeout\n");
- result = -ETIMEDOUT;
- goto error;
- }
-
- if (priv->state != CAIF_CONNECTED) {
- pr_debug("connect failed\n");
- result = -ECONNREFUSED;
- goto error;
- }
- pr_debug("CAIF Netdevice connected\n");
- return 0;
-
-error:
- caif_disconnect_client(dev_net(dev), &priv->chnl);
- priv->state = CAIF_DISCONNECTED;
- pr_debug("state disconnected\n");
- return result;
-
-}
-
-static int chnl_net_stop(struct net_device *dev)
-{
- struct chnl_net *priv;
-
- ASSERT_RTNL();
- priv = netdev_priv(dev);
- priv->state = CAIF_DISCONNECTED;
- caif_disconnect_client(dev_net(dev), &priv->chnl);
- return 0;
-}
-
-static int chnl_net_init(struct net_device *dev)
-{
- struct chnl_net *priv;
- ASSERT_RTNL();
- priv = netdev_priv(dev);
- INIT_LIST_HEAD(&priv->list_field);
- return 0;
-}
-
-static void chnl_net_uninit(struct net_device *dev)
-{
- struct chnl_net *priv;
- ASSERT_RTNL();
- priv = netdev_priv(dev);
- list_del_init(&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 chnl_net_destructor(struct net_device *dev)
-{
- struct chnl_net *priv = netdev_priv(dev);
- caif_free_client(&priv->chnl);
-}
-
-static void ipcaif_net_setup(struct net_device *dev)
-{
- struct chnl_net *priv;
- dev->netdev_ops = &netdev_ops;
- dev->needs_free_netdev = true;
- dev->priv_destructor = chnl_net_destructor;
- dev->flags |= IFF_NOARP;
- dev->flags |= IFF_POINTOPOINT;
- dev->mtu = GPRS_PDP_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 = UNDEF_CONNID;
- priv->flowenabled = false;
-
- init_waitqueue_head(&priv->netmgmt_wq);
-}
-
-
-static int ipcaif_fill_info(struct sk_buff *skb, const struct net_device *dev)
-{
- struct chnl_net *priv;
- u8 loop;
- priv = netdev_priv(dev);
- if (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))
- goto nla_put_failure;
- loop = priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP;
- if (nla_put_u8(skb, IFLA_CAIF_LOOPBACK, loop))
- goto nla_put_failure;
- return 0;
-nla_put_failure:
- return -EMSGSIZE;
-
-}
-
-static void caif_netlink_parms(struct nlattr *data[],
- struct caif_connect_request *conn_req)
-{
- if (!data) {
- pr_warn("no params data found\n");
- 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_device *dev,
- struct rtnl_newlink_params *params,
- struct netlink_ext_ack *extack)
-{
- struct nlattr **data = params->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_warn("device rtml registration failed\n");
- else
- list_add(&caifdev->list_field, &chnl_net_list);
-
- /* Use ifindex as connection id, and use loopback channel default. */
- if (caifdev->conn_req.sockaddr.u.dgm.connection_id == UNDEF_CONNID) {
- caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex;
- caifdev->conn_req.protocol = CAIFPROTO_DATAGRAM_LOOP;
- }
- return ret;
-}
-
-static int ipcaif_changelink(struct net_device *dev, struct nlattr *tb[],
- struct nlattr *data[],
- struct netlink_ext_ack *extack)
-{
- 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_init(list_node);
- delete_device(dev);
- }
- rtnl_unlock();
-}
-
-module_init(chnl_init_module);
-module_exit(chnl_exit_module);
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index e88533b78327..de4af7c750ca 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -37,7 +37,6 @@ CONFIG_CFG80211=y
CONFIG_CFG80211_DEBUGFS=y
CONFIG_MAC80211=y
CONFIG_MAC80211_LEDS=y
-CONFIG_CAIF=y
CONFIG_NFC=m
CONFIG_NFC_HCI=m
CONFIG_NFC_SHDLC=y
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-deletions] caif: remove CAIF NETWORK LAYER
2026-04-16 18:28 [PATCH net-deletions] caif: remove CAIF NETWORK LAYER Jakub Kicinski
@ 2026-04-17 9:06 ` Michael S. Tsirkin
2026-04-18 8:48 ` Greg KH
1 sibling, 0 replies; 3+ messages in thread
From: Michael S. Tsirkin @ 2026-04-17 9:06 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, alexs, si.yanteng, dzm91, linux, jasowang, xuanzhuo,
eperezma, xu.xin16, wang.yaxin, jiang.kun2, linusw,
jihed.chaibi.dev, arnd, tytso, jiayuan.chen, gregkh
On Thu, Apr 16, 2026 at 11:28:28AM -0700, Jakub Kicinski wrote:
> Remove CAIF (Communication CPU to Application CPU Interface), the
> ST-Ericsson modem protocol. The subsystem has been orphaned since 2013.
> The last meaningful changes from the maintainers were in March 2013:
> a8c7687bf216 ("caif_virtio: Check that vringh_config is not null")
> b2273be8d2df ("caif_virtio: Use vringh_notify_enable correctly")
> 0d2e1a2926b1 ("caif_virtio: Introduce caif over virtio")
>
> Not-so-coincidentally, according to "the Internet" ST-Ericsson officially
> shut down its modem joint venture in Aug 2013.
>
> If anyone is using this code please yell!
>
> In the 13 years since, the code has accumulated 200 non-merge commits,
> of which 71 were cross-tree API changes, 21 carried Fixes: tags, and
> the remaining ~110 were cleanups, doc conversions, treewide refactors,
> and one partial removal (caif_hsi, ca75bcf0a83b).
>
> We are still getting fixes to this code, in the last 10 days there were
> 3 reports on security@ about CAIF that I have been CCed on.
>
> UAPI constants (AF_CAIF, ARPHRD_CAIF, N_CAIF, VIRTIO_ID_CAIF) and the
> SELinux classmap entry are intentionally kept for ABI stability.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The device was never specced out.
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> I think we should accumulate such patches over the coming days on a separate
> branch. CAIF is a no-brainer IMO but other removals may be more controversial.
>
> CC: corbet@lwn.net
> CC: skhan@linuxfoundation.org
> CC: alexs@kernel.org
> CC: si.yanteng@linux.dev
> CC: dzm91@hust.edu.cn
> CC: linux@armlinux.org.uk
> CC: mst@redhat.com
> CC: jasowang@redhat.com
> CC: xuanzhuo@linux.alibaba.com
> CC: eperezma@redhat.com
> CC: xu.xin16@zte.com.cn
> CC: wang.yaxin@zte.com.cn
> CC: jiang.kun2@zte.com.cn
> CC: linusw@kernel.org
> CC: jihed.chaibi.dev@gmail.com
> CC: arnd@arndb.de
> CC: tytso@mit.edu
> CC: jiayuan.chen@shopee.com
> CC: gregkh@linuxfoundation.org
> ---
> MAINTAINERS | 9 -
> Documentation/networking/caif/caif.rst | 138 --
> Documentation/networking/caif/index.rst | 12 -
> Documentation/networking/caif/linux_caif.rst | 195 ---
> Documentation/networking/index.rst | 1 -
> .../translations/zh_CN/networking/index.rst | 1 -
> drivers/net/Kconfig | 2 -
> drivers/net/caif/Kconfig | 33 -
> net/Kconfig | 1 -
> net/caif/Kconfig | 54 -
> drivers/net/Makefile | 1 -
> drivers/net/caif/Makefile | 8 -
> net/Makefile | 1 -
> net/caif/Makefile | 16 -
> include/linux/virtio_caif.h | 24 -
> include/net/caif/caif_dev.h | 128 --
> include/net/caif/caif_device.h | 55 -
> include/net/caif/caif_layer.h | 277 ----
> include/net/caif/cfcnfg.h | 90 --
> include/net/caif/cfctrl.h | 130 --
> include/net/caif/cffrml.h | 21 -
> include/net/caif/cfmuxl.h | 20 -
> include/net/caif/cfpkt.h | 232 ----
> include/net/caif/cfserl.h | 13 -
> include/net/caif/cfsrvl.h | 61 -
> include/uapi/linux/caif/caif_socket.h | 195 ---
> include/uapi/linux/caif/if_caif.h | 35 -
> drivers/net/caif/caif_serial.c | 443 -------
> drivers/net/caif/caif_virtio.c | 791 ------------
> net/caif/caif_dev.c | 586 ---------
> net/caif/caif_socket.c | 1114 -----------------
> net/caif/caif_usb.c | 216 ----
> net/caif/cfcnfg.c | 612 ---------
> net/caif/cfctrl.c | 631 ----------
> net/caif/cfdbgl.c | 55 -
> net/caif/cfdgml.c | 113 --
> net/caif/cffrml.c | 204 ---
> net/caif/cfmuxl.c | 267 ----
> net/caif/cfpkt_skbuff.c | 373 ------
> net/caif/cfrfml.c | 299 -----
> net/caif/cfserl.c | 192 ---
> net/caif/cfsrvl.c | 224 ----
> net/caif/cfutill.c | 104 --
> net/caif/cfveil.c | 101 --
> net/caif/cfvidl.c | 65 -
> net/caif/chnl_net.c | 531 --------
> arch/arm/configs/u8500_defconfig | 1 -
> 47 files changed, 8675 deletions(-)
> delete mode 100644 Documentation/networking/caif/caif.rst
> delete mode 100644 Documentation/networking/caif/index.rst
> delete mode 100644 Documentation/networking/caif/linux_caif.rst
> delete mode 100644 drivers/net/caif/Kconfig
> delete mode 100644 net/caif/Kconfig
> delete mode 100644 drivers/net/caif/Makefile
> delete mode 100644 net/caif/Makefile
> delete mode 100644 include/linux/virtio_caif.h
> delete mode 100644 include/net/caif/caif_dev.h
> delete mode 100644 include/net/caif/caif_device.h
> delete mode 100644 include/net/caif/caif_layer.h
> delete mode 100644 include/net/caif/cfcnfg.h
> delete mode 100644 include/net/caif/cfctrl.h
> delete mode 100644 include/net/caif/cffrml.h
> delete mode 100644 include/net/caif/cfmuxl.h
> delete mode 100644 include/net/caif/cfpkt.h
> delete mode 100644 include/net/caif/cfserl.h
> delete mode 100644 include/net/caif/cfsrvl.h
> delete mode 100644 include/uapi/linux/caif/caif_socket.h
> delete mode 100644 include/uapi/linux/caif/if_caif.h
> delete mode 100644 drivers/net/caif/caif_serial.c
> delete mode 100644 drivers/net/caif/caif_virtio.c
> delete mode 100644 net/caif/caif_dev.c
> delete mode 100644 net/caif/caif_socket.c
> delete mode 100644 net/caif/caif_usb.c
> delete mode 100644 net/caif/cfcnfg.c
> delete mode 100644 net/caif/cfctrl.c
> delete mode 100644 net/caif/cfdbgl.c
> delete mode 100644 net/caif/cfdgml.c
> delete mode 100644 net/caif/cffrml.c
> delete mode 100644 net/caif/cfmuxl.c
> delete mode 100644 net/caif/cfpkt_skbuff.c
> delete mode 100644 net/caif/cfrfml.c
> delete mode 100644 net/caif/cfserl.c
> delete mode 100644 net/caif/cfsrvl.c
> delete mode 100644 net/caif/cfutill.c
> delete mode 100644 net/caif/cfveil.c
> delete mode 100644 net/caif/cfvidl.c
> delete mode 100644 net/caif/chnl_net.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e7dc9e6fad2e..2b1b5e93c272 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5674,15 +5674,6 @@ T: git git://linuxtv.org/media.git
> F: Documentation/admin-guide/media/cafe_ccic*
> F: drivers/media/platform/marvell/
>
> -CAIF NETWORK LAYER
> -L: netdev@vger.kernel.org
> -S: Orphan
> -F: Documentation/networking/caif/
> -F: drivers/net/caif/
> -F: include/net/caif/
> -F: include/uapi/linux/caif/
> -F: net/caif/
> -
> CAKE QDISC
> M: Toke Høiland-Jørgensen <toke@toke.dk>
> L: cake@lists.bufferbloat.net (moderated for non-subscribers)
> diff --git a/Documentation/networking/caif/caif.rst b/Documentation/networking/caif/caif.rst
> deleted file mode 100644
> index d922d419c513..000000000000
> --- a/Documentation/networking/caif/caif.rst
> +++ /dev/null
> @@ -1,138 +0,0 @@
> -.. SPDX-License-Identifier: GPL-2.0
> -.. include:: <isonum.txt>
> -
> -
> -================
> -Using Linux CAIF
> -================
> -
> -
> -:Copyright: |copy| ST-Ericsson AB 2010
> -
> -:Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
> -
> -Start
> -=====
> -
> -If you have compiled CAIF for modules do::
> -
> - $modprobe crc_ccitt
> - $modprobe caif
> - $modprobe caif_socket
> - $modprobe chnl_net
> -
> -
> -Preparing the setup with a STE modem
> -====================================
> -
> -If you are working on integration of CAIF you should make sure
> -that the kernel is built with module support.
> -
> -There are some things that need to be tweaked to get the host TTY correctly
> -set up to talk to the modem.
> -Since the CAIF stack is running in the kernel and we want to use the existing
> -TTY, we are installing our physical serial driver as a line discipline above
> -the TTY device.
> -
> -To achieve this we need to install the N_CAIF ldisc from user space.
> -The benefit is that we can hook up to any TTY.
> -
> -The use of Start-of-frame-extension (STX) must also be set as
> -module parameter "ser_use_stx".
> -
> -Normally Frame Checksum is always used on UART, but this is also provided as a
> -module parameter "ser_use_fcs".
> -
> -::
> -
> - $ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
> - $ ifconfig caif_ttyS0 up
> -
> -PLEASE NOTE:
> - There is a limitation in Android shell.
> - It only accepts one argument to insmod/modprobe!
> -
> -Trouble shooting
> -================
> -
> -There are debugfs parameters provided for serial communication.
> -/sys/kernel/debug/caif_serial/<tty-name>/
> -
> -* ser_state: Prints the bit-mask status where
> -
> - - 0x02 means SENDING, this is a transient state.
> - - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
> - and is blocking further send operation. Flow OFF has been propagated
> - to all CAIF Channels using this TTY.
> -
> -* tty_status: Prints the bit-mask tty status information
> -
> - - 0x01 - tty->warned is on.
> - - 0x04 - tty->packed is on.
> - - 0x08 - tty->flow.tco_stopped is on.
> - - 0x10 - tty->hw_stopped is on.
> - - 0x20 - tty->flow.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.
> diff --git a/Documentation/networking/caif/index.rst b/Documentation/networking/caif/index.rst
> deleted file mode 100644
> index ec29b6f4bdb4..000000000000
> --- a/Documentation/networking/caif/index.rst
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -.. SPDX-License-Identifier: GPL-2.0
> -
> -CAIF
> -====
> -
> -Contents:
> -
> -.. toctree::
> - :maxdepth: 2
> -
> - linux_caif
> - caif
> diff --git a/Documentation/networking/caif/linux_caif.rst b/Documentation/networking/caif/linux_caif.rst
> deleted file mode 100644
> index a0480862ab8c..000000000000
> --- a/Documentation/networking/caif/linux_caif.rst
> +++ /dev/null
> @@ -1,195 +0,0 @@
> -.. SPDX-License-Identifier: GPL-2.0
> -.. include:: <isonum.txt>
> -
> -==========
> -Linux CAIF
> -==========
> -
> -Copyright |copy| 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 and GPRS IP Interface.
> -* CAIF Core Protocol Implementation
> -* CAIF Link Layer, implemented as NET devices.
> -
> -::
> -
> - RTNL
> - !
> - ! +------+ +------+
> - ! +------+! +------+!
> - ! ! IP !! !Socket!!
> - +-------> !interf!+ ! API !+ <- CAIF Client APIs
> - ! +------+ +------!
> - ! ! !
> - ! +-----------+
> - ! !
> - ! +------+ <- CAIF Core Protocol
> - ! ! CAIF !
> - ! ! Core !
> - ! +------+
> - ! +----------!---------+
> - ! ! ! !
> - ! +------+ +-----+ +------+
> - +--> ! HSI ! ! TTY ! ! USB ! <- Link Layer (Net Devices)
> - +------+ +-----+ +------+
> -
> -
> -
> -Implementation
> -==============
> -
> -
> -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 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 function)
> -
> -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.
> -
> -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 appropriate 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);
> -
> -
> -CAIF Socket and IP interface
> -============================
> -
> -The IP interface and CAIF socket API are implemented on top of the
> -CAIF Core protocol. The IP Interface 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.
> -
> -Configuration of Link Layer
> ----------------------------
> -The Link Layer is implemented as Linux network 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/index.rst b/Documentation/networking/index.rst
> index c2406bd8ae0b..2e946924ad3f 100644
> --- a/Documentation/networking/index.rst
> +++ b/Documentation/networking/index.rst
> @@ -17,7 +17,6 @@ Refer to :ref:`netdev-FAQ` for a guide on netdev development process specifics.
> diagnostic/index
> dsa/index
> devlink/index
> - caif/index
> ethtool-netlink
> ieee802154
> iso15765-2
> diff --git a/Documentation/translations/zh_CN/networking/index.rst b/Documentation/translations/zh_CN/networking/index.rst
> index c276c0993c51..333e9f6cafff 100644
> --- a/Documentation/translations/zh_CN/networking/index.rst
> +++ b/Documentation/translations/zh_CN/networking/index.rst
> @@ -42,7 +42,6 @@ 目录:
> * diagnostic/index
> * dsa/index
> * devlink/index
> -* caif/index
> * ethtool-netlink
> * ieee802154
> * iso15765-2
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index edaab759dc50..8ec98f6dfef9 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -503,8 +503,6 @@ source "drivers/net/arcnet/Kconfig"
>
> source "drivers/atm/Kconfig"
>
> -source "drivers/net/caif/Kconfig"
> -
> source "drivers/net/dsa/Kconfig"
>
> source "drivers/net/ethernet/Kconfig"
> diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
> deleted file mode 100644
> index 709660cb38f8..000000000000
> --- a/drivers/net/caif/Kconfig
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# CAIF physical drivers
> -#
> -
> -menuconfig CAIF_DRIVERS
> - bool "CAIF transport drivers"
> - depends on CAIF
> - help
> - Enable this to see CAIF physical drivers.
> -
> -if CAIF_DRIVERS
> -
> -config CAIF_TTY
> - tristate "CAIF TTY transport driver"
> - depends on CAIF && TTY
> - default n
> - help
> - The CAIF TTY transport driver is a Line Discipline (ldisc)
> - identified as N_CAIF. When this ldisc is opened from user space
> - it will redirect the TTY's traffic into the CAIF stack.
> -
> -config CAIF_VIRTIO
> - tristate "CAIF virtio transport driver"
> - depends on CAIF && HAS_DMA
> - select VHOST_RING
> - select VIRTIO
> - select GENERIC_ALLOCATOR
> - default n
> - help
> - The CAIF driver for CAIF over Virtio.
> -
> -endif # CAIF_DRIVERS
> diff --git a/net/Kconfig b/net/Kconfig
> index 62266eaf0e95..5c588dbcbdbd 100644
> --- a/net/Kconfig
> +++ b/net/Kconfig
> @@ -439,7 +439,6 @@ endif # WIRELESS
>
> source "net/rfkill/Kconfig"
> source "net/9p/Kconfig"
> -source "net/caif/Kconfig"
> source "net/ceph/Kconfig"
> source "net/nfc/Kconfig"
> source "net/psample/Kconfig"
> diff --git a/net/caif/Kconfig b/net/caif/Kconfig
> deleted file mode 100644
> index 87205251cc25..000000000000
> --- a/net/caif/Kconfig
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# CAIF net configurations
> -#
> -
> -menuconfig CAIF
> - tristate "CAIF support"
> - select CRC_CCITT
> - default n
> - help
> - The "Communication CPU to Application CPU Interface" (CAIF) is a packet
> - based connection-oriented MUX protocol developed by ST-Ericsson for use
> - with its modems. It is accessed from user space as sockets (PF_CAIF).
> -
> - Say Y (or M) here if you build for a phone product (e.g. Android or
> - MeeGo) that uses CAIF as transport. If unsure say N.
> -
> - If you select to build it as module then CAIF_NETDEV also needs to be
> - built as a module. You will also need to say Y (or M) to any CAIF
> - physical devices that your platform requires.
> -
> - See Documentation/networking/caif for a further explanation on how to
> - use and configure CAIF.
> -
> -config CAIF_DEBUG
> - bool "Enable Debug"
> - depends on CAIF
> - 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"
> - depends on CAIF
> - 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.
> -
> -config CAIF_USB
> - tristate "CAIF USB support"
> - depends on CAIF
> - default n
> - help
> - Say Y if you are using CAIF over USB CDC NCM.
> - 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 N.
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 5b01215f6829..3b2d28127634 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -48,7 +48,6 @@ obj-$(CONFIG_MHI_NET) += mhi_net.o
> # Networking Drivers
> #
> obj-$(CONFIG_ARCNET) += arcnet/
> -obj-$(CONFIG_CAIF) += caif/
> obj-$(CONFIG_CAN) += can/
> ifdef CONFIG_NET_DSA
> obj-y += dsa/
> diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
> deleted file mode 100644
> index 97f664f8016c..000000000000
> --- a/drivers/net/caif/Makefile
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
> -
> -# Serial interface
> -obj-$(CONFIG_CAIF_TTY) += caif_serial.o
> -
> -# Virtio interface
> -obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
> diff --git a/net/Makefile b/net/Makefile
> index 90e3d72bf58b..98e182829eff 100644
> --- a/net/Makefile
> +++ b/net/Makefile
> @@ -53,7 +53,6 @@ obj-$(CONFIG_IUCV) += iucv/
> obj-$(CONFIG_SMC) += smc/
> obj-$(CONFIG_RFKILL) += rfkill/
> obj-$(CONFIG_NET_9P) += 9p/
> -obj-$(CONFIG_CAIF) += caif/
> obj-$(CONFIG_DCB) += dcb/
> obj-$(CONFIG_6LOWPAN) += 6lowpan/
> obj-$(CONFIG_IEEE802154) += ieee802154/
> diff --git a/net/caif/Makefile b/net/caif/Makefile
> deleted file mode 100644
> index 4f6c0517cdfb..000000000000
> --- a/net/caif/Makefile
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0
> -ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
> -
> -caif-y := 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
> -
> -obj-$(CONFIG_CAIF) += caif.o
> -obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
> -obj-$(CONFIG_CAIF) += caif_socket.o
> -obj-$(CONFIG_CAIF_USB) += caif_usb.o
> -
> -export-y := caif.o
> diff --git a/include/linux/virtio_caif.h b/include/linux/virtio_caif.h
> deleted file mode 100644
> index ea722479510c..000000000000
> --- a/include/linux/virtio_caif.h
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -/*
> - * Copyright (C) ST-Ericsson AB 2012
> - * Author: Sjur Brændeland <sjur.brandeland@stericsson.com>
> - *
> - * This header is BSD licensed so
> - * anyone can use the definitions to implement compatible remote processors
> - */
> -
> -#ifndef VIRTIO_CAIF_H
> -#define VIRTIO_CAIF_H
> -
> -#include <linux/types.h>
> -struct virtio_caif_transf_config {
> - __virtio16 headroom;
> - __virtio16 tailroom;
> - __virtio32 mtu;
> - u8 reserved[4];
> -};
> -
> -struct virtio_caif_config {
> - struct virtio_caif_transf_config uplink, downlink;
> - u8 reserved[8];
> -};
> -#endif
> diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h
> deleted file mode 100644
> index b655d8666f55..000000000000
> --- a/include/net/caif/caif_dev.h
> +++ /dev/null
> @@ -1,128 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CAIF_DEV_H_
> -#define CAIF_DEV_H_
> -
> -#include <net/caif/caif_layer.h>
> -#include <net/caif/cfcnfg.h>
> -#include <net/caif/caif_device.h>
> -#include <linux/caif/caif_socket.h>
> -#include <linux/if.h>
> -#include <linux/net.h>
> -
> -/**
> - * struct caif_param - CAIF parameters.
> - * @size: Length of data
> - * @data: Binary Data Blob
> - */
> -struct caif_param {
> - u16 size;
> - u8 data[256];
> -};
> -
> -/**
> - * struct caif_connect_request - Request data for CAIF channel setup.
> - * @protocol: Type of CAIF protocol to use (at, datagram etc)
> - * @sockaddr: Socket address to connect.
> - * @priority: Priority of the connection.
> - * @link_selector: Link selector (high bandwidth or low latency)
> - * @ifindex: kernel index of the interface.
> - * @param: Connect Request parameters (CAIF_SO_REQ_PARAM).
> - *
> - * This struct is used when connecting a CAIF channel.
> - * It contains all CAIF channel configuration options.
> - */
> -struct caif_connect_request {
> - enum caif_protocol_type protocol;
> - struct sockaddr_caif sockaddr;
> - enum caif_channel_priority priority;
> - enum caif_link_selector link_selector;
> - int ifindex;
> - 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.
> - * @ifindex: Link layer interface index used for this connection.
> - * @headroom: Head room needed by CAIF protocol.
> - * @tailroom: Tail room needed by CAIF protocol.
> - *
> - * 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 net *net,
> - struct caif_connect_request *conn_req,
> - struct cflayer *client_layer, int *ifindex,
> - int *headroom, int *tailroom);
> -
> -/**
> - * caif_disconnect_client - Disconnects a client from the CAIF stack.
> - *
> - * @client_layer: Client layer to be disconnected.
> - */
> -int caif_disconnect_client(struct net *net, struct cflayer *client_layer);
> -
> -
> -/**
> - * caif_client_register_refcnt - register ref-count functions provided by client.
> - *
> - * @adapt_layer: Client layer using CAIF Stack.
> - * @hold: Function provided by client layer increasing ref-count
> - * @put: Function provided by client layer decreasing ref-count
> - *
> - * Client of the CAIF Stack must register functions for reference counting.
> - * These functions are called by the CAIF Stack for every upstream packet,
> - * and must therefore be implemented efficiently.
> - *
> - * Client should call caif_free_client when reference count degrease to zero.
> - */
> -
> -void caif_client_register_refcnt(struct cflayer *adapt_layer,
> - void (*hold)(struct cflayer *lyr),
> - void (*put)(struct cflayer *lyr));
> -/**
> - * caif_free_client - Free memory used to manage the client in the CAIF Stack.
> - *
> - * @client_layer: Client layer to be removed.
> - *
> - * This function must be called from client layer in order to free memory.
> - * Caller must guarantee that no packets are in flight upstream when calling
> - * this function.
> - */
> -void caif_free_client(struct cflayer *adap_layer);
> -
> -/**
> - * struct caif_enroll_dev - Enroll a net-device as a CAIF Link layer
> - * @dev: Network device to enroll.
> - * @caifdev: Configuration information from CAIF Link Layer
> - * @link_support: Link layer support layer
> - * @head_room: Head room needed by link support layer
> - * @layer: Lowest layer in CAIF stack
> - * @rcv_fun: Receive function for CAIF stack.
> - *
> - * This function enroll a CAIF link layer into CAIF Stack and
> - * expects the interface to be able to handle CAIF payload.
> - * The link_support layer is used to add any Link Layer specific
> - * framing.
> - */
> -int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
> - struct cflayer *link_support, int head_room,
> - struct cflayer **layer, int (**rcv_func)(
> - struct sk_buff *, struct net_device *,
> - struct packet_type *, struct net_device *));
> -
> -#endif /* CAIF_DEV_H_ */
> diff --git a/include/net/caif/caif_device.h b/include/net/caif/caif_device.h
> deleted file mode 100644
> index 91d1fd5b44a4..000000000000
> --- a/include/net/caif/caif_device.h
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#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_ */
> diff --git a/include/net/caif/caif_layer.h b/include/net/caif/caif_layer.h
> deleted file mode 100644
> index 053e7c6a6a66..000000000000
> --- a/include/net/caif/caif_layer.h
> +++ /dev/null
> @@ -1,277 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CAIF_LAYER_H_
> -#define CAIF_LAYER_H_
> -
> -#include <linux/list.h>
> -
> -struct cflayer;
> -struct cfpkt;
> -struct caif_payload_info;
> -
> -#define CAIF_LAYER_NAME_SZ 16
> -
> -/**
> - * 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 fails. 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 function.
> - * @ctrlcmd: Used for control signalling upwards in the stack.
> - * @modemcmd: Used for control signaling downwards in the stack.
> - * @id: The identity 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's 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 (non-blocking).
> - * Contract: Each layer must implement a receive function passing the
> - * CAIF packets upwards in the stack.
> - * Packet handling rules:
> - * - The CAIF packet (cfpkt) ownership is passed to the
> - * called receive function. This means that the
> - * packet cannot be accessed after passing it to the
> - * above layer using up->receive().
> - *
> - * - If parsing of the packet fails, the packet must be
> - * destroyed and negative error code returned
> - * from the function.
> - * EXCEPTION: If the framing layer (cffrml) returns
> - * -EILSEQ, the packet is not freed.
> - *
> - * - 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 (non-blocking).
> - * 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 packet
> - * cannot be accessed after passing it to the below
> - * layer using dn->transmit().
> - *
> - * - Upon error the packet ownership is still passed on,
> - * so the packet shall be freed where error is detected.
> - * Callers of the transmit function shall not free packets,
> - * but errors shall be returned.
> - *
> - * - Return value less than zero means error, zero or
> - * greater than zero means OK.
> - *
> - * Returns result < 0 indicates an error, 0 or positive value
> - * indicates 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 (non-blocking).
> - * 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 int id;
> - 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
> deleted file mode 100644
> index 8819ff4db35a..000000000000
> --- a/include/net/caif/cfcnfg.h
> +++ /dev/null
> @@ -1,90 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CFCNFG_H_
> -#define CFCNFG_H_
> -#include <linux/spinlock.h>
> -#include <linux/netdevice.h>
> -#include <net/caif/caif_layer.h>
> -#include <net/caif/cfctrl.h>
> -
> -struct cfcnfg;
> -
> -/**
> - * 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() - Get the CAIF configuration object given network.
> - * @net: Network for the CAIF configuration object.
> - */
> -struct cfcnfg *get_cfcnfg(struct net *net);
> -
> -/**
> - * 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().
> - * @dev: Pointer to link layer device
> - * @phy_layer: Specify the physical layer. The transmit function
> - * MUST be set in the structure.
> - * @pref: The phy (link layer) preference.
> - * @link_support: Protocol implementation for link layer specific protocol.
> - * @fcs: Specify if checksum is used in CAIF Framing Layer.
> - * @head_room: Head space needed by link specific protocol.
> - */
> -int
> -cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
> - struct net_device *dev, struct cflayer *phy_layer,
> - enum cfcnfg_phy_preference pref,
> - struct cflayer *link_support,
> - bool fcs, int head_room);
> -
> -/**
> - * 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_set_phy_state() - Set the state of the physical interface device.
> - * @cnfg: Configuration object
> - * @phy_layer: Physical Layer representation
> - * @up: State of device
> - */
> -int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
> - bool up);
> -
> -#endif /* CFCNFG_H_ */
> diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h
> deleted file mode 100644
> index 86d17315c8a1..000000000000
> --- a/include/net/caif/cfctrl.h
> +++ /dev/null
> @@ -1,130 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#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);
> - 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 cflayer *client_layer;
> - struct list_head list;
> -};
> -
> -struct cfctrl {
> - struct cfsrvl serv;
> - struct cfctrl_rsp res;
> - atomic_t req_seq_no;
> - atomic_t rsp_seq_no;
> - struct list_head list;
> - /* Protects from simultaneous access to first_req list */
> - spinlock_t info_list_lock;
> -#ifndef CAIF_NO_LOOP
> - u8 loop_linkid;
> - int loop_linkused[256];
> - /* Protects simultaneous access to loop_linkid and loop_linkused */
> - spinlock_t loop_linkid_lock;
> -#endif
> -
> -};
> -
> -void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid);
> -int 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);
> -
> -struct cflayer *cfctrl_create(void);
> -struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer);
> -int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
> -void cfctrl_remove(struct cflayer *layr);
> -
> -#endif /* CFCTRL_H_ */
> diff --git a/include/net/caif/cffrml.h b/include/net/caif/cffrml.h
> deleted file mode 100644
> index 1ab8a80ede4d..000000000000
> --- a/include/net/caif/cffrml.h
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CFFRML_H_
> -#define CFFRML_H_
> -#include <net/caif/caif_layer.h>
> -#include <linux/netdevice.h>
> -
> -struct cffrml;
> -struct cflayer *cffrml_create(u16 phyid, bool use_fcs);
> -void cffrml_free(struct cflayer *layr);
> -void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up);
> -void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn);
> -void cffrml_put(struct cflayer *layr);
> -void cffrml_hold(struct cflayer *layr);
> -int cffrml_refcnt_read(struct cflayer *layr);
> -
> -#endif /* CFFRML_H_ */
> diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h
> deleted file mode 100644
> index 92ccb2648309..000000000000
> --- a/include/net/caif/cfmuxl.h
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#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);
> -
> -#endif /* CFMUXL_H_ */
> diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h
> deleted file mode 100644
> index acf664227d96..000000000000
> --- a/include/net/caif/cfpkt.h
> +++ /dev/null
> @@ -1,232 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#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);
> -
> -/*
> - * Destroy a CAIF Packet.
> - * pkt Packet to be destroyed.
> - */
> -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);
> -
> -static inline u8 cfpkt_extr_head_u8(struct cfpkt *pkt)
> -{
> - u8 tmp;
> -
> - cfpkt_extr_head(pkt, &tmp, 1);
> -
> - return tmp;
> -}
> -
> -static inline u16 cfpkt_extr_head_u16(struct cfpkt *pkt)
> -{
> - __le16 tmp;
> -
> - cfpkt_extr_head(pkt, &tmp, 2);
> -
> - return le16_to_cpu(tmp);
> -}
> -
> -static inline u32 cfpkt_extr_head_u32(struct cfpkt *pkt)
> -{
> - __le32 tmp;
> -
> - cfpkt_extr_head(pkt, &tmp, 4);
> -
> - return le32_to_cpu(tmp);
> -}
> -
> -/*
> - * 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.
> - */
> -
> -int cfpkt_iterate(struct cfpkt *pkt,
> - u16 (*iter_func)(u16 chks, void *buf, u16 len),
> - u16 data);
> -
> -/* 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);
> -
> -/*
> - * Returns packet information for a packet.
> - * pkt Packet to get info from;
> - * @return Packet information
> - */
> -struct caif_payload_info *cfpkt_info(struct cfpkt *pkt);
> -
> -/** cfpkt_set_prio - set priority for a CAIF packet.
> - *
> - * @pkt: The CAIF packet to be adjusted.
> - * @prio: one of TC_PRIO_ constants.
> - */
> -void cfpkt_set_prio(struct cfpkt *pkt, int prio);
> -
> -#endif /* CFPKT_H_ */
> diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h
> deleted file mode 100644
> index 67cce8757175..000000000000
> --- a/include/net/caif/cfserl.h
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CFSERL_H_
> -#define CFSERL_H_
> -#include <net/caif/caif_layer.h>
> -
> -struct cflayer *cfserl_create(int instance, bool use_stx);
> -void cfserl_release(struct cflayer *layer);
> -#endif
> diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h
> deleted file mode 100644
> index a000dc45f966..000000000000
> --- a/include/net/caif/cfsrvl.h
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#ifndef CFSRVL_H_
> -#define CFSRVL_H_
> -#include <linux/list.h>
> -#include <linux/stddef.h>
> -#include <linux/types.h>
> -#include <linux/kref.h>
> -#include <linux/rculist.h>
> -
> -struct cfsrvl {
> - struct cflayer layer;
> - bool open;
> - bool phy_flow_on;
> - bool modem_flow_on;
> - bool supports_flowctrl;
> - void (*release)(struct cflayer *layer);
> - struct dev_info dev_info;
> - void (*hold)(struct cflayer *lyr);
> - void (*put)(struct cflayer *lyr);
> - struct rcu_head rcu;
> -};
> -
> -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,
> - int mtu_size);
> -struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info);
> -
> -bool cfsrvl_phyid_match(struct cflayer *layer, int phyid);
> -
> -void cfsrvl_init(struct cfsrvl *service,
> - u8 channel_id,
> - struct dev_info *dev_info,
> - bool supports_flowctrl);
> -bool cfsrvl_ready(struct cfsrvl *service, int *err);
> -
> -static inline void cfsrvl_get(struct cflayer *layr)
> -{
> - struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
> - if (layr == NULL || layr->up == NULL || s->hold == NULL)
> - return;
> -
> - s->hold(layr->up);
> -}
> -
> -static inline void cfsrvl_put(struct cflayer *layr)
> -{
> - struct cfsrvl *s = container_of(layr, struct cfsrvl, layer);
> - if (layr == NULL || layr->up == NULL || s->hold == NULL)
> - return;
> -
> - s->put(layr->up);
> -}
> -#endif /* CFSRVL_H_ */
> diff --git a/include/uapi/linux/caif/caif_socket.h b/include/uapi/linux/caif/caif_socket.h
> deleted file mode 100644
> index d9970bbaa156..000000000000
> --- a/include/uapi/linux/caif/caif_socket.h
> +++ /dev/null
> @@ -1,195 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/* linux/caif_socket.h
> - * CAIF Definitions for CAIF socket and network layer
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - * License terms: GNU General Public License (GPL) version 2
> - */
> -
> -#ifndef _LINUX_CAIF_SOCKET_H
> -#define _LINUX_CAIF_SOCKET_H
> -
> -#include <linux/types.h>
> -#include <linux/socket.h>
> -
> -/**
> - * 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
> - * @CAIFPROTO_DEBUG: Debug link
> - *
> - * 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_DEBUG,
> - _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
> -};
> - /**
> - * enum caif_debug_type - Content selection for debug connection
> - * @CAIF_DEBUG_TRACE_INTERACTIVE: Connection will contain
> - * both trace and interactive debug.
> - * @CAIF_DEBUG_TRACE: Connection contains trace only.
> - * @CAIF_DEBUG_INTERACTIVE: Connection to interactive debug.
> - */
> -enum caif_debug_type {
> - CAIF_DEBUG_TRACE_INTERACTIVE = 0,
> - CAIF_DEBUG_TRACE,
> - CAIF_DEBUG_INTERACTIVE,
> -};
> -
> -/**
> - * enum caif_debug_service - Debug Service Endpoint
> - * @CAIF_RADIO_DEBUG_SERVICE: Debug service on the Radio sub-system
> - * @CAIF_APP_DEBUG_SERVICE: Debug for the applications sub-system
> - */
> -enum caif_debug_service {
> - CAIF_RADIO_DEBUG_SERVICE = 1,
> - CAIF_APP_DEBUG_SERVICE
> -};
> -
> -/**
> - * struct sockaddr_caif - the sockaddr structure for CAIF sockets.
> - * @family: Address family number, must be AF_CAIF.
> - * @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.
> - *
> - * @u.dbg: Applies when family = CAIFPROTO_DEBUG.
> - *
> - * @u.dbg.type: Type of debug connection to set up
> - * (caif_debug_type).
> - *
> - * @u.dbg.service: Service sub-system to connect (caif_debug_service
> - * 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 {
> - __kernel_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 */
> - struct {
> - __u8 type; /* type:enum caif_debug_type */
> - __u8 service; /* service:caif_debug_service */
> - } dbg; /* CAIFPROTO_DEBUG */
> - } 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
> - * 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
> - * of type PF_CAIF.
> - *
> - */
> -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/uapi/linux/caif/if_caif.h b/include/uapi/linux/caif/if_caif.h
> deleted file mode 100644
> index 74bca19403fa..000000000000
> --- a/include/uapi/linux/caif/if_caif.h
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - * 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_*/
> diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
> deleted file mode 100644
> index 1873d8287bb9..000000000000
> --- a/drivers/net/caif/caif_serial.c
> +++ /dev/null
> @@ -1,443 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#include <linux/hardirq.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/device.h>
> -#include <linux/types.h>
> -#include <linux/skbuff.h>
> -#include <linux/netdevice.h>
> -#include <linux/rtnetlink.h>
> -#include <linux/tty.h>
> -#include <linux/file.h>
> -#include <linux/if_arp.h>
> -#include <net/caif/caif_device.h>
> -#include <net/caif/cfcnfg.h>
> -#include <linux/err.h>
> -#include <linux/debugfs.h>
> -
> -MODULE_LICENSE("GPL");
> -MODULE_AUTHOR("Sjur Brendeland");
> -MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS_LDISC(N_CAIF);
> -
> -#define SEND_QUEUE_LOW 10
> -#define SEND_QUEUE_HIGH 100
> -#define CAIF_SENDING 1 /* Bit 1 = 0x02*/
> -#define CAIF_FLOW_OFF_SENT 4 /* Bit 4 = 0x10 */
> -#define MAX_WRITE_CHUNK 4096
> -#define ON 1
> -#define OFF 0
> -#define CAIF_MAX_MTU 4096
> -
> -static DEFINE_SPINLOCK(ser_lock);
> -static LIST_HEAD(ser_list);
> -static LIST_HEAD(ser_release_list);
> -
> -static bool ser_loop;
> -module_param(ser_loop, bool, 0444);
> -MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
> -
> -static bool ser_use_stx = true;
> -module_param(ser_use_stx, bool, 0444);
> -MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
> -
> -static bool ser_use_fcs = true;
> -
> -module_param(ser_use_fcs, bool, 0444);
> -MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
> -
> -static int ser_write_chunk = MAX_WRITE_CHUNK;
> -module_param(ser_write_chunk, int, 0444);
> -
> -MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
> -
> -static struct dentry *debugfsdir;
> -
> -static int caif_net_open(struct net_device *dev);
> -static int caif_net_close(struct net_device *dev);
> -
> -struct ser_device {
> - struct caif_dev_common common;
> - struct list_head node;
> - struct net_device *dev;
> - struct sk_buff_head head;
> - struct tty_struct *tty;
> - bool tx_started;
> - unsigned long state;
> -#ifdef CONFIG_DEBUG_FS
> - struct dentry *debugfs_tty_dir;
> - struct debugfs_blob_wrapper tx_blob;
> - struct debugfs_blob_wrapper rx_blob;
> - u8 rx_data[128];
> - u8 tx_data[128];
> - u8 tty_status;
> -
> -#endif
> -};
> -
> -static void caifdev_setup(struct net_device *dev);
> -static void ldisc_tx_wakeup(struct tty_struct *tty);
> -#ifdef CONFIG_DEBUG_FS
> -static inline void update_tty_status(struct ser_device *ser)
> -{
> - ser->tty_status =
> - ser->tty->flow.stopped << 5 |
> - ser->tty->flow.tco_stopped << 3 |
> - ser->tty->ctrl.packet << 2;
> -}
> -static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
> -{
> - ser->debugfs_tty_dir = debugfs_create_dir(tty->name, debugfsdir);
> -
> - debugfs_create_blob("last_tx_msg", 0400, ser->debugfs_tty_dir,
> - &ser->tx_blob);
> -
> - debugfs_create_blob("last_rx_msg", 0400, ser->debugfs_tty_dir,
> - &ser->rx_blob);
> -
> - debugfs_create_xul("ser_state", 0400, ser->debugfs_tty_dir,
> - &ser->state);
> -
> - debugfs_create_x8("tty_status", 0400, ser->debugfs_tty_dir,
> - &ser->tty_status);
> -
> - ser->tx_blob.data = ser->tx_data;
> - ser->tx_blob.size = 0;
> - ser->rx_blob.data = ser->rx_data;
> - ser->rx_blob.size = 0;
> -}
> -
> -static inline void debugfs_deinit(struct ser_device *ser)
> -{
> - debugfs_remove_recursive(ser->debugfs_tty_dir);
> -}
> -
> -static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
> -{
> - if (size > sizeof(ser->rx_data))
> - size = sizeof(ser->rx_data);
> - memcpy(ser->rx_data, data, size);
> - ser->rx_blob.data = ser->rx_data;
> - ser->rx_blob.size = size;
> -}
> -#else
> -static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
> -{
> -}
> -
> -static inline void debugfs_deinit(struct ser_device *ser)
> -{
> -}
> -
> -static inline void update_tty_status(struct ser_device *ser)
> -{
> -}
> -
> -static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
> -{
> -}
> -#endif
> -
> -static void ldisc_receive(struct tty_struct *tty, const u8 *data,
> - const u8 *flags, size_t count)
> -{
> - struct sk_buff *skb = NULL;
> - struct ser_device *ser;
> - int ret;
> -
> - ser = tty->disc_data;
> -
> - /*
> - * NOTE: flags may contain information about break or overrun.
> - * This is not yet handled.
> - */
> -
> -
> - /*
> - * Workaround for garbage at start of transmission,
> - * only enable if STX handling is not enabled.
> - */
> - if (!ser->common.use_stx && !ser->tx_started) {
> - dev_info(&ser->dev->dev,
> - "Bytes received before initial transmission -"
> - "bytes discarded.\n");
> - return;
> - }
> -
> - BUG_ON(ser->dev == NULL);
> -
> - /* Get a suitable caif packet and copy in data. */
> - skb = netdev_alloc_skb(ser->dev, count+1);
> - if (skb == NULL)
> - return;
> - skb_put_data(skb, data, count);
> -
> - skb->protocol = htons(ETH_P_CAIF);
> - skb_reset_mac_header(skb);
> - debugfs_rx(ser, data, count);
> - /* Push received packet up the stack. */
> - ret = netif_rx(skb);
> - if (!ret) {
> - ser->dev->stats.rx_packets++;
> - ser->dev->stats.rx_bytes += count;
> - } else
> - ++ser->dev->stats.rx_dropped;
> - update_tty_status(ser);
> -}
> -
> -static int handle_tx(struct ser_device *ser)
> -{
> - struct tty_struct *tty;
> - struct sk_buff *skb;
> - int tty_wr, len, room;
> -
> - tty = ser->tty;
> - ser->tx_started = true;
> -
> - /* Enter critical section */
> - if (test_and_set_bit(CAIF_SENDING, &ser->state))
> - return 0;
> -
> - /* skb_peek is safe because handle_tx is called after skb_queue_tail */
> - while ((skb = skb_peek(&ser->head)) != NULL) {
> -
> - /* Make sure you don't write too much */
> - len = skb->len;
> - room = tty_write_room(tty);
> - if (!room)
> - break;
> - if (room > ser_write_chunk)
> - room = ser_write_chunk;
> - if (len > room)
> - len = room;
> -
> - /* Write to tty or loopback */
> - if (!ser_loop) {
> - tty_wr = tty->ops->write(tty, skb->data, len);
> - update_tty_status(ser);
> - } else {
> - tty_wr = len;
> - ldisc_receive(tty, skb->data, NULL, len);
> - }
> - ser->dev->stats.tx_packets++;
> - ser->dev->stats.tx_bytes += tty_wr;
> -
> - /* Error on TTY ?! */
> - if (tty_wr < 0)
> - goto error;
> - /* Reduce buffer written, and discard if empty */
> - skb_pull(skb, tty_wr);
> - if (skb->len == 0) {
> - struct sk_buff *tmp = skb_dequeue(&ser->head);
> - WARN_ON(tmp != skb);
> - dev_consume_skb_any(skb);
> - }
> - }
> - /* Send flow off if queue is empty */
> - if (ser->head.qlen <= SEND_QUEUE_LOW &&
> - test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
> - ser->common.flowctrl != NULL)
> - ser->common.flowctrl(ser->dev, ON);
> - clear_bit(CAIF_SENDING, &ser->state);
> - return 0;
> -error:
> - clear_bit(CAIF_SENDING, &ser->state);
> - return tty_wr;
> -}
> -
> -static netdev_tx_t caif_xmit(struct sk_buff *skb, struct net_device *dev)
> -{
> - struct ser_device *ser;
> -
> - ser = netdev_priv(dev);
> -
> - /* Send flow off once, on high water mark */
> - if (ser->head.qlen > SEND_QUEUE_HIGH &&
> - !test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
> - ser->common.flowctrl != NULL)
> -
> - ser->common.flowctrl(ser->dev, OFF);
> -
> - skb_queue_tail(&ser->head, skb);
> - return handle_tx(ser);
> -}
> -
> -
> -static void ldisc_tx_wakeup(struct tty_struct *tty)
> -{
> - struct ser_device *ser;
> -
> - ser = tty->disc_data;
> - BUG_ON(ser == NULL);
> - WARN_ON(ser->tty != tty);
> - handle_tx(ser);
> -}
> -
> -
> -static void ser_release(struct work_struct *work)
> -{
> - struct list_head list;
> - struct ser_device *ser, *tmp;
> - struct tty_struct *tty;
> -
> - spin_lock(&ser_lock);
> - list_replace_init(&ser_release_list, &list);
> - spin_unlock(&ser_lock);
> -
> - if (!list_empty(&list)) {
> - rtnl_lock();
> - list_for_each_entry_safe(ser, tmp, &list, node) {
> - tty = ser->tty;
> - dev_close(ser->dev);
> - unregister_netdevice(ser->dev);
> - debugfs_deinit(ser);
> - tty_kref_put(tty->link);
> - tty_kref_put(tty);
> - }
> - rtnl_unlock();
> - }
> -}
> -
> -static DECLARE_WORK(ser_release_work, ser_release);
> -
> -static int ldisc_open(struct tty_struct *tty)
> -{
> - struct ser_device *ser;
> - struct net_device *dev;
> - char name[64];
> - int result;
> -
> - /* No write no play */
> - if (tty->ops->write == NULL)
> - return -EOPNOTSUPP;
> - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG))
> - return -EPERM;
> -
> - /* release devices to avoid name collision */
> - ser_release(NULL);
> -
> - result = snprintf(name, sizeof(name), "cf%s", tty->name);
> - if (result >= IFNAMSIZ)
> - return -EINVAL;
> - dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN,
> - caifdev_setup);
> - if (!dev)
> - return -ENOMEM;
> -
> - ser = netdev_priv(dev);
> - ser->tty = tty_kref_get(tty);
> - tty_kref_get(tty->link);
> - ser->dev = dev;
> - debugfs_init(ser, tty);
> - tty->receive_room = 4096;
> - tty->disc_data = ser;
> - set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
> - rtnl_lock();
> - result = register_netdevice(dev);
> - if (result) {
> - tty_kref_put(tty->link);
> - tty_kref_put(tty);
> - rtnl_unlock();
> - free_netdev(dev);
> - return -ENODEV;
> - }
> -
> - spin_lock(&ser_lock);
> - list_add(&ser->node, &ser_list);
> - spin_unlock(&ser_lock);
> - rtnl_unlock();
> - netif_stop_queue(dev);
> - update_tty_status(ser);
> - return 0;
> -}
> -
> -static void ldisc_close(struct tty_struct *tty)
> -{
> - struct ser_device *ser = tty->disc_data;
> -
> - spin_lock(&ser_lock);
> - list_move(&ser->node, &ser_release_list);
> - spin_unlock(&ser_lock);
> - schedule_work(&ser_release_work);
> -}
> -
> -/* The line discipline structure. */
> -static struct tty_ldisc_ops caif_ldisc = {
> - .owner = THIS_MODULE,
> - .num = N_CAIF,
> - .name = "n_caif",
> - .open = ldisc_open,
> - .close = ldisc_close,
> - .receive_buf = ldisc_receive,
> - .write_wakeup = ldisc_tx_wakeup
> -};
> -
> -static const struct net_device_ops netdev_ops = {
> - .ndo_open = caif_net_open,
> - .ndo_stop = caif_net_close,
> - .ndo_start_xmit = caif_xmit
> -};
> -
> -static void caifdev_setup(struct net_device *dev)
> -{
> - struct ser_device *serdev = netdev_priv(dev);
> -
> - dev->features = 0;
> - dev->netdev_ops = &netdev_ops;
> - dev->type = ARPHRD_CAIF;
> - dev->flags = IFF_POINTOPOINT | IFF_NOARP;
> - dev->mtu = CAIF_MAX_MTU;
> - dev->priv_flags |= IFF_NO_QUEUE;
> - dev->needs_free_netdev = true;
> - skb_queue_head_init(&serdev->head);
> - serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
> - serdev->common.use_frag = true;
> - serdev->common.use_stx = ser_use_stx;
> - serdev->common.use_fcs = ser_use_fcs;
> - serdev->dev = dev;
> -}
> -
> -
> -static int caif_net_open(struct net_device *dev)
> -{
> - netif_wake_queue(dev);
> - return 0;
> -}
> -
> -static int caif_net_close(struct net_device *dev)
> -{
> - netif_stop_queue(dev);
> - return 0;
> -}
> -
> -static int __init caif_ser_init(void)
> -{
> - int ret;
> -
> - ret = tty_register_ldisc(&caif_ldisc);
> - if (ret < 0)
> - pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret);
> -
> - debugfsdir = debugfs_create_dir("caif_serial", NULL);
> - return ret;
> -}
> -
> -static void __exit caif_ser_exit(void)
> -{
> - spin_lock(&ser_lock);
> - list_splice(&ser_list, &ser_release_list);
> - spin_unlock(&ser_lock);
> - ser_release(NULL);
> - cancel_work_sync(&ser_release_work);
> - tty_unregister_ldisc(&caif_ldisc);
> - debugfs_remove_recursive(debugfsdir);
> -}
> -
> -module_init(caif_ser_init);
> -module_exit(caif_ser_exit);
> diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
> deleted file mode 100644
> index 8ac1a4b8e055..000000000000
> --- a/drivers/net/caif/caif_virtio.c
> +++ /dev/null
> @@ -1,791 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2013
> - * Authors: Vicram Arv
> - * Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
> - * Sjur Brendeland
> - */
> -#include <linux/module.h>
> -#include <linux/if_arp.h>
> -#include <linux/virtio.h>
> -#include <linux/vringh.h>
> -#include <linux/debugfs.h>
> -#include <linux/spinlock.h>
> -#include <linux/genalloc.h>
> -#include <linux/interrupt.h>
> -#include <linux/netdevice.h>
> -#include <linux/rtnetlink.h>
> -#include <linux/virtio_ids.h>
> -#include <linux/virtio_caif.h>
> -#include <linux/virtio_ring.h>
> -#include <linux/dma-mapping.h>
> -#include <net/caif/caif_dev.h>
> -#include <linux/virtio_config.h>
> -
> -MODULE_LICENSE("GPL v2");
> -MODULE_AUTHOR("Vicram Arv");
> -MODULE_AUTHOR("Sjur Brendeland");
> -MODULE_DESCRIPTION("Virtio CAIF Driver");
> -
> -/* NAPI schedule quota */
> -#define CFV_DEFAULT_QUOTA 32
> -
> -/* Defaults used if virtio config space is unavailable */
> -#define CFV_DEF_MTU_SIZE 4096
> -#define CFV_DEF_HEADROOM 32
> -#define CFV_DEF_TAILROOM 32
> -
> -/* Required IP header alignment */
> -#define IP_HDR_ALIGN 4
> -
> -/* struct cfv_napi_contxt - NAPI context info
> - * @riov: IOV holding data read from the ring. Note that riov may
> - * still hold data when cfv_rx_poll() returns.
> - * @head: Last descriptor ID we received from vringh_getdesc_kern.
> - * We use this to put descriptor back on the used ring. USHRT_MAX is
> - * used to indicate invalid head-id.
> - */
> -struct cfv_napi_context {
> - struct vringh_kiov riov;
> - unsigned short head;
> -};
> -
> -/* struct cfv_stats - statistics for debugfs
> - * @rx_napi_complete: Number of NAPI completions (RX)
> - * @rx_napi_resched: Number of calls where the full quota was used (RX)
> - * @rx_nomem: Number of SKB alloc failures (RX)
> - * @rx_kicks: Number of RX kicks
> - * @tx_full_ring: Number times TX ring was full
> - * @tx_no_mem: Number of times TX went out of memory
> - * @tx_flow_on: Number of flow on (TX)
> - * @tx_kicks: Number of TX kicks
> - */
> -struct cfv_stats {
> - u32 rx_napi_complete;
> - u32 rx_napi_resched;
> - u32 rx_nomem;
> - u32 rx_kicks;
> - u32 tx_full_ring;
> - u32 tx_no_mem;
> - u32 tx_flow_on;
> - u32 tx_kicks;
> -};
> -
> -/* struct cfv_info - Caif Virtio control structure
> - * @cfdev: caif common header
> - * @vdev: Associated virtio device
> - * @vr_rx: rx/downlink host vring
> - * @vq_tx: tx/uplink virtqueue
> - * @ndev: CAIF link layer device
> - * @watermark_tx: indicates number of free descriptors we need
> - * to reopen the tx-queues after overload.
> - * @tx_lock: protects vq_tx from concurrent use
> - * @tx_release_tasklet: Tasklet for freeing consumed TX buffers
> - * @napi: Napi context used in cfv_rx_poll()
> - * @ctx: Context data used in cfv_rx_poll()
> - * @tx_hr: transmit headroom
> - * @rx_hr: receive headroom
> - * @tx_tr: transmit tail room
> - * @rx_tr: receive tail room
> - * @mtu: transmit max size
> - * @mru: receive max size
> - * @allocsz: size of dma memory reserved for TX buffers
> - * @alloc_addr: virtual address to dma memory for TX buffers
> - * @alloc_dma: dma address to dma memory for TX buffers
> - * @genpool: Gen Pool used for allocating TX buffers
> - * @reserved_mem: Pointer to memory reserve allocated from genpool
> - * @reserved_size: Size of memory reserve allocated from genpool
> - * @stats: Statistics exposed in sysfs
> - * @debugfs: Debugfs dentry for statistic counters
> - */
> -struct cfv_info {
> - struct caif_dev_common cfdev;
> - struct virtio_device *vdev;
> - struct vringh *vr_rx;
> - struct virtqueue *vq_tx;
> - struct net_device *ndev;
> - unsigned int watermark_tx;
> - /* Protect access to vq_tx */
> - spinlock_t tx_lock;
> - struct tasklet_struct tx_release_tasklet;
> - struct napi_struct napi;
> - struct cfv_napi_context ctx;
> - u16 tx_hr;
> - u16 rx_hr;
> - u16 tx_tr;
> - u16 rx_tr;
> - u32 mtu;
> - u32 mru;
> - size_t allocsz;
> - void *alloc_addr;
> - dma_addr_t alloc_dma;
> - struct gen_pool *genpool;
> - unsigned long reserved_mem;
> - size_t reserved_size;
> - struct cfv_stats stats;
> - struct dentry *debugfs;
> -};
> -
> -/* struct buf_info - maintains transmit buffer data handle
> - * @size: size of transmit buffer
> - * @dma_handle: handle to allocated dma device memory area
> - * @vaddr: virtual address mapping to allocated memory area
> - */
> -struct buf_info {
> - size_t size;
> - u8 *vaddr;
> -};
> -
> -/* Called from virtio device, in IRQ context */
> -static void cfv_release_cb(struct virtqueue *vq_tx)
> -{
> - struct cfv_info *cfv = vq_tx->vdev->priv;
> -
> - ++cfv->stats.tx_kicks;
> - tasklet_schedule(&cfv->tx_release_tasklet);
> -}
> -
> -static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info)
> -{
> - if (!buf_info)
> - return;
> - gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr,
> - buf_info->size);
> - kfree(buf_info);
> -}
> -
> -/* This is invoked whenever the remote processor completed processing
> - * a TX msg we just sent, and the buffer is put back to the used ring.
> - */
> -static void cfv_release_used_buf(struct virtqueue *vq_tx)
> -{
> - struct cfv_info *cfv = vq_tx->vdev->priv;
> - unsigned long flags;
> -
> - BUG_ON(vq_tx != cfv->vq_tx);
> -
> - for (;;) {
> - unsigned int len;
> - struct buf_info *buf_info;
> -
> - /* Get used buffer from used ring to recycle used descriptors */
> - spin_lock_irqsave(&cfv->tx_lock, flags);
> - buf_info = virtqueue_get_buf(vq_tx, &len);
> - spin_unlock_irqrestore(&cfv->tx_lock, flags);
> -
> - /* Stop looping if there are no more buffers to free */
> - if (!buf_info)
> - break;
> -
> - free_buf_info(cfv, buf_info);
> -
> - /* watermark_tx indicates if we previously stopped the tx
> - * queues. If we have enough free stots in the virtio ring,
> - * re-establish memory reserved and open up tx queues.
> - */
> - if (cfv->vq_tx->num_free <= cfv->watermark_tx)
> - continue;
> -
> - /* Re-establish memory reserve */
> - if (cfv->reserved_mem == 0 && cfv->genpool)
> - cfv->reserved_mem =
> - gen_pool_alloc(cfv->genpool,
> - cfv->reserved_size);
> -
> - /* Open up the tx queues */
> - if (cfv->reserved_mem) {
> - cfv->watermark_tx =
> - virtqueue_get_vring_size(cfv->vq_tx);
> - netif_tx_wake_all_queues(cfv->ndev);
> - /* Buffers are recycled in cfv_netdev_tx, so
> - * disable notifications when queues are opened.
> - */
> - virtqueue_disable_cb(cfv->vq_tx);
> - ++cfv->stats.tx_flow_on;
> - } else {
> - /* if no memory reserve, wait for more free slots */
> - WARN_ON(cfv->watermark_tx >
> - virtqueue_get_vring_size(cfv->vq_tx));
> - cfv->watermark_tx +=
> - virtqueue_get_vring_size(cfv->vq_tx) / 4;
> - }
> - }
> -}
> -
> -/* Allocate a SKB and copy packet data to it */
> -static struct sk_buff *cfv_alloc_and_copy_skb(int *err,
> - struct cfv_info *cfv,
> - u8 *frm, u32 frm_len)
> -{
> - struct sk_buff *skb;
> - u32 cfpkt_len, pad_len;
> -
> - *err = 0;
> - /* Verify that packet size with down-link header and mtu size */
> - if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) {
> - netdev_err(cfv->ndev,
> - "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n",
> - frm_len, cfv->mru, cfv->rx_hr,
> - cfv->rx_tr);
> - *err = -EPROTO;
> - return NULL;
> - }
> -
> - cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr);
> - pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1);
> -
> - skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len);
> - if (!skb) {
> - *err = -ENOMEM;
> - return NULL;
> - }
> -
> - skb_reserve(skb, cfv->rx_hr + pad_len);
> -
> - skb_put_data(skb, frm + cfv->rx_hr, cfpkt_len);
> - return skb;
> -}
> -
> -/* Get packets from the host vring */
> -static int cfv_rx_poll(struct napi_struct *napi, int quota)
> -{
> - struct cfv_info *cfv = container_of(napi, struct cfv_info, napi);
> - int rxcnt = 0;
> - int err = 0;
> - void *buf;
> - struct sk_buff *skb;
> - struct vringh_kiov *riov = &cfv->ctx.riov;
> - unsigned int skb_len;
> -
> - do {
> - skb = NULL;
> -
> - /* Put the previous iovec back on the used ring and
> - * fetch a new iovec if we have processed all elements.
> - */
> - if (riov->i == riov->used) {
> - if (cfv->ctx.head != USHRT_MAX) {
> - vringh_complete_kern(cfv->vr_rx,
> - cfv->ctx.head,
> - 0);
> - cfv->ctx.head = USHRT_MAX;
> - }
> -
> - err = vringh_getdesc_kern(
> - cfv->vr_rx,
> - riov,
> - NULL,
> - &cfv->ctx.head,
> - GFP_ATOMIC);
> -
> - if (err <= 0)
> - goto exit;
> - }
> -
> - buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base);
> - /* TODO: Add check on valid buffer address */
> -
> - skb = cfv_alloc_and_copy_skb(&err, cfv, buf,
> - riov->iov[riov->i].iov_len);
> - if (unlikely(err))
> - goto exit;
> -
> - /* Push received packet up the stack. */
> - skb_len = skb->len;
> - skb->protocol = htons(ETH_P_CAIF);
> - skb_reset_mac_header(skb);
> - skb->dev = cfv->ndev;
> - err = netif_receive_skb(skb);
> - if (unlikely(err)) {
> - ++cfv->ndev->stats.rx_dropped;
> - } else {
> - ++cfv->ndev->stats.rx_packets;
> - cfv->ndev->stats.rx_bytes += skb_len;
> - }
> -
> - ++riov->i;
> - ++rxcnt;
> - } while (rxcnt < quota);
> -
> - ++cfv->stats.rx_napi_resched;
> - goto out;
> -
> -exit:
> - switch (err) {
> - case 0:
> - ++cfv->stats.rx_napi_complete;
> -
> - /* Really out of packets? (stolen from virtio_net)*/
> - napi_complete(napi);
> - if (unlikely(!vringh_notify_enable_kern(cfv->vr_rx)) &&
> - napi_schedule_prep(napi)) {
> - vringh_notify_disable_kern(cfv->vr_rx);
> - __napi_schedule(napi);
> - }
> - break;
> -
> - case -ENOMEM:
> - ++cfv->stats.rx_nomem;
> - dev_kfree_skb(skb);
> - /* Stop NAPI poll on OOM, we hope to be polled later */
> - napi_complete(napi);
> - vringh_notify_enable_kern(cfv->vr_rx);
> - break;
> -
> - default:
> - /* We're doomed, any modem fault is fatal */
> - netdev_warn(cfv->ndev, "Bad ring, disable device\n");
> - cfv->ndev->stats.rx_dropped = riov->used - riov->i;
> - napi_complete(napi);
> - vringh_notify_disable_kern(cfv->vr_rx);
> - netif_carrier_off(cfv->ndev);
> - break;
> - }
> -out:
> - if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0)
> - vringh_notify(cfv->vr_rx);
> - return rxcnt;
> -}
> -
> -static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx)
> -{
> - struct cfv_info *cfv = vdev->priv;
> -
> - ++cfv->stats.rx_kicks;
> - vringh_notify_disable_kern(cfv->vr_rx);
> - napi_schedule(&cfv->napi);
> -}
> -
> -static void cfv_destroy_genpool(struct cfv_info *cfv)
> -{
> - if (cfv->alloc_addr)
> - dma_free_coherent(cfv->vdev->dev.parent->parent,
> - cfv->allocsz, cfv->alloc_addr,
> - cfv->alloc_dma);
> -
> - if (!cfv->genpool)
> - return;
> - gen_pool_free(cfv->genpool, cfv->reserved_mem,
> - cfv->reserved_size);
> - gen_pool_destroy(cfv->genpool);
> - cfv->genpool = NULL;
> -}
> -
> -static int cfv_create_genpool(struct cfv_info *cfv)
> -{
> - int err;
> -
> - /* dma_alloc can only allocate whole pages, and we need a more
> - * fine graned allocation so we use genpool. We ask for space needed
> - * by IP and a full ring. If the dma allcoation fails we retry with a
> - * smaller allocation size.
> - */
> - err = -ENOMEM;
> - cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) *
> - (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10;
> - if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu)
> - return -EINVAL;
> -
> - for (;;) {
> - if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) {
> - netdev_info(cfv->ndev, "Not enough device memory\n");
> - return -ENOMEM;
> - }
> -
> - cfv->alloc_addr = dma_alloc_coherent(
> - cfv->vdev->dev.parent->parent,
> - cfv->allocsz, &cfv->alloc_dma,
> - GFP_ATOMIC);
> - if (cfv->alloc_addr)
> - break;
> -
> - cfv->allocsz = (cfv->allocsz * 3) >> 2;
> - }
> -
> - netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n",
> - cfv->allocsz);
> -
> - /* Allocate on 128 bytes boundaries (1 << 7)*/
> - cfv->genpool = gen_pool_create(7, -1);
> - if (!cfv->genpool)
> - goto err;
> -
> - err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr,
> - (phys_addr_t)virt_to_phys(cfv->alloc_addr),
> - cfv->allocsz, -1);
> - if (err)
> - goto err;
> -
> - /* Reserve some memory for low memory situations. If we hit the roof
> - * in the memory pool, we stop TX flow and release the reserve.
> - */
> - cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu;
> - cfv->reserved_mem = gen_pool_alloc(cfv->genpool,
> - cfv->reserved_size);
> - if (!cfv->reserved_mem) {
> - err = -ENOMEM;
> - goto err;
> - }
> -
> - cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx);
> - return 0;
> -err:
> - cfv_destroy_genpool(cfv);
> - return err;
> -}
> -
> -/* Enable the CAIF interface and allocate the memory-pool */
> -static int cfv_netdev_open(struct net_device *netdev)
> -{
> - struct cfv_info *cfv = netdev_priv(netdev);
> -
> - if (cfv_create_genpool(cfv))
> - return -ENOMEM;
> -
> - netif_carrier_on(netdev);
> - napi_enable(&cfv->napi);
> -
> - /* Schedule NAPI to read any pending packets */
> - napi_schedule(&cfv->napi);
> - return 0;
> -}
> -
> -/* Disable the CAIF interface and free the memory-pool */
> -static int cfv_netdev_close(struct net_device *netdev)
> -{
> - struct cfv_info *cfv = netdev_priv(netdev);
> - unsigned long flags;
> - struct buf_info *buf_info;
> -
> - /* Disable interrupts, queues and NAPI polling */
> - netif_carrier_off(netdev);
> - virtqueue_disable_cb(cfv->vq_tx);
> - vringh_notify_disable_kern(cfv->vr_rx);
> - napi_disable(&cfv->napi);
> -
> - /* Release any TX buffers on both used and available rings */
> - cfv_release_used_buf(cfv->vq_tx);
> - spin_lock_irqsave(&cfv->tx_lock, flags);
> - while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx)))
> - free_buf_info(cfv, buf_info);
> - spin_unlock_irqrestore(&cfv->tx_lock, flags);
> -
> - /* Release all dma allocated memory and destroy the pool */
> - cfv_destroy_genpool(cfv);
> - return 0;
> -}
> -
> -/* Allocate a buffer in dma-memory and copy skb to it */
> -static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv,
> - struct sk_buff *skb,
> - struct scatterlist *sg)
> -{
> - struct caif_payload_info *info = (void *)&skb->cb;
> - struct buf_info *buf_info = NULL;
> - u8 pad_len, hdr_ofs;
> -
> - if (!cfv->genpool)
> - goto err;
> -
> - if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) {
> - netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n",
> - cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu);
> - goto err;
> - }
> -
> - buf_info = kmalloc_obj(struct buf_info, GFP_ATOMIC);
> - if (unlikely(!buf_info))
> - goto err;
> -
> - /* Make the IP header aligned in the buffer */
> - hdr_ofs = cfv->tx_hr + info->hdr_len;
> - pad_len = hdr_ofs & (IP_HDR_ALIGN - 1);
> - buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len;
> -
> - /* allocate dma memory buffer */
> - buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size);
> - if (unlikely(!buf_info->vaddr))
> - goto err;
> -
> - /* copy skbuf contents to send buffer */
> - skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len);
> - sg_init_one(sg, buf_info->vaddr + pad_len,
> - skb->len + cfv->tx_hr + cfv->rx_hr);
> -
> - return buf_info;
> -err:
> - kfree(buf_info);
> - return NULL;
> -}
> -
> -/* Put the CAIF packet on the virtio ring and kick the receiver */
> -static netdev_tx_t cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
> -{
> - struct cfv_info *cfv = netdev_priv(netdev);
> - struct buf_info *buf_info;
> - struct scatterlist sg;
> - unsigned long flags;
> - bool flow_off = false;
> - int ret;
> -
> - /* garbage collect released buffers */
> - cfv_release_used_buf(cfv->vq_tx);
> - spin_lock_irqsave(&cfv->tx_lock, flags);
> -
> - /* Flow-off check takes into account number of cpus to make sure
> - * virtqueue will not be overfilled in any possible smp conditions.
> - *
> - * Flow-on is triggered when sufficient buffers are freed
> - */
> - if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) {
> - flow_off = true;
> - cfv->stats.tx_full_ring++;
> - }
> -
> - /* If we run out of memory, we release the memory reserve and retry
> - * allocation.
> - */
> - buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
> - if (unlikely(!buf_info)) {
> - cfv->stats.tx_no_mem++;
> - flow_off = true;
> -
> - if (cfv->reserved_mem && cfv->genpool) {
> - gen_pool_free(cfv->genpool, cfv->reserved_mem,
> - cfv->reserved_size);
> - cfv->reserved_mem = 0;
> - buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
> - }
> - }
> -
> - if (unlikely(flow_off)) {
> - /* Turn flow on when a 1/4 of the descriptors are released */
> - cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4;
> - /* Enable notifications of recycled TX buffers */
> - virtqueue_enable_cb(cfv->vq_tx);
> - netif_tx_stop_all_queues(netdev);
> - }
> -
> - if (unlikely(!buf_info)) {
> - /* If the memory reserve does it's job, this shouldn't happen */
> - netdev_warn(cfv->ndev, "Out of gen_pool memory\n");
> - goto err;
> - }
> -
> - ret = virtqueue_add_outbuf(cfv->vq_tx, &sg, 1, buf_info, GFP_ATOMIC);
> - if (unlikely((ret < 0))) {
> - /* If flow control works, this shouldn't happen */
> - netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n",
> - ret);
> - goto err;
> - }
> -
> - /* update netdev statistics */
> - cfv->ndev->stats.tx_packets++;
> - cfv->ndev->stats.tx_bytes += skb->len;
> - spin_unlock_irqrestore(&cfv->tx_lock, flags);
> -
> - /* tell the remote processor it has a pending message to read */
> - virtqueue_kick(cfv->vq_tx);
> -
> - dev_kfree_skb(skb);
> - return NETDEV_TX_OK;
> -err:
> - spin_unlock_irqrestore(&cfv->tx_lock, flags);
> - cfv->ndev->stats.tx_dropped++;
> - free_buf_info(cfv, buf_info);
> - dev_kfree_skb(skb);
> - return NETDEV_TX_OK;
> -}
> -
> -static void cfv_tx_release_tasklet(struct tasklet_struct *t)
> -{
> - struct cfv_info *cfv = from_tasklet(cfv, t, tx_release_tasklet);
> - cfv_release_used_buf(cfv->vq_tx);
> -}
> -
> -static const struct net_device_ops cfv_netdev_ops = {
> - .ndo_open = cfv_netdev_open,
> - .ndo_stop = cfv_netdev_close,
> - .ndo_start_xmit = cfv_netdev_tx,
> -};
> -
> -static void cfv_netdev_setup(struct net_device *netdev)
> -{
> - netdev->netdev_ops = &cfv_netdev_ops;
> - netdev->type = ARPHRD_CAIF;
> - netdev->tx_queue_len = 100;
> - netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
> - netdev->mtu = CFV_DEF_MTU_SIZE;
> - netdev->needs_free_netdev = true;
> -}
> -
> -/* Create debugfs counters for the device */
> -static inline void debugfs_init(struct cfv_info *cfv)
> -{
> - cfv->debugfs = debugfs_create_dir(netdev_name(cfv->ndev), NULL);
> -
> - debugfs_create_u32("rx-napi-complete", 0400, cfv->debugfs,
> - &cfv->stats.rx_napi_complete);
> - debugfs_create_u32("rx-napi-resched", 0400, cfv->debugfs,
> - &cfv->stats.rx_napi_resched);
> - debugfs_create_u32("rx-nomem", 0400, cfv->debugfs,
> - &cfv->stats.rx_nomem);
> - debugfs_create_u32("rx-kicks", 0400, cfv->debugfs,
> - &cfv->stats.rx_kicks);
> - debugfs_create_u32("tx-full-ring", 0400, cfv->debugfs,
> - &cfv->stats.tx_full_ring);
> - debugfs_create_u32("tx-no-mem", 0400, cfv->debugfs,
> - &cfv->stats.tx_no_mem);
> - debugfs_create_u32("tx-kicks", 0400, cfv->debugfs,
> - &cfv->stats.tx_kicks);
> - debugfs_create_u32("tx-flow-on", 0400, cfv->debugfs,
> - &cfv->stats.tx_flow_on);
> -}
> -
> -/* Setup CAIF for the a virtio device */
> -static int cfv_probe(struct virtio_device *vdev)
> -{
> - vrh_callback_t *vrh_cbs = cfv_recv;
> - const char *cfv_netdev_name = "cfvrt";
> - struct net_device *netdev;
> - struct cfv_info *cfv;
> - int err;
> -
> - netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
> - NET_NAME_UNKNOWN, cfv_netdev_setup);
> - if (!netdev)
> - return -ENOMEM;
> -
> - cfv = netdev_priv(netdev);
> - cfv->vdev = vdev;
> - cfv->ndev = netdev;
> -
> - spin_lock_init(&cfv->tx_lock);
> -
> - /* Get the RX virtio ring. This is a "host side vring". */
> - err = -ENODEV;
> - if (!vdev->vringh_config || !vdev->vringh_config->find_vrhs)
> - goto err;
> -
> - err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs);
> - if (err)
> - goto err;
> -
> - /* Get the TX virtio ring. This is a "guest side vring". */
> - cfv->vq_tx = virtio_find_single_vq(vdev, cfv_release_cb, "output");
> - if (IS_ERR(cfv->vq_tx)) {
> - err = PTR_ERR(cfv->vq_tx);
> - goto err;
> - }
> -
> - /* Get the CAIF configuration from virtio config space, if available */
> - if (vdev->config->get) {
> - virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
> - &cfv->tx_hr);
> - virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
> - &cfv->rx_hr);
> - virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
> - &cfv->tx_tr);
> - virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
> - &cfv->rx_tr);
> - virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
> - &cfv->mtu);
> - virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
> - &cfv->mru);
> - } else {
> - cfv->tx_hr = CFV_DEF_HEADROOM;
> - cfv->rx_hr = CFV_DEF_HEADROOM;
> - cfv->tx_tr = CFV_DEF_TAILROOM;
> - cfv->rx_tr = CFV_DEF_TAILROOM;
> - cfv->mtu = CFV_DEF_MTU_SIZE;
> - cfv->mru = CFV_DEF_MTU_SIZE;
> - }
> -
> - netdev->needed_headroom = cfv->tx_hr;
> - netdev->needed_tailroom = cfv->tx_tr;
> -
> - /* Disable buffer release interrupts unless we have stopped TX queues */
> - virtqueue_disable_cb(cfv->vq_tx);
> -
> - netdev->mtu = cfv->mtu - cfv->tx_tr;
> - vdev->priv = cfv;
> -
> - /* Initialize NAPI poll context data */
> - vringh_kiov_init(&cfv->ctx.riov, NULL, 0);
> - cfv->ctx.head = USHRT_MAX;
> - netif_napi_add_weight(netdev, &cfv->napi, cfv_rx_poll,
> - CFV_DEFAULT_QUOTA);
> -
> - tasklet_setup(&cfv->tx_release_tasklet, cfv_tx_release_tasklet);
> -
> - /* Carrier is off until netdevice is opened */
> - netif_carrier_off(netdev);
> -
> - /* serialize netdev register + virtio_device_ready() with ndo_open() */
> - rtnl_lock();
> -
> - /* register Netdev */
> - err = register_netdevice(netdev);
> - if (err) {
> - rtnl_unlock();
> - dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
> - goto err;
> - }
> -
> - virtio_device_ready(vdev);
> -
> - rtnl_unlock();
> -
> - debugfs_init(cfv);
> -
> - return 0;
> -err:
> - netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err);
> -
> - if (cfv->vr_rx)
> - vdev->vringh_config->del_vrhs(cfv->vdev);
> - if (cfv->vq_tx)
> - vdev->config->del_vqs(cfv->vdev);
> - free_netdev(netdev);
> - return err;
> -}
> -
> -static void cfv_remove(struct virtio_device *vdev)
> -{
> - struct cfv_info *cfv = vdev->priv;
> -
> - rtnl_lock();
> - dev_close(cfv->ndev);
> - rtnl_unlock();
> -
> - tasklet_kill(&cfv->tx_release_tasklet);
> - debugfs_remove_recursive(cfv->debugfs);
> -
> - vringh_kiov_cleanup(&cfv->ctx.riov);
> - virtio_reset_device(vdev);
> - vdev->vringh_config->del_vrhs(cfv->vdev);
> - cfv->vr_rx = NULL;
> - vdev->config->del_vqs(cfv->vdev);
> - unregister_netdev(cfv->ndev);
> -}
> -
> -static struct virtio_device_id id_table[] = {
> - { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID },
> - { 0 },
> -};
> -
> -static unsigned int features[] = {
> -};
> -
> -static struct virtio_driver caif_virtio_driver = {
> - .feature_table = features,
> - .feature_table_size = ARRAY_SIZE(features),
> - .driver.name = KBUILD_MODNAME,
> - .id_table = id_table,
> - .probe = cfv_probe,
> - .remove = cfv_remove,
> -};
> -
> -module_virtio_driver(caif_virtio_driver);
> -MODULE_DEVICE_TABLE(virtio, id_table);
> diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
> deleted file mode 100644
> index 922de3d611c0..000000000000
> --- a/net/caif/caif_dev.c
> +++ /dev/null
> @@ -1,586 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * CAIF Interface registration.
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - *
> - * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont
> - * and Sakari Ailus <sakari.ailus@nokia.com>
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/kernel.h>
> -#include <linux/if_arp.h>
> -#include <linux/net.h>
> -#include <linux/netdevice.h>
> -#include <linux/mutex.h>
> -#include <linux/module.h>
> -#include <linux/spinlock.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_layer.h>
> -#include <net/caif/caif_dev.h>
> -#include <net/caif/cfpkt.h>
> -#include <net/caif/cfcnfg.h>
> -#include <net/caif/cfserl.h>
> -
> -MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol support");
> -MODULE_LICENSE("GPL");
> -
> -/* Used for local tracking of the CAIF net devices */
> -struct caif_device_entry {
> - struct cflayer layer;
> - struct list_head list;
> - struct net_device *netdev;
> - int __percpu *pcpu_refcnt;
> - spinlock_t flow_lock;
> - struct sk_buff *xoff_skb;
> - void (*xoff_skb_dtor)(struct sk_buff *skb);
> - bool xoff;
> -};
> -
> -struct caif_device_entry_list {
> - struct list_head list;
> - /* Protects simulanous deletes in list */
> - struct mutex lock;
> -};
> -
> -struct caif_net {
> - struct cfcnfg *cfg;
> - struct caif_device_entry_list caifdevs;
> -};
> -
> -static unsigned int caif_net_id;
> -static int q_high = 50; /* Percent */
> -
> -struct cfcnfg *get_cfcnfg(struct net *net)
> -{
> - struct caif_net *caifn;
> - caifn = net_generic(net, caif_net_id);
> - return caifn->cfg;
> -}
> -EXPORT_SYMBOL(get_cfcnfg);
> -
> -static struct caif_device_entry_list *caif_device_list(struct net *net)
> -{
> - struct caif_net *caifn;
> - caifn = net_generic(net, caif_net_id);
> - return &caifn->caifdevs;
> -}
> -
> -static void caifd_put(struct caif_device_entry *e)
> -{
> - this_cpu_dec(*e->pcpu_refcnt);
> -}
> -
> -static void caifd_hold(struct caif_device_entry *e)
> -{
> - this_cpu_inc(*e->pcpu_refcnt);
> -}
> -
> -static int caifd_refcnt_read(struct caif_device_entry *e)
> -{
> - int i, refcnt = 0;
> - for_each_possible_cpu(i)
> - refcnt += *per_cpu_ptr(e->pcpu_refcnt, i);
> - return refcnt;
> -}
> -
> -/* Allocate new CAIF device. */
> -static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
> -{
> - struct caif_device_entry *caifd;
> -
> - caifd = kzalloc_obj(*caifd);
> - if (!caifd)
> - return NULL;
> - caifd->pcpu_refcnt = alloc_percpu(int);
> - if (!caifd->pcpu_refcnt) {
> - kfree(caifd);
> - return NULL;
> - }
> - caifd->netdev = dev;
> - dev_hold(dev);
> - 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;
> -
> - list_for_each_entry_rcu(caifd, &caifdevs->list, list,
> - lockdep_rtnl_is_held()) {
> - if (caifd->netdev == dev)
> - return caifd;
> - }
> - return NULL;
> -}
> -
> -static void caif_flow_cb(struct sk_buff *skb)
> -{
> - struct caif_device_entry *caifd;
> - void (*dtor)(struct sk_buff *skb) = NULL;
> - bool send_xoff;
> -
> - WARN_ON(skb->dev == NULL);
> -
> - rcu_read_lock();
> - caifd = caif_get(skb->dev);
> -
> - WARN_ON(caifd == NULL);
> - if (!caifd) {
> - rcu_read_unlock();
> - return;
> - }
> -
> - caifd_hold(caifd);
> - rcu_read_unlock();
> -
> - spin_lock_bh(&caifd->flow_lock);
> - send_xoff = caifd->xoff;
> - caifd->xoff = false;
> - dtor = caifd->xoff_skb_dtor;
> -
> - if (WARN_ON(caifd->xoff_skb != skb))
> - skb = NULL;
> -
> - caifd->xoff_skb = NULL;
> - caifd->xoff_skb_dtor = NULL;
> -
> - spin_unlock_bh(&caifd->flow_lock);
> -
> - if (dtor && skb)
> - dtor(skb);
> -
> - if (send_xoff)
> - caifd->layer.up->
> - ctrlcmd(caifd->layer.up,
> - _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND,
> - caifd->layer.id);
> - caifd_put(caifd);
> -}
> -
> -static int transmit(struct cflayer *layer, struct cfpkt *pkt)
> -{
> - int err, high = 0, qlen = 0;
> - struct caif_device_entry *caifd =
> - container_of(layer, struct caif_device_entry, layer);
> - struct sk_buff *skb;
> - struct netdev_queue *txq;
> -
> - rcu_read_lock_bh();
> -
> - skb = cfpkt_tonative(pkt);
> - skb->dev = caifd->netdev;
> - skb_reset_network_header(skb);
> - skb->protocol = htons(ETH_P_CAIF);
> -
> - /* Check if we need to handle xoff */
> - if (likely(caifd->netdev->priv_flags & IFF_NO_QUEUE))
> - goto noxoff;
> -
> - if (unlikely(caifd->xoff))
> - goto noxoff;
> -
> - if (likely(!netif_queue_stopped(caifd->netdev))) {
> - struct Qdisc *sch;
> -
> - /* If we run with a TX queue, check if the queue is too long*/
> - txq = netdev_get_tx_queue(skb->dev, 0);
> - sch = rcu_dereference_bh(txq->qdisc);
> - if (likely(qdisc_is_empty(sch)))
> - goto noxoff;
> -
> - /* can check for explicit qdisc len value only !NOLOCK,
> - * always set flow off otherwise
> - */
> - high = (caifd->netdev->tx_queue_len * q_high) / 100;
> - if (!(sch->flags & TCQ_F_NOLOCK) && likely(sch->q.qlen < high))
> - goto noxoff;
> - }
> -
> - /* Hold lock while accessing xoff */
> - spin_lock_bh(&caifd->flow_lock);
> - if (caifd->xoff) {
> - spin_unlock_bh(&caifd->flow_lock);
> - goto noxoff;
> - }
> -
> - /*
> - * Handle flow off, we do this by temporary hi-jacking this
> - * skb's destructor function, and replace it with our own
> - * flow-on callback. The callback will set flow-on and call
> - * the original destructor.
> - */
> -
> - pr_debug("queue has stopped(%d) or is full (%d > %d)\n",
> - netif_queue_stopped(caifd->netdev),
> - qlen, high);
> - caifd->xoff = true;
> - caifd->xoff_skb = skb;
> - caifd->xoff_skb_dtor = skb->destructor;
> - skb->destructor = caif_flow_cb;
> - spin_unlock_bh(&caifd->flow_lock);
> -
> - caifd->layer.up->ctrlcmd(caifd->layer.up,
> - _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
> - caifd->layer.id);
> -noxoff:
> - rcu_read_unlock_bh();
> -
> - err = dev_queue_xmit(skb);
> - if (err > 0)
> - err = -EIO;
> -
> - return err;
> -}
> -
> -/*
> - * Stuff received packets into the CAIF stack.
> - * 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 cfpkt *pkt;
> - struct caif_device_entry *caifd;
> - int err;
> -
> - pkt = cfpkt_fromnative(CAIF_DIR_IN, skb);
> -
> - rcu_read_lock();
> - caifd = caif_get(dev);
> -
> - if (!caifd || !caifd->layer.up || !caifd->layer.up->receive ||
> - !netif_oper_up(caifd->netdev)) {
> - rcu_read_unlock();
> - kfree_skb(skb);
> - return NET_RX_DROP;
> - }
> -
> - /* Hold reference to netdevice while using CAIF stack */
> - caifd_hold(caifd);
> - rcu_read_unlock();
> -
> - err = caifd->layer.up->receive(caifd->layer.up, pkt);
> -
> - /* For -EILSEQ the packet is not freed so free it now */
> - if (err == -EILSEQ)
> - cfpkt_destroy(pkt);
> -
> - /* Release reference to stack upwards */
> - caifd_put(caifd);
> -
> - if (err != 0)
> - err = NET_RX_DROP;
> - return err;
> -}
> -
> -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;
> -
> - rcu_read_lock();
> -
> - caifd = caif_get(dev);
> - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
> - rcu_read_unlock();
> - return;
> - }
> -
> - caifd_hold(caifd);
> - rcu_read_unlock();
> -
> - caifd->layer.up->ctrlcmd(caifd->layer.up,
> - on ?
> - _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND :
> - _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND,
> - caifd->layer.id);
> - caifd_put(caifd);
> -}
> -
> -int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
> - struct cflayer *link_support, int head_room,
> - struct cflayer **layer,
> - int (**rcv_func)(struct sk_buff *, struct net_device *,
> - struct packet_type *,
> - struct net_device *))
> -{
> - struct caif_device_entry *caifd;
> - enum cfcnfg_phy_preference pref;
> - struct cfcnfg *cfg = get_cfcnfg(dev_net(dev));
> - struct caif_device_entry_list *caifdevs;
> - int res;
> -
> - caifdevs = caif_device_list(dev_net(dev));
> - caifd = caif_device_alloc(dev);
> - if (!caifd)
> - return -ENOMEM;
> - *layer = &caifd->layer;
> - spin_lock_init(&caifd->flow_lock);
> -
> - switch (caifdev->link_select) {
> - case CAIF_LINK_HIGH_BANDW:
> - pref = CFPHYPREF_HIGH_BW;
> - break;
> - case CAIF_LINK_LOW_LATENCY:
> - pref = CFPHYPREF_LOW_LAT;
> - break;
> - default:
> - pref = CFPHYPREF_HIGH_BW;
> - break;
> - }
> - mutex_lock(&caifdevs->lock);
> - list_add_rcu(&caifd->list, &caifdevs->list);
> -
> - strscpy(caifd->layer.name, dev->name,
> - sizeof(caifd->layer.name));
> - caifd->layer.transmit = transmit;
> - res = cfcnfg_add_phy_layer(cfg,
> - dev,
> - &caifd->layer,
> - pref,
> - link_support,
> - caifdev->use_fcs,
> - head_room);
> - mutex_unlock(&caifdevs->lock);
> - if (rcv_func)
> - *rcv_func = receive;
> - return res;
> -}
> -EXPORT_SYMBOL(caif_enroll_dev);
> -
> -/* notify Caif of device events */
> -static int caif_device_notify(struct notifier_block *me, unsigned long what,
> - void *ptr)
> -{
> - struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> - struct caif_device_entry *caifd = NULL;
> - struct caif_dev_common *caifdev;
> - struct cfcnfg *cfg;
> - struct cflayer *layer, *link_support;
> - int head_room = 0;
> - struct caif_device_entry_list *caifdevs;
> - int res;
> -
> - cfg = get_cfcnfg(dev_net(dev));
> - caifdevs = caif_device_list(dev_net(dev));
> -
> - caifd = caif_get(dev);
> - if (caifd == NULL && dev->type != ARPHRD_CAIF)
> - return 0;
> -
> - switch (what) {
> - case NETDEV_REGISTER:
> - if (caifd != NULL)
> - break;
> -
> - caifdev = netdev_priv(dev);
> -
> - link_support = NULL;
> - if (caifdev->use_frag) {
> - head_room = 1;
> - link_support = cfserl_create(dev->ifindex,
> - caifdev->use_stx);
> - if (!link_support) {
> - pr_warn("Out of memory\n");
> - break;
> - }
> - }
> - res = caif_enroll_dev(dev, caifdev, link_support, head_room,
> - &layer, NULL);
> - if (res)
> - cfserl_release(link_support);
> - caifdev->flowctrl = dev_flowctrl;
> - break;
> -
> - case NETDEV_UP:
> - rcu_read_lock();
> -
> - caifd = caif_get(dev);
> - if (caifd == NULL) {
> - rcu_read_unlock();
> - break;
> - }
> -
> - caifd->xoff = false;
> - cfcnfg_set_phy_state(cfg, &caifd->layer, true);
> - rcu_read_unlock();
> -
> - break;
> -
> - case NETDEV_DOWN:
> - rcu_read_lock();
> -
> - caifd = caif_get(dev);
> - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) {
> - rcu_read_unlock();
> - return -EINVAL;
> - }
> -
> - cfcnfg_set_phy_state(cfg, &caifd->layer, false);
> - caifd_hold(caifd);
> - rcu_read_unlock();
> -
> - caifd->layer.up->ctrlcmd(caifd->layer.up,
> - _CAIF_CTRLCMD_PHYIF_DOWN_IND,
> - caifd->layer.id);
> -
> - spin_lock_bh(&caifd->flow_lock);
> -
> - /*
> - * Replace our xoff-destructor with original destructor.
> - * We trust that skb->destructor *always* is called before
> - * the skb reference is invalid. The hijacked SKB destructor
> - * takes the flow_lock so manipulating the skb->destructor here
> - * should be safe.
> - */
> - if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL)
> - caifd->xoff_skb->destructor = caifd->xoff_skb_dtor;
> -
> - caifd->xoff = false;
> - caifd->xoff_skb_dtor = NULL;
> - caifd->xoff_skb = NULL;
> -
> - spin_unlock_bh(&caifd->flow_lock);
> - caifd_put(caifd);
> - break;
> -
> - case NETDEV_UNREGISTER:
> - mutex_lock(&caifdevs->lock);
> -
> - caifd = caif_get(dev);
> - if (caifd == NULL) {
> - mutex_unlock(&caifdevs->lock);
> - break;
> - }
> - list_del_rcu(&caifd->list);
> -
> - /*
> - * NETDEV_UNREGISTER is called repeatedly until all reference
> - * counts for the net-device are released. If references to
> - * caifd is taken, simply ignore NETDEV_UNREGISTER and wait for
> - * the next call to NETDEV_UNREGISTER.
> - *
> - * If any packets are in flight down the CAIF Stack,
> - * cfcnfg_del_phy_layer will return nonzero.
> - * If no packets are in flight, the CAIF Stack associated
> - * with the net-device un-registering is freed.
> - */
> -
> - if (caifd_refcnt_read(caifd) != 0 ||
> - cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0) {
> -
> - pr_info("Wait for device inuse\n");
> - /* Enrole device if CAIF Stack is still in use */
> - list_add_rcu(&caifd->list, &caifdevs->list);
> - mutex_unlock(&caifdevs->lock);
> - break;
> - }
> -
> - synchronize_rcu();
> - dev_put(caifd->netdev);
> - free_percpu(caifd->pcpu_refcnt);
> - kfree(caifd);
> -
> - mutex_unlock(&caifdevs->lock);
> - break;
> - }
> - return 0;
> -}
> -
> -static struct notifier_block caif_device_notifier = {
> - .notifier_call = caif_device_notify,
> - .priority = 0,
> -};
> -
> -/* 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);
> - mutex_init(&caifn->caifdevs.lock);
> -
> - caifn->cfg = cfcnfg_create();
> - if (!caifn->cfg)
> - return -ENOMEM;
> -
> - return 0;
> -}
> -
> -static void caif_exit_net(struct net *net)
> -{
> - struct caif_device_entry *caifd, *tmp;
> - struct caif_device_entry_list *caifdevs =
> - caif_device_list(net);
> - struct cfcnfg *cfg = get_cfcnfg(net);
> -
> - rtnl_lock();
> - mutex_lock(&caifdevs->lock);
> -
> - list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
> - int i = 0;
> - list_del_rcu(&caifd->list);
> - cfcnfg_set_phy_state(cfg, &caifd->layer, false);
> -
> - while (i < 10 &&
> - (caifd_refcnt_read(caifd) != 0 ||
> - cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0)) {
> -
> - pr_info("Wait for device inuse\n");
> - msleep(250);
> - i++;
> - }
> - synchronize_rcu();
> - dev_put(caifd->netdev);
> - free_percpu(caifd->pcpu_refcnt);
> - kfree(caifd);
> - }
> - cfcnfg_remove(cfg);
> -
> - mutex_unlock(&caifdevs->lock);
> - 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 */
> -static int __init caif_device_init(void)
> -{
> - int result;
> -
> - result = register_pernet_subsys(&caif_net_ops);
> -
> - if (result)
> - return result;
> -
> - register_netdevice_notifier(&caif_device_notifier);
> - dev_add_pack(&caif_packet_type);
> -
> - return result;
> -}
> -
> -static void __exit caif_device_exit(void)
> -{
> - unregister_netdevice_notifier(&caif_device_notifier);
> - dev_remove_pack(&caif_packet_type);
> - unregister_pernet_subsys(&caif_net_ops);
> -}
> -
> -module_init(caif_device_init);
> -module_exit(caif_device_exit);
> diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
> deleted file mode 100644
> index af218742af5a..000000000000
> --- a/net/caif/caif_socket.c
> +++ /dev/null
> @@ -1,1114 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/filter.h>
> -#include <linux/fs.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/sched/signal.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 <linux/debugfs.h>
> -#include <linux/caif/caif_socket.h>
> -#include <linux/pkt_sched.h>
> -#include <net/sock.h>
> -#include <net/tcp_states.h>
> -#include <net/caif/caif_layer.h>
> -#include <net/caif/caif_dev.h>
> -#include <net/caif/cfpkt.h>
> -
> -MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol socket support (AF_CAIF)");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS_NETPROTO(AF_CAIF);
> -
> -/*
> - * CAIF state is re-using the TCP socket states.
> - * caif_states stored in sk_state reflect the state as reported by
> - * the CAIF stack, while sk_socket->state is the state of the socket.
> - */
> -enum caif_states {
> - CAIF_CONNECTED = TCP_ESTABLISHED,
> - CAIF_CONNECTING = TCP_SYN_SENT,
> - CAIF_DISCONNECTED = TCP_CLOSE
> -};
> -
> -#define TX_FLOW_ON_BIT 1
> -#define RX_FLOW_ON_BIT 2
> -
> -struct caifsock {
> - struct sock sk; /* must be first member */
> - struct cflayer layer;
> - unsigned long flow_state;
> - struct caif_connect_request conn_req;
> - struct mutex readlock;
> - struct dentry *debugfs_socket_dir;
> - int headroom, tailroom, maxframe;
> -};
> -
> -static int rx_flow_is_on(struct caifsock *cf_sk)
> -{
> - return test_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static int tx_flow_is_on(struct caifsock *cf_sk)
> -{
> - return test_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static void set_rx_flow_off(struct caifsock *cf_sk)
> -{
> - clear_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static void set_rx_flow_on(struct caifsock *cf_sk)
> -{
> - set_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static void set_tx_flow_off(struct caifsock *cf_sk)
> -{
> - clear_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static void set_tx_flow_on(struct caifsock *cf_sk)
> -{
> - set_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state);
> -}
> -
> -static void caif_read_lock(struct sock *sk)
> -{
> - struct caifsock *cf_sk;
> - cf_sk = container_of(sk, struct caifsock, sk);
> - mutex_lock(&cf_sk->readlock);
> -}
> -
> -static void caif_read_unlock(struct sock *sk)
> -{
> - struct caifsock *cf_sk;
> - cf_sk = container_of(sk, struct caifsock, sk);
> - mutex_unlock(&cf_sk->readlock);
> -}
> -
> -static int sk_rcvbuf_lowwater(struct caifsock *cf_sk)
> -{
> - /* A quarter of full buffer is used a low water mark */
> - return cf_sk->sk.sk_rcvbuf / 4;
> -}
> -
> -static void caif_flow_ctrl(struct sock *sk, int mode)
> -{
> - struct caifsock *cf_sk;
> - cf_sk = container_of(sk, struct caifsock, sk);
> - if (cf_sk->layer.dn && cf_sk->layer.dn->modemcmd)
> - cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode);
> -}
> -
> -/*
> - * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are
> - * not dropped, but CAIF is sending flow off instead.
> - */
> -static void caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
> -{
> - int err;
> - unsigned long flags;
> - struct sk_buff_head *list = &sk->sk_receive_queue;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - bool queued = false;
> -
> - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
> - (unsigned int)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) {
> - net_dbg_ratelimited("sending flow OFF (queue len = %d %d)\n",
> - atomic_read(&cf_sk->sk.sk_rmem_alloc),
> - sk_rcvbuf_lowwater(cf_sk));
> - set_rx_flow_off(cf_sk);
> - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
> - }
> -
> - err = sk_filter(sk, skb);
> - if (err)
> - goto out;
> -
> - if (!sk_rmem_schedule(sk, skb, skb->truesize) && rx_flow_is_on(cf_sk)) {
> - set_rx_flow_off(cf_sk);
> - net_dbg_ratelimited("sending flow OFF due to rmem_schedule\n");
> - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
> - }
> - skb->dev = NULL;
> - skb_set_owner_r(skb, sk);
> - spin_lock_irqsave(&list->lock, flags);
> - queued = !sock_flag(sk, SOCK_DEAD);
> - if (queued)
> - __skb_queue_tail(list, skb);
> - spin_unlock_irqrestore(&list->lock, flags);
> -out:
> - if (queued)
> - sk->sk_data_ready(sk);
> - else
> - kfree_skb(skb);
> -}
> -
> -/* Packet Receive Callback function called from CAIF Stack */
> -static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - struct caifsock *cf_sk;
> - struct sk_buff *skb;
> -
> - cf_sk = container_of(layr, struct caifsock, layer);
> - skb = cfpkt_tonative(pkt);
> -
> - if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) {
> - kfree_skb(skb);
> - return 0;
> - }
> - caif_queue_rcv_skb(&cf_sk->sk, skb);
> - return 0;
> -}
> -
> -static void cfsk_hold(struct cflayer *layr)
> -{
> - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
> - sock_hold(&cf_sk->sk);
> -}
> -
> -static void cfsk_put(struct cflayer *layr)
> -{
> - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
> - sock_put(&cf_sk->sk);
> -}
> -
> -/* Packet Control Callback function called from CAIF */
> -static void caif_ctrl_cb(struct cflayer *layr,
> - enum caif_ctrlcmd flow,
> - int phyid)
> -{
> - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer);
> - switch (flow) {
> - case CAIF_CTRLCMD_FLOW_ON_IND:
> - /* OK from modem to start sending again */
> - set_tx_flow_on(cf_sk);
> - cf_sk->sk.sk_state_change(&cf_sk->sk);
> - break;
> -
> - case CAIF_CTRLCMD_FLOW_OFF_IND:
> - /* Modem asks us to shut up */
> - set_tx_flow_off(cf_sk);
> - cf_sk->sk.sk_state_change(&cf_sk->sk);
> - break;
> -
> - case CAIF_CTRLCMD_INIT_RSP:
> - /* We're now connected */
> - caif_client_register_refcnt(&cf_sk->layer,
> - cfsk_hold, cfsk_put);
> - cf_sk->sk.sk_state = CAIF_CONNECTED;
> - set_tx_flow_on(cf_sk);
> - cf_sk->sk.sk_shutdown = 0;
> - cf_sk->sk.sk_state_change(&cf_sk->sk);
> - break;
> -
> - case CAIF_CTRLCMD_DEINIT_RSP:
> - /* We're now disconnected */
> - cf_sk->sk.sk_state = CAIF_DISCONNECTED;
> - cf_sk->sk.sk_state_change(&cf_sk->sk);
> - break;
> -
> - case CAIF_CTRLCMD_INIT_FAIL_RSP:
> - /* Connect request failed */
> - cf_sk->sk.sk_err = ECONNREFUSED;
> - cf_sk->sk.sk_state = CAIF_DISCONNECTED;
> - cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
> - /*
> - * Socket "standards" seems to require POLLOUT to
> - * be set at connect failure.
> - */
> - set_tx_flow_on(cf_sk);
> - cf_sk->sk.sk_state_change(&cf_sk->sk);
> - break;
> -
> - case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
> - /* Modem has closed this connection, or device is down. */
> - cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
> - cf_sk->sk.sk_err = ECONNRESET;
> - set_rx_flow_on(cf_sk);
> - sk_error_report(&cf_sk->sk);
> - break;
> -
> - default:
> - pr_debug("Unexpected flow command %d\n", flow);
> - }
> -}
> -
> -static void caif_check_flow_release(struct sock *sk)
> -{
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> -
> - if (rx_flow_is_on(cf_sk))
> - return;
> -
> - if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) {
> - set_rx_flow_on(cf_sk);
> - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ);
> - }
> -}
> -
> -/*
> - * Copied from unix_dgram_recvmsg, but removed credit checks,
> - * changed locking, address handling and added MSG_TRUNC.
> - */
> -static int caif_seqpkt_recvmsg(struct socket *sock, struct msghdr *m,
> - size_t len, int flags)
> -
> -{
> - struct sock *sk = sock->sk;
> - struct sk_buff *skb;
> - int ret;
> - int copylen;
> -
> - ret = -EOPNOTSUPP;
> - if (flags & MSG_OOB)
> - goto read_error;
> -
> - skb = skb_recv_datagram(sk, flags, &ret);
> - if (!skb)
> - goto read_error;
> - copylen = skb->len;
> - if (len < copylen) {
> - m->msg_flags |= MSG_TRUNC;
> - copylen = len;
> - }
> -
> - ret = skb_copy_datagram_msg(skb, 0, m, copylen);
> - if (ret)
> - goto out_free;
> -
> - ret = (flags & MSG_TRUNC) ? skb->len : copylen;
> -out_free:
> - skb_free_datagram(sk, skb);
> - caif_check_flow_release(sk);
> - return ret;
> -
> -read_error:
> - return ret;
> -}
> -
> -
> -/* Copied from unix_stream_wait_data, identical except for lock call. */
> -static long caif_stream_data_wait(struct sock *sk, long timeo)
> -{
> - DEFINE_WAIT(wait);
> - lock_sock(sk);
> -
> - for (;;) {
> - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
> -
> - if (!skb_queue_empty(&sk->sk_receive_queue) ||
> - sk->sk_err ||
> - sk->sk_state != CAIF_CONNECTED ||
> - sock_flag(sk, SOCK_DEAD) ||
> - (sk->sk_shutdown & RCV_SHUTDOWN) ||
> - signal_pending(current) ||
> - !timeo)
> - break;
> -
> - sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
> - release_sock(sk);
> - timeo = schedule_timeout(timeo);
> - lock_sock(sk);
> -
> - if (sock_flag(sk, SOCK_DEAD))
> - break;
> -
> - sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
> - }
> -
> - finish_wait(sk_sleep(sk), &wait);
> - release_sock(sk);
> - return timeo;
> -}
> -
> -
> -/*
> - * Copied from unix_stream_recvmsg, but removed credit checks,
> - * changed locking calls, changed address handling.
> - */
> -static int caif_stream_recvmsg(struct socket *sock, struct msghdr *msg,
> - size_t size, int flags)
> -{
> - struct sock *sk = sock->sk;
> - int copied = 0;
> - int target;
> - int err = 0;
> - long timeo;
> -
> - err = -EOPNOTSUPP;
> - if (flags&MSG_OOB)
> - goto out;
> -
> - /*
> - * Lock the socket to prevent queue disordering
> - * while sleeps in memcpy_tomsg
> - */
> - err = -EAGAIN;
> - if (sk->sk_state == CAIF_CONNECTING)
> - goto out;
> -
> - caif_read_lock(sk);
> - target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
> - timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
> -
> - do {
> - int chunk;
> - struct sk_buff *skb;
> -
> - lock_sock(sk);
> - if (sock_flag(sk, SOCK_DEAD)) {
> - err = -ECONNRESET;
> - goto unlock;
> - }
> - skb = skb_dequeue(&sk->sk_receive_queue);
> - caif_check_flow_release(sk);
> -
> - if (skb == NULL) {
> - if (copied >= target)
> - goto unlock;
> - /*
> - * POSIX 1003.1g mandates this order.
> - */
> - err = sock_error(sk);
> - if (err)
> - goto unlock;
> - err = -ECONNRESET;
> - if (sk->sk_shutdown & RCV_SHUTDOWN)
> - goto unlock;
> -
> - err = -EPIPE;
> - if (sk->sk_state != CAIF_CONNECTED)
> - goto unlock;
> - if (sock_flag(sk, SOCK_DEAD))
> - goto unlock;
> -
> - release_sock(sk);
> -
> - err = -EAGAIN;
> - if (!timeo)
> - break;
> -
> - caif_read_unlock(sk);
> -
> - timeo = caif_stream_data_wait(sk, timeo);
> -
> - if (signal_pending(current)) {
> - err = sock_intr_errno(timeo);
> - goto out;
> - }
> - caif_read_lock(sk);
> - continue;
> -unlock:
> - release_sock(sk);
> - break;
> - }
> - release_sock(sk);
> - chunk = min_t(unsigned int, skb->len, size);
> - if (memcpy_to_msg(msg, skb->data, chunk)) {
> - skb_queue_head(&sk->sk_receive_queue, skb);
> - if (copied == 0)
> - copied = -EFAULT;
> - break;
> - }
> - copied += chunk;
> - size -= chunk;
> -
> - /* Mark read part of skb as used */
> - if (!(flags & MSG_PEEK)) {
> - skb_pull(skb, chunk);
> -
> - /* put the skb back if we didn't use it up. */
> - if (skb->len) {
> - skb_queue_head(&sk->sk_receive_queue, skb);
> - break;
> - }
> - kfree_skb(skb);
> -
> - } else {
> - /*
> - * It is questionable, see note in unix_dgram_recvmsg.
> - */
> - /* put message back and return */
> - skb_queue_head(&sk->sk_receive_queue, skb);
> - break;
> - }
> - } while (size);
> - caif_read_unlock(sk);
> -
> -out:
> - return copied ? : err;
> -}
> -
> -/*
> - * Copied from sock.c:sock_wait_for_wmem, but change to wait for
> - * CAIF flow-on and sock_writable.
> - */
> -static long caif_wait_for_flow_on(struct caifsock *cf_sk,
> - int wait_writeable, long timeo, int *err)
> -{
> - struct sock *sk = &cf_sk->sk;
> - DEFINE_WAIT(wait);
> - for (;;) {
> - *err = 0;
> - if (tx_flow_is_on(cf_sk) &&
> - (!wait_writeable || sock_writeable(&cf_sk->sk)))
> - break;
> - *err = -ETIMEDOUT;
> - if (!timeo)
> - break;
> - *err = -ERESTARTSYS;
> - if (signal_pending(current))
> - break;
> - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
> - *err = -ECONNRESET;
> - if (sk->sk_shutdown & SHUTDOWN_MASK)
> - break;
> - *err = -sk->sk_err;
> - if (sk->sk_err)
> - break;
> - *err = -EPIPE;
> - if (cf_sk->sk.sk_state != CAIF_CONNECTED)
> - break;
> - timeo = schedule_timeout(timeo);
> - }
> - finish_wait(sk_sleep(sk), &wait);
> - return timeo;
> -}
> -
> -/*
> - * Transmit a SKB. The device may temporarily request re-transmission
> - * by returning EAGAIN.
> - */
> -static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
> - int noblock, long timeo)
> -{
> - struct cfpkt *pkt;
> -
> - pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
> - memset(skb->cb, 0, sizeof(struct caif_payload_info));
> - cfpkt_set_prio(pkt, cf_sk->sk.sk_priority);
> -
> - if (cf_sk->layer.dn == NULL) {
> - kfree_skb(skb);
> - return -EINVAL;
> - }
> -
> - return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
> -}
> -
> -/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */
> -static int caif_seqpkt_sendmsg(struct socket *sock, struct msghdr *msg,
> - size_t len)
> -{
> - struct sock *sk = sock->sk;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - int buffer_size;
> - int ret = 0;
> - struct sk_buff *skb = NULL;
> - int noblock;
> - long timeo;
> - caif_assert(cf_sk);
> - ret = sock_error(sk);
> - if (ret)
> - goto err;
> -
> - ret = -EOPNOTSUPP;
> - if (msg->msg_flags&MSG_OOB)
> - goto err;
> -
> - ret = -EOPNOTSUPP;
> - if (msg->msg_namelen)
> - goto err;
> -
> - noblock = msg->msg_flags & MSG_DONTWAIT;
> -
> - timeo = sock_sndtimeo(sk, noblock);
> - timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk),
> - 1, timeo, &ret);
> -
> - if (ret)
> - goto err;
> - ret = -EPIPE;
> - if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
> - sock_flag(sk, SOCK_DEAD) ||
> - (sk->sk_shutdown & RCV_SHUTDOWN))
> - goto err;
> -
> - /* Error if trying to write more than maximum frame size. */
> - ret = -EMSGSIZE;
> - if (len > cf_sk->maxframe && cf_sk->sk.sk_protocol != CAIFPROTO_RFM)
> - goto err;
> -
> - buffer_size = len + cf_sk->headroom + cf_sk->tailroom;
> -
> - ret = -ENOMEM;
> - skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret);
> -
> - if (!skb || skb_tailroom(skb) < buffer_size)
> - goto err;
> -
> - skb_reserve(skb, cf_sk->headroom);
> -
> - ret = memcpy_from_msg(skb_put(skb, len), msg, len);
> -
> - if (ret)
> - goto err;
> - ret = transmit_skb(skb, cf_sk, noblock, timeo);
> - if (ret < 0)
> - /* skb is already freed */
> - return ret;
> -
> - return len;
> -err:
> - kfree_skb(skb);
> - return ret;
> -}
> -
> -/*
> - * Copied from unix_stream_sendmsg and adapted to CAIF:
> - * Changed removed permission handling and added waiting for flow on
> - * and other minor adaptations.
> - */
> -static int caif_stream_sendmsg(struct socket *sock, struct msghdr *msg,
> - size_t len)
> -{
> - struct sock *sk = sock->sk;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - int err, size;
> - struct sk_buff *skb;
> - int sent = 0;
> - long timeo;
> -
> - err = -EOPNOTSUPP;
> - if (unlikely(msg->msg_flags&MSG_OOB))
> - goto out_err;
> -
> - if (unlikely(msg->msg_namelen))
> - goto out_err;
> -
> - timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
> - timeo = caif_wait_for_flow_on(cf_sk, 1, timeo, &err);
> -
> - if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN))
> - goto pipe_err;
> -
> - while (sent < len) {
> -
> - size = len-sent;
> -
> - if (size > cf_sk->maxframe)
> - size = cf_sk->maxframe;
> -
> - /* If size is more than half of sndbuf, chop up message */
> - if (size > ((sk->sk_sndbuf >> 1) - 64))
> - size = (sk->sk_sndbuf >> 1) - 64;
> -
> - if (size > SKB_MAX_ALLOC)
> - size = SKB_MAX_ALLOC;
> -
> - skb = sock_alloc_send_skb(sk,
> - size + cf_sk->headroom +
> - cf_sk->tailroom,
> - msg->msg_flags&MSG_DONTWAIT,
> - &err);
> - if (skb == NULL)
> - goto out_err;
> -
> - skb_reserve(skb, cf_sk->headroom);
> - /*
> - * If you pass two values to the sock_alloc_send_skb
> - * it tries to grab the large buffer with GFP_NOFS
> - * (which can fail easily), and if it fails grab the
> - * fallback size buffer which is under a page and will
> - * succeed. [Alan]
> - */
> - size = min_t(int, size, skb_tailroom(skb));
> -
> - err = memcpy_from_msg(skb_put(skb, size), msg, size);
> - if (err) {
> - kfree_skb(skb);
> - goto out_err;
> - }
> - err = transmit_skb(skb, cf_sk,
> - msg->msg_flags&MSG_DONTWAIT, timeo);
> - if (err < 0)
> - /* skb is already freed */
> - goto pipe_err;
> -
> - sent += size;
> - }
> -
> - return sent;
> -
> -pipe_err:
> - if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
> - send_sig(SIGPIPE, current, 0);
> - err = -EPIPE;
> -out_err:
> - return sent ? : err;
> -}
> -
> -static int setsockopt(struct socket *sock, int lvl, int opt, sockptr_t ov,
> - unsigned int ol)
> -{
> - struct sock *sk = sock->sk;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - int linksel;
> -
> - if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED)
> - return -ENOPROTOOPT;
> -
> - switch (opt) {
> - case CAIFSO_LINK_SELECT:
> - if (ol < sizeof(int))
> - return -EINVAL;
> - if (lvl != SOL_CAIF)
> - goto bad_sol;
> - if (copy_from_sockptr(&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 CAIFSO_REQ_PARAM:
> - if (lvl != SOL_CAIF)
> - goto bad_sol;
> - if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL)
> - return -ENOPROTOOPT;
> - lock_sock(&(cf_sk->sk));
> - if (ol > sizeof(cf_sk->conn_req.param.data) ||
> - copy_from_sockptr(&cf_sk->conn_req.param.data, ov, ol)) {
> - release_sock(&cf_sk->sk);
> - return -EINVAL;
> - }
> - cf_sk->conn_req.param.size = ol;
> - release_sock(&cf_sk->sk);
> - return 0;
> -
> - default:
> - return -ENOPROTOOPT;
> - }
> -
> - return 0;
> -bad_sol:
> - return -ENOPROTOOPT;
> -
> -}
> -
> -/*
> - * caif_connect() - Connect a CAIF Socket
> - * Copied and modified af_irda.c:irda_connect().
> - *
> - * Note : by consulting "errno", the user space caller may learn the cause
> - * of the failure. Most of them are visible in the function, others may come
> - * from subroutines called and are listed here :
> - * o -EAFNOSUPPORT: bad socket family or type.
> - * o -ESOCKTNOSUPPORT: bad socket type or protocol
> - * o -EINVAL: bad socket address, or CAIF link type
> - * o -ECONNREFUSED: remote end refused the connection.
> - * o -EINPROGRESS: connect request sent but timed out (or non-blocking)
> - * o -EISCONN: already connected.
> - * o -ETIMEDOUT: Connection timed out (send timeout)
> - * o -ENODEV: No link layer to send request
> - * o -ECONNRESET: Received Shutdown indication or lost link layer
> - * o -ENOMEM: Out of memory
> - *
> - * State Strategy:
> - * o sk_state: holds the CAIF_* protocol state, it's updated by
> - * caif_ctrl_cb.
> - * o sock->state: holds the SS_* socket state and is updated by connect and
> - * disconnect.
> - */
> -static int caif_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
> - int addr_len, int flags)
> -{
> - struct sock *sk = sock->sk;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - long timeo;
> - int err;
> - int ifindex, headroom, tailroom;
> - unsigned int mtu;
> - struct net_device *dev;
> -
> - lock_sock(sk);
> -
> - err = -EINVAL;
> - if (addr_len < offsetofend(struct sockaddr, sa_family))
> - goto out;
> -
> - err = -EAFNOSUPPORT;
> - if (uaddr->sa_family != AF_CAIF)
> - goto out;
> -
> - switch (sock->state) {
> - case SS_UNCONNECTED:
> - /* Normal case, a fresh connect */
> - caif_assert(sk->sk_state == CAIF_DISCONNECTED);
> - break;
> - case SS_CONNECTING:
> - switch (sk->sk_state) {
> - case CAIF_CONNECTED:
> - sock->state = SS_CONNECTED;
> - err = -EISCONN;
> - goto out;
> - case CAIF_DISCONNECTED:
> - /* Reconnect allowed */
> - break;
> - case CAIF_CONNECTING:
> - err = -EALREADY;
> - if (flags & O_NONBLOCK)
> - goto out;
> - goto wait_connect;
> - }
> - break;
> - case SS_CONNECTED:
> - caif_assert(sk->sk_state == CAIF_CONNECTED ||
> - sk->sk_state == CAIF_DISCONNECTED);
> - if (sk->sk_shutdown & SHUTDOWN_MASK) {
> - /* Allow re-connect after SHUTDOWN_IND */
> - caif_disconnect_client(sock_net(sk), &cf_sk->layer);
> - caif_free_client(&cf_sk->layer);
> - break;
> - }
> - /* No reconnect on a seqpacket socket */
> - err = -EISCONN;
> - goto out;
> - case SS_DISCONNECTING:
> - case SS_FREE:
> - caif_assert(1); /*Should never happen */
> - break;
> - }
> - sk->sk_state = CAIF_DISCONNECTED;
> - sock->state = SS_UNCONNECTED;
> - sk_stream_kill_queues(&cf_sk->sk);
> -
> - err = -EINVAL;
> - if (addr_len != sizeof(struct sockaddr_caif))
> - goto out;
> -
> - memcpy(&cf_sk->conn_req.sockaddr, uaddr,
> - sizeof(struct sockaddr_caif));
> -
> - /* Move to connecting socket, start sending Connect Requests */
> - sock->state = SS_CONNECTING;
> - sk->sk_state = CAIF_CONNECTING;
> -
> - /* Check priority value comming from socket */
> - /* if priority value is out of range it will be ajusted */
> - if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
> - cf_sk->conn_req.priority = CAIF_PRIO_MAX;
> - else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN)
> - cf_sk->conn_req.priority = CAIF_PRIO_MIN;
> - else
> - cf_sk->conn_req.priority = cf_sk->sk.sk_priority;
> -
> - /*ifindex = id of the interface.*/
> - cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
> -
> - cf_sk->layer.receive = caif_sktrecv_cb;
> -
> - err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
> - &cf_sk->layer, &ifindex, &headroom, &tailroom);
> -
> - if (err < 0) {
> - cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
> - cf_sk->sk.sk_state = CAIF_DISCONNECTED;
> - goto out;
> - }
> -
> - err = -ENODEV;
> - rcu_read_lock();
> - dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
> - if (!dev) {
> - rcu_read_unlock();
> - goto out;
> - }
> - cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom);
> - mtu = dev->mtu;
> - rcu_read_unlock();
> -
> - cf_sk->tailroom = tailroom;
> - cf_sk->maxframe = mtu - (headroom + tailroom);
> - if (cf_sk->maxframe < 1) {
> - pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu);
> - err = -ENODEV;
> - goto out;
> - }
> -
> - err = -EINPROGRESS;
> -wait_connect:
> -
> - if (sk->sk_state != CAIF_CONNECTED && (flags & O_NONBLOCK))
> - goto out;
> -
> - timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
> -
> - release_sock(sk);
> - err = -ERESTARTSYS;
> - timeo = wait_event_interruptible_timeout(*sk_sleep(sk),
> - sk->sk_state != CAIF_CONNECTING,
> - timeo);
> - lock_sock(sk);
> - if (timeo < 0)
> - goto out; /* -ERESTARTSYS */
> -
> - err = -ETIMEDOUT;
> - if (timeo == 0 && sk->sk_state != CAIF_CONNECTED)
> - goto out;
> - if (sk->sk_state != CAIF_CONNECTED) {
> - sock->state = SS_UNCONNECTED;
> - err = sock_error(sk);
> - if (!err)
> - err = -ECONNREFUSED;
> - goto out;
> - }
> - sock->state = SS_CONNECTED;
> - err = 0;
> -out:
> - release_sock(sk);
> - return err;
> -}
> -
> -/*
> - * caif_release() - Disconnect a CAIF Socket
> - * Copied and modified af_irda.c:irda_release().
> - */
> -static int caif_release(struct socket *sock)
> -{
> - struct sock *sk = sock->sk;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> -
> - if (!sk)
> - return 0;
> -
> - set_tx_flow_off(cf_sk);
> -
> - /*
> - * Ensure that packets are not queued after this point in time.
> - * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock,
> - * this ensures no packets when sock is dead.
> - */
> - spin_lock_bh(&sk->sk_receive_queue.lock);
> - sock_set_flag(sk, SOCK_DEAD);
> - spin_unlock_bh(&sk->sk_receive_queue.lock);
> - sock->sk = NULL;
> -
> - WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
> - debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
> -
> - lock_sock(&(cf_sk->sk));
> - sk->sk_state = CAIF_DISCONNECTED;
> - sk->sk_shutdown = SHUTDOWN_MASK;
> -
> - caif_disconnect_client(sock_net(sk), &cf_sk->layer);
> - cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
> - wake_up_interruptible_poll(sk_sleep(sk), EPOLLERR|EPOLLHUP);
> -
> - sock_orphan(sk);
> - sk_stream_kill_queues(&cf_sk->sk);
> - release_sock(sk);
> - sock_put(sk);
> - return 0;
> -}
> -
> -/* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */
> -static __poll_t caif_poll(struct file *file,
> - struct socket *sock, poll_table *wait)
> -{
> - struct sock *sk = sock->sk;
> - __poll_t mask;
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> -
> - sock_poll_wait(file, sock, wait);
> - mask = 0;
> -
> - /* exceptional events? */
> - if (sk->sk_err)
> - mask |= EPOLLERR;
> - if (sk->sk_shutdown == SHUTDOWN_MASK)
> - mask |= EPOLLHUP;
> - if (sk->sk_shutdown & RCV_SHUTDOWN)
> - mask |= EPOLLRDHUP;
> -
> - /* readable? */
> - if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
> - (sk->sk_shutdown & RCV_SHUTDOWN))
> - mask |= EPOLLIN | EPOLLRDNORM;
> -
> - /*
> - * we set writable also when the other side has shut down the
> - * connection. This prevents stuck sockets.
> - */
> - if (sock_writeable(sk) && tx_flow_is_on(cf_sk))
> - mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
> -
> - return mask;
> -}
> -
> -static const struct proto_ops caif_seqpacket_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 = sock_no_shutdown,
> - .setsockopt = setsockopt,
> - .sendmsg = caif_seqpkt_sendmsg,
> - .recvmsg = caif_seqpkt_recvmsg,
> - .mmap = sock_no_mmap,
> -};
> -
> -static const struct proto_ops caif_stream_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 = sock_no_shutdown,
> - .setsockopt = setsockopt,
> - .sendmsg = caif_stream_sendmsg,
> - .recvmsg = caif_stream_recvmsg,
> - .mmap = sock_no_mmap,
> -};
> -
> -/* This function is called when a socket is finally destroyed. */
> -static void caif_sock_destructor(struct sock *sk)
> -{
> - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
> - caif_assert(!refcount_read(&sk->sk_wmem_alloc));
> - caif_assert(sk_unhashed(sk));
> - caif_assert(!sk->sk_socket);
> - if (!sock_flag(sk, SOCK_DEAD)) {
> - pr_debug("Attempt to release alive CAIF socket: %p\n", sk);
> - return;
> - }
> - sk_stream_kill_queues(&cf_sk->sk);
> - WARN_ON_ONCE(sk->sk_forward_alloc);
> - caif_free_client(&cf_sk->layer);
> -}
> -
> -static int caif_create(struct net *net, struct socket *sock, int protocol,
> - int kern)
> -{
> - struct sock *sk = NULL;
> - struct caifsock *cf_sk = NULL;
> - static struct proto prot = {.name = "PF_CAIF",
> - .owner = THIS_MODULE,
> - .obj_size = sizeof(struct caifsock),
> - .useroffset = offsetof(struct caifsock, conn_req.param),
> - .usersize = sizeof_field(struct caifsock, conn_req.param)
> - };
> -
> - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN))
> - return -EPERM;
> - /*
> - * The sock->type specifies the socket type to use.
> - * The CAIF socket is a packet stream in the sense
> - * that it is packet based. CAIF trusts the reliability
> - * of the link, no resending is implemented.
> - */
> - if (sock->type == SOCK_SEQPACKET)
> - sock->ops = &caif_seqpacket_ops;
> - else if (sock->type == SOCK_STREAM)
> - sock->ops = &caif_stream_ops;
> - else
> - return -ESOCKTNOSUPPORT;
> -
> - 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.
> - */
> - sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot, kern);
> - if (!sk)
> - return -ENOMEM;
> -
> - cf_sk = container_of(sk, struct caifsock, sk);
> -
> - /* Store the protocol */
> - sk->sk_protocol = (unsigned char) protocol;
> -
> - /* Initialize default priority for well-known cases */
> - switch (protocol) {
> - case CAIFPROTO_AT:
> - sk->sk_priority = TC_PRIO_CONTROL;
> - break;
> - case CAIFPROTO_RFM:
> - sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
> - break;
> - default:
> - sk->sk_priority = TC_PRIO_BESTEFFORT;
> - }
> -
> - /*
> - * 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);
> - sk->sk_destruct = caif_sock_destructor;
> -
> - mutex_init(&cf_sk->readlock); /* single task reading lock */
> - cf_sk->layer.ctrlcmd = caif_ctrl_cb;
> - cf_sk->sk.sk_socket->state = SS_UNCONNECTED;
> - cf_sk->sk.sk_state = CAIF_DISCONNECTED;
> -
> - set_tx_flow_off(cf_sk);
> - set_rx_flow_on(cf_sk);
> -
> - /* Set default options on configuration */
> - cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
> - cf_sk->conn_req.protocol = protocol;
> - release_sock(&cf_sk->sk);
> - return 0;
> -}
> -
> -
> -static const struct net_proto_family caif_family_ops = {
> - .family = PF_CAIF,
> - .create = caif_create,
> - .owner = THIS_MODULE,
> -};
> -
> -static int __init caif_sktinit_module(void)
> -{
> - return sock_register(&caif_family_ops);
> -}
> -
> -static void __exit caif_sktexit_module(void)
> -{
> - sock_unregister(PF_CAIF);
> -}
> -module_init(caif_sktinit_module);
> -module_exit(caif_sktexit_module);
> diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c
> deleted file mode 100644
> index 4d44960d4c2f..000000000000
> --- a/net/caif/caif_usb.c
> +++ /dev/null
> @@ -1,216 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * CAIF USB handler
> - * Copyright (C) ST-Ericsson AB 2011
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/module.h>
> -#include <linux/netdevice.h>
> -#include <linux/slab.h>
> -#include <linux/mii.h>
> -#include <linux/usb.h>
> -#include <linux/usb/usbnet.h>
> -#include <linux/etherdevice.h>
> -#include <net/netns/generic.h>
> -#include <net/caif/caif_dev.h>
> -#include <net/caif/caif_layer.h>
> -#include <net/caif/cfpkt.h>
> -#include <net/caif/cfcnfg.h>
> -
> -MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol USB support");
> -MODULE_LICENSE("GPL");
> -
> -#define CFUSB_PAD_DESCR_SZ 1 /* Alignment descriptor length */
> -#define CFUSB_ALIGNMENT 4 /* Number of bytes to align. */
> -#define CFUSB_MAX_HEADLEN (CFUSB_PAD_DESCR_SZ + CFUSB_ALIGNMENT-1)
> -#define STE_USB_VID 0x04cc /* USB Product ID for ST-Ericsson */
> -#define STE_USB_PID_CAIF 0x230f /* Product id for CAIF Modems */
> -
> -struct cfusbl {
> - struct cflayer layer;
> - u8 tx_eth_hdr[ETH_HLEN];
> -};
> -
> -static bool pack_added;
> -
> -static int cfusbl_receive(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - u8 hpad;
> -
> - /* Remove padding. */
> - cfpkt_extr_head(pkt, &hpad, 1);
> - cfpkt_extr_head(pkt, NULL, hpad);
> - return layr->up->receive(layr->up, pkt);
> -}
> -
> -static int cfusbl_transmit(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - struct caif_payload_info *info;
> - u8 hpad;
> - u8 zeros[CFUSB_ALIGNMENT];
> - struct sk_buff *skb;
> - struct cfusbl *usbl = container_of(layr, struct cfusbl, layer);
> -
> - skb = cfpkt_tonative(pkt);
> -
> - skb_reset_network_header(skb);
> - skb->protocol = htons(ETH_P_IP);
> -
> - info = cfpkt_info(pkt);
> - hpad = (info->hdr_len + CFUSB_PAD_DESCR_SZ) & (CFUSB_ALIGNMENT - 1);
> -
> - if (skb_headroom(skb) < ETH_HLEN + CFUSB_PAD_DESCR_SZ + hpad) {
> - pr_warn("Headroom too small\n");
> - kfree_skb(skb);
> - return -EIO;
> - }
> - memset(zeros, 0, hpad);
> -
> - cfpkt_add_head(pkt, zeros, hpad);
> - cfpkt_add_head(pkt, &hpad, 1);
> - cfpkt_add_head(pkt, usbl->tx_eth_hdr, sizeof(usbl->tx_eth_hdr));
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> -
> -static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
> - int phyid)
> -{
> - if (layr->up && layr->up->ctrlcmd)
> - layr->up->ctrlcmd(layr->up, ctrl, layr->id);
> -}
> -
> -static struct cflayer *cfusbl_create(int phyid, const u8 ethaddr[ETH_ALEN],
> - u8 braddr[ETH_ALEN])
> -{
> - struct cfusbl *this = kmalloc_obj(struct cfusbl, GFP_ATOMIC);
> -
> - if (!this)
> - return NULL;
> -
> - caif_assert(offsetof(struct cfusbl, layer) == 0);
> -
> - memset(&this->layer, 0, sizeof(this->layer));
> - this->layer.receive = cfusbl_receive;
> - this->layer.transmit = cfusbl_transmit;
> - this->layer.ctrlcmd = cfusbl_ctrlcmd;
> - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "usb%d", phyid);
> - this->layer.id = phyid;
> -
> - /*
> - * Construct TX ethernet header:
> - * 0-5 destination address
> - * 5-11 source address
> - * 12-13 protocol type
> - */
> - ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], braddr);
> - ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], ethaddr);
> - this->tx_eth_hdr[12] = cpu_to_be16(ETH_P_802_EX1) & 0xff;
> - this->tx_eth_hdr[13] = (cpu_to_be16(ETH_P_802_EX1) >> 8) & 0xff;
> - pr_debug("caif ethernet TX-header dst:%pM src:%pM type:%02x%02x\n",
> - this->tx_eth_hdr, this->tx_eth_hdr + ETH_ALEN,
> - this->tx_eth_hdr[12], this->tx_eth_hdr[13]);
> -
> - return (struct cflayer *) this;
> -}
> -
> -static void cfusbl_release(struct cflayer *layer)
> -{
> - kfree(layer);
> -}
> -
> -static struct packet_type caif_usb_type __read_mostly = {
> - .type = cpu_to_be16(ETH_P_802_EX1),
> -};
> -
> -static int cfusbl_device_notify(struct notifier_block *me, unsigned long what,
> - void *ptr)
> -{
> - struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> - struct caif_dev_common common;
> - struct cflayer *layer, *link_support;
> - struct usbnet *usbnet;
> - struct usb_device *usbdev;
> - int res;
> -
> - if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED)
> - return 0;
> -
> - /* Check whether we have a NCM device, and find its VID/PID. */
> - if (!(dev->dev.parent && dev->dev.parent->driver &&
> - strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0))
> - return 0;
> -
> - usbnet = netdev_priv(dev);
> - usbdev = usbnet->udev;
> -
> - pr_debug("USB CDC NCM device VID:0x%4x PID:0x%4x\n",
> - le16_to_cpu(usbdev->descriptor.idVendor),
> - le16_to_cpu(usbdev->descriptor.idProduct));
> -
> - /* Check for VID/PID that supports CAIF */
> - if (!(le16_to_cpu(usbdev->descriptor.idVendor) == STE_USB_VID &&
> - le16_to_cpu(usbdev->descriptor.idProduct) == STE_USB_PID_CAIF))
> - return 0;
> -
> - if (what == NETDEV_UNREGISTER)
> - module_put(THIS_MODULE);
> -
> - if (what != NETDEV_REGISTER)
> - return 0;
> -
> - __module_get(THIS_MODULE);
> -
> - memset(&common, 0, sizeof(common));
> - common.use_frag = false;
> - common.use_fcs = false;
> - common.use_stx = false;
> - common.link_select = CAIF_LINK_HIGH_BANDW;
> - common.flowctrl = NULL;
> -
> - link_support = cfusbl_create(dev->ifindex, dev->dev_addr,
> - dev->broadcast);
> -
> - if (!link_support)
> - return -ENOMEM;
> -
> - if (dev->num_tx_queues > 1)
> - pr_warn("USB device uses more than one tx queue\n");
> -
> - res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
> - &layer, &caif_usb_type.func);
> - if (res)
> - goto err;
> -
> - if (!pack_added)
> - dev_add_pack(&caif_usb_type);
> - pack_added = true;
> -
> - strscpy(layer->name, dev->name, sizeof(layer->name));
> -
> - return 0;
> -err:
> - cfusbl_release(link_support);
> - return res;
> -}
> -
> -static struct notifier_block caif_device_notifier = {
> - .notifier_call = cfusbl_device_notify,
> - .priority = 0,
> -};
> -
> -static int __init cfusbl_init(void)
> -{
> - return register_netdevice_notifier(&caif_device_notifier);
> -}
> -
> -static void __exit cfusbl_exit(void)
> -{
> - unregister_netdevice_notifier(&caif_device_notifier);
> - dev_remove_pack(&caif_usb_type);
> -}
> -
> -module_init(cfusbl_init);
> -module_exit(cfusbl_exit);
> diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
> deleted file mode 100644
> index 8a80914783e8..000000000000
> --- a/net/caif/cfcnfg.c
> +++ /dev/null
> @@ -1,612 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/kernel.h>
> -#include <linux/stddef.h>
> -#include <linux/slab.h>
> -#include <linux/netdevice.h>
> -#include <linux/module.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 <net/caif/caif_dev.h>
> -
> -#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 {
> - struct list_head node;
> - bool up;
> -
> - /* 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;
> -
> - /* Information about the physical device */
> - struct dev_info dev_info;
> -
> - /* Interface index */
> - int ifindex;
> -
> - /* Protocol head room added for CAIF link layer */
> - int head_room;
> -
> - /* Use Start of frame checksum */
> - bool use_fcs;
> -};
> -
> -struct cfcnfg {
> - struct cflayer layer;
> - struct cflayer *ctrl;
> - struct cflayer *mux;
> - struct list_head phys;
> - struct mutex lock;
> -};
> -
> -static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id,
> - enum cfctrl_srv serv, u8 phyid,
> - struct cflayer *adapt_layer);
> -static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id);
> -static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
> - struct cflayer *adapt_layer);
> -static void cfctrl_resp_func(void);
> -static void cfctrl_enum_resp(void);
> -
> -struct cfcnfg *cfcnfg_create(void)
> -{
> - struct cfcnfg *this;
> - struct cfctrl_rsp *resp;
> -
> - might_sleep();
> -
> - /* Initiate this layer */
> - this = kzalloc_obj(struct cfcnfg, GFP_ATOMIC);
> - if (!this)
> - return NULL;
> - 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 = cfcnfg_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 = cfcnfg_linkup_rsp;
> - resp->reject_rsp = cfcnfg_reject_rsp;
> - INIT_LIST_HEAD(&this->phys);
> -
> - cfmuxl_set_uplayer(this->mux, this->ctrl, 0);
> - layer_set_dn(this->ctrl, this->mux);
> - layer_set_up(this->ctrl, this);
> - mutex_init(&this->lock);
> -
> - return this;
> -out_of_mem:
> - synchronize_rcu();
> -
> - kfree(this->mux);
> - kfree(this->ctrl);
> - kfree(this);
> - return NULL;
> -}
> -
> -void cfcnfg_remove(struct cfcnfg *cfg)
> -{
> - might_sleep();
> - if (cfg) {
> - synchronize_rcu();
> -
> - kfree(cfg->mux);
> - cfctrl_remove(cfg->ctrl);
> - kfree(cfg);
> - }
> -}
> -
> -static void cfctrl_resp_func(void)
> -{
> -}
> -
> -static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo_rcu(struct cfcnfg *cnfg,
> - u8 phyid)
> -{
> - struct cfcnfg_phyinfo *phy;
> -
> - list_for_each_entry_rcu(phy, &cnfg->phys, node)
> - if (phy->id == phyid)
> - return phy;
> - return NULL;
> -}
> -
> -static void cfctrl_enum_resp(void)
> -{
> -}
> -
> -static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
> - enum cfcnfg_phy_preference phy_pref)
> -{
> - /* Try to match with specified preference */
> - struct cfcnfg_phyinfo *phy;
> -
> - list_for_each_entry_rcu(phy, &cnfg->phys, node) {
> - if (phy->up && phy->pref == phy_pref &&
> - phy->frm_layer != NULL)
> -
> - return &phy->dev_info;
> - }
> -
> - /* Otherwise just return something */
> - list_for_each_entry_rcu(phy, &cnfg->phys, node)
> - if (phy->up)
> - return &phy->dev_info;
> -
> - return NULL;
> -}
> -
> -static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
> -{
> - struct cfcnfg_phyinfo *phy;
> -
> - list_for_each_entry_rcu(phy, &cnfg->phys, node)
> - if (phy->ifindex == ifi && phy->up)
> - return phy->id;
> - return -ENODEV;
> -}
> -
> -int caif_disconnect_client(struct net *net, struct cflayer *adap_layer)
> -{
> - u8 channel_id;
> - struct cfcnfg *cfg = get_cfcnfg(net);
> -
> - caif_assert(adap_layer != NULL);
> - cfctrl_cancel_req(cfg->ctrl, adap_layer);
> - channel_id = adap_layer->id;
> - if (channel_id != 0) {
> - struct cflayer *servl;
> - servl = cfmuxl_remove_uplayer(cfg->mux, channel_id);
> - cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer);
> - if (servl != NULL)
> - layer_set_up(servl, NULL);
> - } else
> - pr_debug("nothing to disconnect\n");
> -
> - /* Do RCU sync before initiating cleanup */
> - synchronize_rcu();
> - if (adap_layer->ctrlcmd != NULL)
> - adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0);
> - return 0;
> -
> -}
> -EXPORT_SYMBOL(caif_disconnect_client);
> -
> -static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
> -{
> -}
> -
> -static const int protohead[CFCTRL_SRV_MASK] = {
> - [CFCTRL_SRV_VEI] = 4,
> - [CFCTRL_SRV_DATAGRAM] = 7,
> - [CFCTRL_SRV_UTIL] = 4,
> - [CFCTRL_SRV_RFM] = 3,
> - [CFCTRL_SRV_DBG] = 3,
> -};
> -
> -
> -static int caif_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;
> - int res;
> -
> - memset(l, 0, sizeof(*l));
> - /* In caif protocol low value is high priority */
> - l->priority = CAIF_PRIO_MAX - s->priority + 1;
> -
> - if (s->ifindex != 0) {
> - res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
> - if (res < 0)
> - return res;
> - l->phyid = res;
> - } 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;
> - l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3;
> - l->chtype = s->sockaddr.u.at.type & 0x3;
> - 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;
> - strscpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
> - sizeof(l->u.rfm.volume));
> - break;
> - case CAIFPROTO_UTIL:
> - l->linktype = CFCTRL_SRV_UTIL;
> - l->endpoint = 0x00;
> - l->chtype = 0x00;
> - strscpy(l->u.utility.name, s->sockaddr.u.util.service,
> - sizeof(l->u.utility.name));
> - 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;
> - case CAIFPROTO_DEBUG:
> - l->linktype = CFCTRL_SRV_DBG;
> - l->endpoint = s->sockaddr.u.dbg.service;
> - l->chtype = s->sockaddr.u.dbg.type;
> - break;
> - default:
> - return -EINVAL;
> - }
> - return 0;
> -}
> -
> -int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
> - struct cflayer *adap_layer, int *ifindex,
> - int *proto_head, int *proto_tail)
> -{
> - struct cflayer *frml;
> - struct cfcnfg_phyinfo *phy;
> - int err;
> - struct cfctrl_link_param param;
> - struct cfcnfg *cfg = get_cfcnfg(net);
> -
> - rcu_read_lock();
> - err = caif_connect_req_to_link_param(cfg, conn_req, ¶m);
> - if (err)
> - goto unlock;
> -
> - phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid);
> - if (!phy) {
> - err = -ENODEV;
> - goto unlock;
> - }
> - err = -EINVAL;
> -
> - if (adap_layer == NULL) {
> - pr_err("adap_layer is zero\n");
> - goto unlock;
> - }
> - if (adap_layer->receive == NULL) {
> - pr_err("adap_layer->receive is NULL\n");
> - goto unlock;
> - }
> - if (adap_layer->ctrlcmd == NULL) {
> - pr_err("adap_layer->ctrlcmd == NULL\n");
> - goto unlock;
> - }
> -
> - err = -ENODEV;
> - frml = phy->frm_layer;
> - if (frml == NULL) {
> - pr_err("Specified PHY type does not exist!\n");
> - goto unlock;
> - }
> - caif_assert(param.phyid == phy->id);
> - caif_assert(phy->frm_layer->id ==
> - param.phyid);
> - caif_assert(phy->phy_layer->id ==
> - param.phyid);
> -
> - *ifindex = phy->ifindex;
> - *proto_tail = 2;
> - *proto_head = protohead[param.linktype] + phy->head_room;
> -
> - rcu_read_unlock();
> -
> - /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
> - cfctrl_enum_req(cfg->ctrl, param.phyid);
> - return cfctrl_linkup_request(cfg->ctrl, ¶m, adap_layer);
> -
> -unlock:
> - rcu_read_unlock();
> - return err;
> -}
> -EXPORT_SYMBOL(caif_connect_client);
> -
> -static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
> - 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
> -cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
> - u8 phyid, struct cflayer *adapt_layer)
> -{
> - struct cfcnfg *cnfg = container_obj(layer);
> - struct cflayer *servicel = NULL;
> - struct cfcnfg_phyinfo *phyinfo;
> - struct net_device *netdev;
> -
> - if (channel_id == 0) {
> - pr_warn("received channel_id zero\n");
> - if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL)
> - adapt_layer->ctrlcmd(adapt_layer,
> - CAIF_CTRLCMD_INIT_FAIL_RSP, 0);
> - return;
> - }
> -
> - rcu_read_lock();
> -
> - if (adapt_layer == NULL) {
> - pr_debug("link setup response but no client exist, send linkdown back\n");
> - cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
> - goto unlock;
> - }
> -
> - caif_assert(cnfg != NULL);
> - caif_assert(phyid != 0);
> -
> - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
> - if (phyinfo == NULL) {
> - pr_err("ERROR: Link Layer Device disappeared while connecting\n");
> - goto unlock;
> - }
> -
> - caif_assert(phyinfo != NULL);
> - caif_assert(phyinfo->id == phyid);
> - caif_assert(phyinfo->phy_layer != NULL);
> - caif_assert(phyinfo->phy_layer->id == phyid);
> -
> - adapt_layer->id = channel_id;
> -
> - switch (serv) {
> - case CFCTRL_SRV_VEI:
> - servicel = cfvei_create(channel_id, &phyinfo->dev_info);
> - break;
> - case CFCTRL_SRV_DATAGRAM:
> - servicel = cfdgml_create(channel_id,
> - &phyinfo->dev_info);
> - break;
> - case CFCTRL_SRV_RFM:
> - netdev = phyinfo->dev_info.dev;
> - servicel = cfrfml_create(channel_id, &phyinfo->dev_info,
> - netdev->mtu);
> - break;
> - case CFCTRL_SRV_UTIL:
> - servicel = cfutill_create(channel_id, &phyinfo->dev_info);
> - break;
> - case CFCTRL_SRV_VIDEO:
> - servicel = cfvidl_create(channel_id, &phyinfo->dev_info);
> - break;
> - case CFCTRL_SRV_DBG:
> - servicel = cfdbgl_create(channel_id, &phyinfo->dev_info);
> - break;
> - default:
> - pr_err("Protocol error. Link setup response - unknown channel type\n");
> - goto unlock;
> - }
> - if (!servicel)
> - goto unlock;
> - layer_set_dn(servicel, cnfg->mux);
> - cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id);
> - layer_set_up(servicel, adapt_layer);
> - layer_set_dn(adapt_layer, servicel);
> -
> - rcu_read_unlock();
> -
> - servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
> - return;
> -unlock:
> - rcu_read_unlock();
> -}
> -
> -int
> -cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
> - struct net_device *dev, struct cflayer *phy_layer,
> - enum cfcnfg_phy_preference pref,
> - struct cflayer *link_support,
> - bool fcs, int head_room)
> -{
> - struct cflayer *frml;
> - struct cfcnfg_phyinfo *phyinfo = NULL;
> - int i, res = 0;
> - u8 phyid;
> -
> - mutex_lock(&cnfg->lock);
> -
> - /* CAIF protocol allow maximum 6 link-layers */
> - for (i = 0; i < 7; i++) {
> - phyid = (dev->ifindex + i) & 0x7;
> - if (phyid == 0)
> - continue;
> - if (cfcnfg_get_phyinfo_rcu(cnfg, phyid) == NULL)
> - goto got_phyid;
> - }
> - pr_warn("Too many CAIF Link Layers (max 6)\n");
> - res = -EEXIST;
> - goto out;
> -
> -got_phyid:
> - phyinfo = kzalloc_obj(struct cfcnfg_phyinfo, GFP_ATOMIC);
> - if (!phyinfo) {
> - res = -ENOMEM;
> - goto out;
> - }
> -
> - phy_layer->id = phyid;
> - phyinfo->pref = pref;
> - phyinfo->id = phyid;
> - phyinfo->dev_info.id = phyid;
> - phyinfo->dev_info.dev = dev;
> - phyinfo->phy_layer = phy_layer;
> - phyinfo->ifindex = dev->ifindex;
> - phyinfo->head_room = head_room;
> - phyinfo->use_fcs = fcs;
> -
> - frml = cffrml_create(phyid, fcs);
> -
> - if (!frml) {
> - res = -ENOMEM;
> - goto out_err;
> - }
> - phyinfo->frm_layer = frml;
> - layer_set_up(frml, cnfg->mux);
> -
> - if (link_support != NULL) {
> - link_support->id = phyid;
> - layer_set_dn(frml, link_support);
> - layer_set_up(link_support, frml);
> - layer_set_dn(link_support, phy_layer);
> - layer_set_up(phy_layer, link_support);
> - } else {
> - layer_set_dn(frml, phy_layer);
> - layer_set_up(phy_layer, frml);
> - }
> -
> - list_add_rcu(&phyinfo->node, &cnfg->phys);
> -out:
> - mutex_unlock(&cnfg->lock);
> - return res;
> -
> -out_err:
> - kfree(phyinfo);
> - mutex_unlock(&cnfg->lock);
> - return res;
> -}
> -EXPORT_SYMBOL(cfcnfg_add_phy_layer);
> -
> -int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer,
> - bool up)
> -{
> - struct cfcnfg_phyinfo *phyinfo;
> -
> - rcu_read_lock();
> - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phy_layer->id);
> - if (phyinfo == NULL) {
> - rcu_read_unlock();
> - return -ENODEV;
> - }
> -
> - if (phyinfo->up == up) {
> - rcu_read_unlock();
> - return 0;
> - }
> - phyinfo->up = up;
> -
> - if (up) {
> - cffrml_hold(phyinfo->frm_layer);
> - cfmuxl_set_dnlayer(cnfg->mux, phyinfo->frm_layer,
> - phy_layer->id);
> - } else {
> - cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id);
> - cffrml_put(phyinfo->frm_layer);
> - }
> -
> - rcu_read_unlock();
> - return 0;
> -}
> -EXPORT_SYMBOL(cfcnfg_set_phy_state);
> -
> -int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer)
> -{
> - struct cflayer *frml, *frml_dn;
> - u16 phyid;
> - struct cfcnfg_phyinfo *phyinfo;
> -
> - might_sleep();
> -
> - mutex_lock(&cnfg->lock);
> -
> - phyid = phy_layer->id;
> - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid);
> -
> - if (phyinfo == NULL) {
> - mutex_unlock(&cnfg->lock);
> - return 0;
> - }
> - caif_assert(phyid == phyinfo->id);
> - caif_assert(phy_layer == phyinfo->phy_layer);
> - caif_assert(phy_layer->id == phyid);
> - caif_assert(phyinfo->frm_layer->id == phyid);
> -
> - list_del_rcu(&phyinfo->node);
> - synchronize_rcu();
> -
> - /* Fail if reference count is not zero */
> - if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) {
> - pr_info("Wait for device inuse\n");
> - list_add_rcu(&phyinfo->node, &cnfg->phys);
> - mutex_unlock(&cnfg->lock);
> - return -EAGAIN;
> - }
> -
> - frml = phyinfo->frm_layer;
> - frml_dn = frml->dn;
> - cffrml_set_uplayer(frml, NULL);
> - cffrml_set_dnlayer(frml, NULL);
> - if (phy_layer != frml_dn) {
> - layer_set_up(frml_dn, NULL);
> - layer_set_dn(frml_dn, NULL);
> - }
> - layer_set_up(phy_layer, NULL);
> -
> - if (phyinfo->phy_layer != frml_dn)
> - kfree(frml_dn);
> -
> - cffrml_free(frml);
> - kfree(phyinfo);
> - mutex_unlock(&cnfg->lock);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(cfcnfg_del_phy_layer);
> diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
> deleted file mode 100644
> index c6cc2bfed65d..000000000000
> --- a/net/caif/cfctrl.c
> +++ /dev/null
> @@ -1,631 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/stddef.h>
> -#include <linux/spinlock.h>
> -#include <linux/slab.h>
> -#include <linux/pkt_sched.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 int handle_loop(struct cfctrl *ctrl,
> - int cmd, struct cfpkt *pkt){
> - return -1;
> -}
> -#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(void)
> -{
> - struct dev_info dev_info;
> - struct cfctrl *this =
> - kzalloc_obj(struct cfctrl, GFP_ATOMIC);
> - if (!this)
> - return NULL;
> - caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
> - memset(&dev_info, 0, sizeof(dev_info));
> - dev_info.id = 0xff;
> - cfsrvl_init(&this->serv, 0, &dev_info, false);
> - atomic_set(&this->req_seq_no, 1);
> - atomic_set(&this->rsp_seq_no, 1);
> - this->serv.layer.receive = cfctrl_recv;
> - sprintf(this->serv.layer.name, "ctrl");
> - this->serv.layer.ctrlcmd = cfctrl_ctrlcmd;
> -#ifndef CAIF_NO_LOOP
> - spin_lock_init(&this->loop_linkid_lock);
> - this->loop_linkid = 1;
> -#endif
> - spin_lock_init(&this->info_list_lock);
> - INIT_LIST_HEAD(&this->list);
> - return &this->serv.layer;
> -}
> -
> -void cfctrl_remove(struct cflayer *layer)
> -{
> - struct cfctrl_request_info *p, *tmp;
> - struct cfctrl *ctrl = container_obj(layer);
> -
> - spin_lock_bh(&ctrl->info_list_lock);
> - list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
> - list_del(&p->list);
> - kfree(p);
> - }
> - spin_unlock_bh(&ctrl->info_list_lock);
> - kfree(layer);
> -}
> -
> -static bool param_eq(const struct cfctrl_link_param *p1,
> - const 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;
> -}
> -
> -static bool cfctrl_req_eq(const struct cfctrl_request_info *r1,
> - const 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 */
> -static void cfctrl_insert_req(struct cfctrl *ctrl,
> - struct cfctrl_request_info *req)
> -{
> - spin_lock_bh(&ctrl->info_list_lock);
> - atomic_inc(&ctrl->req_seq_no);
> - req->sequence_no = atomic_read(&ctrl->req_seq_no);
> - list_add_tail(&req->list, &ctrl->list);
> - spin_unlock_bh(&ctrl->info_list_lock);
> -}
> -
> -/* Compare and remove request */
> -static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
> - struct cfctrl_request_info *req)
> -{
> - struct cfctrl_request_info *p, *tmp, *first;
> -
> - first = list_first_entry(&ctrl->list, struct cfctrl_request_info, list);
> -
> - list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
> - if (cfctrl_req_eq(req, p)) {
> - if (p != first)
> - pr_warn("Requests are not received in order\n");
> -
> - atomic_set(&ctrl->rsp_seq_no,
> - p->sequence_no);
> - list_del(&p->list);
> - goto out;
> - }
> - }
> - p = NULL;
> -out:
> - return p;
> -}
> -
> -struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer)
> -{
> - struct cfctrl *this = container_obj(layer);
> - return &this->res;
> -}
> -
> -static 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 cfpkt *pkt;
> - struct cfctrl *cfctrl = container_obj(layer);
> - struct cflayer *dn = cfctrl->serv.layer.dn;
> -
> - if (!dn) {
> - pr_debug("not able to send enum request\n");
> - return;
> - }
> - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
> - if (!pkt)
> - 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);
> - cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
> - dn->transmit(dn, pkt);
> -}
> -
> -int cfctrl_linkup_request(struct cflayer *layer,
> - struct cfctrl_link_param *param,
> - struct cflayer *user_layer)
> -{
> - struct cfctrl *cfctrl = container_obj(layer);
> - struct cflayer *dn = cfctrl->serv.layer.dn;
> - char utility_name[UTILITY_NAME_LENGTH];
> - struct cfctrl_request_info *req;
> - struct cfpkt *pkt;
> - u32 tmp32;
> - u16 tmp16;
> - u8 tmp8;
> - int ret;
> -
> - if (!dn) {
> - pr_debug("not able to send linkup request\n");
> - return -ENODEV;
> - }
> -
> - if (cfctrl_cancel_req(layer, user_layer) > 0) {
> - /* Slight Paranoia, check if already connecting */
> - pr_err("Duplicate connect request for same client\n");
> - WARN_ON(1);
> - return -EALREADY;
> - }
> -
> - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
> - if (!pkt)
> - return -ENOMEM;
> - 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);
> - strscpy_pad(utility_name, param->u.utility.name);
> - 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_warn("Request setup of bad link type = %d\n",
> - param->linktype);
> - cfpkt_destroy(pkt);
> - return -EINVAL;
> - }
> - req = kzalloc_obj(*req);
> - if (!req) {
> - cfpkt_destroy(pkt);
> - return -ENOMEM;
> - }
> -
> - 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);
> - /*
> - * NOTE:Always send linkup and linkdown request on the same
> - * device as the payload. Otherwise old queued up payload
> - * might arrive with the newly allocated channel ID.
> - */
> - cfpkt_info(pkt)->dev_info->id = param->phyid;
> - cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
> - ret =
> - dn->transmit(dn, pkt);
> - if (ret < 0) {
> - int count;
> -
> - count = cfctrl_cancel_req(&cfctrl->serv.layer,
> - user_layer);
> - if (count != 1) {
> - pr_err("Could not remove request (%d)", count);
> - return -ENODEV;
> - }
> - }
> - return 0;
> -}
> -
> -int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
> - struct cflayer *client)
> -{
> - int ret;
> - struct cfpkt *pkt;
> - struct cfctrl *cfctrl = container_obj(layer);
> - struct cflayer *dn = cfctrl->serv.layer.dn;
> -
> - if (!dn) {
> - pr_debug("not able to send link-down request\n");
> - return -ENODEV;
> - }
> - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
> - if (!pkt)
> - return -ENOMEM;
> - cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
> - cfpkt_addbdy(pkt, channelid);
> - init_info(cfpkt_info(pkt), cfctrl);
> - cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
> - ret =
> - dn->transmit(dn, pkt);
> -#ifndef CAIF_NO_LOOP
> - cfctrl->loop_linkused[channelid] = 0;
> -#endif
> - return ret;
> -}
> -
> -int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
> -{
> - struct cfctrl_request_info *p, *tmp;
> - struct cfctrl *ctrl = container_obj(layr);
> - int found = 0;
> - spin_lock_bh(&ctrl->info_list_lock);
> -
> - list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
> - if (p->client_layer == adap_layer) {
> - list_del(&p->list);
> - kfree(p);
> - found++;
> - }
> - }
> -
> - spin_unlock_bh(&ctrl->info_list_lock);
> - return found;
> -}
> -
> -static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp)
> -{
> - u8 len;
> - u8 linkid = 0;
> - enum cfctrl_srv serv;
> - enum cfctrl_srv servtype;
> - u8 endpoint;
> - u8 physlinkid;
> - u8 prio;
> - u8 tmp;
> - u8 *cp;
> - int i;
> - struct cfctrl_link_param linkparam;
> - struct cfctrl_request_info rsp, *req;
> -
> - memset(&linkparam, 0, sizeof(linkparam));
> -
> - tmp = cfpkt_extr_head_u8(pkt);
> -
> - serv = tmp & CFCTRL_SRV_MASK;
> - linkparam.linktype = serv;
> -
> - servtype = tmp >> 4;
> - linkparam.chtype = servtype;
> -
> - tmp = cfpkt_extr_head_u8(pkt);
> - physlinkid = tmp & 0x07;
> - prio = tmp >> 3;
> -
> - linkparam.priority = prio;
> - linkparam.phyid = physlinkid;
> - endpoint = cfpkt_extr_head_u8(pkt);
> - linkparam.endpoint = endpoint & 0x03;
> -
> - switch (serv) {
> - case CFCTRL_SRV_VEI:
> - case CFCTRL_SRV_DBG:
> - if (CFCTRL_ERR_BIT & cmdrsp)
> - break;
> - /* Link ID */
> - linkid = cfpkt_extr_head_u8(pkt);
> - break;
> - case CFCTRL_SRV_VIDEO:
> - tmp = cfpkt_extr_head_u8(pkt);
> - linkparam.u.video.connid = tmp;
> - if (CFCTRL_ERR_BIT & cmdrsp)
> - break;
> - /* Link ID */
> - linkid = cfpkt_extr_head_u8(pkt);
> - break;
> -
> - case CFCTRL_SRV_DATAGRAM:
> - linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt);
> - if (CFCTRL_ERR_BIT & cmdrsp)
> - break;
> - /* Link ID */
> - linkid = cfpkt_extr_head_u8(pkt);
> - break;
> - case CFCTRL_SRV_RFM:
> - /* Construct a frame, convert
> - * DatagramConnectionID
> - * to network format long and copy it out...
> - */
> - linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt);
> - cp = (u8 *) linkparam.u.rfm.volume;
> - for (tmp = cfpkt_extr_head_u8(pkt);
> - cfpkt_more(pkt) && tmp != '\0';
> - tmp = cfpkt_extr_head_u8(pkt))
> - *cp++ = tmp;
> - *cp = '\0';
> -
> - if (CFCTRL_ERR_BIT & cmdrsp)
> - break;
> - /* Link ID */
> - linkid = cfpkt_extr_head_u8(pkt);
> -
> - break;
> - case CFCTRL_SRV_UTIL:
> - /* Construct a frame, convert
> - * DatagramConnectionID
> - * to network format long and copy it out...
> - */
> - /* Fifosize KB */
> - linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt);
> - /* Fifosize bufs */
> - linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt);
> - /* 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++) {
> - tmp = cfpkt_extr_head_u8(pkt);
> - *cp++ = tmp;
> - }
> - /* Length */
> - len = cfpkt_extr_head_u8(pkt);
> - linkparam.u.utility.paramlen = len;
> - /* Param Data */
> - cp = linkparam.u.utility.params;
> - while (cfpkt_more(pkt) && len--) {
> - tmp = cfpkt_extr_head_u8(pkt);
> - *cp++ = tmp;
> - }
> - if (CFCTRL_ERR_BIT & cmdrsp)
> - break;
> - /* Link ID */
> - linkid = cfpkt_extr_head_u8(pkt);
> - /* Length */
> - len = cfpkt_extr_head_u8(pkt);
> - /* Param Data */
> - cfpkt_extr_head(pkt, NULL, len);
> - break;
> - default:
> - pr_warn("Request setup, invalid type (%d)\n", serv);
> - return -1;
> - }
> -
> - rsp.cmd = CFCTRL_CMD_LINK_SETUP;
> - rsp.param = linkparam;
> - spin_lock_bh(&cfctrl->info_list_lock);
> - req = cfctrl_remove_req(cfctrl, &rsp);
> -
> - if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
> - cfpkt_erroneous(pkt)) {
> - pr_err("Invalid O/E bit or parse error "
> - "on CAIF control channel\n");
> - 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);
> - }
> -
> - kfree(req);
> -
> - spin_unlock_bh(&cfctrl->info_list_lock);
> -
> - return 0;
> -}
> -
> -static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
> -{
> - u8 cmdrsp;
> - u8 cmd;
> - int ret = 0;
> - u8 linkid = 0;
> - struct cfctrl *cfctrl = container_obj(layer);
> -
> - cmdrsp = cfpkt_extr_head_u8(pkt);
> - cmd = cmdrsp & CFCTRL_CMD_MASK;
> - if (cmd != CFCTRL_CMD_LINK_ERR
> - && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)
> - && CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) {
> - if (handle_loop(cfctrl, cmd, pkt) != 0)
> - cmdrsp |= CFCTRL_ERR_BIT;
> - }
> -
> - switch (cmd) {
> - case CFCTRL_CMD_LINK_SETUP:
> - ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp);
> - break;
> - case CFCTRL_CMD_LINK_DESTROY:
> - linkid = cfpkt_extr_head_u8(pkt);
> - cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid);
> - break;
> - case CFCTRL_CMD_LINK_ERR:
> - pr_err("Frame Error Indication received\n");
> - 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("Unrecognized Control Frame\n");
> - ret = -1;
> - goto error;
> - }
> -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_bh(&this->info_list_lock);
> - if (!list_empty(&this->list))
> - pr_debug("Received flow off in control layer\n");
> - spin_unlock_bh(&this->info_list_lock);
> - break;
> - case _CAIF_CTRLCMD_PHYIF_DOWN_IND: {
> - struct cfctrl_request_info *p, *tmp;
> -
> - /* Find all connect request and report failure */
> - spin_lock_bh(&this->info_list_lock);
> - list_for_each_entry_safe(p, tmp, &this->list, list) {
> - if (p->param.phyid == phyid) {
> - list_del(&p->list);
> - p->client_layer->ctrlcmd(p->client_layer,
> - CAIF_CTRLCMD_INIT_FAIL_RSP,
> - phyid);
> - kfree(p);
> - }
> - }
> - spin_unlock_bh(&this->info_list_lock);
> - break;
> - }
> - default:
> - break;
> - }
> -}
> -
> -#ifndef CAIF_NO_LOOP
> -static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt)
> -{
> - static int last_linkid;
> - static int dec;
> - u8 linkid, linktype, tmp;
> - switch (cmd) {
> - case CFCTRL_CMD_LINK_SETUP:
> - spin_lock_bh(&ctrl->loop_linkid_lock);
> - if (!dec) {
> - for (linkid = last_linkid + 1; linkid < 254; linkid++)
> - if (!ctrl->loop_linkused[linkid])
> - goto found;
> - }
> - dec = 1;
> - for (linkid = last_linkid - 1; linkid > 1; linkid--)
> - if (!ctrl->loop_linkused[linkid])
> - goto found;
> - spin_unlock_bh(&ctrl->loop_linkid_lock);
> - return -1;
> -found:
> - if (linkid < 10)
> - dec = 0;
> -
> - if (!ctrl->loop_linkused[linkid])
> - ctrl->loop_linkused[linkid] = 1;
> -
> - last_linkid = linkid;
> -
> - cfpkt_add_trail(pkt, &linkid, 1);
> - spin_unlock_bh(&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_bh(&ctrl->loop_linkid_lock);
> - cfpkt_peek_head(pkt, &linkid, 1);
> - ctrl->loop_linkused[linkid] = 0;
> - spin_unlock_bh(&ctrl->loop_linkid_lock);
> - break;
> - default:
> - break;
> - }
> - return 0;
> -}
> -#endif
> diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c
> deleted file mode 100644
> index 57ad3f82e004..000000000000
> --- a/net/caif/cfdbgl.c
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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 container_obj(layr) ((struct cfsrvl *) layr)
> -
> -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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
> - if (!dbg)
> - return NULL;
> - caif_assert(offsetof(struct cfsrvl, layer) == 0);
> - cfsrvl_init(dbg, channel_id, dev_info, false);
> - dbg->layer.receive = cfdbgl_receive;
> - dbg->layer.transmit = cfdbgl_transmit;
> - snprintf(dbg->layer.name, CAIF_LAYER_NAME_SZ, "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)
> -{
> - struct cfsrvl *service = container_obj(layr);
> - struct caif_payload_info *info;
> - int ret;
> -
> - if (!cfsrvl_ready(service, &ret)) {
> - cfpkt_destroy(pkt);
> - return ret;
> - }
> -
> - /* 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;
> -
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
> deleted file mode 100644
> index c451ddd155a7..000000000000
> --- a/net/caif/cfdgml.c
> +++ /dev/null
> @@ -1,113 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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_MTU 1500
> -
> -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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
> - if (!dgm)
> - return NULL;
> - caif_assert(offsetof(struct cfsrvl, layer) == 0);
> - cfsrvl_init(dgm, channel_id, dev_info, true);
> - dgm->layer.receive = cfdgml_receive;
> - dgm->layer.transmit = cfdgml_transmit;
> - snprintf(dgm->layer.name, CAIF_LAYER_NAME_SZ, "dgm%d", channel_id);
> - 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("Packet is erroneous!\n");
> - cfpkt_destroy(pkt);
> - return -EPROTO;
> - }
> -
> - if ((cmd & DGM_CMD_BIT) == 0) {
> - if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) {
> - pr_err("Packet is erroneous!\n");
> - 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("Unknown datagram control %d (0x%x)\n", cmd, cmd);
> - return -EPROTO;
> - }
> -}
> -
> -static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - u8 packet_type;
> - u32 zero = 0;
> - struct caif_payload_info *info;
> - struct cfsrvl *service = container_obj(layr);
> - int ret;
> -
> - if (!cfsrvl_ready(service, &ret)) {
> - cfpkt_destroy(pkt);
> - return ret;
> - }
> -
> - /* STE Modem cannot handle more than 1500 bytes datagrams */
> - if (cfpkt_getlen(pkt) > DGM_MTU) {
> - cfpkt_destroy(pkt);
> - return -EMSGSIZE;
> - }
> -
> - cfpkt_add_head(pkt, &zero, 3);
> - packet_type = 0x08; /* B9 set - UNCLASSIFIED */
> - cfpkt_add_head(pkt, &packet_type, 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 = 4;
> - info->dev_info = &service->dev_info;
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
> deleted file mode 100644
> index 0f4979d89fcb..000000000000
> --- a/net/caif/cffrml.c
> +++ /dev/null
> @@ -1,204 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * CAIF Framing Layer.
> - *
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/stddef.h>
> -#include <linux/spinlock.h>
> -#include <linux/slab.h>
> -#include <linux/crc-ccitt.h>
> -#include <linux/netdevice.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 */
> - int __percpu *pcpu_refcnt;
> -};
> -
> -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);
> -
> -static u32 cffrml_rcv_error;
> -static u32 cffrml_rcv_checsum_error;
> -struct cflayer *cffrml_create(u16 phyid, bool use_fcs)
> -{
> - struct cffrml *this = kzalloc_obj(struct cffrml, GFP_ATOMIC);
> - if (!this)
> - return NULL;
> - this->pcpu_refcnt = alloc_percpu(int);
> - if (this->pcpu_refcnt == NULL) {
> - kfree(this);
> - return NULL;
> - }
> -
> - caif_assert(offsetof(struct cffrml, layer) == 0);
> -
> - 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_free(struct cflayer *layer)
> -{
> - struct cffrml *this = container_obj(layer);
> - free_percpu(this->pcpu_refcnt);
> - kfree(layer);
> -}
> -
> -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;
> - int 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) {
> - if (len < 2) {
> - ++cffrml_rcv_error;
> - pr_err("Invalid frame length (%d)\n", len);
> - cfpkt_destroy(pkt);
> - return -EPROTO;
> - }
> - len -= 2;
> - }
> -
> - if (cfpkt_setlen(pkt, len) < 0) {
> - ++cffrml_rcv_error;
> - pr_err("Framing length error (%d)\n", 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("Frame checksum error (0x%x != 0x%x)\n",
> - hdrchks, pktchks);
> - return -EILSEQ;
> - }
> - }
> - if (cfpkt_erroneous(pkt)) {
> - ++cffrml_rcv_error;
> - pr_err("Packet is erroneous!\n");
> - cfpkt_destroy(pkt);
> - return -EPROTO;
> - }
> -
> - if (layr->up == NULL) {
> - pr_err("Layr up is missing!\n");
> - cfpkt_destroy(pkt);
> - return -EINVAL;
> - }
> -
> - return layr->up->receive(layr->up, pkt);
> -}
> -
> -static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - u16 chks;
> - u16 len;
> - __le16 data;
> -
> - struct cffrml *this = container_obj(layr);
> - if (this->dofcs) {
> - chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
> - data = cpu_to_le16(chks);
> - cfpkt_add_trail(pkt, &data, 2);
> - } else {
> - cfpkt_pad_trail(pkt, 2);
> - }
> - len = cfpkt_getlen(pkt);
> - data = cpu_to_le16(len);
> - cfpkt_add_head(pkt, &data, 2);
> - cfpkt_info(pkt)->hdr_len += 2;
> - if (cfpkt_erroneous(pkt)) {
> - pr_err("Packet is erroneous!\n");
> - cfpkt_destroy(pkt);
> - return -EPROTO;
> - }
> -
> - if (layr->dn == NULL) {
> - cfpkt_destroy(pkt);
> - return -ENODEV;
> -
> - }
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> -
> -static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
> - int phyid)
> -{
> - if (layr->up && layr->up->ctrlcmd)
> - layr->up->ctrlcmd(layr->up, ctrl, layr->id);
> -}
> -
> -void cffrml_put(struct cflayer *layr)
> -{
> - struct cffrml *this = container_obj(layr);
> - if (layr != NULL && this->pcpu_refcnt != NULL)
> - this_cpu_dec(*this->pcpu_refcnt);
> -}
> -
> -void cffrml_hold(struct cflayer *layr)
> -{
> - struct cffrml *this = container_obj(layr);
> - if (layr != NULL && this->pcpu_refcnt != NULL)
> - this_cpu_inc(*this->pcpu_refcnt);
> -}
> -
> -int cffrml_refcnt_read(struct cflayer *layr)
> -{
> - int i, refcnt = 0;
> - struct cffrml *this = container_obj(layr);
> - for_each_possible_cpu(i)
> - refcnt += *per_cpu_ptr(this->pcpu_refcnt, i);
> - return refcnt;
> -}
> diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
> deleted file mode 100644
> index 77a1f31639b7..000000000000
> --- a/net/caif/cfmuxl.c
> +++ /dev/null
> @@ -1,267 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/stddef.h>
> -#include <linux/spinlock.h>
> -#include <linux/slab.h>
> -#include <linux/rculist.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, u16 id);
> -
> -struct cflayer *cfmuxl_create(void)
> -{
> - struct cfmuxl *this = kzalloc_obj(struct cfmuxl, GFP_ATOMIC);
> -
> - if (!this)
> - return NULL;
> - 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_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
> -{
> - struct cfmuxl *muxl = (struct cfmuxl *) layr;
> -
> - spin_lock_bh(&muxl->transmit_lock);
> - list_add_rcu(&dn->node, &muxl->frml_list);
> - spin_unlock_bh(&muxl->transmit_lock);
> - return 0;
> -}
> -
> -static struct cflayer *get_from_id(struct list_head *list, u16 id)
> -{
> - struct cflayer *lyr;
> - list_for_each_entry_rcu(lyr, list, node) {
> - if (lyr->id == id)
> - return lyr;
> - }
> -
> - return NULL;
> -}
> -
> -int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
> -{
> - struct cfmuxl *muxl = container_obj(layr);
> - struct cflayer *old;
> -
> - spin_lock_bh(&muxl->receive_lock);
> -
> - /* Two entries with same id is wrong, so remove old layer from mux */
> - old = get_from_id(&muxl->srvl_list, linkid);
> - if (old != NULL)
> - list_del_rcu(&old->node);
> -
> - list_add_rcu(&up->node, &muxl->srvl_list);
> - spin_unlock_bh(&muxl->receive_lock);
> -
> - return 0;
> -}
> -
> -struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
> -{
> - struct cfmuxl *muxl = container_obj(layr);
> - struct cflayer *dn;
> - int idx = phyid % DN_CACHE_SIZE;
> -
> - spin_lock_bh(&muxl->transmit_lock);
> - RCU_INIT_POINTER(muxl->dn_cache[idx], NULL);
> - dn = get_from_id(&muxl->frml_list, phyid);
> - if (dn == NULL)
> - goto out;
> -
> - list_del_rcu(&dn->node);
> - caif_assert(dn != NULL);
> -out:
> - spin_unlock_bh(&muxl->transmit_lock);
> - return dn;
> -}
> -
> -static struct cflayer *get_up(struct cfmuxl *muxl, u16 id)
> -{
> - struct cflayer *up;
> - int idx = id % UP_CACHE_SIZE;
> - up = rcu_dereference(muxl->up_cache[idx]);
> - if (up == NULL || up->id != id) {
> - spin_lock_bh(&muxl->receive_lock);
> - up = get_from_id(&muxl->srvl_list, id);
> - rcu_assign_pointer(muxl->up_cache[idx], up);
> - spin_unlock_bh(&muxl->receive_lock);
> - }
> - return up;
> -}
> -
> -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 = rcu_dereference(muxl->dn_cache[idx]);
> - if (dn == NULL || dn->id != dev_info->id) {
> - spin_lock_bh(&muxl->transmit_lock);
> - dn = get_from_id(&muxl->frml_list, dev_info->id);
> - rcu_assign_pointer(muxl->dn_cache[idx], dn);
> - spin_unlock_bh(&muxl->transmit_lock);
> - }
> - return dn;
> -}
> -
> -struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
> -{
> - struct cflayer *up;
> - struct cfmuxl *muxl = container_obj(layr);
> - int idx = id % UP_CACHE_SIZE;
> -
> - if (id == 0) {
> - pr_warn("Trying to remove control layer\n");
> - return NULL;
> - }
> -
> - spin_lock_bh(&muxl->receive_lock);
> - up = get_from_id(&muxl->srvl_list, id);
> - if (up == NULL)
> - goto out;
> -
> - RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
> - list_del_rcu(&up->node);
> -out:
> - spin_unlock_bh(&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("erroneous Caif Packet\n");
> - cfpkt_destroy(pkt);
> - return -EPROTO;
> - }
> - rcu_read_lock();
> - up = get_up(muxl, id);
> -
> - if (up == NULL) {
> - pr_debug("Received data on unknown link ID = %d (0x%x)"
> - " up == NULL", id, id);
> - cfpkt_destroy(pkt);
> - /*
> - * Don't return ERROR, since modem misbehaves and sends out
> - * flow on before linksetup response.
> - */
> -
> - rcu_read_unlock();
> - return /* CFGLU_EPROT; */ 0;
> - }
> -
> - /* We can't hold rcu_lock during receive, so take a ref count instead */
> - cfsrvl_get(up);
> - rcu_read_unlock();
> -
> - ret = up->receive(up, pkt);
> -
> - cfsrvl_put(up);
> - return ret;
> -}
> -
> -static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - struct cfmuxl *muxl = container_obj(layr);
> - int err;
> - u8 linkid;
> - struct cflayer *dn;
> - struct caif_payload_info *info = cfpkt_info(pkt);
> - BUG_ON(!info);
> -
> - rcu_read_lock();
> -
> - dn = get_dn(muxl, info->dev_info);
> - if (dn == NULL) {
> - pr_debug("Send data on unknown phy ID = %d (0x%x)\n",
> - info->dev_info->id, info->dev_info->id);
> - rcu_read_unlock();
> - cfpkt_destroy(pkt);
> - return -ENOTCONN;
> - }
> -
> - info->hdr_len += 1;
> - linkid = info->channel_id;
> - cfpkt_add_head(pkt, &linkid, 1);
> -
> - /* We can't hold rcu_lock during receive, so take a ref count instead */
> - cffrml_hold(dn);
> -
> - rcu_read_unlock();
> -
> - err = dn->transmit(dn, pkt);
> -
> - cffrml_put(dn);
> - return err;
> -}
> -
> -static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
> - int phyid)
> -{
> - struct cfmuxl *muxl = container_obj(layr);
> - struct cflayer *layer;
> -
> - rcu_read_lock();
> - list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
> -
> - if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) {
> -
> - if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
> - ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
> - layer->id != 0)
> - cfmuxl_remove_uplayer(layr, layer->id);
> -
> - /* NOTE: ctrlcmd is not allowed to block */
> - layer->ctrlcmd(layer, ctrl, phyid);
> - }
> - }
> - rcu_read_unlock();
> -}
> diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
> deleted file mode 100644
> index 96236d21b18e..000000000000
> --- a/net/caif/cfpkt_skbuff.c
> +++ /dev/null
> @@ -1,373 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/string.h>
> -#include <linux/skbuff.h>
> -#include <linux/export.h>
> -#include <net/caif/cfpkt.h>
> -
> -#define PKT_PREFIX 48
> -#define PKT_POSTFIX 2
> -#define PKT_LEN_WHEN_EXTENDING 128
> -#define PKT_ERROR(pkt, errmsg) \
> -do { \
> - cfpkt_priv(pkt)->erronous = true; \
> - skb_reset_tail_pointer(&pkt->skb); \
> - pr_warn(errmsg); \
> -} while (0)
> -
> -/*
> - * 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;
> -};
> -
> -static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
> -{
> - return (struct cfpkt_priv_data *) pkt->skb.cb;
> -}
> -
> -static inline bool is_erronous(struct cfpkt *pkt)
> -{
> - return cfpkt_priv(pkt)->erronous;
> -}
> -
> -static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
> -{
> - return &pkt->skb;
> -}
> -
> -static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
> -{
> - return (struct cfpkt *) skb;
> -}
> -
> -struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt)
> -{
> - struct cfpkt *pkt = skb_to_pkt(nativepkt);
> - cfpkt_priv(pkt)->erronous = false;
> - return pkt;
> -}
> -EXPORT_SYMBOL(cfpkt_fromnative);
> -
> -void *cfpkt_tonative(struct cfpkt *pkt)
> -{
> - return (void *) pkt;
> -}
> -EXPORT_SYMBOL(cfpkt_tonative);
> -
> -static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
> -{
> - struct sk_buff *skb;
> -
> - skb = alloc_skb(len + pfx, GFP_ATOMIC);
> - if (unlikely(skb == NULL))
> - return NULL;
> -
> - skb_reserve(skb, pfx);
> - return skb_to_pkt(skb);
> -}
> -
> -inline struct cfpkt *cfpkt_create(u16 len)
> -{
> - return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
> -}
> -
> -void cfpkt_destroy(struct cfpkt *pkt)
> -{
> - struct sk_buff *skb = pkt_to_skb(pkt);
> - kfree_skb(skb);
> -}
> -
> -inline bool cfpkt_more(struct cfpkt *pkt)
> -{
> - struct sk_buff *skb = pkt_to_skb(pkt);
> - return skb->len > 0;
> -}
> -
> -int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
> -{
> - struct sk_buff *skb = pkt_to_skb(pkt);
> - if (skb_headlen(skb) >= len) {
> - memcpy(data, skb->data, len);
> - return 0;
> - }
> - return !cfpkt_extr_head(pkt, data, len) &&
> - !cfpkt_add_head(pkt, data, len);
> -}
> -
> -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, "read beyond end of packet\n");
> - return -EPROTO;
> - }
> -
> - if (unlikely(len > skb_headlen(skb))) {
> - if (unlikely(skb_linearize(skb) != 0)) {
> - PKT_ERROR(pkt, "linearize failed\n");
> - return -EPROTO;
> - }
> - }
> - from = skb_pull(skb, len);
> - from -= len;
> - if (data)
> - 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, "linearize failed\n");
> - return -EPROTO;
> - }
> - if (unlikely(skb->data + len > skb_tail_pointer(skb))) {
> - PKT_ERROR(pkt, "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;
> -}
> -
> -int cfpkt_pad_trail(struct cfpkt *pkt, u16 len)
> -{
> - return cfpkt_add_body(pkt, NULL, len);
> -}
> -
> -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, "cow failed\n");
> - return -EPROTO;
> - }
> - }
> -
> - /* All set to put the last SKB and optionally write data there. */
> - to = pskb_put(skb, lastskb, len);
> - if (likely(data))
> - memcpy(to, data, len);
> - return 0;
> -}
> -
> -inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data)
> -{
> - return cfpkt_add_body(pkt, &data, 1);
> -}
> -
> -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;
> - int ret;
> - if (unlikely(is_erronous(pkt)))
> - return -EPROTO;
> - if (unlikely(skb_headroom(skb) < len)) {
> - PKT_ERROR(pkt, "no headroom\n");
> - return -EPROTO;
> - }
> -
> - /* Make sure data is writable */
> - ret = skb_cow_data(skb, 0, &lastskb);
> - if (unlikely(ret < 0)) {
> - PKT_ERROR(pkt, "cow failed\n");
> - return ret;
> - }
> -
> - 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);
> -}
> -
> -inline u16 cfpkt_getlen(struct cfpkt *pkt)
> -{
> - struct sk_buff *skb = pkt_to_skb(pkt);
> - return skb->len;
> -}
> -
> -int 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, "linearize failed\n");
> - return -EPROTO;
> - }
> - return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
> -}
> -
> -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, "skb_pad_trail failed\n");
> -
> - return cfpkt_getlen(pkt);
> -}
> -
> -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 = skb_headlen(add);
> - u16 neededtailspace;
> - struct sk_buff *tmp;
> - u16 dstlen;
> - u16 createlen;
> - if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
> - return dstpkt;
> - }
> -
> - neededtailspace = max(expectlen, addlen);
> -
> - if (dst->tail + neededtailspace > dst->end) {
> - /* Create a dumplicate of 'dst' with more tail space */
> - struct cfpkt *tmppkt;
> - dstlen = skb_headlen(dst);
> - createlen = dstlen + neededtailspace;
> - tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
> - if (tmppkt == NULL)
> - return NULL;
> - tmp = pkt_to_skb(tmppkt);
> - skb_put_data(tmp, dst->data, dstlen);
> - cfpkt_destroy(dstpkt);
> - dst = tmp;
> - }
> - skb_put_data(dst, add->data, skb_headlen(add));
> - cfpkt_destroy(addpkt);
> - return skb_to_pkt(dst);
> -}
> -
> -struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
> -{
> - struct sk_buff *skb2;
> - struct sk_buff *skb = pkt_to_skb(pkt);
> - struct cfpkt *tmppkt;
> - u8 *split = skb->data + pos;
> - u16 len2nd = skb_tail_pointer(skb) - split;
> -
> - if (unlikely(is_erronous(pkt)))
> - return NULL;
> -
> - if (skb->data + pos > skb_tail_pointer(skb)) {
> - PKT_ERROR(pkt, "trying to split beyond end of packet\n");
> - return NULL;
> - }
> -
> - /* Create a new packet for the second part of the data */
> - tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
> - PKT_PREFIX);
> - if (tmppkt == NULL)
> - return NULL;
> - skb2 = pkt_to_skb(tmppkt);
> -
> -
> - if (skb2 == NULL)
> - return NULL;
> -
> - skb_put_data(skb2, split, len2nd);
> -
> - /* Reduce the length of the original packet */
> - skb_trim(skb, pos);
> -
> - skb2->priority = skb->priority;
> - return skb_to_pkt(skb2);
> -}
> -
> -bool cfpkt_erroneous(struct cfpkt *pkt)
> -{
> - return cfpkt_priv(pkt)->erronous;
> -}
> -
> -struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
> -{
> - return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
> -}
> -EXPORT_SYMBOL(cfpkt_info);
> -
> -void cfpkt_set_prio(struct cfpkt *pkt, int prio)
> -{
> - pkt_to_skb(pkt)->priority = prio;
> -}
> -EXPORT_SYMBOL(cfpkt_set_prio);
> diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c
> deleted file mode 100644
> index 93732ebbd1e2..000000000000
> --- a/net/caif/cfrfml.c
> +++ /dev/null
> @@ -1,299 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/stddef.h>
> -#include <linux/spinlock.h>
> -#include <linux/slab.h>
> -#include <linux/unaligned.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 cfrfml, serv.layer)
> -#define RFM_SEGMENTATION_BIT 0x01
> -#define RFM_HEAD_SIZE 7
> -
> -static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt);
> -static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt);
> -
> -struct cfrfml {
> - struct cfsrvl serv;
> - struct cfpkt *incomplete_frm;
> - int fragment_size;
> - u8 seghead[6];
> - u16 pdu_size;
> - /* Protects serialized processing of packets */
> - spinlock_t sync;
> -};
> -
> -static void cfrfml_release(struct cflayer *layer)
> -{
> - struct cfsrvl *srvl = container_of(layer, struct cfsrvl, layer);
> - struct cfrfml *rfml = container_obj(&srvl->layer);
> -
> - if (rfml->incomplete_frm)
> - cfpkt_destroy(rfml->incomplete_frm);
> -
> - kfree(srvl);
> -}
> -
> -struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info,
> - int mtu_size)
> -{
> - int tmp;
> - struct cfrfml *this = kzalloc_obj(struct cfrfml, GFP_ATOMIC);
> -
> - if (!this)
> - return NULL;
> -
> - cfsrvl_init(&this->serv, channel_id, dev_info, false);
> - this->serv.release = cfrfml_release;
> - this->serv.layer.receive = cfrfml_receive;
> - this->serv.layer.transmit = cfrfml_transmit;
> -
> - /* Round down to closest multiple of 16 */
> - tmp = (mtu_size - RFM_HEAD_SIZE - 6) / 16;
> - tmp *= 16;
> -
> - this->fragment_size = tmp;
> - spin_lock_init(&this->sync);
> - snprintf(this->serv.layer.name, CAIF_LAYER_NAME_SZ,
> - "rfm%d", channel_id);
> -
> - return &this->serv.layer;
> -}
> -
> -static struct cfpkt *rfm_append(struct cfrfml *rfml, char *seghead,
> - struct cfpkt *pkt, int *err)
> -{
> - struct cfpkt *tmppkt;
> - *err = -EPROTO;
> - /* n-th but not last segment */
> -
> - if (cfpkt_extr_head(pkt, seghead, 6) < 0)
> - return NULL;
> -
> - /* Verify correct header */
> - if (memcmp(seghead, rfml->seghead, 6) != 0)
> - return NULL;
> -
> - tmppkt = cfpkt_append(rfml->incomplete_frm, pkt,
> - rfml->pdu_size + RFM_HEAD_SIZE);
> -
> - /* If cfpkt_append failes input pkts are not freed */
> - *err = -ENOMEM;
> - if (tmppkt == NULL)
> - return NULL;
> -
> - *err = 0;
> - return tmppkt;
> -}
> -
> -static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - u8 tmp;
> - bool segmented;
> - int err;
> - u8 seghead[6];
> - struct cfrfml *rfml;
> - struct cfpkt *tmppkt = NULL;
> -
> - caif_assert(layr->up != NULL);
> - caif_assert(layr->receive != NULL);
> - rfml = container_obj(layr);
> - spin_lock(&rfml->sync);
> -
> - err = -EPROTO;
> - if (cfpkt_extr_head(pkt, &tmp, 1) < 0)
> - goto out;
> - segmented = tmp & RFM_SEGMENTATION_BIT;
> -
> - if (segmented) {
> - if (rfml->incomplete_frm == NULL) {
> - /* Initial Segment */
> - if (cfpkt_peek_head(pkt, rfml->seghead, 6) != 0)
> - goto out;
> -
> - rfml->pdu_size = get_unaligned_le16(rfml->seghead+4);
> -
> - if (cfpkt_erroneous(pkt))
> - goto out;
> - rfml->incomplete_frm = pkt;
> - pkt = NULL;
> - } else {
> -
> - tmppkt = rfm_append(rfml, seghead, pkt, &err);
> - if (tmppkt == NULL)
> - goto out;
> -
> - if (cfpkt_erroneous(tmppkt))
> - goto out;
> -
> - rfml->incomplete_frm = tmppkt;
> -
> -
> - if (cfpkt_erroneous(tmppkt))
> - goto out;
> - }
> - err = 0;
> - goto out;
> - }
> -
> - if (rfml->incomplete_frm) {
> -
> - /* Last Segment */
> - tmppkt = rfm_append(rfml, seghead, pkt, &err);
> - if (tmppkt == NULL)
> - goto out;
> -
> - if (cfpkt_erroneous(tmppkt))
> - goto out;
> -
> - rfml->incomplete_frm = NULL;
> - pkt = tmppkt;
> - tmppkt = NULL;
> -
> - /* Verify that length is correct */
> - err = -EPROTO;
> - if (rfml->pdu_size != cfpkt_getlen(pkt) - RFM_HEAD_SIZE + 1)
> - goto out;
> - }
> -
> - err = rfml->serv.layer.up->receive(rfml->serv.layer.up, pkt);
> -
> -out:
> -
> - if (err != 0) {
> - if (tmppkt)
> - cfpkt_destroy(tmppkt);
> - if (pkt)
> - cfpkt_destroy(pkt);
> - if (rfml->incomplete_frm)
> - cfpkt_destroy(rfml->incomplete_frm);
> - rfml->incomplete_frm = NULL;
> -
> - pr_info("Connection error %d triggered on RFM link\n", err);
> -
> - /* Trigger connection error upon failure.*/
> - layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
> - rfml->serv.dev_info.id);
> - }
> - spin_unlock(&rfml->sync);
> -
> - if (unlikely(err == -EAGAIN))
> - /* It is not possible to recover after drop of a fragment */
> - err = -EIO;
> -
> - return err;
> -}
> -
> -
> -static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt)
> -{
> - caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size + RFM_HEAD_SIZE);
> -
> - /* Add info for MUX-layer to route the packet out. */
> - cfpkt_info(pkt)->channel_id = rfml->serv.layer.id;
> -
> - /*
> - * To optimize alignment, we add up the size of CAIF header before
> - * payload.
> - */
> - cfpkt_info(pkt)->hdr_len = RFM_HEAD_SIZE;
> - cfpkt_info(pkt)->dev_info = &rfml->serv.dev_info;
> -
> - return rfml->serv.layer.dn->transmit(rfml->serv.layer.dn, pkt);
> -}
> -
> -static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - int err;
> - u8 seg;
> - u8 head[6];
> - struct cfpkt *rearpkt = NULL;
> - struct cfpkt *frontpkt = pkt;
> - struct cfrfml *rfml = container_obj(layr);
> -
> - caif_assert(layr->dn != NULL);
> - caif_assert(layr->dn->transmit != NULL);
> -
> - if (!cfsrvl_ready(&rfml->serv, &err))
> - goto out;
> -
> - err = -EPROTO;
> - if (cfpkt_getlen(pkt) <= RFM_HEAD_SIZE-1)
> - goto out;
> -
> - err = 0;
> - if (cfpkt_getlen(pkt) > rfml->fragment_size + RFM_HEAD_SIZE)
> - err = cfpkt_peek_head(pkt, head, 6);
> -
> - if (err != 0)
> - goto out;
> -
> - while (cfpkt_getlen(frontpkt) > rfml->fragment_size + RFM_HEAD_SIZE) {
> -
> - seg = 1;
> - err = -EPROTO;
> -
> - if (cfpkt_add_head(frontpkt, &seg, 1) < 0)
> - goto out;
> - /*
> - * On OOM error cfpkt_split returns NULL.
> - *
> - * NOTE: Segmented pdu is not correctly aligned.
> - * This has negative performance impact.
> - */
> -
> - rearpkt = cfpkt_split(frontpkt, rfml->fragment_size);
> - if (rearpkt == NULL)
> - goto out;
> -
> - err = cfrfml_transmit_segment(rfml, frontpkt);
> -
> - if (err != 0) {
> - frontpkt = NULL;
> - goto out;
> - }
> -
> - frontpkt = rearpkt;
> - rearpkt = NULL;
> -
> - err = -EPROTO;
> - if (cfpkt_add_head(frontpkt, head, 6) < 0)
> - goto out;
> -
> - }
> -
> - seg = 0;
> - err = -EPROTO;
> -
> - if (cfpkt_add_head(frontpkt, &seg, 1) < 0)
> - goto out;
> -
> - err = cfrfml_transmit_segment(rfml, frontpkt);
> -
> - frontpkt = NULL;
> -out:
> -
> - if (err != 0) {
> - pr_info("Connection error %d triggered on RFM link\n", err);
> - /* Trigger connection error upon failure.*/
> -
> - layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND,
> - rfml->serv.dev_info.id);
> -
> - if (rearpkt)
> - cfpkt_destroy(rearpkt);
> -
> - if (frontpkt)
> - cfpkt_destroy(frontpkt);
> - }
> -
> - return err;
> -}
> diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
> deleted file mode 100644
> index faf78fb754e2..000000000000
> --- a/net/caif/cfserl.c
> +++ /dev/null
> @@ -1,192 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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/cfserl.h>
> -
> -#define container_obj(layr) ((struct cfserl *) layr)
> -
> -#define CFSERL_STX 0x02
> -#define SERIAL_MINIUM_PACKET_SIZE 4
> -#define SERIAL_MAX_FRAMESIZE 4096
> -struct cfserl {
> - struct cflayer layer;
> - struct cfpkt *incomplete_frm;
> - /* Protects parallel processing of incoming packets */
> - spinlock_t sync;
> - bool usestx;
> -};
> -
> -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);
> -
> -void cfserl_release(struct cflayer *layer)
> -{
> - kfree(layer);
> -}
> -
> -struct cflayer *cfserl_create(int instance, bool use_stx)
> -{
> - struct cfserl *this = kzalloc_obj(struct cfserl, GFP_ATOMIC);
> - if (!this)
> - return NULL;
> - caif_assert(offsetof(struct cfserl, layer) == 0);
> - this->layer.receive = cfserl_receive;
> - this->layer.transmit = cfserl_transmit;
> - this->layer.ctrlcmd = cfserl_ctrlcmd;
> - this->usestx = use_stx;
> - spin_lock_init(&this->sync);
> - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "ser1");
> - return &this->layer;
> -}
> -
> -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;
> - if (pkt == NULL) {
> - spin_unlock(&layr->sync);
> - return -ENOMEM;
> - }
> - } 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 < SERIAL_MINIUM_PACKET_SIZE
> - || expectlen > SERIAL_MAX_FRAMESIZE) {
> - if (!layr->usestx) {
> - if (pkt != NULL)
> - cfpkt_destroy(pkt);
> - layr->incomplete_frm = NULL;
> - 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);
> - u8 tmp8 = CFSERL_STX;
> - if (layr->usestx)
> - cfpkt_add_head(newpkt, &tmp8, 1);
> - return layer->dn->transmit(layer->dn, newpkt);
> -}
> -
> -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
> deleted file mode 100644
> index d687fd0b4ed3..000000000000
> --- a/net/caif/cfsrvl.c
> +++ /dev/null
> @@ -1,224 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/errno.h>
> -#include <linux/slab.h>
> -#include <linux/module.h>
> -#include <linux/pkt_sched.h>
> -#include <net/caif/caif_layer.h>
> -#include <net/caif/cfsrvl.h>
> -#include <net/caif/cfpkt.h>
> -#include <net/caif/caif_dev.h>
> -
> -#define SRVL_CTRL_PKT_SIZE 1
> -#define SRVL_FLOW_OFF 0x81
> -#define SRVL_FLOW_ON 0x80
> -#define SRVL_SET_PIN 0x82
> -
> -#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);
> -
> - if (layr->up == NULL || layr->up->ctrlcmd == NULL)
> - return;
> -
> - 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_warn("Unexpected ctrl in cfsrvl (%d)\n", 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);
> -
> - if (!service->supports_flowctrl)
> - return 0;
> -
> - 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)
> - return -ENOMEM;
> -
> - if (cfpkt_add_head(pkt, &flow_on, 1) < 0) {
> - pr_err("Packet is erroneous!\n");
> - 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;
> - cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
> - 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 (!pkt)
> - return -ENOMEM;
> -
> - if (cfpkt_add_head(pkt, &flow_off, 1) < 0) {
> - pr_err("Packet is erroneous!\n");
> - 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;
> - cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
> - return layr->dn->transmit(layr->dn, pkt);
> - }
> - default:
> - break;
> - }
> - return -EINVAL;
> -}
> -
> -static void cfsrvl_release(struct cflayer *layer)
> -{
> - struct cfsrvl *service = container_of(layer, struct cfsrvl, layer);
> - kfree(service);
> -}
> -
> -void cfsrvl_init(struct cfsrvl *service,
> - u8 channel_id,
> - struct dev_info *dev_info,
> - bool supports_flowctrl)
> -{
> - 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;
> - service->supports_flowctrl = supports_flowctrl;
> - service->release = cfsrvl_release;
> -}
> -
> -bool cfsrvl_ready(struct cfsrvl *service, int *err)
> -{
> - if (!service->open) {
> - *err = -ENOTCONN;
> - return false;
> - }
> - return true;
> -}
> -
> -bool cfsrvl_phyid_match(struct cflayer *layer, int phyid)
> -{
> - struct cfsrvl *servl = container_obj(layer);
> - return servl->dev_info.id == phyid;
> -}
> -
> -void caif_free_client(struct cflayer *adap_layer)
> -{
> - struct cflayer *serv_layer;
> - struct cfsrvl *servl;
> -
> - if (!adap_layer)
> - return;
> -
> - serv_layer = adap_layer->dn;
> - if (!serv_layer)
> - return;
> -
> - layer_set_dn(adap_layer, NULL);
> - layer_set_up(serv_layer, NULL);
> -
> - servl = container_obj(serv_layer);
> - servl->release(&servl->layer);
> -}
> -EXPORT_SYMBOL(caif_free_client);
> -
> -void caif_client_register_refcnt(struct cflayer *adapt_layer,
> - void (*hold)(struct cflayer *lyr),
> - void (*put)(struct cflayer *lyr))
> -{
> - struct cfsrvl *service;
> -
> - if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL))
> - return;
> - service = container_of(adapt_layer->dn, struct cfsrvl, layer);
> - service->hold = hold;
> - service->put = put;
> -}
> -EXPORT_SYMBOL(caif_client_register_refcnt);
> diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
> deleted file mode 100644
> index 5111090bb2c0..000000000000
> --- a/net/caif/cfutill.c
> +++ /dev/null
> @@ -1,104 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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
> -
> -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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
> - if (!util)
> - return NULL;
> - caif_assert(offsetof(struct cfsrvl, layer) == 0);
> - cfsrvl_init(util, channel_id, dev_info, true);
> - util->layer.receive = cfutill_receive;
> - util->layer.transmit = cfutill_transmit;
> - snprintf(util->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
> - 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("REMOTE SHUTDOWN REQUEST RECEIVED\n");
> - layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0);
> - service->open = false;
> - cfpkt_destroy(pkt);
> - return 0;
> - default:
> - cfpkt_destroy(pkt);
> - pr_warn("Unknown service control %d (0x%x)\n", 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)) {
> - cfpkt_destroy(pkt);
> - return ret;
> - }
> -
> - 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;
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
> deleted file mode 100644
> index 53f844c49bbb..000000000000
> --- a/net/caif/cfveil.c
> +++ /dev/null
> @@ -1,101 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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 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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
> - if (!vei)
> - return NULL;
> - caif_assert(offsetof(struct cfsrvl, layer) == 0);
> - cfsrvl_init(vei, channel_id, dev_info, true);
> - vei->layer.receive = cfvei_receive;
> - vei->layer.transmit = cfvei_transmit;
> - snprintf(vei->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
> - 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_warn("Unknown VEI control packet %d (0x%x)!\n", 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))
> - goto err;
> - caif_assert(layr->dn != NULL);
> - caif_assert(layr->dn->transmit != NULL);
> -
> - if (cfpkt_add_head(pkt, &tmp, 1) < 0) {
> - pr_err("Packet is erroneous!\n");
> - ret = -EPROTO;
> - goto err;
> - }
> -
> - /* 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;
> - return layr->dn->transmit(layr->dn, pkt);
> -err:
> - cfpkt_destroy(pkt);
> - return ret;
> -}
> diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
> deleted file mode 100644
> index 39e075b0a259..000000000000
> --- a/net/caif/cfvidl.c
> +++ /dev/null
> @@ -1,65 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Author: Sjur Brendeland
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#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 = kzalloc_obj(struct cfsrvl, GFP_ATOMIC);
> - if (!vid)
> - return NULL;
> - caif_assert(offsetof(struct cfsrvl, layer) == 0);
> -
> - cfsrvl_init(vid, channel_id, dev_info, false);
> - vid->layer.receive = cfvidl_receive;
> - vid->layer.transmit = cfvidl_transmit;
> - snprintf(vid->layer.name, CAIF_LAYER_NAME_SZ, "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("Packet is erroneous!\n");
> - 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)) {
> - cfpkt_destroy(pkt);
> - 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;
> - return layr->dn->transmit(layr->dn, pkt);
> -}
> diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
> deleted file mode 100644
> index fa6a3c2634a8..000000000000
> --- a/net/caif/chnl_net.c
> +++ /dev/null
> @@ -1,531 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * Copyright (C) ST-Ericsson AB 2010
> - * Authors: Sjur Brendeland
> - * Daniel Martensson
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
> -
> -#include <linux/fs.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/netdevice.h>
> -#include <linux/if_ether.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/cfpkt.h>
> -#include <net/caif/caif_dev.h>
> -
> -/* GPRS PDP connection has MTU to 1500 */
> -#define GPRS_PDP_MTU 1500
> -/* 5 sec. connect timeout */
> -#define CONNECT_TIMEOUT (5 * HZ)
> -#define CAIF_NET_DEFAULT_QUEUE_LEN 500
> -#define UNDEF_CONNID 0xffffffff
> -
> -/*This list is protected by the rtnl lock. */
> -static LIST_HEAD(chnl_net_list);
> -
> -MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol GPRS network device");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS_RTNL_LINK("caif");
> -
> -enum caif_states {
> - CAIF_CONNECTED = 1,
> - CAIF_CONNECTING,
> - CAIF_DISCONNECTED,
> - CAIF_SHUTDOWN
> -};
> -
> -struct chnl_net {
> - struct cflayer chnl;
> - struct caif_connect_request conn_req;
> - struct list_head list_field;
> - struct net_device *netdev;
> - wait_queue_head_t netmgmt_wq;
> - /* Flow status to remember and control the transmission. */
> - bool flowenabled;
> - enum caif_states state;
> -};
> -
> -static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
> -{
> - struct sk_buff *skb;
> - struct chnl_net *priv;
> - int pktlen;
> - const u8 *ip_version;
> - u8 buf;
> -
> - priv = container_of(layr, struct chnl_net, chnl);
> -
> - skb = (struct sk_buff *) cfpkt_tonative(pkt);
> -
> - /* Get length of CAIF packet. */
> - pktlen = skb->len;
> -
> - /* Pass some minimum information and
> - * send the packet to the net stack.
> - */
> - skb->dev = priv->netdev;
> -
> - /* check the version of IP */
> - ip_version = skb_header_pointer(skb, 0, 1, &buf);
> - if (!ip_version) {
> - kfree_skb(skb);
> - return -EINVAL;
> - }
> -
> - switch (*ip_version >> 4) {
> - case 4:
> - skb->protocol = htons(ETH_P_IP);
> - break;
> - case 6:
> - skb->protocol = htons(ETH_P_IPV6);
> - break;
> - default:
> - kfree_skb(skb);
> - priv->netdev->stats.rx_errors++;
> - return -EINVAL;
> - }
> -
> - /* If we change the header in loop mode, the checksum is corrupted. */
> - if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP)
> - skb->ip_summed = CHECKSUM_UNNECESSARY;
> - else
> - skb->ip_summed = CHECKSUM_NONE;
> -
> - netif_rx(skb);
> -
> - /* Update statistics. */
> - priv->netdev->stats.rx_packets++;
> - priv->netdev->stats.rx_bytes += pktlen;
> -
> - return 0;
> -}
> -
> -static int delete_device(struct chnl_net *dev)
> -{
> - ASSERT_RTNL();
> - if (dev->netdev)
> - unregister_netdevice(dev->netdev);
> - return 0;
> -}
> -
> -static void close_work(struct work_struct *work)
> -{
> - struct chnl_net *dev = NULL;
> - struct list_head *list_node;
> - struct list_head *_tmp;
> -
> - rtnl_lock();
> - list_for_each_safe(list_node, _tmp, &chnl_net_list) {
> - dev = list_entry(list_node, struct chnl_net, list_field);
> - if (dev->state == CAIF_SHUTDOWN)
> - dev_close(dev->netdev);
> - }
> - rtnl_unlock();
> -}
> -static DECLARE_WORK(close_worker, close_work);
> -
> -static void chnl_hold(struct cflayer *lyr)
> -{
> - struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
> - dev_hold(priv->netdev);
> -}
> -
> -static void chnl_put(struct cflayer *lyr)
> -{
> - struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl);
> - dev_put(priv->netdev);
> -}
> -
> -static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
> - int phyid)
> -{
> - struct chnl_net *priv = container_of(layr, struct chnl_net, chnl);
> - pr_debug("NET flowctrl func called flow: %s\n",
> - 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" : "UNKNOWN CTRL COMMAND");
> -
> -
> -
> - switch (flow) {
> - case CAIF_CTRLCMD_FLOW_OFF_IND:
> - priv->flowenabled = false;
> - netif_stop_queue(priv->netdev);
> - break;
> - case CAIF_CTRLCMD_DEINIT_RSP:
> - priv->state = CAIF_DISCONNECTED;
> - break;
> - case CAIF_CTRLCMD_INIT_FAIL_RSP:
> - priv->state = CAIF_DISCONNECTED;
> - wake_up_interruptible(&priv->netmgmt_wq);
> - break;
> - case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
> - priv->state = CAIF_SHUTDOWN;
> - netif_tx_disable(priv->netdev);
> - schedule_work(&close_worker);
> - break;
> - case CAIF_CTRLCMD_FLOW_ON_IND:
> - priv->flowenabled = true;
> - netif_wake_queue(priv->netdev);
> - break;
> - case CAIF_CTRLCMD_INIT_RSP:
> - caif_client_register_refcnt(&priv->chnl, chnl_hold, chnl_put);
> - priv->state = CAIF_CONNECTED;
> - priv->flowenabled = true;
> - netif_wake_queue(priv->netdev);
> - wake_up_interruptible(&priv->netmgmt_wq);
> - break;
> - default:
> - break;
> - }
> -}
> -
> -static netdev_tx_t 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_warn("Size of skb exceeded MTU\n");
> - kfree_skb(skb);
> - dev->stats.tx_errors++;
> - return NETDEV_TX_OK;
> - }
> -
> - if (!priv->flowenabled) {
> - pr_debug("dropping packets flow off\n");
> - kfree_skb(skb);
> - dev->stats.tx_dropped++;
> - return NETDEV_TX_OK;
> - }
> -
> - 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) {
> - dev->stats.tx_dropped++;
> - return NETDEV_TX_OK;
> - }
> -
> - /* 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;
> - int llifindex, headroom, tailroom, mtu;
> - struct net_device *lldev;
> - ASSERT_RTNL();
> - priv = netdev_priv(dev);
> - if (!priv) {
> - pr_debug("chnl_net_open: no priv\n");
> - return -ENODEV;
> - }
> -
> - if (priv->state != CAIF_CONNECTING) {
> - priv->state = CAIF_CONNECTING;
> - result = caif_connect_client(dev_net(dev), &priv->conn_req,
> - &priv->chnl, &llifindex,
> - &headroom, &tailroom);
> - if (result != 0) {
> - pr_debug("err: "
> - "Unable to register and open device,"
> - " Err:%d\n",
> - result);
> - goto error;
> - }
> -
> - lldev = __dev_get_by_index(dev_net(dev), llifindex);
> -
> - if (lldev == NULL) {
> - pr_debug("no interface?\n");
> - result = -ENODEV;
> - goto error;
> - }
> -
> - dev->needed_tailroom = tailroom + lldev->needed_tailroom;
> - dev->hard_header_len = headroom + lldev->hard_header_len +
> - lldev->needed_tailroom;
> -
> - /*
> - * MTU, head-room etc is not know before we have a
> - * CAIF link layer device available. MTU calculation may
> - * override initial RTNL configuration.
> - * MTU is minimum of current mtu, link layer mtu pluss
> - * CAIF head and tail, and PDP GPRS contexts max MTU.
> - */
> - mtu = min_t(int, dev->mtu, lldev->mtu - (headroom + tailroom));
> - mtu = min_t(int, GPRS_PDP_MTU, mtu);
> - dev_set_mtu(dev, mtu);
> -
> - if (mtu < 100) {
> - pr_warn("CAIF Interface MTU too small (%d)\n", mtu);
> - result = -ENODEV;
> - goto error;
> - }
> - }
> -
> - rtnl_unlock(); /* Release RTNL lock during connect wait */
> -
> - result = wait_event_interruptible_timeout(priv->netmgmt_wq,
> - priv->state != CAIF_CONNECTING,
> - CONNECT_TIMEOUT);
> -
> - rtnl_lock();
> -
> - if (result == -ERESTARTSYS) {
> - pr_debug("wait_event_interruptible woken by a signal\n");
> - result = -ERESTARTSYS;
> - goto error;
> - }
> -
> - if (result == 0) {
> - pr_debug("connect timeout\n");
> - result = -ETIMEDOUT;
> - goto error;
> - }
> -
> - if (priv->state != CAIF_CONNECTED) {
> - pr_debug("connect failed\n");
> - result = -ECONNREFUSED;
> - goto error;
> - }
> - pr_debug("CAIF Netdevice connected\n");
> - return 0;
> -
> -error:
> - caif_disconnect_client(dev_net(dev), &priv->chnl);
> - priv->state = CAIF_DISCONNECTED;
> - pr_debug("state disconnected\n");
> - return result;
> -
> -}
> -
> -static int chnl_net_stop(struct net_device *dev)
> -{
> - struct chnl_net *priv;
> -
> - ASSERT_RTNL();
> - priv = netdev_priv(dev);
> - priv->state = CAIF_DISCONNECTED;
> - caif_disconnect_client(dev_net(dev), &priv->chnl);
> - return 0;
> -}
> -
> -static int chnl_net_init(struct net_device *dev)
> -{
> - struct chnl_net *priv;
> - ASSERT_RTNL();
> - priv = netdev_priv(dev);
> - INIT_LIST_HEAD(&priv->list_field);
> - return 0;
> -}
> -
> -static void chnl_net_uninit(struct net_device *dev)
> -{
> - struct chnl_net *priv;
> - ASSERT_RTNL();
> - priv = netdev_priv(dev);
> - list_del_init(&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 chnl_net_destructor(struct net_device *dev)
> -{
> - struct chnl_net *priv = netdev_priv(dev);
> - caif_free_client(&priv->chnl);
> -}
> -
> -static void ipcaif_net_setup(struct net_device *dev)
> -{
> - struct chnl_net *priv;
> - dev->netdev_ops = &netdev_ops;
> - dev->needs_free_netdev = true;
> - dev->priv_destructor = chnl_net_destructor;
> - dev->flags |= IFF_NOARP;
> - dev->flags |= IFF_POINTOPOINT;
> - dev->mtu = GPRS_PDP_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 = UNDEF_CONNID;
> - priv->flowenabled = false;
> -
> - init_waitqueue_head(&priv->netmgmt_wq);
> -}
> -
> -
> -static int ipcaif_fill_info(struct sk_buff *skb, const struct net_device *dev)
> -{
> - struct chnl_net *priv;
> - u8 loop;
> - priv = netdev_priv(dev);
> - if (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))
> - goto nla_put_failure;
> - loop = priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP;
> - if (nla_put_u8(skb, IFLA_CAIF_LOOPBACK, loop))
> - goto nla_put_failure;
> - return 0;
> -nla_put_failure:
> - return -EMSGSIZE;
> -
> -}
> -
> -static void caif_netlink_parms(struct nlattr *data[],
> - struct caif_connect_request *conn_req)
> -{
> - if (!data) {
> - pr_warn("no params data found\n");
> - 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_device *dev,
> - struct rtnl_newlink_params *params,
> - struct netlink_ext_ack *extack)
> -{
> - struct nlattr **data = params->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_warn("device rtml registration failed\n");
> - else
> - list_add(&caifdev->list_field, &chnl_net_list);
> -
> - /* Use ifindex as connection id, and use loopback channel default. */
> - if (caifdev->conn_req.sockaddr.u.dgm.connection_id == UNDEF_CONNID) {
> - caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex;
> - caifdev->conn_req.protocol = CAIFPROTO_DATAGRAM_LOOP;
> - }
> - return ret;
> -}
> -
> -static int ipcaif_changelink(struct net_device *dev, struct nlattr *tb[],
> - struct nlattr *data[],
> - struct netlink_ext_ack *extack)
> -{
> - 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_init(list_node);
> - delete_device(dev);
> - }
> - rtnl_unlock();
> -}
> -
> -module_init(chnl_init_module);
> -module_exit(chnl_exit_module);
> diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
> index e88533b78327..de4af7c750ca 100644
> --- a/arch/arm/configs/u8500_defconfig
> +++ b/arch/arm/configs/u8500_defconfig
> @@ -37,7 +37,6 @@ CONFIG_CFG80211=y
> CONFIG_CFG80211_DEBUGFS=y
> CONFIG_MAC80211=y
> CONFIG_MAC80211_LEDS=y
> -CONFIG_CAIF=y
> CONFIG_NFC=m
> CONFIG_NFC_HCI=m
> CONFIG_NFC_SHDLC=y
> --
> 2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-deletions] caif: remove CAIF NETWORK LAYER
2026-04-16 18:28 [PATCH net-deletions] caif: remove CAIF NETWORK LAYER Jakub Kicinski
2026-04-17 9:06 ` Michael S. Tsirkin
@ 2026-04-18 8:48 ` Greg KH
1 sibling, 0 replies; 3+ messages in thread
From: Greg KH @ 2026-04-18 8:48 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, alexs, si.yanteng, dzm91, linux, mst, jasowang, xuanzhuo,
eperezma, xu.xin16, wang.yaxin, jiang.kun2, linusw,
jihed.chaibi.dev, arnd, tytso, jiayuan.chen
On Thu, Apr 16, 2026 at 11:28:28AM -0700, Jakub Kicinski wrote:
> Remove CAIF (Communication CPU to Application CPU Interface), the
> ST-Ericsson modem protocol. The subsystem has been orphaned since 2013.
> The last meaningful changes from the maintainers were in March 2013:
> a8c7687bf216 ("caif_virtio: Check that vringh_config is not null")
> b2273be8d2df ("caif_virtio: Use vringh_notify_enable correctly")
> 0d2e1a2926b1 ("caif_virtio: Introduce caif over virtio")
>
> Not-so-coincidentally, according to "the Internet" ST-Ericsson officially
> shut down its modem joint venture in Aug 2013.
>
> If anyone is using this code please yell!
>
> In the 13 years since, the code has accumulated 200 non-merge commits,
> of which 71 were cross-tree API changes, 21 carried Fixes: tags, and
> the remaining ~110 were cleanups, doc conversions, treewide refactors,
> and one partial removal (caif_hsi, ca75bcf0a83b).
>
> We are still getting fixes to this code, in the last 10 days there were
> 3 reports on security@ about CAIF that I have been CCed on.
>
> UAPI constants (AF_CAIF, ARPHRD_CAIF, N_CAIF, VIRTIO_ID_CAIF) and the
> SELinux classmap entry are intentionally kept for ABI stability.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> I think we should accumulate such patches over the coming days on a separate
> branch. CAIF is a no-brainer IMO but other removals may be more controversial.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-18 8:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-16 18:28 [PATCH net-deletions] caif: remove CAIF NETWORK LAYER Jakub Kicinski
2026-04-17 9:06 ` Michael S. Tsirkin
2026-04-18 8:48 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox