Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

caif: remove CAIF NETWORK LAYER

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.

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260416182829.1440262-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

-8675
-138
Documentation/networking/caif/caif.rst
··· 1 - .. SPDX-License-Identifier: GPL-2.0 2 - .. include:: <isonum.txt> 3 - 4 - 5 - ================ 6 - Using Linux CAIF 7 - ================ 8 - 9 - 10 - :Copyright: |copy| ST-Ericsson AB 2010 11 - 12 - :Author: Sjur Brendeland/ sjur.brandeland@stericsson.com 13 - 14 - Start 15 - ===== 16 - 17 - If you have compiled CAIF for modules do:: 18 - 19 - $modprobe crc_ccitt 20 - $modprobe caif 21 - $modprobe caif_socket 22 - $modprobe chnl_net 23 - 24 - 25 - Preparing the setup with a STE modem 26 - ==================================== 27 - 28 - If you are working on integration of CAIF you should make sure 29 - that the kernel is built with module support. 30 - 31 - There are some things that need to be tweaked to get the host TTY correctly 32 - set up to talk to the modem. 33 - Since the CAIF stack is running in the kernel and we want to use the existing 34 - TTY, we are installing our physical serial driver as a line discipline above 35 - the TTY device. 36 - 37 - To achieve this we need to install the N_CAIF ldisc from user space. 38 - The benefit is that we can hook up to any TTY. 39 - 40 - The use of Start-of-frame-extension (STX) must also be set as 41 - module parameter "ser_use_stx". 42 - 43 - Normally Frame Checksum is always used on UART, but this is also provided as a 44 - module parameter "ser_use_fcs". 45 - 46 - :: 47 - 48 - $ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes 49 - $ ifconfig caif_ttyS0 up 50 - 51 - PLEASE NOTE: 52 - There is a limitation in Android shell. 53 - It only accepts one argument to insmod/modprobe! 54 - 55 - Trouble shooting 56 - ================ 57 - 58 - There are debugfs parameters provided for serial communication. 59 - /sys/kernel/debug/caif_serial/<tty-name>/ 60 - 61 - * ser_state: Prints the bit-mask status where 62 - 63 - - 0x02 means SENDING, this is a transient state. 64 - - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent 65 - and is blocking further send operation. Flow OFF has been propagated 66 - to all CAIF Channels using this TTY. 67 - 68 - * tty_status: Prints the bit-mask tty status information 69 - 70 - - 0x01 - tty->warned is on. 71 - - 0x04 - tty->packed is on. 72 - - 0x08 - tty->flow.tco_stopped is on. 73 - - 0x10 - tty->hw_stopped is on. 74 - - 0x20 - tty->flow.stopped is on. 75 - 76 - * last_tx_msg: Binary blob Prints the last transmitted frame. 77 - 78 - This can be printed with:: 79 - 80 - $od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg. 81 - 82 - The first two tx messages sent look like this. Note: The initial 83 - byte 02 is start of frame extension (STX) used for re-syncing 84 - upon errors. 85 - 86 - - Enumeration:: 87 - 88 - 0000000 02 05 00 00 03 01 d2 02 89 - | | | | | | 90 - STX(1) | | | | 91 - Length(2)| | | 92 - Control Channel(1) 93 - Command:Enumeration(1) 94 - Link-ID(1) 95 - Checksum(2) 96 - 97 - - Channel Setup:: 98 - 99 - 0000000 02 07 00 00 00 21 a1 00 48 df 100 - | | | | | | | | 101 - STX(1) | | | | | | 102 - Length(2)| | | | | 103 - Control Channel(1) 104 - Command:Channel Setup(1) 105 - Channel Type(1) 106 - Priority and Link-ID(1) 107 - Endpoint(1) 108 - Checksum(2) 109 - 110 - * last_rx_msg: Prints the last transmitted frame. 111 - 112 - The RX messages for LinkSetup look almost identical but they have the 113 - bit 0x20 set in the command bit, and Channel Setup has added one byte 114 - before Checksum containing Channel ID. 115 - 116 - NOTE: 117 - Several CAIF Messages might be concatenated. The maximum debug 118 - buffer size is 128 bytes. 119 - 120 - Error Scenarios 121 - =============== 122 - 123 - - last_tx_msg contains channel setup message and last_rx_msg is empty -> 124 - The host seems to be able to send over the UART, at least the CAIF ldisc get 125 - notified that sending is completed. 126 - 127 - - last_tx_msg contains enumeration message and last_rx_msg is empty -> 128 - The host is not able to send the message from UART, the tty has not been 129 - able to complete the transmit operation. 130 - 131 - - if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there 132 - might be problems transmitting over UART. 133 - 134 - E.g. host and modem wiring is not correct you will typically see 135 - tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT). 136 - 137 - You will probably see the enumeration message in last_tx_message 138 - and empty last_rx_message.
-12
Documentation/networking/caif/index.rst
··· 1 - .. SPDX-License-Identifier: GPL-2.0 2 - 3 - CAIF 4 - ==== 5 - 6 - Contents: 7 - 8 - .. toctree:: 9 - :maxdepth: 2 10 - 11 - linux_caif 12 - caif
-195
Documentation/networking/caif/linux_caif.rst
··· 1 - .. SPDX-License-Identifier: GPL-2.0 2 - .. include:: <isonum.txt> 3 - 4 - ========== 5 - Linux CAIF 6 - ========== 7 - 8 - Copyright |copy| ST-Ericsson AB 2010 9 - 10 - :Author: Sjur Brendeland/ sjur.brandeland@stericsson.com 11 - :License terms: GNU General Public License (GPL) version 2 12 - 13 - 14 - Introduction 15 - ============ 16 - 17 - CAIF is a MUX protocol used by ST-Ericsson cellular modems for 18 - communication between Modem and host. The host processes can open virtual AT 19 - channels, initiate GPRS Data connections, Video channels and Utility Channels. 20 - The Utility Channels are general purpose pipes between modem and host. 21 - 22 - ST-Ericsson modems support a number of transports between modem 23 - and host. Currently, UART and Loopback are available for Linux. 24 - 25 - 26 - Architecture 27 - ============ 28 - 29 - The implementation of CAIF is divided into: 30 - 31 - * CAIF Socket Layer and GPRS IP Interface. 32 - * CAIF Core Protocol Implementation 33 - * CAIF Link Layer, implemented as NET devices. 34 - 35 - :: 36 - 37 - RTNL 38 - ! 39 - ! +------+ +------+ 40 - ! +------+! +------+! 41 - ! ! IP !! !Socket!! 42 - +-------> !interf!+ ! API !+ <- CAIF Client APIs 43 - ! +------+ +------! 44 - ! ! ! 45 - ! +-----------+ 46 - ! ! 47 - ! +------+ <- CAIF Core Protocol 48 - ! ! CAIF ! 49 - ! ! Core ! 50 - ! +------+ 51 - ! +----------!---------+ 52 - ! ! ! ! 53 - ! +------+ +-----+ +------+ 54 - +--> ! HSI ! ! TTY ! ! USB ! <- Link Layer (Net Devices) 55 - +------+ +-----+ +------+ 56 - 57 - 58 - 59 - Implementation 60 - ============== 61 - 62 - 63 - CAIF Core Protocol Layer 64 - ------------------------ 65 - 66 - CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson. 67 - It implements the CAIF protocol stack in a layered approach, where 68 - each layer described in the specification is implemented as a separate layer. 69 - The architecture is inspired by the design patterns "Protocol Layer" and 70 - "Protocol Packet". 71 - 72 - CAIF structure 73 - ^^^^^^^^^^^^^^ 74 - 75 - The Core CAIF implementation contains: 76 - 77 - - Simple implementation of CAIF. 78 - - Layered architecture (a la Streams), each layer in the CAIF 79 - specification is implemented in a separate c-file. 80 - - Clients must call configuration function to add PHY layer. 81 - - Clients must implement CAIF layer to consume/produce 82 - CAIF payload with receive and transmit functions. 83 - - Clients must call configuration function to add and connect the 84 - Client layer. 85 - - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed 86 - to the called function (except for framing layers' receive function) 87 - 88 - Layered Architecture 89 - ==================== 90 - 91 - The CAIF protocol can be divided into two parts: Support functions and Protocol 92 - Implementation. The support functions include: 93 - 94 - - CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The 95 - CAIF Packet has functions for creating, destroying and adding content 96 - and for adding/extracting header and trailers to protocol packets. 97 - 98 - The CAIF Protocol implementation contains: 99 - 100 - - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol 101 - Stack and provides a Client interface for adding Link-Layer and 102 - Driver interfaces on top of the CAIF Stack. 103 - 104 - - CFCTRL CAIF Control layer. Encodes and Decodes control messages 105 - such as enumeration and channel setup. Also matches request and 106 - response messages. 107 - 108 - - CFSERVL General CAIF Service Layer functionality; handles flow 109 - control and remote shutdown requests. 110 - 111 - - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual 112 - External Interface). This layer encodes/decodes VEI frames. 113 - 114 - - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP 115 - traffic), encodes/decodes Datagram frames. 116 - 117 - - CFMUX CAIF Mux layer. Handles multiplexing between multiple 118 - physical bearers and multiple channels such as VEI, Datagram, etc. 119 - The MUX keeps track of the existing CAIF Channels and 120 - Physical Instances and selects the appropriate instance based 121 - on Channel-Id and Physical-ID. 122 - 123 - - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length 124 - and frame checksum. 125 - 126 - - CFSERL CAIF Serial layer. Handles concatenation/split of frames 127 - into CAIF Frames with correct length. 128 - 129 - :: 130 - 131 - +---------+ 132 - | Config | 133 - | CFCNFG | 134 - +---------+ 135 - ! 136 - +---------+ +---------+ +---------+ 137 - | AT | | Control | | Datagram| 138 - | CFVEIL | | CFCTRL | | CFDGML | 139 - +---------+ +---------+ +---------+ 140 - \_____________!______________/ 141 - ! 142 - +---------+ 143 - | MUX | 144 - | | 145 - +---------+ 146 - _____!_____ 147 - / \ 148 - +---------+ +---------+ 149 - | CFFRML | | CFFRML | 150 - | Framing | | Framing | 151 - +---------+ +---------+ 152 - ! ! 153 - +---------+ +---------+ 154 - | | | Serial | 155 - | | | CFSERL | 156 - +---------+ +---------+ 157 - 158 - 159 - In this layered approach the following "rules" apply. 160 - 161 - - All layers embed the same structure "struct cflayer" 162 - - A layer does not depend on any other layer's private data. 163 - - Layers are stacked by setting the pointers:: 164 - 165 - layer->up , layer->dn 166 - 167 - - In order to send data upwards, each layer should do:: 168 - 169 - layer->up->receive(layer->up, packet); 170 - 171 - - In order to send data downwards, each layer should do:: 172 - 173 - layer->dn->transmit(layer->dn, packet); 174 - 175 - 176 - CAIF Socket and IP interface 177 - ============================ 178 - 179 - The IP interface and CAIF socket API are implemented on top of the 180 - CAIF Core protocol. The IP Interface and CAIF socket have an instance of 181 - 'struct cflayer', just like the CAIF Core protocol stack. 182 - Net device and Socket implement the 'receive()' function defined by 183 - 'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and 184 - receive of packets is handled as by the rest of the layers: the 'dn->transmit()' 185 - function is called in order to transmit data. 186 - 187 - Configuration of Link Layer 188 - --------------------------- 189 - The Link Layer is implemented as Linux network devices (struct net_device). 190 - Payload handling and registration is done using standard Linux mechanisms. 191 - 192 - The CAIF Protocol relies on a loss-less link layer without implementing 193 - retransmission. This implies that packet drops must not happen. 194 - Therefore a flow-control mechanism is implemented where the physical 195 - interface can initiate flow stop for all CAIF Channels.
-1
Documentation/networking/index.rst
··· 17 17 diagnostic/index 18 18 dsa/index 19 19 devlink/index 20 - caif/index 21 20 ethtool-netlink 22 21 ieee802154 23 22 iso15765-2
-1
Documentation/translations/zh_CN/networking/index.rst
··· 42 42 * diagnostic/index 43 43 * dsa/index 44 44 * devlink/index 45 - * caif/index 46 45 * ethtool-netlink 47 46 * ieee802154 48 47 * iso15765-2
-9
MAINTAINERS
··· 5674 5674 F: Documentation/admin-guide/media/cafe_ccic* 5675 5675 F: drivers/media/platform/marvell/ 5676 5676 5677 - CAIF NETWORK LAYER 5678 - L: netdev@vger.kernel.org 5679 - S: Orphan 5680 - F: Documentation/networking/caif/ 5681 - F: drivers/net/caif/ 5682 - F: include/net/caif/ 5683 - F: include/uapi/linux/caif/ 5684 - F: net/caif/ 5685 - 5686 5677 CAKE QDISC 5687 5678 M: Toke Høiland-Jørgensen <toke@toke.dk> 5688 5679 L: cake@lists.bufferbloat.net (moderated for non-subscribers)
-1
arch/arm/configs/u8500_defconfig
··· 37 37 CONFIG_CFG80211_DEBUGFS=y 38 38 CONFIG_MAC80211=y 39 39 CONFIG_MAC80211_LEDS=y 40 - CONFIG_CAIF=y 41 40 CONFIG_NFC=m 42 41 CONFIG_NFC_HCI=m 43 42 CONFIG_NFC_SHDLC=y
-2
drivers/net/Kconfig
··· 503 503 504 504 source "drivers/atm/Kconfig" 505 505 506 - source "drivers/net/caif/Kconfig" 507 - 508 506 source "drivers/net/dsa/Kconfig" 509 507 510 508 source "drivers/net/ethernet/Kconfig"
-1
drivers/net/Makefile
··· 48 48 # Networking Drivers 49 49 # 50 50 obj-$(CONFIG_ARCNET) += arcnet/ 51 - obj-$(CONFIG_CAIF) += caif/ 52 51 obj-$(CONFIG_CAN) += can/ 53 52 ifdef CONFIG_NET_DSA 54 53 obj-y += dsa/
-33
drivers/net/caif/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # CAIF physical drivers 4 - # 5 - 6 - menuconfig CAIF_DRIVERS 7 - bool "CAIF transport drivers" 8 - depends on CAIF 9 - help 10 - Enable this to see CAIF physical drivers. 11 - 12 - if CAIF_DRIVERS 13 - 14 - config CAIF_TTY 15 - tristate "CAIF TTY transport driver" 16 - depends on CAIF && TTY 17 - default n 18 - help 19 - The CAIF TTY transport driver is a Line Discipline (ldisc) 20 - identified as N_CAIF. When this ldisc is opened from user space 21 - it will redirect the TTY's traffic into the CAIF stack. 22 - 23 - config CAIF_VIRTIO 24 - tristate "CAIF virtio transport driver" 25 - depends on CAIF && HAS_DMA 26 - select VHOST_RING 27 - select VIRTIO 28 - select GENERIC_ALLOCATOR 29 - default n 30 - help 31 - The CAIF driver for CAIF over Virtio. 32 - 33 - endif # CAIF_DRIVERS
-8
drivers/net/caif/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG 3 - 4 - # Serial interface 5 - obj-$(CONFIG_CAIF_TTY) += caif_serial.o 6 - 7 - # Virtio interface 8 - obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
-443
drivers/net/caif/caif_serial.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #include <linux/hardirq.h> 8 - #include <linux/init.h> 9 - #include <linux/module.h> 10 - #include <linux/device.h> 11 - #include <linux/types.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/netdevice.h> 14 - #include <linux/rtnetlink.h> 15 - #include <linux/tty.h> 16 - #include <linux/file.h> 17 - #include <linux/if_arp.h> 18 - #include <net/caif/caif_device.h> 19 - #include <net/caif/cfcnfg.h> 20 - #include <linux/err.h> 21 - #include <linux/debugfs.h> 22 - 23 - MODULE_LICENSE("GPL"); 24 - MODULE_AUTHOR("Sjur Brendeland"); 25 - MODULE_DESCRIPTION("CAIF serial device TTY line discipline"); 26 - MODULE_LICENSE("GPL"); 27 - MODULE_ALIAS_LDISC(N_CAIF); 28 - 29 - #define SEND_QUEUE_LOW 10 30 - #define SEND_QUEUE_HIGH 100 31 - #define CAIF_SENDING 1 /* Bit 1 = 0x02*/ 32 - #define CAIF_FLOW_OFF_SENT 4 /* Bit 4 = 0x10 */ 33 - #define MAX_WRITE_CHUNK 4096 34 - #define ON 1 35 - #define OFF 0 36 - #define CAIF_MAX_MTU 4096 37 - 38 - static DEFINE_SPINLOCK(ser_lock); 39 - static LIST_HEAD(ser_list); 40 - static LIST_HEAD(ser_release_list); 41 - 42 - static bool ser_loop; 43 - module_param(ser_loop, bool, 0444); 44 - MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode."); 45 - 46 - static bool ser_use_stx = true; 47 - module_param(ser_use_stx, bool, 0444); 48 - MODULE_PARM_DESC(ser_use_stx, "STX enabled or not."); 49 - 50 - static bool ser_use_fcs = true; 51 - 52 - module_param(ser_use_fcs, bool, 0444); 53 - MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not."); 54 - 55 - static int ser_write_chunk = MAX_WRITE_CHUNK; 56 - module_param(ser_write_chunk, int, 0444); 57 - 58 - MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART."); 59 - 60 - static struct dentry *debugfsdir; 61 - 62 - static int caif_net_open(struct net_device *dev); 63 - static int caif_net_close(struct net_device *dev); 64 - 65 - struct ser_device { 66 - struct caif_dev_common common; 67 - struct list_head node; 68 - struct net_device *dev; 69 - struct sk_buff_head head; 70 - struct tty_struct *tty; 71 - bool tx_started; 72 - unsigned long state; 73 - #ifdef CONFIG_DEBUG_FS 74 - struct dentry *debugfs_tty_dir; 75 - struct debugfs_blob_wrapper tx_blob; 76 - struct debugfs_blob_wrapper rx_blob; 77 - u8 rx_data[128]; 78 - u8 tx_data[128]; 79 - u8 tty_status; 80 - 81 - #endif 82 - }; 83 - 84 - static void caifdev_setup(struct net_device *dev); 85 - static void ldisc_tx_wakeup(struct tty_struct *tty); 86 - #ifdef CONFIG_DEBUG_FS 87 - static inline void update_tty_status(struct ser_device *ser) 88 - { 89 - ser->tty_status = 90 - ser->tty->flow.stopped << 5 | 91 - ser->tty->flow.tco_stopped << 3 | 92 - ser->tty->ctrl.packet << 2; 93 - } 94 - static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) 95 - { 96 - ser->debugfs_tty_dir = debugfs_create_dir(tty->name, debugfsdir); 97 - 98 - debugfs_create_blob("last_tx_msg", 0400, ser->debugfs_tty_dir, 99 - &ser->tx_blob); 100 - 101 - debugfs_create_blob("last_rx_msg", 0400, ser->debugfs_tty_dir, 102 - &ser->rx_blob); 103 - 104 - debugfs_create_xul("ser_state", 0400, ser->debugfs_tty_dir, 105 - &ser->state); 106 - 107 - debugfs_create_x8("tty_status", 0400, ser->debugfs_tty_dir, 108 - &ser->tty_status); 109 - 110 - ser->tx_blob.data = ser->tx_data; 111 - ser->tx_blob.size = 0; 112 - ser->rx_blob.data = ser->rx_data; 113 - ser->rx_blob.size = 0; 114 - } 115 - 116 - static inline void debugfs_deinit(struct ser_device *ser) 117 - { 118 - debugfs_remove_recursive(ser->debugfs_tty_dir); 119 - } 120 - 121 - static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size) 122 - { 123 - if (size > sizeof(ser->rx_data)) 124 - size = sizeof(ser->rx_data); 125 - memcpy(ser->rx_data, data, size); 126 - ser->rx_blob.data = ser->rx_data; 127 - ser->rx_blob.size = size; 128 - } 129 - #else 130 - static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) 131 - { 132 - } 133 - 134 - static inline void debugfs_deinit(struct ser_device *ser) 135 - { 136 - } 137 - 138 - static inline void update_tty_status(struct ser_device *ser) 139 - { 140 - } 141 - 142 - static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size) 143 - { 144 - } 145 - #endif 146 - 147 - static void ldisc_receive(struct tty_struct *tty, const u8 *data, 148 - const u8 *flags, size_t count) 149 - { 150 - struct sk_buff *skb = NULL; 151 - struct ser_device *ser; 152 - int ret; 153 - 154 - ser = tty->disc_data; 155 - 156 - /* 157 - * NOTE: flags may contain information about break or overrun. 158 - * This is not yet handled. 159 - */ 160 - 161 - 162 - /* 163 - * Workaround for garbage at start of transmission, 164 - * only enable if STX handling is not enabled. 165 - */ 166 - if (!ser->common.use_stx && !ser->tx_started) { 167 - dev_info(&ser->dev->dev, 168 - "Bytes received before initial transmission -" 169 - "bytes discarded.\n"); 170 - return; 171 - } 172 - 173 - BUG_ON(ser->dev == NULL); 174 - 175 - /* Get a suitable caif packet and copy in data. */ 176 - skb = netdev_alloc_skb(ser->dev, count+1); 177 - if (skb == NULL) 178 - return; 179 - skb_put_data(skb, data, count); 180 - 181 - skb->protocol = htons(ETH_P_CAIF); 182 - skb_reset_mac_header(skb); 183 - debugfs_rx(ser, data, count); 184 - /* Push received packet up the stack. */ 185 - ret = netif_rx(skb); 186 - if (!ret) { 187 - ser->dev->stats.rx_packets++; 188 - ser->dev->stats.rx_bytes += count; 189 - } else 190 - ++ser->dev->stats.rx_dropped; 191 - update_tty_status(ser); 192 - } 193 - 194 - static int handle_tx(struct ser_device *ser) 195 - { 196 - struct tty_struct *tty; 197 - struct sk_buff *skb; 198 - int tty_wr, len, room; 199 - 200 - tty = ser->tty; 201 - ser->tx_started = true; 202 - 203 - /* Enter critical section */ 204 - if (test_and_set_bit(CAIF_SENDING, &ser->state)) 205 - return 0; 206 - 207 - /* skb_peek is safe because handle_tx is called after skb_queue_tail */ 208 - while ((skb = skb_peek(&ser->head)) != NULL) { 209 - 210 - /* Make sure you don't write too much */ 211 - len = skb->len; 212 - room = tty_write_room(tty); 213 - if (!room) 214 - break; 215 - if (room > ser_write_chunk) 216 - room = ser_write_chunk; 217 - if (len > room) 218 - len = room; 219 - 220 - /* Write to tty or loopback */ 221 - if (!ser_loop) { 222 - tty_wr = tty->ops->write(tty, skb->data, len); 223 - update_tty_status(ser); 224 - } else { 225 - tty_wr = len; 226 - ldisc_receive(tty, skb->data, NULL, len); 227 - } 228 - ser->dev->stats.tx_packets++; 229 - ser->dev->stats.tx_bytes += tty_wr; 230 - 231 - /* Error on TTY ?! */ 232 - if (tty_wr < 0) 233 - goto error; 234 - /* Reduce buffer written, and discard if empty */ 235 - skb_pull(skb, tty_wr); 236 - if (skb->len == 0) { 237 - struct sk_buff *tmp = skb_dequeue(&ser->head); 238 - WARN_ON(tmp != skb); 239 - dev_consume_skb_any(skb); 240 - } 241 - } 242 - /* Send flow off if queue is empty */ 243 - if (ser->head.qlen <= SEND_QUEUE_LOW && 244 - test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) && 245 - ser->common.flowctrl != NULL) 246 - ser->common.flowctrl(ser->dev, ON); 247 - clear_bit(CAIF_SENDING, &ser->state); 248 - return 0; 249 - error: 250 - clear_bit(CAIF_SENDING, &ser->state); 251 - return tty_wr; 252 - } 253 - 254 - static netdev_tx_t caif_xmit(struct sk_buff *skb, struct net_device *dev) 255 - { 256 - struct ser_device *ser; 257 - 258 - ser = netdev_priv(dev); 259 - 260 - /* Send flow off once, on high water mark */ 261 - if (ser->head.qlen > SEND_QUEUE_HIGH && 262 - !test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) && 263 - ser->common.flowctrl != NULL) 264 - 265 - ser->common.flowctrl(ser->dev, OFF); 266 - 267 - skb_queue_tail(&ser->head, skb); 268 - return handle_tx(ser); 269 - } 270 - 271 - 272 - static void ldisc_tx_wakeup(struct tty_struct *tty) 273 - { 274 - struct ser_device *ser; 275 - 276 - ser = tty->disc_data; 277 - BUG_ON(ser == NULL); 278 - WARN_ON(ser->tty != tty); 279 - handle_tx(ser); 280 - } 281 - 282 - 283 - static void ser_release(struct work_struct *work) 284 - { 285 - struct list_head list; 286 - struct ser_device *ser, *tmp; 287 - struct tty_struct *tty; 288 - 289 - spin_lock(&ser_lock); 290 - list_replace_init(&ser_release_list, &list); 291 - spin_unlock(&ser_lock); 292 - 293 - if (!list_empty(&list)) { 294 - rtnl_lock(); 295 - list_for_each_entry_safe(ser, tmp, &list, node) { 296 - tty = ser->tty; 297 - dev_close(ser->dev); 298 - unregister_netdevice(ser->dev); 299 - debugfs_deinit(ser); 300 - tty_kref_put(tty->link); 301 - tty_kref_put(tty); 302 - } 303 - rtnl_unlock(); 304 - } 305 - } 306 - 307 - static DECLARE_WORK(ser_release_work, ser_release); 308 - 309 - static int ldisc_open(struct tty_struct *tty) 310 - { 311 - struct ser_device *ser; 312 - struct net_device *dev; 313 - char name[64]; 314 - int result; 315 - 316 - /* No write no play */ 317 - if (tty->ops->write == NULL) 318 - return -EOPNOTSUPP; 319 - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG)) 320 - return -EPERM; 321 - 322 - /* release devices to avoid name collision */ 323 - ser_release(NULL); 324 - 325 - result = snprintf(name, sizeof(name), "cf%s", tty->name); 326 - if (result >= IFNAMSIZ) 327 - return -EINVAL; 328 - dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN, 329 - caifdev_setup); 330 - if (!dev) 331 - return -ENOMEM; 332 - 333 - ser = netdev_priv(dev); 334 - ser->tty = tty_kref_get(tty); 335 - tty_kref_get(tty->link); 336 - ser->dev = dev; 337 - debugfs_init(ser, tty); 338 - tty->receive_room = 4096; 339 - tty->disc_data = ser; 340 - set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 341 - rtnl_lock(); 342 - result = register_netdevice(dev); 343 - if (result) { 344 - tty_kref_put(tty->link); 345 - tty_kref_put(tty); 346 - rtnl_unlock(); 347 - free_netdev(dev); 348 - return -ENODEV; 349 - } 350 - 351 - spin_lock(&ser_lock); 352 - list_add(&ser->node, &ser_list); 353 - spin_unlock(&ser_lock); 354 - rtnl_unlock(); 355 - netif_stop_queue(dev); 356 - update_tty_status(ser); 357 - return 0; 358 - } 359 - 360 - static void ldisc_close(struct tty_struct *tty) 361 - { 362 - struct ser_device *ser = tty->disc_data; 363 - 364 - spin_lock(&ser_lock); 365 - list_move(&ser->node, &ser_release_list); 366 - spin_unlock(&ser_lock); 367 - schedule_work(&ser_release_work); 368 - } 369 - 370 - /* The line discipline structure. */ 371 - static struct tty_ldisc_ops caif_ldisc = { 372 - .owner = THIS_MODULE, 373 - .num = N_CAIF, 374 - .name = "n_caif", 375 - .open = ldisc_open, 376 - .close = ldisc_close, 377 - .receive_buf = ldisc_receive, 378 - .write_wakeup = ldisc_tx_wakeup 379 - }; 380 - 381 - static const struct net_device_ops netdev_ops = { 382 - .ndo_open = caif_net_open, 383 - .ndo_stop = caif_net_close, 384 - .ndo_start_xmit = caif_xmit 385 - }; 386 - 387 - static void caifdev_setup(struct net_device *dev) 388 - { 389 - struct ser_device *serdev = netdev_priv(dev); 390 - 391 - dev->features = 0; 392 - dev->netdev_ops = &netdev_ops; 393 - dev->type = ARPHRD_CAIF; 394 - dev->flags = IFF_POINTOPOINT | IFF_NOARP; 395 - dev->mtu = CAIF_MAX_MTU; 396 - dev->priv_flags |= IFF_NO_QUEUE; 397 - dev->needs_free_netdev = true; 398 - skb_queue_head_init(&serdev->head); 399 - serdev->common.link_select = CAIF_LINK_LOW_LATENCY; 400 - serdev->common.use_frag = true; 401 - serdev->common.use_stx = ser_use_stx; 402 - serdev->common.use_fcs = ser_use_fcs; 403 - serdev->dev = dev; 404 - } 405 - 406 - 407 - static int caif_net_open(struct net_device *dev) 408 - { 409 - netif_wake_queue(dev); 410 - return 0; 411 - } 412 - 413 - static int caif_net_close(struct net_device *dev) 414 - { 415 - netif_stop_queue(dev); 416 - return 0; 417 - } 418 - 419 - static int __init caif_ser_init(void) 420 - { 421 - int ret; 422 - 423 - ret = tty_register_ldisc(&caif_ldisc); 424 - if (ret < 0) 425 - pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret); 426 - 427 - debugfsdir = debugfs_create_dir("caif_serial", NULL); 428 - return ret; 429 - } 430 - 431 - static void __exit caif_ser_exit(void) 432 - { 433 - spin_lock(&ser_lock); 434 - list_splice(&ser_list, &ser_release_list); 435 - spin_unlock(&ser_lock); 436 - ser_release(NULL); 437 - cancel_work_sync(&ser_release_work); 438 - tty_unregister_ldisc(&caif_ldisc); 439 - debugfs_remove_recursive(debugfsdir); 440 - } 441 - 442 - module_init(caif_ser_init); 443 - module_exit(caif_ser_exit);
-791
drivers/net/caif/caif_virtio.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2013 4 - * Authors: Vicram Arv 5 - * Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> 6 - * Sjur Brendeland 7 - */ 8 - #include <linux/module.h> 9 - #include <linux/if_arp.h> 10 - #include <linux/virtio.h> 11 - #include <linux/vringh.h> 12 - #include <linux/debugfs.h> 13 - #include <linux/spinlock.h> 14 - #include <linux/genalloc.h> 15 - #include <linux/interrupt.h> 16 - #include <linux/netdevice.h> 17 - #include <linux/rtnetlink.h> 18 - #include <linux/virtio_ids.h> 19 - #include <linux/virtio_caif.h> 20 - #include <linux/virtio_ring.h> 21 - #include <linux/dma-mapping.h> 22 - #include <net/caif/caif_dev.h> 23 - #include <linux/virtio_config.h> 24 - 25 - MODULE_LICENSE("GPL v2"); 26 - MODULE_AUTHOR("Vicram Arv"); 27 - MODULE_AUTHOR("Sjur Brendeland"); 28 - MODULE_DESCRIPTION("Virtio CAIF Driver"); 29 - 30 - /* NAPI schedule quota */ 31 - #define CFV_DEFAULT_QUOTA 32 32 - 33 - /* Defaults used if virtio config space is unavailable */ 34 - #define CFV_DEF_MTU_SIZE 4096 35 - #define CFV_DEF_HEADROOM 32 36 - #define CFV_DEF_TAILROOM 32 37 - 38 - /* Required IP header alignment */ 39 - #define IP_HDR_ALIGN 4 40 - 41 - /* struct cfv_napi_contxt - NAPI context info 42 - * @riov: IOV holding data read from the ring. Note that riov may 43 - * still hold data when cfv_rx_poll() returns. 44 - * @head: Last descriptor ID we received from vringh_getdesc_kern. 45 - * We use this to put descriptor back on the used ring. USHRT_MAX is 46 - * used to indicate invalid head-id. 47 - */ 48 - struct cfv_napi_context { 49 - struct vringh_kiov riov; 50 - unsigned short head; 51 - }; 52 - 53 - /* struct cfv_stats - statistics for debugfs 54 - * @rx_napi_complete: Number of NAPI completions (RX) 55 - * @rx_napi_resched: Number of calls where the full quota was used (RX) 56 - * @rx_nomem: Number of SKB alloc failures (RX) 57 - * @rx_kicks: Number of RX kicks 58 - * @tx_full_ring: Number times TX ring was full 59 - * @tx_no_mem: Number of times TX went out of memory 60 - * @tx_flow_on: Number of flow on (TX) 61 - * @tx_kicks: Number of TX kicks 62 - */ 63 - struct cfv_stats { 64 - u32 rx_napi_complete; 65 - u32 rx_napi_resched; 66 - u32 rx_nomem; 67 - u32 rx_kicks; 68 - u32 tx_full_ring; 69 - u32 tx_no_mem; 70 - u32 tx_flow_on; 71 - u32 tx_kicks; 72 - }; 73 - 74 - /* struct cfv_info - Caif Virtio control structure 75 - * @cfdev: caif common header 76 - * @vdev: Associated virtio device 77 - * @vr_rx: rx/downlink host vring 78 - * @vq_tx: tx/uplink virtqueue 79 - * @ndev: CAIF link layer device 80 - * @watermark_tx: indicates number of free descriptors we need 81 - * to reopen the tx-queues after overload. 82 - * @tx_lock: protects vq_tx from concurrent use 83 - * @tx_release_tasklet: Tasklet for freeing consumed TX buffers 84 - * @napi: Napi context used in cfv_rx_poll() 85 - * @ctx: Context data used in cfv_rx_poll() 86 - * @tx_hr: transmit headroom 87 - * @rx_hr: receive headroom 88 - * @tx_tr: transmit tail room 89 - * @rx_tr: receive tail room 90 - * @mtu: transmit max size 91 - * @mru: receive max size 92 - * @allocsz: size of dma memory reserved for TX buffers 93 - * @alloc_addr: virtual address to dma memory for TX buffers 94 - * @alloc_dma: dma address to dma memory for TX buffers 95 - * @genpool: Gen Pool used for allocating TX buffers 96 - * @reserved_mem: Pointer to memory reserve allocated from genpool 97 - * @reserved_size: Size of memory reserve allocated from genpool 98 - * @stats: Statistics exposed in sysfs 99 - * @debugfs: Debugfs dentry for statistic counters 100 - */ 101 - struct cfv_info { 102 - struct caif_dev_common cfdev; 103 - struct virtio_device *vdev; 104 - struct vringh *vr_rx; 105 - struct virtqueue *vq_tx; 106 - struct net_device *ndev; 107 - unsigned int watermark_tx; 108 - /* Protect access to vq_tx */ 109 - spinlock_t tx_lock; 110 - struct tasklet_struct tx_release_tasklet; 111 - struct napi_struct napi; 112 - struct cfv_napi_context ctx; 113 - u16 tx_hr; 114 - u16 rx_hr; 115 - u16 tx_tr; 116 - u16 rx_tr; 117 - u32 mtu; 118 - u32 mru; 119 - size_t allocsz; 120 - void *alloc_addr; 121 - dma_addr_t alloc_dma; 122 - struct gen_pool *genpool; 123 - unsigned long reserved_mem; 124 - size_t reserved_size; 125 - struct cfv_stats stats; 126 - struct dentry *debugfs; 127 - }; 128 - 129 - /* struct buf_info - maintains transmit buffer data handle 130 - * @size: size of transmit buffer 131 - * @dma_handle: handle to allocated dma device memory area 132 - * @vaddr: virtual address mapping to allocated memory area 133 - */ 134 - struct buf_info { 135 - size_t size; 136 - u8 *vaddr; 137 - }; 138 - 139 - /* Called from virtio device, in IRQ context */ 140 - static void cfv_release_cb(struct virtqueue *vq_tx) 141 - { 142 - struct cfv_info *cfv = vq_tx->vdev->priv; 143 - 144 - ++cfv->stats.tx_kicks; 145 - tasklet_schedule(&cfv->tx_release_tasklet); 146 - } 147 - 148 - static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info) 149 - { 150 - if (!buf_info) 151 - return; 152 - gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr, 153 - buf_info->size); 154 - kfree(buf_info); 155 - } 156 - 157 - /* This is invoked whenever the remote processor completed processing 158 - * a TX msg we just sent, and the buffer is put back to the used ring. 159 - */ 160 - static void cfv_release_used_buf(struct virtqueue *vq_tx) 161 - { 162 - struct cfv_info *cfv = vq_tx->vdev->priv; 163 - unsigned long flags; 164 - 165 - BUG_ON(vq_tx != cfv->vq_tx); 166 - 167 - for (;;) { 168 - unsigned int len; 169 - struct buf_info *buf_info; 170 - 171 - /* Get used buffer from used ring to recycle used descriptors */ 172 - spin_lock_irqsave(&cfv->tx_lock, flags); 173 - buf_info = virtqueue_get_buf(vq_tx, &len); 174 - spin_unlock_irqrestore(&cfv->tx_lock, flags); 175 - 176 - /* Stop looping if there are no more buffers to free */ 177 - if (!buf_info) 178 - break; 179 - 180 - free_buf_info(cfv, buf_info); 181 - 182 - /* watermark_tx indicates if we previously stopped the tx 183 - * queues. If we have enough free stots in the virtio ring, 184 - * re-establish memory reserved and open up tx queues. 185 - */ 186 - if (cfv->vq_tx->num_free <= cfv->watermark_tx) 187 - continue; 188 - 189 - /* Re-establish memory reserve */ 190 - if (cfv->reserved_mem == 0 && cfv->genpool) 191 - cfv->reserved_mem = 192 - gen_pool_alloc(cfv->genpool, 193 - cfv->reserved_size); 194 - 195 - /* Open up the tx queues */ 196 - if (cfv->reserved_mem) { 197 - cfv->watermark_tx = 198 - virtqueue_get_vring_size(cfv->vq_tx); 199 - netif_tx_wake_all_queues(cfv->ndev); 200 - /* Buffers are recycled in cfv_netdev_tx, so 201 - * disable notifications when queues are opened. 202 - */ 203 - virtqueue_disable_cb(cfv->vq_tx); 204 - ++cfv->stats.tx_flow_on; 205 - } else { 206 - /* if no memory reserve, wait for more free slots */ 207 - WARN_ON(cfv->watermark_tx > 208 - virtqueue_get_vring_size(cfv->vq_tx)); 209 - cfv->watermark_tx += 210 - virtqueue_get_vring_size(cfv->vq_tx) / 4; 211 - } 212 - } 213 - } 214 - 215 - /* Allocate a SKB and copy packet data to it */ 216 - static struct sk_buff *cfv_alloc_and_copy_skb(int *err, 217 - struct cfv_info *cfv, 218 - u8 *frm, u32 frm_len) 219 - { 220 - struct sk_buff *skb; 221 - u32 cfpkt_len, pad_len; 222 - 223 - *err = 0; 224 - /* Verify that packet size with down-link header and mtu size */ 225 - if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) { 226 - netdev_err(cfv->ndev, 227 - "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n", 228 - frm_len, cfv->mru, cfv->rx_hr, 229 - cfv->rx_tr); 230 - *err = -EPROTO; 231 - return NULL; 232 - } 233 - 234 - cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr); 235 - pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1); 236 - 237 - skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len); 238 - if (!skb) { 239 - *err = -ENOMEM; 240 - return NULL; 241 - } 242 - 243 - skb_reserve(skb, cfv->rx_hr + pad_len); 244 - 245 - skb_put_data(skb, frm + cfv->rx_hr, cfpkt_len); 246 - return skb; 247 - } 248 - 249 - /* Get packets from the host vring */ 250 - static int cfv_rx_poll(struct napi_struct *napi, int quota) 251 - { 252 - struct cfv_info *cfv = container_of(napi, struct cfv_info, napi); 253 - int rxcnt = 0; 254 - int err = 0; 255 - void *buf; 256 - struct sk_buff *skb; 257 - struct vringh_kiov *riov = &cfv->ctx.riov; 258 - unsigned int skb_len; 259 - 260 - do { 261 - skb = NULL; 262 - 263 - /* Put the previous iovec back on the used ring and 264 - * fetch a new iovec if we have processed all elements. 265 - */ 266 - if (riov->i == riov->used) { 267 - if (cfv->ctx.head != USHRT_MAX) { 268 - vringh_complete_kern(cfv->vr_rx, 269 - cfv->ctx.head, 270 - 0); 271 - cfv->ctx.head = USHRT_MAX; 272 - } 273 - 274 - err = vringh_getdesc_kern( 275 - cfv->vr_rx, 276 - riov, 277 - NULL, 278 - &cfv->ctx.head, 279 - GFP_ATOMIC); 280 - 281 - if (err <= 0) 282 - goto exit; 283 - } 284 - 285 - buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base); 286 - /* TODO: Add check on valid buffer address */ 287 - 288 - skb = cfv_alloc_and_copy_skb(&err, cfv, buf, 289 - riov->iov[riov->i].iov_len); 290 - if (unlikely(err)) 291 - goto exit; 292 - 293 - /* Push received packet up the stack. */ 294 - skb_len = skb->len; 295 - skb->protocol = htons(ETH_P_CAIF); 296 - skb_reset_mac_header(skb); 297 - skb->dev = cfv->ndev; 298 - err = netif_receive_skb(skb); 299 - if (unlikely(err)) { 300 - ++cfv->ndev->stats.rx_dropped; 301 - } else { 302 - ++cfv->ndev->stats.rx_packets; 303 - cfv->ndev->stats.rx_bytes += skb_len; 304 - } 305 - 306 - ++riov->i; 307 - ++rxcnt; 308 - } while (rxcnt < quota); 309 - 310 - ++cfv->stats.rx_napi_resched; 311 - goto out; 312 - 313 - exit: 314 - switch (err) { 315 - case 0: 316 - ++cfv->stats.rx_napi_complete; 317 - 318 - /* Really out of packets? (stolen from virtio_net)*/ 319 - napi_complete(napi); 320 - if (unlikely(!vringh_notify_enable_kern(cfv->vr_rx)) && 321 - napi_schedule_prep(napi)) { 322 - vringh_notify_disable_kern(cfv->vr_rx); 323 - __napi_schedule(napi); 324 - } 325 - break; 326 - 327 - case -ENOMEM: 328 - ++cfv->stats.rx_nomem; 329 - dev_kfree_skb(skb); 330 - /* Stop NAPI poll on OOM, we hope to be polled later */ 331 - napi_complete(napi); 332 - vringh_notify_enable_kern(cfv->vr_rx); 333 - break; 334 - 335 - default: 336 - /* We're doomed, any modem fault is fatal */ 337 - netdev_warn(cfv->ndev, "Bad ring, disable device\n"); 338 - cfv->ndev->stats.rx_dropped = riov->used - riov->i; 339 - napi_complete(napi); 340 - vringh_notify_disable_kern(cfv->vr_rx); 341 - netif_carrier_off(cfv->ndev); 342 - break; 343 - } 344 - out: 345 - if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0) 346 - vringh_notify(cfv->vr_rx); 347 - return rxcnt; 348 - } 349 - 350 - static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx) 351 - { 352 - struct cfv_info *cfv = vdev->priv; 353 - 354 - ++cfv->stats.rx_kicks; 355 - vringh_notify_disable_kern(cfv->vr_rx); 356 - napi_schedule(&cfv->napi); 357 - } 358 - 359 - static void cfv_destroy_genpool(struct cfv_info *cfv) 360 - { 361 - if (cfv->alloc_addr) 362 - dma_free_coherent(cfv->vdev->dev.parent->parent, 363 - cfv->allocsz, cfv->alloc_addr, 364 - cfv->alloc_dma); 365 - 366 - if (!cfv->genpool) 367 - return; 368 - gen_pool_free(cfv->genpool, cfv->reserved_mem, 369 - cfv->reserved_size); 370 - gen_pool_destroy(cfv->genpool); 371 - cfv->genpool = NULL; 372 - } 373 - 374 - static int cfv_create_genpool(struct cfv_info *cfv) 375 - { 376 - int err; 377 - 378 - /* dma_alloc can only allocate whole pages, and we need a more 379 - * fine graned allocation so we use genpool. We ask for space needed 380 - * by IP and a full ring. If the dma allcoation fails we retry with a 381 - * smaller allocation size. 382 - */ 383 - err = -ENOMEM; 384 - cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) * 385 - (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10; 386 - if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu) 387 - return -EINVAL; 388 - 389 - for (;;) { 390 - if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) { 391 - netdev_info(cfv->ndev, "Not enough device memory\n"); 392 - return -ENOMEM; 393 - } 394 - 395 - cfv->alloc_addr = dma_alloc_coherent( 396 - cfv->vdev->dev.parent->parent, 397 - cfv->allocsz, &cfv->alloc_dma, 398 - GFP_ATOMIC); 399 - if (cfv->alloc_addr) 400 - break; 401 - 402 - cfv->allocsz = (cfv->allocsz * 3) >> 2; 403 - } 404 - 405 - netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n", 406 - cfv->allocsz); 407 - 408 - /* Allocate on 128 bytes boundaries (1 << 7)*/ 409 - cfv->genpool = gen_pool_create(7, -1); 410 - if (!cfv->genpool) 411 - goto err; 412 - 413 - err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr, 414 - (phys_addr_t)virt_to_phys(cfv->alloc_addr), 415 - cfv->allocsz, -1); 416 - if (err) 417 - goto err; 418 - 419 - /* Reserve some memory for low memory situations. If we hit the roof 420 - * in the memory pool, we stop TX flow and release the reserve. 421 - */ 422 - cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu; 423 - cfv->reserved_mem = gen_pool_alloc(cfv->genpool, 424 - cfv->reserved_size); 425 - if (!cfv->reserved_mem) { 426 - err = -ENOMEM; 427 - goto err; 428 - } 429 - 430 - cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx); 431 - return 0; 432 - err: 433 - cfv_destroy_genpool(cfv); 434 - return err; 435 - } 436 - 437 - /* Enable the CAIF interface and allocate the memory-pool */ 438 - static int cfv_netdev_open(struct net_device *netdev) 439 - { 440 - struct cfv_info *cfv = netdev_priv(netdev); 441 - 442 - if (cfv_create_genpool(cfv)) 443 - return -ENOMEM; 444 - 445 - netif_carrier_on(netdev); 446 - napi_enable(&cfv->napi); 447 - 448 - /* Schedule NAPI to read any pending packets */ 449 - napi_schedule(&cfv->napi); 450 - return 0; 451 - } 452 - 453 - /* Disable the CAIF interface and free the memory-pool */ 454 - static int cfv_netdev_close(struct net_device *netdev) 455 - { 456 - struct cfv_info *cfv = netdev_priv(netdev); 457 - unsigned long flags; 458 - struct buf_info *buf_info; 459 - 460 - /* Disable interrupts, queues and NAPI polling */ 461 - netif_carrier_off(netdev); 462 - virtqueue_disable_cb(cfv->vq_tx); 463 - vringh_notify_disable_kern(cfv->vr_rx); 464 - napi_disable(&cfv->napi); 465 - 466 - /* Release any TX buffers on both used and available rings */ 467 - cfv_release_used_buf(cfv->vq_tx); 468 - spin_lock_irqsave(&cfv->tx_lock, flags); 469 - while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx))) 470 - free_buf_info(cfv, buf_info); 471 - spin_unlock_irqrestore(&cfv->tx_lock, flags); 472 - 473 - /* Release all dma allocated memory and destroy the pool */ 474 - cfv_destroy_genpool(cfv); 475 - return 0; 476 - } 477 - 478 - /* Allocate a buffer in dma-memory and copy skb to it */ 479 - static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv, 480 - struct sk_buff *skb, 481 - struct scatterlist *sg) 482 - { 483 - struct caif_payload_info *info = (void *)&skb->cb; 484 - struct buf_info *buf_info = NULL; 485 - u8 pad_len, hdr_ofs; 486 - 487 - if (!cfv->genpool) 488 - goto err; 489 - 490 - if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) { 491 - netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n", 492 - cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu); 493 - goto err; 494 - } 495 - 496 - buf_info = kmalloc_obj(struct buf_info, GFP_ATOMIC); 497 - if (unlikely(!buf_info)) 498 - goto err; 499 - 500 - /* Make the IP header aligned in the buffer */ 501 - hdr_ofs = cfv->tx_hr + info->hdr_len; 502 - pad_len = hdr_ofs & (IP_HDR_ALIGN - 1); 503 - buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len; 504 - 505 - /* allocate dma memory buffer */ 506 - buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size); 507 - if (unlikely(!buf_info->vaddr)) 508 - goto err; 509 - 510 - /* copy skbuf contents to send buffer */ 511 - skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len); 512 - sg_init_one(sg, buf_info->vaddr + pad_len, 513 - skb->len + cfv->tx_hr + cfv->rx_hr); 514 - 515 - return buf_info; 516 - err: 517 - kfree(buf_info); 518 - return NULL; 519 - } 520 - 521 - /* Put the CAIF packet on the virtio ring and kick the receiver */ 522 - static netdev_tx_t cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev) 523 - { 524 - struct cfv_info *cfv = netdev_priv(netdev); 525 - struct buf_info *buf_info; 526 - struct scatterlist sg; 527 - unsigned long flags; 528 - bool flow_off = false; 529 - int ret; 530 - 531 - /* garbage collect released buffers */ 532 - cfv_release_used_buf(cfv->vq_tx); 533 - spin_lock_irqsave(&cfv->tx_lock, flags); 534 - 535 - /* Flow-off check takes into account number of cpus to make sure 536 - * virtqueue will not be overfilled in any possible smp conditions. 537 - * 538 - * Flow-on is triggered when sufficient buffers are freed 539 - */ 540 - if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) { 541 - flow_off = true; 542 - cfv->stats.tx_full_ring++; 543 - } 544 - 545 - /* If we run out of memory, we release the memory reserve and retry 546 - * allocation. 547 - */ 548 - buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg); 549 - if (unlikely(!buf_info)) { 550 - cfv->stats.tx_no_mem++; 551 - flow_off = true; 552 - 553 - if (cfv->reserved_mem && cfv->genpool) { 554 - gen_pool_free(cfv->genpool, cfv->reserved_mem, 555 - cfv->reserved_size); 556 - cfv->reserved_mem = 0; 557 - buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg); 558 - } 559 - } 560 - 561 - if (unlikely(flow_off)) { 562 - /* Turn flow on when a 1/4 of the descriptors are released */ 563 - cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4; 564 - /* Enable notifications of recycled TX buffers */ 565 - virtqueue_enable_cb(cfv->vq_tx); 566 - netif_tx_stop_all_queues(netdev); 567 - } 568 - 569 - if (unlikely(!buf_info)) { 570 - /* If the memory reserve does it's job, this shouldn't happen */ 571 - netdev_warn(cfv->ndev, "Out of gen_pool memory\n"); 572 - goto err; 573 - } 574 - 575 - ret = virtqueue_add_outbuf(cfv->vq_tx, &sg, 1, buf_info, GFP_ATOMIC); 576 - if (unlikely((ret < 0))) { 577 - /* If flow control works, this shouldn't happen */ 578 - netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n", 579 - ret); 580 - goto err; 581 - } 582 - 583 - /* update netdev statistics */ 584 - cfv->ndev->stats.tx_packets++; 585 - cfv->ndev->stats.tx_bytes += skb->len; 586 - spin_unlock_irqrestore(&cfv->tx_lock, flags); 587 - 588 - /* tell the remote processor it has a pending message to read */ 589 - virtqueue_kick(cfv->vq_tx); 590 - 591 - dev_kfree_skb(skb); 592 - return NETDEV_TX_OK; 593 - err: 594 - spin_unlock_irqrestore(&cfv->tx_lock, flags); 595 - cfv->ndev->stats.tx_dropped++; 596 - free_buf_info(cfv, buf_info); 597 - dev_kfree_skb(skb); 598 - return NETDEV_TX_OK; 599 - } 600 - 601 - static void cfv_tx_release_tasklet(struct tasklet_struct *t) 602 - { 603 - struct cfv_info *cfv = from_tasklet(cfv, t, tx_release_tasklet); 604 - cfv_release_used_buf(cfv->vq_tx); 605 - } 606 - 607 - static const struct net_device_ops cfv_netdev_ops = { 608 - .ndo_open = cfv_netdev_open, 609 - .ndo_stop = cfv_netdev_close, 610 - .ndo_start_xmit = cfv_netdev_tx, 611 - }; 612 - 613 - static void cfv_netdev_setup(struct net_device *netdev) 614 - { 615 - netdev->netdev_ops = &cfv_netdev_ops; 616 - netdev->type = ARPHRD_CAIF; 617 - netdev->tx_queue_len = 100; 618 - netdev->flags = IFF_POINTOPOINT | IFF_NOARP; 619 - netdev->mtu = CFV_DEF_MTU_SIZE; 620 - netdev->needs_free_netdev = true; 621 - } 622 - 623 - /* Create debugfs counters for the device */ 624 - static inline void debugfs_init(struct cfv_info *cfv) 625 - { 626 - cfv->debugfs = debugfs_create_dir(netdev_name(cfv->ndev), NULL); 627 - 628 - debugfs_create_u32("rx-napi-complete", 0400, cfv->debugfs, 629 - &cfv->stats.rx_napi_complete); 630 - debugfs_create_u32("rx-napi-resched", 0400, cfv->debugfs, 631 - &cfv->stats.rx_napi_resched); 632 - debugfs_create_u32("rx-nomem", 0400, cfv->debugfs, 633 - &cfv->stats.rx_nomem); 634 - debugfs_create_u32("rx-kicks", 0400, cfv->debugfs, 635 - &cfv->stats.rx_kicks); 636 - debugfs_create_u32("tx-full-ring", 0400, cfv->debugfs, 637 - &cfv->stats.tx_full_ring); 638 - debugfs_create_u32("tx-no-mem", 0400, cfv->debugfs, 639 - &cfv->stats.tx_no_mem); 640 - debugfs_create_u32("tx-kicks", 0400, cfv->debugfs, 641 - &cfv->stats.tx_kicks); 642 - debugfs_create_u32("tx-flow-on", 0400, cfv->debugfs, 643 - &cfv->stats.tx_flow_on); 644 - } 645 - 646 - /* Setup CAIF for the a virtio device */ 647 - static int cfv_probe(struct virtio_device *vdev) 648 - { 649 - vrh_callback_t *vrh_cbs = cfv_recv; 650 - const char *cfv_netdev_name = "cfvrt"; 651 - struct net_device *netdev; 652 - struct cfv_info *cfv; 653 - int err; 654 - 655 - netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name, 656 - NET_NAME_UNKNOWN, cfv_netdev_setup); 657 - if (!netdev) 658 - return -ENOMEM; 659 - 660 - cfv = netdev_priv(netdev); 661 - cfv->vdev = vdev; 662 - cfv->ndev = netdev; 663 - 664 - spin_lock_init(&cfv->tx_lock); 665 - 666 - /* Get the RX virtio ring. This is a "host side vring". */ 667 - err = -ENODEV; 668 - if (!vdev->vringh_config || !vdev->vringh_config->find_vrhs) 669 - goto err; 670 - 671 - err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs); 672 - if (err) 673 - goto err; 674 - 675 - /* Get the TX virtio ring. This is a "guest side vring". */ 676 - cfv->vq_tx = virtio_find_single_vq(vdev, cfv_release_cb, "output"); 677 - if (IS_ERR(cfv->vq_tx)) { 678 - err = PTR_ERR(cfv->vq_tx); 679 - goto err; 680 - } 681 - 682 - /* Get the CAIF configuration from virtio config space, if available */ 683 - if (vdev->config->get) { 684 - virtio_cread(vdev, struct virtio_caif_transf_config, headroom, 685 - &cfv->tx_hr); 686 - virtio_cread(vdev, struct virtio_caif_transf_config, headroom, 687 - &cfv->rx_hr); 688 - virtio_cread(vdev, struct virtio_caif_transf_config, tailroom, 689 - &cfv->tx_tr); 690 - virtio_cread(vdev, struct virtio_caif_transf_config, tailroom, 691 - &cfv->rx_tr); 692 - virtio_cread(vdev, struct virtio_caif_transf_config, mtu, 693 - &cfv->mtu); 694 - virtio_cread(vdev, struct virtio_caif_transf_config, mtu, 695 - &cfv->mru); 696 - } else { 697 - cfv->tx_hr = CFV_DEF_HEADROOM; 698 - cfv->rx_hr = CFV_DEF_HEADROOM; 699 - cfv->tx_tr = CFV_DEF_TAILROOM; 700 - cfv->rx_tr = CFV_DEF_TAILROOM; 701 - cfv->mtu = CFV_DEF_MTU_SIZE; 702 - cfv->mru = CFV_DEF_MTU_SIZE; 703 - } 704 - 705 - netdev->needed_headroom = cfv->tx_hr; 706 - netdev->needed_tailroom = cfv->tx_tr; 707 - 708 - /* Disable buffer release interrupts unless we have stopped TX queues */ 709 - virtqueue_disable_cb(cfv->vq_tx); 710 - 711 - netdev->mtu = cfv->mtu - cfv->tx_tr; 712 - vdev->priv = cfv; 713 - 714 - /* Initialize NAPI poll context data */ 715 - vringh_kiov_init(&cfv->ctx.riov, NULL, 0); 716 - cfv->ctx.head = USHRT_MAX; 717 - netif_napi_add_weight(netdev, &cfv->napi, cfv_rx_poll, 718 - CFV_DEFAULT_QUOTA); 719 - 720 - tasklet_setup(&cfv->tx_release_tasklet, cfv_tx_release_tasklet); 721 - 722 - /* Carrier is off until netdevice is opened */ 723 - netif_carrier_off(netdev); 724 - 725 - /* serialize netdev register + virtio_device_ready() with ndo_open() */ 726 - rtnl_lock(); 727 - 728 - /* register Netdev */ 729 - err = register_netdevice(netdev); 730 - if (err) { 731 - rtnl_unlock(); 732 - dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err); 733 - goto err; 734 - } 735 - 736 - virtio_device_ready(vdev); 737 - 738 - rtnl_unlock(); 739 - 740 - debugfs_init(cfv); 741 - 742 - return 0; 743 - err: 744 - netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err); 745 - 746 - if (cfv->vr_rx) 747 - vdev->vringh_config->del_vrhs(cfv->vdev); 748 - if (cfv->vq_tx) 749 - vdev->config->del_vqs(cfv->vdev); 750 - free_netdev(netdev); 751 - return err; 752 - } 753 - 754 - static void cfv_remove(struct virtio_device *vdev) 755 - { 756 - struct cfv_info *cfv = vdev->priv; 757 - 758 - rtnl_lock(); 759 - dev_close(cfv->ndev); 760 - rtnl_unlock(); 761 - 762 - tasklet_kill(&cfv->tx_release_tasklet); 763 - debugfs_remove_recursive(cfv->debugfs); 764 - 765 - vringh_kiov_cleanup(&cfv->ctx.riov); 766 - virtio_reset_device(vdev); 767 - vdev->vringh_config->del_vrhs(cfv->vdev); 768 - cfv->vr_rx = NULL; 769 - vdev->config->del_vqs(cfv->vdev); 770 - unregister_netdev(cfv->ndev); 771 - } 772 - 773 - static struct virtio_device_id id_table[] = { 774 - { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID }, 775 - { 0 }, 776 - }; 777 - 778 - static unsigned int features[] = { 779 - }; 780 - 781 - static struct virtio_driver caif_virtio_driver = { 782 - .feature_table = features, 783 - .feature_table_size = ARRAY_SIZE(features), 784 - .driver.name = KBUILD_MODNAME, 785 - .id_table = id_table, 786 - .probe = cfv_probe, 787 - .remove = cfv_remove, 788 - }; 789 - 790 - module_virtio_driver(caif_virtio_driver); 791 - MODULE_DEVICE_TABLE(virtio, id_table);
-24
include/linux/virtio_caif.h
··· 1 - /* 2 - * Copyright (C) ST-Ericsson AB 2012 3 - * Author: Sjur Brændeland <sjur.brandeland@stericsson.com> 4 - * 5 - * This header is BSD licensed so 6 - * anyone can use the definitions to implement compatible remote processors 7 - */ 8 - 9 - #ifndef VIRTIO_CAIF_H 10 - #define VIRTIO_CAIF_H 11 - 12 - #include <linux/types.h> 13 - struct virtio_caif_transf_config { 14 - __virtio16 headroom; 15 - __virtio16 tailroom; 16 - __virtio32 mtu; 17 - u8 reserved[4]; 18 - }; 19 - 20 - struct virtio_caif_config { 21 - struct virtio_caif_transf_config uplink, downlink; 22 - u8 reserved[8]; 23 - }; 24 - #endif
-128
include/net/caif/caif_dev.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CAIF_DEV_H_ 8 - #define CAIF_DEV_H_ 9 - 10 - #include <net/caif/caif_layer.h> 11 - #include <net/caif/cfcnfg.h> 12 - #include <net/caif/caif_device.h> 13 - #include <linux/caif/caif_socket.h> 14 - #include <linux/if.h> 15 - #include <linux/net.h> 16 - 17 - /** 18 - * struct caif_param - CAIF parameters. 19 - * @size: Length of data 20 - * @data: Binary Data Blob 21 - */ 22 - struct caif_param { 23 - u16 size; 24 - u8 data[256]; 25 - }; 26 - 27 - /** 28 - * struct caif_connect_request - Request data for CAIF channel setup. 29 - * @protocol: Type of CAIF protocol to use (at, datagram etc) 30 - * @sockaddr: Socket address to connect. 31 - * @priority: Priority of the connection. 32 - * @link_selector: Link selector (high bandwidth or low latency) 33 - * @ifindex: kernel index of the interface. 34 - * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). 35 - * 36 - * This struct is used when connecting a CAIF channel. 37 - * It contains all CAIF channel configuration options. 38 - */ 39 - struct caif_connect_request { 40 - enum caif_protocol_type protocol; 41 - struct sockaddr_caif sockaddr; 42 - enum caif_channel_priority priority; 43 - enum caif_link_selector link_selector; 44 - int ifindex; 45 - struct caif_param param; 46 - }; 47 - 48 - /** 49 - * caif_connect_client - Connect a client to CAIF Core Stack. 50 - * @config: Channel setup parameters, specifying what address 51 - * to connect on the Modem. 52 - * @client_layer: User implementation of client layer. This layer 53 - * MUST have receive and control callback functions 54 - * implemented. 55 - * @ifindex: Link layer interface index used for this connection. 56 - * @headroom: Head room needed by CAIF protocol. 57 - * @tailroom: Tail room needed by CAIF protocol. 58 - * 59 - * This function connects a CAIF channel. The Client must implement 60 - * the struct cflayer. This layer represents the Client layer and holds 61 - * receive functions and control callback functions. Control callback 62 - * function will receive information about connect/disconnect responses, 63 - * flow control etc (see enum caif_control). 64 - * E.g. CAIF Socket will call this function for each socket it connects 65 - * and have one client_layer instance for each socket. 66 - */ 67 - int caif_connect_client(struct net *net, 68 - struct caif_connect_request *conn_req, 69 - struct cflayer *client_layer, int *ifindex, 70 - int *headroom, int *tailroom); 71 - 72 - /** 73 - * caif_disconnect_client - Disconnects a client from the CAIF stack. 74 - * 75 - * @client_layer: Client layer to be disconnected. 76 - */ 77 - int caif_disconnect_client(struct net *net, struct cflayer *client_layer); 78 - 79 - 80 - /** 81 - * caif_client_register_refcnt - register ref-count functions provided by client. 82 - * 83 - * @adapt_layer: Client layer using CAIF Stack. 84 - * @hold: Function provided by client layer increasing ref-count 85 - * @put: Function provided by client layer decreasing ref-count 86 - * 87 - * Client of the CAIF Stack must register functions for reference counting. 88 - * These functions are called by the CAIF Stack for every upstream packet, 89 - * and must therefore be implemented efficiently. 90 - * 91 - * Client should call caif_free_client when reference count degrease to zero. 92 - */ 93 - 94 - void caif_client_register_refcnt(struct cflayer *adapt_layer, 95 - void (*hold)(struct cflayer *lyr), 96 - void (*put)(struct cflayer *lyr)); 97 - /** 98 - * caif_free_client - Free memory used to manage the client in the CAIF Stack. 99 - * 100 - * @client_layer: Client layer to be removed. 101 - * 102 - * This function must be called from client layer in order to free memory. 103 - * Caller must guarantee that no packets are in flight upstream when calling 104 - * this function. 105 - */ 106 - void caif_free_client(struct cflayer *adap_layer); 107 - 108 - /** 109 - * struct caif_enroll_dev - Enroll a net-device as a CAIF Link layer 110 - * @dev: Network device to enroll. 111 - * @caifdev: Configuration information from CAIF Link Layer 112 - * @link_support: Link layer support layer 113 - * @head_room: Head room needed by link support layer 114 - * @layer: Lowest layer in CAIF stack 115 - * @rcv_fun: Receive function for CAIF stack. 116 - * 117 - * This function enroll a CAIF link layer into CAIF Stack and 118 - * expects the interface to be able to handle CAIF payload. 119 - * The link_support layer is used to add any Link Layer specific 120 - * framing. 121 - */ 122 - int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, 123 - struct cflayer *link_support, int head_room, 124 - struct cflayer **layer, int (**rcv_func)( 125 - struct sk_buff *, struct net_device *, 126 - struct packet_type *, struct net_device *)); 127 - 128 - #endif /* CAIF_DEV_H_ */
-55
include/net/caif/caif_device.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CAIF_DEVICE_H_ 8 - #define CAIF_DEVICE_H_ 9 - #include <linux/kernel.h> 10 - #include <linux/net.h> 11 - #include <linux/netdevice.h> 12 - #include <linux/caif/caif_socket.h> 13 - #include <net/caif/caif_device.h> 14 - 15 - /** 16 - * struct caif_dev_common - data shared between CAIF drivers and stack. 17 - * @flowctrl: Flow Control callback function. This function is 18 - * supplied by CAIF Core Stack and is used by CAIF 19 - * Link Layer to send flow-stop to CAIF Core. 20 - * The flow information will be distributed to all 21 - * clients of CAIF. 22 - * 23 - * @link_select: Profile of device, either high-bandwidth or 24 - * low-latency. This member is set by CAIF Link 25 - * Layer Device in order to indicate if this device 26 - * is a high bandwidth or low latency device. 27 - * 28 - * @use_frag: CAIF Frames may be fragmented. 29 - * Is set by CAIF Link Layer in order to indicate if the 30 - * interface receives fragmented frames that must be 31 - * assembled by CAIF Core Layer. 32 - * 33 - * @use_fcs: Indicate if Frame CheckSum (fcs) is used. 34 - * Is set if the physical interface is 35 - * using Frame Checksum on the CAIF Frames. 36 - * 37 - * @use_stx: Indicate STart of frame eXtension (stx) in use. 38 - * Is set if the CAIF Link Layer expects 39 - * CAIF Frames to start with the STX byte. 40 - * 41 - * This structure is shared between the CAIF drivers and the CAIF stack. 42 - * It is used by the device to register its behavior. 43 - * CAIF Core layer must set the member flowctrl in order to supply 44 - * CAIF Link Layer with the flow control function. 45 - * 46 - */ 47 - struct caif_dev_common { 48 - void (*flowctrl)(struct net_device *net, int on); 49 - enum caif_link_selector link_select; 50 - int use_frag; 51 - int use_fcs; 52 - int use_stx; 53 - }; 54 - 55 - #endif /* CAIF_DEVICE_H_ */
-277
include/net/caif/caif_layer.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CAIF_LAYER_H_ 8 - #define CAIF_LAYER_H_ 9 - 10 - #include <linux/list.h> 11 - 12 - struct cflayer; 13 - struct cfpkt; 14 - struct caif_payload_info; 15 - 16 - #define CAIF_LAYER_NAME_SZ 16 17 - 18 - /** 19 - * caif_assert() - Assert function for CAIF. 20 - * @assert: expression to evaluate. 21 - * 22 - * This function will print a error message and a do WARN_ON if the 23 - * assertion fails. Normally this will do a stack up at the current location. 24 - */ 25 - #define caif_assert(assert) \ 26 - do { \ 27 - if (!(assert)) { \ 28 - pr_err("caif:Assert detected:'%s'\n", #assert); \ 29 - WARN_ON(!(assert)); \ 30 - } \ 31 - } while (0) 32 - 33 - /** 34 - * enum caif_ctrlcmd - CAIF Stack Control Signaling sent in layer.ctrlcmd(). 35 - * 36 - * @CAIF_CTRLCMD_FLOW_OFF_IND: Flow Control is OFF, transmit function 37 - * should stop sending data 38 - * 39 - * @CAIF_CTRLCMD_FLOW_ON_IND: Flow Control is ON, transmit function 40 - * can start sending data 41 - * 42 - * @CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: Remote end modem has decided to close 43 - * down channel 44 - * 45 - * @CAIF_CTRLCMD_INIT_RSP: Called initially when the layer below 46 - * has finished initialization 47 - * 48 - * @CAIF_CTRLCMD_DEINIT_RSP: Called when de-initialization is 49 - * complete 50 - * 51 - * @CAIF_CTRLCMD_INIT_FAIL_RSP: Called if initialization fails 52 - * 53 - * @_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: CAIF Link layer temporarily cannot 54 - * send more packets. 55 - * @_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND: Called if CAIF Link layer is able 56 - * to send packets again. 57 - * @_CAIF_CTRLCMD_PHYIF_DOWN_IND: Called if CAIF Link layer is going 58 - * down. 59 - * 60 - * These commands are sent upwards in the CAIF stack to the CAIF Client. 61 - * They are used for signaling originating from the modem or CAIF Link Layer. 62 - * These are either responses (*_RSP) or events (*_IND). 63 - */ 64 - enum caif_ctrlcmd { 65 - CAIF_CTRLCMD_FLOW_OFF_IND, 66 - CAIF_CTRLCMD_FLOW_ON_IND, 67 - CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 68 - CAIF_CTRLCMD_INIT_RSP, 69 - CAIF_CTRLCMD_DEINIT_RSP, 70 - CAIF_CTRLCMD_INIT_FAIL_RSP, 71 - _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND, 72 - _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND, 73 - _CAIF_CTRLCMD_PHYIF_DOWN_IND, 74 - }; 75 - 76 - /** 77 - * enum caif_modemcmd - Modem Control Signaling, sent from CAIF Client 78 - * to the CAIF Link Layer or modem. 79 - * 80 - * @CAIF_MODEMCMD_FLOW_ON_REQ: Flow Control is ON, transmit function 81 - * can start sending data. 82 - * 83 - * @CAIF_MODEMCMD_FLOW_OFF_REQ: Flow Control is OFF, transmit function 84 - * should stop sending data. 85 - * 86 - * @_CAIF_MODEMCMD_PHYIF_USEFULL: Notify physical layer that it is in use 87 - * 88 - * @_CAIF_MODEMCMD_PHYIF_USELESS: Notify physical layer that it is 89 - * no longer in use. 90 - * 91 - * These are requests sent 'downwards' in the stack. 92 - * Flow ON, OFF can be indicated to the modem. 93 - */ 94 - enum caif_modemcmd { 95 - CAIF_MODEMCMD_FLOW_ON_REQ = 0, 96 - CAIF_MODEMCMD_FLOW_OFF_REQ = 1, 97 - _CAIF_MODEMCMD_PHYIF_USEFULL = 3, 98 - _CAIF_MODEMCMD_PHYIF_USELESS = 4 99 - }; 100 - 101 - /** 102 - * enum caif_direction - CAIF Packet Direction. 103 - * Indicate if a packet is to be sent out or to be received in. 104 - * @CAIF_DIR_IN: Incoming packet received. 105 - * @CAIF_DIR_OUT: Outgoing packet to be transmitted. 106 - */ 107 - enum caif_direction { 108 - CAIF_DIR_IN = 0, 109 - CAIF_DIR_OUT = 1 110 - }; 111 - 112 - /** 113 - * struct cflayer - CAIF Stack layer. 114 - * Defines the framework for the CAIF Core Stack. 115 - * @up: Pointer up to the layer above. 116 - * @dn: Pointer down to the layer below. 117 - * @node: List node used when layer participate in a list. 118 - * @receive: Packet receive function. 119 - * @transmit: Packet transmit function. 120 - * @ctrlcmd: Used for control signalling upwards in the stack. 121 - * @modemcmd: Used for control signaling downwards in the stack. 122 - * @id: The identity of this layer 123 - * @name: Name of the layer. 124 - * 125 - * This structure defines the layered structure in CAIF. 126 - * 127 - * It defines CAIF layering structure, used by all CAIF Layers and the 128 - * layers interfacing CAIF. 129 - * 130 - * In order to integrate with CAIF an adaptation layer on top of the CAIF stack 131 - * and PHY layer below the CAIF stack 132 - * must be implemented. These layer must follow the design principles below. 133 - * 134 - * Principles for layering of protocol layers: 135 - * - All layers must use this structure. If embedding it, then place this 136 - * structure first in the layer specific structure. 137 - * 138 - * - Each layer should not depend on any others layer's private data. 139 - * 140 - * - In order to send data upwards do 141 - * layer->up->receive(layer->up, packet); 142 - * 143 - * - In order to send data downwards do 144 - * layer->dn->transmit(layer->dn, info, packet); 145 - */ 146 - struct cflayer { 147 - struct cflayer *up; 148 - struct cflayer *dn; 149 - struct list_head node; 150 - 151 - /* 152 - * receive() - Receive Function (non-blocking). 153 - * Contract: Each layer must implement a receive function passing the 154 - * CAIF packets upwards in the stack. 155 - * Packet handling rules: 156 - * - The CAIF packet (cfpkt) ownership is passed to the 157 - * called receive function. This means that the 158 - * packet cannot be accessed after passing it to the 159 - * above layer using up->receive(). 160 - * 161 - * - If parsing of the packet fails, the packet must be 162 - * destroyed and negative error code returned 163 - * from the function. 164 - * EXCEPTION: If the framing layer (cffrml) returns 165 - * -EILSEQ, the packet is not freed. 166 - * 167 - * - If parsing succeeds (and above layers return OK) then 168 - * the function must return a value >= 0. 169 - * 170 - * Returns result < 0 indicates an error, 0 or positive value 171 - * indicates success. 172 - * 173 - * @layr: Pointer to the current layer the receive function is 174 - * implemented for (this pointer). 175 - * @cfpkt: Pointer to CaifPacket to be handled. 176 - */ 177 - int (*receive)(struct cflayer *layr, struct cfpkt *cfpkt); 178 - 179 - /* 180 - * transmit() - Transmit Function (non-blocking). 181 - * Contract: Each layer must implement a transmit function passing the 182 - * CAIF packet downwards in the stack. 183 - * Packet handling rules: 184 - * - The CAIF packet (cfpkt) ownership is passed to the 185 - * transmit function. This means that the packet 186 - * cannot be accessed after passing it to the below 187 - * layer using dn->transmit(). 188 - * 189 - * - Upon error the packet ownership is still passed on, 190 - * so the packet shall be freed where error is detected. 191 - * Callers of the transmit function shall not free packets, 192 - * but errors shall be returned. 193 - * 194 - * - Return value less than zero means error, zero or 195 - * greater than zero means OK. 196 - * 197 - * Returns result < 0 indicates an error, 0 or positive value 198 - * indicates success. 199 - * 200 - * @layr: Pointer to the current layer the receive function 201 - * isimplemented for (this pointer). 202 - * @cfpkt: Pointer to CaifPacket to be handled. 203 - */ 204 - int (*transmit) (struct cflayer *layr, struct cfpkt *cfpkt); 205 - 206 - /* 207 - * cttrlcmd() - Control Function upwards in CAIF Stack (non-blocking). 208 - * Used for signaling responses (CAIF_CTRLCMD_*_RSP) 209 - * and asynchronous events from the modem (CAIF_CTRLCMD_*_IND) 210 - * 211 - * @layr: Pointer to the current layer the receive function 212 - * is implemented for (this pointer). 213 - * @ctrl: Control Command. 214 - */ 215 - void (*ctrlcmd) (struct cflayer *layr, enum caif_ctrlcmd ctrl, 216 - int phyid); 217 - 218 - /* 219 - * modemctrl() - Control Function used for controlling the modem. 220 - * Used to signal down-wards in the CAIF stack. 221 - * Returns 0 on success, < 0 upon failure. 222 - * 223 - * @layr: Pointer to the current layer the receive function 224 - * is implemented for (this pointer). 225 - * @ctrl: Control Command. 226 - */ 227 - int (*modemcmd) (struct cflayer *layr, enum caif_modemcmd ctrl); 228 - 229 - unsigned int id; 230 - char name[CAIF_LAYER_NAME_SZ]; 231 - }; 232 - 233 - /** 234 - * layer_set_up() - Set the up pointer for a specified layer. 235 - * @layr: Layer where up pointer shall be set. 236 - * @above: Layer above. 237 - */ 238 - #define layer_set_up(layr, above) ((layr)->up = (struct cflayer *)(above)) 239 - 240 - /** 241 - * layer_set_dn() - Set the down pointer for a specified layer. 242 - * @layr: Layer where down pointer shall be set. 243 - * @below: Layer below. 244 - */ 245 - #define layer_set_dn(layr, below) ((layr)->dn = (struct cflayer *)(below)) 246 - 247 - /** 248 - * struct dev_info - Physical Device info information about physical layer. 249 - * @dev: Pointer to native physical device. 250 - * @id: Physical ID of the physical connection used by the 251 - * logical CAIF connection. Used by service layers to 252 - * identify their physical id to Caif MUX (CFMUXL)so 253 - * that the MUX can add the correct physical ID to the 254 - * packet. 255 - */ 256 - struct dev_info { 257 - void *dev; 258 - unsigned int id; 259 - }; 260 - 261 - /** 262 - * struct caif_payload_info - Payload information embedded in packet (sk_buff). 263 - * 264 - * @dev_info: Information about the receiving device. 265 - * 266 - * @hdr_len: Header length, used to align pay load on 32bit boundary. 267 - * 268 - * @channel_id: Channel ID of the logical CAIF connection. 269 - * Used by mux to insert channel id into the caif packet. 270 - */ 271 - struct caif_payload_info { 272 - struct dev_info *dev_info; 273 - unsigned short hdr_len; 274 - unsigned short channel_id; 275 - }; 276 - 277 - #endif /* CAIF_LAYER_H_ */
-90
include/net/caif/cfcnfg.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFCNFG_H_ 8 - #define CFCNFG_H_ 9 - #include <linux/spinlock.h> 10 - #include <linux/netdevice.h> 11 - #include <net/caif/caif_layer.h> 12 - #include <net/caif/cfctrl.h> 13 - 14 - struct cfcnfg; 15 - 16 - /** 17 - * enum cfcnfg_phy_preference - Physical preference HW Abstraction 18 - * 19 - * @CFPHYPREF_UNSPECIFIED: Default physical interface 20 - * 21 - * @CFPHYPREF_LOW_LAT: Default physical interface for low-latency 22 - * traffic 23 - * @CFPHYPREF_HIGH_BW: Default physical interface for high-bandwidth 24 - * traffic 25 - * @CFPHYPREF_LOOP: TEST only Loopback interface simulating modem 26 - * responses. 27 - * 28 - */ 29 - enum cfcnfg_phy_preference { 30 - CFPHYPREF_UNSPECIFIED, 31 - CFPHYPREF_LOW_LAT, 32 - CFPHYPREF_HIGH_BW, 33 - CFPHYPREF_LOOP 34 - }; 35 - 36 - /** 37 - * cfcnfg_create() - Get the CAIF configuration object given network. 38 - * @net: Network for the CAIF configuration object. 39 - */ 40 - struct cfcnfg *get_cfcnfg(struct net *net); 41 - 42 - /** 43 - * cfcnfg_create() - Create the CAIF configuration object. 44 - */ 45 - struct cfcnfg *cfcnfg_create(void); 46 - 47 - /** 48 - * cfcnfg_remove() - Remove the CFCNFG object 49 - * @cfg: config object 50 - */ 51 - void cfcnfg_remove(struct cfcnfg *cfg); 52 - 53 - /** 54 - * cfcnfg_add_phy_layer() - Adds a physical layer to the CAIF stack. 55 - * @cnfg: Pointer to a CAIF configuration object, created by 56 - * cfcnfg_create(). 57 - * @dev: Pointer to link layer device 58 - * @phy_layer: Specify the physical layer. The transmit function 59 - * MUST be set in the structure. 60 - * @pref: The phy (link layer) preference. 61 - * @link_support: Protocol implementation for link layer specific protocol. 62 - * @fcs: Specify if checksum is used in CAIF Framing Layer. 63 - * @head_room: Head space needed by link specific protocol. 64 - */ 65 - int 66 - cfcnfg_add_phy_layer(struct cfcnfg *cnfg, 67 - struct net_device *dev, struct cflayer *phy_layer, 68 - enum cfcnfg_phy_preference pref, 69 - struct cflayer *link_support, 70 - bool fcs, int head_room); 71 - 72 - /** 73 - * cfcnfg_del_phy_layer - Deletes an phy layer from the CAIF stack. 74 - * 75 - * @cnfg: Pointer to a CAIF configuration object, created by 76 - * cfcnfg_create(). 77 - * @phy_layer: Adaptation layer to be removed. 78 - */ 79 - int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer); 80 - 81 - /** 82 - * cfcnfg_set_phy_state() - Set the state of the physical interface device. 83 - * @cnfg: Configuration object 84 - * @phy_layer: Physical Layer representation 85 - * @up: State of device 86 - */ 87 - int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer, 88 - bool up); 89 - 90 - #endif /* CFCNFG_H_ */
-130
include/net/caif/cfctrl.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFCTRL_H_ 8 - #define CFCTRL_H_ 9 - #include <net/caif/caif_layer.h> 10 - #include <net/caif/cfsrvl.h> 11 - 12 - /* CAIF Control packet commands */ 13 - enum cfctrl_cmd { 14 - CFCTRL_CMD_LINK_SETUP = 0, 15 - CFCTRL_CMD_LINK_DESTROY = 1, 16 - CFCTRL_CMD_LINK_ERR = 2, 17 - CFCTRL_CMD_ENUM = 3, 18 - CFCTRL_CMD_SLEEP = 4, 19 - CFCTRL_CMD_WAKE = 5, 20 - CFCTRL_CMD_LINK_RECONF = 6, 21 - CFCTRL_CMD_START_REASON = 7, 22 - CFCTRL_CMD_RADIO_SET = 8, 23 - CFCTRL_CMD_MODEM_SET = 9, 24 - CFCTRL_CMD_MASK = 0xf 25 - }; 26 - 27 - /* Channel types */ 28 - enum cfctrl_srv { 29 - CFCTRL_SRV_DECM = 0, 30 - CFCTRL_SRV_VEI = 1, 31 - CFCTRL_SRV_VIDEO = 2, 32 - CFCTRL_SRV_DBG = 3, 33 - CFCTRL_SRV_DATAGRAM = 4, 34 - CFCTRL_SRV_RFM = 5, 35 - CFCTRL_SRV_UTIL = 6, 36 - CFCTRL_SRV_MASK = 0xf 37 - }; 38 - 39 - #define CFCTRL_RSP_BIT 0x20 40 - #define CFCTRL_ERR_BIT 0x10 41 - 42 - struct cfctrl_rsp { 43 - void (*linksetup_rsp)(struct cflayer *layer, u8 linkid, 44 - enum cfctrl_srv serv, u8 phyid, 45 - struct cflayer *adapt_layer); 46 - void (*linkdestroy_rsp)(struct cflayer *layer, u8 linkid); 47 - void (*linkerror_ind)(void); 48 - void (*enum_rsp)(void); 49 - void (*sleep_rsp)(void); 50 - void (*wake_rsp)(void); 51 - void (*restart_rsp)(void); 52 - void (*radioset_rsp)(void); 53 - void (*reject_rsp)(struct cflayer *layer, u8 linkid, 54 - struct cflayer *client_layer); 55 - }; 56 - 57 - /* Link Setup Parameters for CAIF-Links. */ 58 - struct cfctrl_link_param { 59 - enum cfctrl_srv linktype;/* (T3,T0) Type of Channel */ 60 - u8 priority; /* (P4,P0) Priority of the channel */ 61 - u8 phyid; /* (U2-U0) Physical interface to connect */ 62 - u8 endpoint; /* (E1,E0) Endpoint for data channels */ 63 - u8 chtype; /* (H1,H0) Channel-Type, applies to 64 - * VEI, DEBUG */ 65 - union { 66 - struct { 67 - u8 connid; /* (D7,D0) Video LinkId */ 68 - } video; 69 - 70 - struct { 71 - u32 connid; /* (N31,Ngit0) Connection ID used 72 - * for Datagram */ 73 - } datagram; 74 - 75 - struct { 76 - u32 connid; /* Connection ID used for RFM */ 77 - char volume[20]; /* Volume to mount for RFM */ 78 - } rfm; /* Configuration for RFM */ 79 - 80 - struct { 81 - u16 fifosize_kb; /* Psock FIFO size in KB */ 82 - u16 fifosize_bufs; /* Psock # signal buffers */ 83 - char name[16]; /* Name of the PSOCK service */ 84 - u8 params[255]; /* Link setup Parameters> */ 85 - u16 paramlen; /* Length of Link Setup 86 - * Parameters */ 87 - } utility; /* Configuration for Utility Links (Psock) */ 88 - } u; 89 - }; 90 - 91 - /* This structure is used internally in CFCTRL */ 92 - struct cfctrl_request_info { 93 - int sequence_no; 94 - enum cfctrl_cmd cmd; 95 - u8 channel_id; 96 - struct cfctrl_link_param param; 97 - struct cflayer *client_layer; 98 - struct list_head list; 99 - }; 100 - 101 - struct cfctrl { 102 - struct cfsrvl serv; 103 - struct cfctrl_rsp res; 104 - atomic_t req_seq_no; 105 - atomic_t rsp_seq_no; 106 - struct list_head list; 107 - /* Protects from simultaneous access to first_req list */ 108 - spinlock_t info_list_lock; 109 - #ifndef CAIF_NO_LOOP 110 - u8 loop_linkid; 111 - int loop_linkused[256]; 112 - /* Protects simultaneous access to loop_linkid and loop_linkused */ 113 - spinlock_t loop_linkid_lock; 114 - #endif 115 - 116 - }; 117 - 118 - void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid); 119 - int cfctrl_linkup_request(struct cflayer *cfctrl, 120 - struct cfctrl_link_param *param, 121 - struct cflayer *user_layer); 122 - int cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid, 123 - struct cflayer *client); 124 - 125 - struct cflayer *cfctrl_create(void); 126 - struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer); 127 - int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer); 128 - void cfctrl_remove(struct cflayer *layr); 129 - 130 - #endif /* CFCTRL_H_ */
-21
include/net/caif/cffrml.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFFRML_H_ 8 - #define CFFRML_H_ 9 - #include <net/caif/caif_layer.h> 10 - #include <linux/netdevice.h> 11 - 12 - struct cffrml; 13 - struct cflayer *cffrml_create(u16 phyid, bool use_fcs); 14 - void cffrml_free(struct cflayer *layr); 15 - void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up); 16 - void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn); 17 - void cffrml_put(struct cflayer *layr); 18 - void cffrml_hold(struct cflayer *layr); 19 - int cffrml_refcnt_read(struct cflayer *layr); 20 - 21 - #endif /* CFFRML_H_ */
-20
include/net/caif/cfmuxl.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFMUXL_H_ 8 - #define CFMUXL_H_ 9 - #include <net/caif/caif_layer.h> 10 - 11 - struct cfsrvl; 12 - struct cffrml; 13 - 14 - struct cflayer *cfmuxl_create(void); 15 - int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid); 16 - struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid); 17 - int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid); 18 - struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid); 19 - 20 - #endif /* CFMUXL_H_ */
-232
include/net/caif/cfpkt.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFPKT_H_ 8 - #define CFPKT_H_ 9 - #include <net/caif/caif_layer.h> 10 - #include <linux/types.h> 11 - struct cfpkt; 12 - 13 - /* Create a CAIF packet. 14 - * len: Length of packet to be created 15 - * @return New packet. 16 - */ 17 - struct cfpkt *cfpkt_create(u16 len); 18 - 19 - /* 20 - * Destroy a CAIF Packet. 21 - * pkt Packet to be destroyed. 22 - */ 23 - void cfpkt_destroy(struct cfpkt *pkt); 24 - 25 - /* 26 - * Extract header from packet. 27 - * 28 - * pkt Packet to extract header data from. 29 - * data Pointer to copy the header data into. 30 - * len Length of head data to copy. 31 - * @return zero on success and error code upon failure 32 - */ 33 - int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len); 34 - 35 - static inline u8 cfpkt_extr_head_u8(struct cfpkt *pkt) 36 - { 37 - u8 tmp; 38 - 39 - cfpkt_extr_head(pkt, &tmp, 1); 40 - 41 - return tmp; 42 - } 43 - 44 - static inline u16 cfpkt_extr_head_u16(struct cfpkt *pkt) 45 - { 46 - __le16 tmp; 47 - 48 - cfpkt_extr_head(pkt, &tmp, 2); 49 - 50 - return le16_to_cpu(tmp); 51 - } 52 - 53 - static inline u32 cfpkt_extr_head_u32(struct cfpkt *pkt) 54 - { 55 - __le32 tmp; 56 - 57 - cfpkt_extr_head(pkt, &tmp, 4); 58 - 59 - return le32_to_cpu(tmp); 60 - } 61 - 62 - /* 63 - * Peek header from packet. 64 - * Reads data from packet without changing packet. 65 - * 66 - * pkt Packet to extract header data from. 67 - * data Pointer to copy the header data into. 68 - * len Length of head data to copy. 69 - * @return zero on success and error code upon failure 70 - */ 71 - int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len); 72 - 73 - /* 74 - * Extract header from trailer (end of packet). 75 - * 76 - * pkt Packet to extract header data from. 77 - * data Pointer to copy the trailer data into. 78 - * len Length of header data to copy. 79 - * @return zero on success and error code upon failure 80 - */ 81 - int cfpkt_extr_trail(struct cfpkt *pkt, void *data, u16 len); 82 - 83 - /* 84 - * Add header to packet. 85 - * 86 - * 87 - * pkt Packet to add header data to. 88 - * data Pointer to data to copy into the header. 89 - * len Length of header data to copy. 90 - * @return zero on success and error code upon failure 91 - */ 92 - int cfpkt_add_head(struct cfpkt *pkt, const void *data, u16 len); 93 - 94 - /* 95 - * Add trailer to packet. 96 - * 97 - * 98 - * pkt Packet to add trailer data to. 99 - * data Pointer to data to copy into the trailer. 100 - * len Length of trailer data to copy. 101 - * @return zero on success and error code upon failure 102 - */ 103 - int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len); 104 - 105 - /* 106 - * Pad trailer on packet. 107 - * Moves data pointer in packet, no content copied. 108 - * 109 - * pkt Packet in which to pad trailer. 110 - * len Length of padding to add. 111 - * @return zero on success and error code upon failure 112 - */ 113 - int cfpkt_pad_trail(struct cfpkt *pkt, u16 len); 114 - 115 - /* 116 - * Add a single byte to packet body (tail). 117 - * 118 - * pkt Packet in which to add byte. 119 - * data Byte to add. 120 - * @return zero on success and error code upon failure 121 - */ 122 - int cfpkt_addbdy(struct cfpkt *pkt, const u8 data); 123 - 124 - /* 125 - * Add a data to packet body (tail). 126 - * 127 - * pkt Packet in which to add data. 128 - * data Pointer to data to copy into the packet body. 129 - * len Length of data to add. 130 - * @return zero on success and error code upon failure 131 - */ 132 - int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len); 133 - 134 - /* 135 - * Checks whether there are more data to process in packet. 136 - * pkt Packet to check. 137 - * @return true if more data are available in packet false otherwise 138 - */ 139 - bool cfpkt_more(struct cfpkt *pkt); 140 - 141 - /* 142 - * Checks whether the packet is erroneous, 143 - * i.e. if it has been attempted to extract more data than available in packet 144 - * or writing more data than has been allocated in cfpkt_create(). 145 - * pkt Packet to check. 146 - * @return true on error false otherwise 147 - */ 148 - bool cfpkt_erroneous(struct cfpkt *pkt); 149 - 150 - /* 151 - * Get the packet length. 152 - * pkt Packet to get length from. 153 - * @return Number of bytes in packet. 154 - */ 155 - u16 cfpkt_getlen(struct cfpkt *pkt); 156 - 157 - /* 158 - * Set the packet length, by adjusting the trailer pointer according to length. 159 - * pkt Packet to set length. 160 - * len Packet length. 161 - * @return Number of bytes in packet. 162 - */ 163 - int cfpkt_setlen(struct cfpkt *pkt, u16 len); 164 - 165 - /* 166 - * cfpkt_append - Appends a packet's data to another packet. 167 - * dstpkt: Packet to append data into, WILL BE FREED BY THIS FUNCTION 168 - * addpkt: Packet to be appended and automatically released, 169 - * WILL BE FREED BY THIS FUNCTION. 170 - * expectlen: Packet's expected total length. This should be considered 171 - * as a hint. 172 - * NB: Input packets will be destroyed after appending and cannot be used 173 - * after calling this function. 174 - * @return The new appended packet. 175 - */ 176 - struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, 177 - u16 expectlen); 178 - 179 - /* 180 - * cfpkt_split - Split a packet into two packets at the specified split point. 181 - * pkt: Packet to be split (will contain the first part of the data on exit) 182 - * pos: Position to split packet in two parts. 183 - * @return The new packet, containing the second part of the data. 184 - */ 185 - struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos); 186 - 187 - /* 188 - * Iteration function, iterates the packet buffers from start to end. 189 - * 190 - * Checksum iteration function used to iterate buffers 191 - * (we may have packets consisting of a chain of buffers) 192 - * pkt: Packet to calculate checksum for 193 - * iter_func: Function pointer to iteration function 194 - * chks: Checksum calculated so far. 195 - * buf: Pointer to the buffer to checksum 196 - * len: Length of buf. 197 - * data: Initial checksum value. 198 - * @return Checksum of buffer. 199 - */ 200 - 201 - int cfpkt_iterate(struct cfpkt *pkt, 202 - u16 (*iter_func)(u16 chks, void *buf, u16 len), 203 - u16 data); 204 - 205 - /* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet. 206 - * dir - Direction indicating whether this packet is to be sent or received. 207 - * nativepkt - The native packet to be transformed to a CAIF packet 208 - * @return The mapped CAIF Packet CFPKT. 209 - */ 210 - struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt); 211 - 212 - /* Map from a CAIF packet to a "native" packet (e.g. Linux Socket Buffer). 213 - * pkt - The CAIF packet to be transformed into a "native" packet. 214 - * @return The native packet transformed from a CAIF packet. 215 - */ 216 - void *cfpkt_tonative(struct cfpkt *pkt); 217 - 218 - /* 219 - * Returns packet information for a packet. 220 - * pkt Packet to get info from; 221 - * @return Packet information 222 - */ 223 - struct caif_payload_info *cfpkt_info(struct cfpkt *pkt); 224 - 225 - /** cfpkt_set_prio - set priority for a CAIF packet. 226 - * 227 - * @pkt: The CAIF packet to be adjusted. 228 - * @prio: one of TC_PRIO_ constants. 229 - */ 230 - void cfpkt_set_prio(struct cfpkt *pkt, int prio); 231 - 232 - #endif /* CFPKT_H_ */
-13
include/net/caif/cfserl.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFSERL_H_ 8 - #define CFSERL_H_ 9 - #include <net/caif/caif_layer.h> 10 - 11 - struct cflayer *cfserl_create(int instance, bool use_stx); 12 - void cfserl_release(struct cflayer *layer); 13 - #endif
-61
include/net/caif/cfsrvl.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #ifndef CFSRVL_H_ 8 - #define CFSRVL_H_ 9 - #include <linux/list.h> 10 - #include <linux/stddef.h> 11 - #include <linux/types.h> 12 - #include <linux/kref.h> 13 - #include <linux/rculist.h> 14 - 15 - struct cfsrvl { 16 - struct cflayer layer; 17 - bool open; 18 - bool phy_flow_on; 19 - bool modem_flow_on; 20 - bool supports_flowctrl; 21 - void (*release)(struct cflayer *layer); 22 - struct dev_info dev_info; 23 - void (*hold)(struct cflayer *lyr); 24 - void (*put)(struct cflayer *lyr); 25 - struct rcu_head rcu; 26 - }; 27 - 28 - struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info); 29 - struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info); 30 - struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info); 31 - struct cflayer *cfvidl_create(u8 linkid, struct dev_info *dev_info); 32 - struct cflayer *cfrfml_create(u8 linkid, struct dev_info *dev_info, 33 - int mtu_size); 34 - struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info); 35 - 36 - bool cfsrvl_phyid_match(struct cflayer *layer, int phyid); 37 - 38 - void cfsrvl_init(struct cfsrvl *service, 39 - u8 channel_id, 40 - struct dev_info *dev_info, 41 - bool supports_flowctrl); 42 - bool cfsrvl_ready(struct cfsrvl *service, int *err); 43 - 44 - static inline void cfsrvl_get(struct cflayer *layr) 45 - { 46 - struct cfsrvl *s = container_of(layr, struct cfsrvl, layer); 47 - if (layr == NULL || layr->up == NULL || s->hold == NULL) 48 - return; 49 - 50 - s->hold(layr->up); 51 - } 52 - 53 - static inline void cfsrvl_put(struct cflayer *layr) 54 - { 55 - struct cfsrvl *s = container_of(layr, struct cfsrvl, layer); 56 - if (layr == NULL || layr->up == NULL || s->hold == NULL) 57 - return; 58 - 59 - s->put(layr->up); 60 - } 61 - #endif /* CFSRVL_H_ */
-195
include/uapi/linux/caif/caif_socket.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 - /* linux/caif_socket.h 3 - * CAIF Definitions for CAIF socket and network layer 4 - * Copyright (C) ST-Ericsson AB 2010 5 - * Author: Sjur Brendeland 6 - * License terms: GNU General Public License (GPL) version 2 7 - */ 8 - 9 - #ifndef _LINUX_CAIF_SOCKET_H 10 - #define _LINUX_CAIF_SOCKET_H 11 - 12 - #include <linux/types.h> 13 - #include <linux/socket.h> 14 - 15 - /** 16 - * enum caif_link_selector - Physical Link Selection. 17 - * @CAIF_LINK_HIGH_BANDW: Physical interface for high-bandwidth 18 - * traffic. 19 - * @CAIF_LINK_LOW_LATENCY: Physical interface for low-latency 20 - * traffic. 21 - * 22 - * CAIF Link Layers can register their link properties. 23 - * This enum is used for choosing between CAIF Link Layers when 24 - * setting up CAIF Channels when multiple CAIF Link Layers exists. 25 - */ 26 - enum caif_link_selector { 27 - CAIF_LINK_HIGH_BANDW, 28 - CAIF_LINK_LOW_LATENCY 29 - }; 30 - 31 - /** 32 - * enum caif_channel_priority - CAIF channel priorities. 33 - * 34 - * @CAIF_PRIO_MIN: Min priority for a channel. 35 - * @CAIF_PRIO_LOW: Low-priority channel. 36 - * @CAIF_PRIO_NORMAL: Normal/default priority level. 37 - * @CAIF_PRIO_HIGH: High priority level 38 - * @CAIF_PRIO_MAX: Max priority for channel 39 - * 40 - * Priority can be set on CAIF Channels in order to 41 - * prioritize between traffic on different CAIF Channels. 42 - * These priority levels are recommended, but the priority value 43 - * is not restricted to the values defined in this enum, any value 44 - * between CAIF_PRIO_MIN and CAIF_PRIO_MAX could be used. 45 - */ 46 - enum caif_channel_priority { 47 - CAIF_PRIO_MIN = 0x01, 48 - CAIF_PRIO_LOW = 0x04, 49 - CAIF_PRIO_NORMAL = 0x0f, 50 - CAIF_PRIO_HIGH = 0x14, 51 - CAIF_PRIO_MAX = 0x1F 52 - }; 53 - 54 - /** 55 - * enum caif_protocol_type - CAIF Channel type. 56 - * @CAIFPROTO_AT: Classic AT channel. 57 - * @CAIFPROTO_DATAGRAM: Datagram channel. 58 - * @CAIFPROTO_DATAGRAM_LOOP: Datagram loopback channel, used for testing. 59 - * @CAIFPROTO_UTIL: Utility (Psock) channel. 60 - * @CAIFPROTO_RFM: Remote File Manager 61 - * @CAIFPROTO_DEBUG: Debug link 62 - * 63 - * This enum defines the CAIF Channel type to be used. This defines 64 - * the service to connect to on the modem. 65 - */ 66 - enum caif_protocol_type { 67 - CAIFPROTO_AT, 68 - CAIFPROTO_DATAGRAM, 69 - CAIFPROTO_DATAGRAM_LOOP, 70 - CAIFPROTO_UTIL, 71 - CAIFPROTO_RFM, 72 - CAIFPROTO_DEBUG, 73 - _CAIFPROTO_MAX 74 - }; 75 - #define CAIFPROTO_MAX _CAIFPROTO_MAX 76 - 77 - /** 78 - * enum caif_at_type - AT Service Endpoint 79 - * @CAIF_ATTYPE_PLAIN: Connects to a plain vanilla AT channel. 80 - */ 81 - enum caif_at_type { 82 - CAIF_ATTYPE_PLAIN = 2 83 - }; 84 - /** 85 - * enum caif_debug_type - Content selection for debug connection 86 - * @CAIF_DEBUG_TRACE_INTERACTIVE: Connection will contain 87 - * both trace and interactive debug. 88 - * @CAIF_DEBUG_TRACE: Connection contains trace only. 89 - * @CAIF_DEBUG_INTERACTIVE: Connection to interactive debug. 90 - */ 91 - enum caif_debug_type { 92 - CAIF_DEBUG_TRACE_INTERACTIVE = 0, 93 - CAIF_DEBUG_TRACE, 94 - CAIF_DEBUG_INTERACTIVE, 95 - }; 96 - 97 - /** 98 - * enum caif_debug_service - Debug Service Endpoint 99 - * @CAIF_RADIO_DEBUG_SERVICE: Debug service on the Radio sub-system 100 - * @CAIF_APP_DEBUG_SERVICE: Debug for the applications sub-system 101 - */ 102 - enum caif_debug_service { 103 - CAIF_RADIO_DEBUG_SERVICE = 1, 104 - CAIF_APP_DEBUG_SERVICE 105 - }; 106 - 107 - /** 108 - * struct sockaddr_caif - the sockaddr structure for CAIF sockets. 109 - * @family: Address family number, must be AF_CAIF. 110 - * @u: Union of address data 'switched' by family. 111 - * : 112 - * @u.at: Applies when family = CAIFPROTO_AT. 113 - * 114 - * @u.at.type: Type of AT link to set up (enum caif_at_type). 115 - * 116 - * @u.util: Applies when family = CAIFPROTO_UTIL 117 - * 118 - * @u.util.service: Utility service name. 119 - * 120 - * @u.dgm: Applies when family = CAIFPROTO_DATAGRAM 121 - * 122 - * @u.dgm.connection_id: Datagram connection id. 123 - * 124 - * @u.dgm.nsapi: NSAPI of the PDP-Context. 125 - * 126 - * @u.rfm: Applies when family = CAIFPROTO_RFM 127 - * 128 - * @u.rfm.connection_id: Connection ID for RFM. 129 - * 130 - * @u.rfm.volume: Volume to mount. 131 - * 132 - * @u.dbg: Applies when family = CAIFPROTO_DEBUG. 133 - * 134 - * @u.dbg.type: Type of debug connection to set up 135 - * (caif_debug_type). 136 - * 137 - * @u.dbg.service: Service sub-system to connect (caif_debug_service 138 - * Description: 139 - * This structure holds the connect parameters used for setting up a 140 - * CAIF Channel. It defines the service to connect to on the modem. 141 - */ 142 - struct sockaddr_caif { 143 - __kernel_sa_family_t family; 144 - union { 145 - struct { 146 - __u8 type; /* type: enum caif_at_type */ 147 - } at; /* CAIFPROTO_AT */ 148 - struct { 149 - char service[16]; 150 - } util; /* CAIFPROTO_UTIL */ 151 - union { 152 - __u32 connection_id; 153 - __u8 nsapi; 154 - } dgm; /* CAIFPROTO_DATAGRAM(_LOOP)*/ 155 - struct { 156 - __u32 connection_id; 157 - char volume[16]; 158 - } rfm; /* CAIFPROTO_RFM */ 159 - struct { 160 - __u8 type; /* type:enum caif_debug_type */ 161 - __u8 service; /* service:caif_debug_service */ 162 - } dbg; /* CAIFPROTO_DEBUG */ 163 - } u; 164 - }; 165 - 166 - /** 167 - * enum caif_socket_opts - CAIF option values for getsockopt and setsockopt. 168 - * 169 - * @CAIFSO_LINK_SELECT: Selector used if multiple CAIF Link layers are 170 - * available. Either a high bandwidth 171 - * link can be selected (CAIF_LINK_HIGH_BANDW) or 172 - * a low latency link (CAIF_LINK_LOW_LATENCY). 173 - * This option is of type __u32. 174 - * Alternatively SO_BINDTODEVICE can be used. 175 - * 176 - * @CAIFSO_REQ_PARAM: Used to set the request parameters for a 177 - * utility channel. (maximum 256 bytes). This 178 - * option must be set before connecting. 179 - * 180 - * @CAIFSO_RSP_PARAM: Gets the response parameters for a utility 181 - * channel. (maximum 256 bytes). This option 182 - * is valid after a successful connect. 183 - * 184 - * 185 - * This enum defines the CAIF Socket options to be used on a socket 186 - * of type PF_CAIF. 187 - * 188 - */ 189 - enum caif_socket_opts { 190 - CAIFSO_LINK_SELECT = 127, 191 - CAIFSO_REQ_PARAM = 128, 192 - CAIFSO_RSP_PARAM = 129, 193 - }; 194 - 195 - #endif /* _LINUX_CAIF_SOCKET_H */
-35
include/uapi/linux/caif/if_caif.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - * License terms: GNU General Public License (GPL) version 2 6 - */ 7 - 8 - #ifndef IF_CAIF_H_ 9 - #define IF_CAIF_H_ 10 - #include <linux/sockios.h> 11 - #include <linux/types.h> 12 - #include <linux/socket.h> 13 - 14 - /** 15 - * enum ifla_caif - CAIF NetlinkRT parameters. 16 - * @IFLA_CAIF_IPV4_CONNID: Connection ID for IPv4 PDP Context. 17 - * The type of attribute is NLA_U32. 18 - * @IFLA_CAIF_IPV6_CONNID: Connection ID for IPv6 PDP Context. 19 - * The type of attribute is NLA_U32. 20 - * @IFLA_CAIF_LOOPBACK: If different from zero, device is doing loopback 21 - * The type of attribute is NLA_U8. 22 - * 23 - * When using RT Netlink to create, destroy or configure a CAIF IP interface, 24 - * enum ifla_caif is used to specify the configuration attributes. 25 - */ 26 - enum ifla_caif { 27 - __IFLA_CAIF_UNSPEC, 28 - IFLA_CAIF_IPV4_CONNID, 29 - IFLA_CAIF_IPV6_CONNID, 30 - IFLA_CAIF_LOOPBACK, 31 - __IFLA_CAIF_MAX 32 - }; 33 - #define IFLA_CAIF_MAX (__IFLA_CAIF_MAX-1) 34 - 35 - #endif /*IF_CAIF_H_*/
-1
net/Kconfig
··· 439 439 440 440 source "net/rfkill/Kconfig" 441 441 source "net/9p/Kconfig" 442 - source "net/caif/Kconfig" 443 442 source "net/ceph/Kconfig" 444 443 source "net/nfc/Kconfig" 445 444 source "net/psample/Kconfig"
-1
net/Makefile
··· 53 53 obj-$(CONFIG_SMC) += smc/ 54 54 obj-$(CONFIG_RFKILL) += rfkill/ 55 55 obj-$(CONFIG_NET_9P) += 9p/ 56 - obj-$(CONFIG_CAIF) += caif/ 57 56 obj-$(CONFIG_DCB) += dcb/ 58 57 obj-$(CONFIG_6LOWPAN) += 6lowpan/ 59 58 obj-$(CONFIG_IEEE802154) += ieee802154/
-54
net/caif/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # CAIF net configurations 4 - # 5 - 6 - menuconfig CAIF 7 - tristate "CAIF support" 8 - select CRC_CCITT 9 - default n 10 - help 11 - The "Communication CPU to Application CPU Interface" (CAIF) is a packet 12 - based connection-oriented MUX protocol developed by ST-Ericsson for use 13 - with its modems. It is accessed from user space as sockets (PF_CAIF). 14 - 15 - Say Y (or M) here if you build for a phone product (e.g. Android or 16 - MeeGo) that uses CAIF as transport. If unsure say N. 17 - 18 - If you select to build it as module then CAIF_NETDEV also needs to be 19 - built as a module. You will also need to say Y (or M) to any CAIF 20 - physical devices that your platform requires. 21 - 22 - See Documentation/networking/caif for a further explanation on how to 23 - use and configure CAIF. 24 - 25 - config CAIF_DEBUG 26 - bool "Enable Debug" 27 - depends on CAIF 28 - default n 29 - help 30 - Enable the inclusion of debug code in the CAIF stack. 31 - Be aware that doing this will impact performance. 32 - If unsure say N. 33 - 34 - config CAIF_NETDEV 35 - tristate "CAIF GPRS Network device" 36 - depends on CAIF 37 - default CAIF 38 - help 39 - Say Y if you will be using a CAIF based GPRS network device. 40 - This can be either built-in or a loadable module. 41 - If you select to build it as a built-in then the main CAIF device must 42 - also be a built-in. 43 - If unsure say Y. 44 - 45 - config CAIF_USB 46 - tristate "CAIF USB support" 47 - depends on CAIF 48 - default n 49 - help 50 - Say Y if you are using CAIF over USB CDC NCM. 51 - This can be either built-in or a loadable module. 52 - If you select to build it as a built-in then the main CAIF device must 53 - also be a built-in. 54 - If unsure say N.
-16
net/caif/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG 3 - 4 - caif-y := caif_dev.o \ 5 - cfcnfg.o cfmuxl.o cfctrl.o \ 6 - cffrml.o cfveil.o cfdbgl.o\ 7 - cfserl.o cfdgml.o \ 8 - cfrfml.o cfvidl.o cfutill.o \ 9 - cfsrvl.o cfpkt_skbuff.o 10 - 11 - obj-$(CONFIG_CAIF) += caif.o 12 - obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o 13 - obj-$(CONFIG_CAIF) += caif_socket.o 14 - obj-$(CONFIG_CAIF_USB) += caif_usb.o 15 - 16 - export-y := caif.o
-586
net/caif/caif_dev.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * CAIF Interface registration. 4 - * Copyright (C) ST-Ericsson AB 2010 5 - * Author: Sjur Brendeland 6 - * 7 - * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont 8 - * and Sakari Ailus <sakari.ailus@nokia.com> 9 - */ 10 - 11 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 12 - 13 - #include <linux/kernel.h> 14 - #include <linux/if_arp.h> 15 - #include <linux/net.h> 16 - #include <linux/netdevice.h> 17 - #include <linux/mutex.h> 18 - #include <linux/module.h> 19 - #include <linux/spinlock.h> 20 - #include <net/netns/generic.h> 21 - #include <net/net_namespace.h> 22 - #include <net/pkt_sched.h> 23 - #include <net/caif/caif_device.h> 24 - #include <net/caif/caif_layer.h> 25 - #include <net/caif/caif_dev.h> 26 - #include <net/caif/cfpkt.h> 27 - #include <net/caif/cfcnfg.h> 28 - #include <net/caif/cfserl.h> 29 - 30 - MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol support"); 31 - MODULE_LICENSE("GPL"); 32 - 33 - /* Used for local tracking of the CAIF net devices */ 34 - struct caif_device_entry { 35 - struct cflayer layer; 36 - struct list_head list; 37 - struct net_device *netdev; 38 - int __percpu *pcpu_refcnt; 39 - spinlock_t flow_lock; 40 - struct sk_buff *xoff_skb; 41 - void (*xoff_skb_dtor)(struct sk_buff *skb); 42 - bool xoff; 43 - }; 44 - 45 - struct caif_device_entry_list { 46 - struct list_head list; 47 - /* Protects simulanous deletes in list */ 48 - struct mutex lock; 49 - }; 50 - 51 - struct caif_net { 52 - struct cfcnfg *cfg; 53 - struct caif_device_entry_list caifdevs; 54 - }; 55 - 56 - static unsigned int caif_net_id; 57 - static int q_high = 50; /* Percent */ 58 - 59 - struct cfcnfg *get_cfcnfg(struct net *net) 60 - { 61 - struct caif_net *caifn; 62 - caifn = net_generic(net, caif_net_id); 63 - return caifn->cfg; 64 - } 65 - EXPORT_SYMBOL(get_cfcnfg); 66 - 67 - static struct caif_device_entry_list *caif_device_list(struct net *net) 68 - { 69 - struct caif_net *caifn; 70 - caifn = net_generic(net, caif_net_id); 71 - return &caifn->caifdevs; 72 - } 73 - 74 - static void caifd_put(struct caif_device_entry *e) 75 - { 76 - this_cpu_dec(*e->pcpu_refcnt); 77 - } 78 - 79 - static void caifd_hold(struct caif_device_entry *e) 80 - { 81 - this_cpu_inc(*e->pcpu_refcnt); 82 - } 83 - 84 - static int caifd_refcnt_read(struct caif_device_entry *e) 85 - { 86 - int i, refcnt = 0; 87 - for_each_possible_cpu(i) 88 - refcnt += *per_cpu_ptr(e->pcpu_refcnt, i); 89 - return refcnt; 90 - } 91 - 92 - /* Allocate new CAIF device. */ 93 - static struct caif_device_entry *caif_device_alloc(struct net_device *dev) 94 - { 95 - struct caif_device_entry *caifd; 96 - 97 - caifd = kzalloc_obj(*caifd); 98 - if (!caifd) 99 - return NULL; 100 - caifd->pcpu_refcnt = alloc_percpu(int); 101 - if (!caifd->pcpu_refcnt) { 102 - kfree(caifd); 103 - return NULL; 104 - } 105 - caifd->netdev = dev; 106 - dev_hold(dev); 107 - return caifd; 108 - } 109 - 110 - static struct caif_device_entry *caif_get(struct net_device *dev) 111 - { 112 - struct caif_device_entry_list *caifdevs = 113 - caif_device_list(dev_net(dev)); 114 - struct caif_device_entry *caifd; 115 - 116 - list_for_each_entry_rcu(caifd, &caifdevs->list, list, 117 - lockdep_rtnl_is_held()) { 118 - if (caifd->netdev == dev) 119 - return caifd; 120 - } 121 - return NULL; 122 - } 123 - 124 - static void caif_flow_cb(struct sk_buff *skb) 125 - { 126 - struct caif_device_entry *caifd; 127 - void (*dtor)(struct sk_buff *skb) = NULL; 128 - bool send_xoff; 129 - 130 - WARN_ON(skb->dev == NULL); 131 - 132 - rcu_read_lock(); 133 - caifd = caif_get(skb->dev); 134 - 135 - WARN_ON(caifd == NULL); 136 - if (!caifd) { 137 - rcu_read_unlock(); 138 - return; 139 - } 140 - 141 - caifd_hold(caifd); 142 - rcu_read_unlock(); 143 - 144 - spin_lock_bh(&caifd->flow_lock); 145 - send_xoff = caifd->xoff; 146 - caifd->xoff = false; 147 - dtor = caifd->xoff_skb_dtor; 148 - 149 - if (WARN_ON(caifd->xoff_skb != skb)) 150 - skb = NULL; 151 - 152 - caifd->xoff_skb = NULL; 153 - caifd->xoff_skb_dtor = NULL; 154 - 155 - spin_unlock_bh(&caifd->flow_lock); 156 - 157 - if (dtor && skb) 158 - dtor(skb); 159 - 160 - if (send_xoff) 161 - caifd->layer.up-> 162 - ctrlcmd(caifd->layer.up, 163 - _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND, 164 - caifd->layer.id); 165 - caifd_put(caifd); 166 - } 167 - 168 - static int transmit(struct cflayer *layer, struct cfpkt *pkt) 169 - { 170 - int err, high = 0, qlen = 0; 171 - struct caif_device_entry *caifd = 172 - container_of(layer, struct caif_device_entry, layer); 173 - struct sk_buff *skb; 174 - struct netdev_queue *txq; 175 - 176 - rcu_read_lock_bh(); 177 - 178 - skb = cfpkt_tonative(pkt); 179 - skb->dev = caifd->netdev; 180 - skb_reset_network_header(skb); 181 - skb->protocol = htons(ETH_P_CAIF); 182 - 183 - /* Check if we need to handle xoff */ 184 - if (likely(caifd->netdev->priv_flags & IFF_NO_QUEUE)) 185 - goto noxoff; 186 - 187 - if (unlikely(caifd->xoff)) 188 - goto noxoff; 189 - 190 - if (likely(!netif_queue_stopped(caifd->netdev))) { 191 - struct Qdisc *sch; 192 - 193 - /* If we run with a TX queue, check if the queue is too long*/ 194 - txq = netdev_get_tx_queue(skb->dev, 0); 195 - sch = rcu_dereference_bh(txq->qdisc); 196 - if (likely(qdisc_is_empty(sch))) 197 - goto noxoff; 198 - 199 - /* can check for explicit qdisc len value only !NOLOCK, 200 - * always set flow off otherwise 201 - */ 202 - high = (caifd->netdev->tx_queue_len * q_high) / 100; 203 - if (!(sch->flags & TCQ_F_NOLOCK) && likely(sch->q.qlen < high)) 204 - goto noxoff; 205 - } 206 - 207 - /* Hold lock while accessing xoff */ 208 - spin_lock_bh(&caifd->flow_lock); 209 - if (caifd->xoff) { 210 - spin_unlock_bh(&caifd->flow_lock); 211 - goto noxoff; 212 - } 213 - 214 - /* 215 - * Handle flow off, we do this by temporary hi-jacking this 216 - * skb's destructor function, and replace it with our own 217 - * flow-on callback. The callback will set flow-on and call 218 - * the original destructor. 219 - */ 220 - 221 - pr_debug("queue has stopped(%d) or is full (%d > %d)\n", 222 - netif_queue_stopped(caifd->netdev), 223 - qlen, high); 224 - caifd->xoff = true; 225 - caifd->xoff_skb = skb; 226 - caifd->xoff_skb_dtor = skb->destructor; 227 - skb->destructor = caif_flow_cb; 228 - spin_unlock_bh(&caifd->flow_lock); 229 - 230 - caifd->layer.up->ctrlcmd(caifd->layer.up, 231 - _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND, 232 - caifd->layer.id); 233 - noxoff: 234 - rcu_read_unlock_bh(); 235 - 236 - err = dev_queue_xmit(skb); 237 - if (err > 0) 238 - err = -EIO; 239 - 240 - return err; 241 - } 242 - 243 - /* 244 - * Stuff received packets into the CAIF stack. 245 - * On error, returns non-zero and releases the skb. 246 - */ 247 - static int receive(struct sk_buff *skb, struct net_device *dev, 248 - struct packet_type *pkttype, struct net_device *orig_dev) 249 - { 250 - struct cfpkt *pkt; 251 - struct caif_device_entry *caifd; 252 - int err; 253 - 254 - pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); 255 - 256 - rcu_read_lock(); 257 - caifd = caif_get(dev); 258 - 259 - if (!caifd || !caifd->layer.up || !caifd->layer.up->receive || 260 - !netif_oper_up(caifd->netdev)) { 261 - rcu_read_unlock(); 262 - kfree_skb(skb); 263 - return NET_RX_DROP; 264 - } 265 - 266 - /* Hold reference to netdevice while using CAIF stack */ 267 - caifd_hold(caifd); 268 - rcu_read_unlock(); 269 - 270 - err = caifd->layer.up->receive(caifd->layer.up, pkt); 271 - 272 - /* For -EILSEQ the packet is not freed so free it now */ 273 - if (err == -EILSEQ) 274 - cfpkt_destroy(pkt); 275 - 276 - /* Release reference to stack upwards */ 277 - caifd_put(caifd); 278 - 279 - if (err != 0) 280 - err = NET_RX_DROP; 281 - return err; 282 - } 283 - 284 - static struct packet_type caif_packet_type __read_mostly = { 285 - .type = cpu_to_be16(ETH_P_CAIF), 286 - .func = receive, 287 - }; 288 - 289 - static void dev_flowctrl(struct net_device *dev, int on) 290 - { 291 - struct caif_device_entry *caifd; 292 - 293 - rcu_read_lock(); 294 - 295 - caifd = caif_get(dev); 296 - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) { 297 - rcu_read_unlock(); 298 - return; 299 - } 300 - 301 - caifd_hold(caifd); 302 - rcu_read_unlock(); 303 - 304 - caifd->layer.up->ctrlcmd(caifd->layer.up, 305 - on ? 306 - _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND : 307 - _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND, 308 - caifd->layer.id); 309 - caifd_put(caifd); 310 - } 311 - 312 - int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, 313 - struct cflayer *link_support, int head_room, 314 - struct cflayer **layer, 315 - int (**rcv_func)(struct sk_buff *, struct net_device *, 316 - struct packet_type *, 317 - struct net_device *)) 318 - { 319 - struct caif_device_entry *caifd; 320 - enum cfcnfg_phy_preference pref; 321 - struct cfcnfg *cfg = get_cfcnfg(dev_net(dev)); 322 - struct caif_device_entry_list *caifdevs; 323 - int res; 324 - 325 - caifdevs = caif_device_list(dev_net(dev)); 326 - caifd = caif_device_alloc(dev); 327 - if (!caifd) 328 - return -ENOMEM; 329 - *layer = &caifd->layer; 330 - spin_lock_init(&caifd->flow_lock); 331 - 332 - switch (caifdev->link_select) { 333 - case CAIF_LINK_HIGH_BANDW: 334 - pref = CFPHYPREF_HIGH_BW; 335 - break; 336 - case CAIF_LINK_LOW_LATENCY: 337 - pref = CFPHYPREF_LOW_LAT; 338 - break; 339 - default: 340 - pref = CFPHYPREF_HIGH_BW; 341 - break; 342 - } 343 - mutex_lock(&caifdevs->lock); 344 - list_add_rcu(&caifd->list, &caifdevs->list); 345 - 346 - strscpy(caifd->layer.name, dev->name, 347 - sizeof(caifd->layer.name)); 348 - caifd->layer.transmit = transmit; 349 - res = cfcnfg_add_phy_layer(cfg, 350 - dev, 351 - &caifd->layer, 352 - pref, 353 - link_support, 354 - caifdev->use_fcs, 355 - head_room); 356 - mutex_unlock(&caifdevs->lock); 357 - if (rcv_func) 358 - *rcv_func = receive; 359 - return res; 360 - } 361 - EXPORT_SYMBOL(caif_enroll_dev); 362 - 363 - /* notify Caif of device events */ 364 - static int caif_device_notify(struct notifier_block *me, unsigned long what, 365 - void *ptr) 366 - { 367 - struct net_device *dev = netdev_notifier_info_to_dev(ptr); 368 - struct caif_device_entry *caifd = NULL; 369 - struct caif_dev_common *caifdev; 370 - struct cfcnfg *cfg; 371 - struct cflayer *layer, *link_support; 372 - int head_room = 0; 373 - struct caif_device_entry_list *caifdevs; 374 - int res; 375 - 376 - cfg = get_cfcnfg(dev_net(dev)); 377 - caifdevs = caif_device_list(dev_net(dev)); 378 - 379 - caifd = caif_get(dev); 380 - if (caifd == NULL && dev->type != ARPHRD_CAIF) 381 - return 0; 382 - 383 - switch (what) { 384 - case NETDEV_REGISTER: 385 - if (caifd != NULL) 386 - break; 387 - 388 - caifdev = netdev_priv(dev); 389 - 390 - link_support = NULL; 391 - if (caifdev->use_frag) { 392 - head_room = 1; 393 - link_support = cfserl_create(dev->ifindex, 394 - caifdev->use_stx); 395 - if (!link_support) { 396 - pr_warn("Out of memory\n"); 397 - break; 398 - } 399 - } 400 - res = caif_enroll_dev(dev, caifdev, link_support, head_room, 401 - &layer, NULL); 402 - if (res) 403 - cfserl_release(link_support); 404 - caifdev->flowctrl = dev_flowctrl; 405 - break; 406 - 407 - case NETDEV_UP: 408 - rcu_read_lock(); 409 - 410 - caifd = caif_get(dev); 411 - if (caifd == NULL) { 412 - rcu_read_unlock(); 413 - break; 414 - } 415 - 416 - caifd->xoff = false; 417 - cfcnfg_set_phy_state(cfg, &caifd->layer, true); 418 - rcu_read_unlock(); 419 - 420 - break; 421 - 422 - case NETDEV_DOWN: 423 - rcu_read_lock(); 424 - 425 - caifd = caif_get(dev); 426 - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) { 427 - rcu_read_unlock(); 428 - return -EINVAL; 429 - } 430 - 431 - cfcnfg_set_phy_state(cfg, &caifd->layer, false); 432 - caifd_hold(caifd); 433 - rcu_read_unlock(); 434 - 435 - caifd->layer.up->ctrlcmd(caifd->layer.up, 436 - _CAIF_CTRLCMD_PHYIF_DOWN_IND, 437 - caifd->layer.id); 438 - 439 - spin_lock_bh(&caifd->flow_lock); 440 - 441 - /* 442 - * Replace our xoff-destructor with original destructor. 443 - * We trust that skb->destructor *always* is called before 444 - * the skb reference is invalid. The hijacked SKB destructor 445 - * takes the flow_lock so manipulating the skb->destructor here 446 - * should be safe. 447 - */ 448 - if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL) 449 - caifd->xoff_skb->destructor = caifd->xoff_skb_dtor; 450 - 451 - caifd->xoff = false; 452 - caifd->xoff_skb_dtor = NULL; 453 - caifd->xoff_skb = NULL; 454 - 455 - spin_unlock_bh(&caifd->flow_lock); 456 - caifd_put(caifd); 457 - break; 458 - 459 - case NETDEV_UNREGISTER: 460 - mutex_lock(&caifdevs->lock); 461 - 462 - caifd = caif_get(dev); 463 - if (caifd == NULL) { 464 - mutex_unlock(&caifdevs->lock); 465 - break; 466 - } 467 - list_del_rcu(&caifd->list); 468 - 469 - /* 470 - * NETDEV_UNREGISTER is called repeatedly until all reference 471 - * counts for the net-device are released. If references to 472 - * caifd is taken, simply ignore NETDEV_UNREGISTER and wait for 473 - * the next call to NETDEV_UNREGISTER. 474 - * 475 - * If any packets are in flight down the CAIF Stack, 476 - * cfcnfg_del_phy_layer will return nonzero. 477 - * If no packets are in flight, the CAIF Stack associated 478 - * with the net-device un-registering is freed. 479 - */ 480 - 481 - if (caifd_refcnt_read(caifd) != 0 || 482 - cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0) { 483 - 484 - pr_info("Wait for device inuse\n"); 485 - /* Enrole device if CAIF Stack is still in use */ 486 - list_add_rcu(&caifd->list, &caifdevs->list); 487 - mutex_unlock(&caifdevs->lock); 488 - break; 489 - } 490 - 491 - synchronize_rcu(); 492 - dev_put(caifd->netdev); 493 - free_percpu(caifd->pcpu_refcnt); 494 - kfree(caifd); 495 - 496 - mutex_unlock(&caifdevs->lock); 497 - break; 498 - } 499 - return 0; 500 - } 501 - 502 - static struct notifier_block caif_device_notifier = { 503 - .notifier_call = caif_device_notify, 504 - .priority = 0, 505 - }; 506 - 507 - /* Per-namespace Caif devices handling */ 508 - static int caif_init_net(struct net *net) 509 - { 510 - struct caif_net *caifn = net_generic(net, caif_net_id); 511 - INIT_LIST_HEAD(&caifn->caifdevs.list); 512 - mutex_init(&caifn->caifdevs.lock); 513 - 514 - caifn->cfg = cfcnfg_create(); 515 - if (!caifn->cfg) 516 - return -ENOMEM; 517 - 518 - return 0; 519 - } 520 - 521 - static void caif_exit_net(struct net *net) 522 - { 523 - struct caif_device_entry *caifd, *tmp; 524 - struct caif_device_entry_list *caifdevs = 525 - caif_device_list(net); 526 - struct cfcnfg *cfg = get_cfcnfg(net); 527 - 528 - rtnl_lock(); 529 - mutex_lock(&caifdevs->lock); 530 - 531 - list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) { 532 - int i = 0; 533 - list_del_rcu(&caifd->list); 534 - cfcnfg_set_phy_state(cfg, &caifd->layer, false); 535 - 536 - while (i < 10 && 537 - (caifd_refcnt_read(caifd) != 0 || 538 - cfcnfg_del_phy_layer(cfg, &caifd->layer) != 0)) { 539 - 540 - pr_info("Wait for device inuse\n"); 541 - msleep(250); 542 - i++; 543 - } 544 - synchronize_rcu(); 545 - dev_put(caifd->netdev); 546 - free_percpu(caifd->pcpu_refcnt); 547 - kfree(caifd); 548 - } 549 - cfcnfg_remove(cfg); 550 - 551 - mutex_unlock(&caifdevs->lock); 552 - rtnl_unlock(); 553 - } 554 - 555 - static struct pernet_operations caif_net_ops = { 556 - .init = caif_init_net, 557 - .exit = caif_exit_net, 558 - .id = &caif_net_id, 559 - .size = sizeof(struct caif_net), 560 - }; 561 - 562 - /* Initialize Caif devices list */ 563 - static int __init caif_device_init(void) 564 - { 565 - int result; 566 - 567 - result = register_pernet_subsys(&caif_net_ops); 568 - 569 - if (result) 570 - return result; 571 - 572 - register_netdevice_notifier(&caif_device_notifier); 573 - dev_add_pack(&caif_packet_type); 574 - 575 - return result; 576 - } 577 - 578 - static void __exit caif_device_exit(void) 579 - { 580 - unregister_netdevice_notifier(&caif_device_notifier); 581 - dev_remove_pack(&caif_packet_type); 582 - unregister_pernet_subsys(&caif_net_ops); 583 - } 584 - 585 - module_init(caif_device_init); 586 - module_exit(caif_device_exit);
-1114
net/caif/caif_socket.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/filter.h> 10 - #include <linux/fs.h> 11 - #include <linux/init.h> 12 - #include <linux/module.h> 13 - #include <linux/sched/signal.h> 14 - #include <linux/spinlock.h> 15 - #include <linux/mutex.h> 16 - #include <linux/list.h> 17 - #include <linux/wait.h> 18 - #include <linux/poll.h> 19 - #include <linux/tcp.h> 20 - #include <linux/uaccess.h> 21 - #include <linux/debugfs.h> 22 - #include <linux/caif/caif_socket.h> 23 - #include <linux/pkt_sched.h> 24 - #include <net/sock.h> 25 - #include <net/tcp_states.h> 26 - #include <net/caif/caif_layer.h> 27 - #include <net/caif/caif_dev.h> 28 - #include <net/caif/cfpkt.h> 29 - 30 - MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol socket support (AF_CAIF)"); 31 - MODULE_LICENSE("GPL"); 32 - MODULE_ALIAS_NETPROTO(AF_CAIF); 33 - 34 - /* 35 - * CAIF state is re-using the TCP socket states. 36 - * caif_states stored in sk_state reflect the state as reported by 37 - * the CAIF stack, while sk_socket->state is the state of the socket. 38 - */ 39 - enum caif_states { 40 - CAIF_CONNECTED = TCP_ESTABLISHED, 41 - CAIF_CONNECTING = TCP_SYN_SENT, 42 - CAIF_DISCONNECTED = TCP_CLOSE 43 - }; 44 - 45 - #define TX_FLOW_ON_BIT 1 46 - #define RX_FLOW_ON_BIT 2 47 - 48 - struct caifsock { 49 - struct sock sk; /* must be first member */ 50 - struct cflayer layer; 51 - unsigned long flow_state; 52 - struct caif_connect_request conn_req; 53 - struct mutex readlock; 54 - struct dentry *debugfs_socket_dir; 55 - int headroom, tailroom, maxframe; 56 - }; 57 - 58 - static int rx_flow_is_on(struct caifsock *cf_sk) 59 - { 60 - return test_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state); 61 - } 62 - 63 - static int tx_flow_is_on(struct caifsock *cf_sk) 64 - { 65 - return test_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state); 66 - } 67 - 68 - static void set_rx_flow_off(struct caifsock *cf_sk) 69 - { 70 - clear_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state); 71 - } 72 - 73 - static void set_rx_flow_on(struct caifsock *cf_sk) 74 - { 75 - set_bit(RX_FLOW_ON_BIT, &cf_sk->flow_state); 76 - } 77 - 78 - static void set_tx_flow_off(struct caifsock *cf_sk) 79 - { 80 - clear_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state); 81 - } 82 - 83 - static void set_tx_flow_on(struct caifsock *cf_sk) 84 - { 85 - set_bit(TX_FLOW_ON_BIT, &cf_sk->flow_state); 86 - } 87 - 88 - static void caif_read_lock(struct sock *sk) 89 - { 90 - struct caifsock *cf_sk; 91 - cf_sk = container_of(sk, struct caifsock, sk); 92 - mutex_lock(&cf_sk->readlock); 93 - } 94 - 95 - static void caif_read_unlock(struct sock *sk) 96 - { 97 - struct caifsock *cf_sk; 98 - cf_sk = container_of(sk, struct caifsock, sk); 99 - mutex_unlock(&cf_sk->readlock); 100 - } 101 - 102 - static int sk_rcvbuf_lowwater(struct caifsock *cf_sk) 103 - { 104 - /* A quarter of full buffer is used a low water mark */ 105 - return cf_sk->sk.sk_rcvbuf / 4; 106 - } 107 - 108 - static void caif_flow_ctrl(struct sock *sk, int mode) 109 - { 110 - struct caifsock *cf_sk; 111 - cf_sk = container_of(sk, struct caifsock, sk); 112 - if (cf_sk->layer.dn && cf_sk->layer.dn->modemcmd) 113 - cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, mode); 114 - } 115 - 116 - /* 117 - * Copied from sock.c:sock_queue_rcv_skb(), but changed so packets are 118 - * not dropped, but CAIF is sending flow off instead. 119 - */ 120 - static void caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 121 - { 122 - int err; 123 - unsigned long flags; 124 - struct sk_buff_head *list = &sk->sk_receive_queue; 125 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 126 - bool queued = false; 127 - 128 - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= 129 - (unsigned int)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { 130 - net_dbg_ratelimited("sending flow OFF (queue len = %d %d)\n", 131 - atomic_read(&cf_sk->sk.sk_rmem_alloc), 132 - sk_rcvbuf_lowwater(cf_sk)); 133 - set_rx_flow_off(cf_sk); 134 - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); 135 - } 136 - 137 - err = sk_filter(sk, skb); 138 - if (err) 139 - goto out; 140 - 141 - if (!sk_rmem_schedule(sk, skb, skb->truesize) && rx_flow_is_on(cf_sk)) { 142 - set_rx_flow_off(cf_sk); 143 - net_dbg_ratelimited("sending flow OFF due to rmem_schedule\n"); 144 - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); 145 - } 146 - skb->dev = NULL; 147 - skb_set_owner_r(skb, sk); 148 - spin_lock_irqsave(&list->lock, flags); 149 - queued = !sock_flag(sk, SOCK_DEAD); 150 - if (queued) 151 - __skb_queue_tail(list, skb); 152 - spin_unlock_irqrestore(&list->lock, flags); 153 - out: 154 - if (queued) 155 - sk->sk_data_ready(sk); 156 - else 157 - kfree_skb(skb); 158 - } 159 - 160 - /* Packet Receive Callback function called from CAIF Stack */ 161 - static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt) 162 - { 163 - struct caifsock *cf_sk; 164 - struct sk_buff *skb; 165 - 166 - cf_sk = container_of(layr, struct caifsock, layer); 167 - skb = cfpkt_tonative(pkt); 168 - 169 - if (unlikely(cf_sk->sk.sk_state != CAIF_CONNECTED)) { 170 - kfree_skb(skb); 171 - return 0; 172 - } 173 - caif_queue_rcv_skb(&cf_sk->sk, skb); 174 - return 0; 175 - } 176 - 177 - static void cfsk_hold(struct cflayer *layr) 178 - { 179 - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer); 180 - sock_hold(&cf_sk->sk); 181 - } 182 - 183 - static void cfsk_put(struct cflayer *layr) 184 - { 185 - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer); 186 - sock_put(&cf_sk->sk); 187 - } 188 - 189 - /* Packet Control Callback function called from CAIF */ 190 - static void caif_ctrl_cb(struct cflayer *layr, 191 - enum caif_ctrlcmd flow, 192 - int phyid) 193 - { 194 - struct caifsock *cf_sk = container_of(layr, struct caifsock, layer); 195 - switch (flow) { 196 - case CAIF_CTRLCMD_FLOW_ON_IND: 197 - /* OK from modem to start sending again */ 198 - set_tx_flow_on(cf_sk); 199 - cf_sk->sk.sk_state_change(&cf_sk->sk); 200 - break; 201 - 202 - case CAIF_CTRLCMD_FLOW_OFF_IND: 203 - /* Modem asks us to shut up */ 204 - set_tx_flow_off(cf_sk); 205 - cf_sk->sk.sk_state_change(&cf_sk->sk); 206 - break; 207 - 208 - case CAIF_CTRLCMD_INIT_RSP: 209 - /* We're now connected */ 210 - caif_client_register_refcnt(&cf_sk->layer, 211 - cfsk_hold, cfsk_put); 212 - cf_sk->sk.sk_state = CAIF_CONNECTED; 213 - set_tx_flow_on(cf_sk); 214 - cf_sk->sk.sk_shutdown = 0; 215 - cf_sk->sk.sk_state_change(&cf_sk->sk); 216 - break; 217 - 218 - case CAIF_CTRLCMD_DEINIT_RSP: 219 - /* We're now disconnected */ 220 - cf_sk->sk.sk_state = CAIF_DISCONNECTED; 221 - cf_sk->sk.sk_state_change(&cf_sk->sk); 222 - break; 223 - 224 - case CAIF_CTRLCMD_INIT_FAIL_RSP: 225 - /* Connect request failed */ 226 - cf_sk->sk.sk_err = ECONNREFUSED; 227 - cf_sk->sk.sk_state = CAIF_DISCONNECTED; 228 - cf_sk->sk.sk_shutdown = SHUTDOWN_MASK; 229 - /* 230 - * Socket "standards" seems to require POLLOUT to 231 - * be set at connect failure. 232 - */ 233 - set_tx_flow_on(cf_sk); 234 - cf_sk->sk.sk_state_change(&cf_sk->sk); 235 - break; 236 - 237 - case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: 238 - /* Modem has closed this connection, or device is down. */ 239 - cf_sk->sk.sk_shutdown = SHUTDOWN_MASK; 240 - cf_sk->sk.sk_err = ECONNRESET; 241 - set_rx_flow_on(cf_sk); 242 - sk_error_report(&cf_sk->sk); 243 - break; 244 - 245 - default: 246 - pr_debug("Unexpected flow command %d\n", flow); 247 - } 248 - } 249 - 250 - static void caif_check_flow_release(struct sock *sk) 251 - { 252 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 253 - 254 - if (rx_flow_is_on(cf_sk)) 255 - return; 256 - 257 - if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) { 258 - set_rx_flow_on(cf_sk); 259 - caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ); 260 - } 261 - } 262 - 263 - /* 264 - * Copied from unix_dgram_recvmsg, but removed credit checks, 265 - * changed locking, address handling and added MSG_TRUNC. 266 - */ 267 - static int caif_seqpkt_recvmsg(struct socket *sock, struct msghdr *m, 268 - size_t len, int flags) 269 - 270 - { 271 - struct sock *sk = sock->sk; 272 - struct sk_buff *skb; 273 - int ret; 274 - int copylen; 275 - 276 - ret = -EOPNOTSUPP; 277 - if (flags & MSG_OOB) 278 - goto read_error; 279 - 280 - skb = skb_recv_datagram(sk, flags, &ret); 281 - if (!skb) 282 - goto read_error; 283 - copylen = skb->len; 284 - if (len < copylen) { 285 - m->msg_flags |= MSG_TRUNC; 286 - copylen = len; 287 - } 288 - 289 - ret = skb_copy_datagram_msg(skb, 0, m, copylen); 290 - if (ret) 291 - goto out_free; 292 - 293 - ret = (flags & MSG_TRUNC) ? skb->len : copylen; 294 - out_free: 295 - skb_free_datagram(sk, skb); 296 - caif_check_flow_release(sk); 297 - return ret; 298 - 299 - read_error: 300 - return ret; 301 - } 302 - 303 - 304 - /* Copied from unix_stream_wait_data, identical except for lock call. */ 305 - static long caif_stream_data_wait(struct sock *sk, long timeo) 306 - { 307 - DEFINE_WAIT(wait); 308 - lock_sock(sk); 309 - 310 - for (;;) { 311 - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 312 - 313 - if (!skb_queue_empty(&sk->sk_receive_queue) || 314 - sk->sk_err || 315 - sk->sk_state != CAIF_CONNECTED || 316 - sock_flag(sk, SOCK_DEAD) || 317 - (sk->sk_shutdown & RCV_SHUTDOWN) || 318 - signal_pending(current) || 319 - !timeo) 320 - break; 321 - 322 - sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); 323 - release_sock(sk); 324 - timeo = schedule_timeout(timeo); 325 - lock_sock(sk); 326 - 327 - if (sock_flag(sk, SOCK_DEAD)) 328 - break; 329 - 330 - sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); 331 - } 332 - 333 - finish_wait(sk_sleep(sk), &wait); 334 - release_sock(sk); 335 - return timeo; 336 - } 337 - 338 - 339 - /* 340 - * Copied from unix_stream_recvmsg, but removed credit checks, 341 - * changed locking calls, changed address handling. 342 - */ 343 - static int caif_stream_recvmsg(struct socket *sock, struct msghdr *msg, 344 - size_t size, int flags) 345 - { 346 - struct sock *sk = sock->sk; 347 - int copied = 0; 348 - int target; 349 - int err = 0; 350 - long timeo; 351 - 352 - err = -EOPNOTSUPP; 353 - if (flags&MSG_OOB) 354 - goto out; 355 - 356 - /* 357 - * Lock the socket to prevent queue disordering 358 - * while sleeps in memcpy_tomsg 359 - */ 360 - err = -EAGAIN; 361 - if (sk->sk_state == CAIF_CONNECTING) 362 - goto out; 363 - 364 - caif_read_lock(sk); 365 - target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); 366 - timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); 367 - 368 - do { 369 - int chunk; 370 - struct sk_buff *skb; 371 - 372 - lock_sock(sk); 373 - if (sock_flag(sk, SOCK_DEAD)) { 374 - err = -ECONNRESET; 375 - goto unlock; 376 - } 377 - skb = skb_dequeue(&sk->sk_receive_queue); 378 - caif_check_flow_release(sk); 379 - 380 - if (skb == NULL) { 381 - if (copied >= target) 382 - goto unlock; 383 - /* 384 - * POSIX 1003.1g mandates this order. 385 - */ 386 - err = sock_error(sk); 387 - if (err) 388 - goto unlock; 389 - err = -ECONNRESET; 390 - if (sk->sk_shutdown & RCV_SHUTDOWN) 391 - goto unlock; 392 - 393 - err = -EPIPE; 394 - if (sk->sk_state != CAIF_CONNECTED) 395 - goto unlock; 396 - if (sock_flag(sk, SOCK_DEAD)) 397 - goto unlock; 398 - 399 - release_sock(sk); 400 - 401 - err = -EAGAIN; 402 - if (!timeo) 403 - break; 404 - 405 - caif_read_unlock(sk); 406 - 407 - timeo = caif_stream_data_wait(sk, timeo); 408 - 409 - if (signal_pending(current)) { 410 - err = sock_intr_errno(timeo); 411 - goto out; 412 - } 413 - caif_read_lock(sk); 414 - continue; 415 - unlock: 416 - release_sock(sk); 417 - break; 418 - } 419 - release_sock(sk); 420 - chunk = min_t(unsigned int, skb->len, size); 421 - if (memcpy_to_msg(msg, skb->data, chunk)) { 422 - skb_queue_head(&sk->sk_receive_queue, skb); 423 - if (copied == 0) 424 - copied = -EFAULT; 425 - break; 426 - } 427 - copied += chunk; 428 - size -= chunk; 429 - 430 - /* Mark read part of skb as used */ 431 - if (!(flags & MSG_PEEK)) { 432 - skb_pull(skb, chunk); 433 - 434 - /* put the skb back if we didn't use it up. */ 435 - if (skb->len) { 436 - skb_queue_head(&sk->sk_receive_queue, skb); 437 - break; 438 - } 439 - kfree_skb(skb); 440 - 441 - } else { 442 - /* 443 - * It is questionable, see note in unix_dgram_recvmsg. 444 - */ 445 - /* put message back and return */ 446 - skb_queue_head(&sk->sk_receive_queue, skb); 447 - break; 448 - } 449 - } while (size); 450 - caif_read_unlock(sk); 451 - 452 - out: 453 - return copied ? : err; 454 - } 455 - 456 - /* 457 - * Copied from sock.c:sock_wait_for_wmem, but change to wait for 458 - * CAIF flow-on and sock_writable. 459 - */ 460 - static long caif_wait_for_flow_on(struct caifsock *cf_sk, 461 - int wait_writeable, long timeo, int *err) 462 - { 463 - struct sock *sk = &cf_sk->sk; 464 - DEFINE_WAIT(wait); 465 - for (;;) { 466 - *err = 0; 467 - if (tx_flow_is_on(cf_sk) && 468 - (!wait_writeable || sock_writeable(&cf_sk->sk))) 469 - break; 470 - *err = -ETIMEDOUT; 471 - if (!timeo) 472 - break; 473 - *err = -ERESTARTSYS; 474 - if (signal_pending(current)) 475 - break; 476 - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 477 - *err = -ECONNRESET; 478 - if (sk->sk_shutdown & SHUTDOWN_MASK) 479 - break; 480 - *err = -sk->sk_err; 481 - if (sk->sk_err) 482 - break; 483 - *err = -EPIPE; 484 - if (cf_sk->sk.sk_state != CAIF_CONNECTED) 485 - break; 486 - timeo = schedule_timeout(timeo); 487 - } 488 - finish_wait(sk_sleep(sk), &wait); 489 - return timeo; 490 - } 491 - 492 - /* 493 - * Transmit a SKB. The device may temporarily request re-transmission 494 - * by returning EAGAIN. 495 - */ 496 - static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk, 497 - int noblock, long timeo) 498 - { 499 - struct cfpkt *pkt; 500 - 501 - pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb); 502 - memset(skb->cb, 0, sizeof(struct caif_payload_info)); 503 - cfpkt_set_prio(pkt, cf_sk->sk.sk_priority); 504 - 505 - if (cf_sk->layer.dn == NULL) { 506 - kfree_skb(skb); 507 - return -EINVAL; 508 - } 509 - 510 - return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); 511 - } 512 - 513 - /* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */ 514 - static int caif_seqpkt_sendmsg(struct socket *sock, struct msghdr *msg, 515 - size_t len) 516 - { 517 - struct sock *sk = sock->sk; 518 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 519 - int buffer_size; 520 - int ret = 0; 521 - struct sk_buff *skb = NULL; 522 - int noblock; 523 - long timeo; 524 - caif_assert(cf_sk); 525 - ret = sock_error(sk); 526 - if (ret) 527 - goto err; 528 - 529 - ret = -EOPNOTSUPP; 530 - if (msg->msg_flags&MSG_OOB) 531 - goto err; 532 - 533 - ret = -EOPNOTSUPP; 534 - if (msg->msg_namelen) 535 - goto err; 536 - 537 - noblock = msg->msg_flags & MSG_DONTWAIT; 538 - 539 - timeo = sock_sndtimeo(sk, noblock); 540 - timeo = caif_wait_for_flow_on(container_of(sk, struct caifsock, sk), 541 - 1, timeo, &ret); 542 - 543 - if (ret) 544 - goto err; 545 - ret = -EPIPE; 546 - if (cf_sk->sk.sk_state != CAIF_CONNECTED || 547 - sock_flag(sk, SOCK_DEAD) || 548 - (sk->sk_shutdown & RCV_SHUTDOWN)) 549 - goto err; 550 - 551 - /* Error if trying to write more than maximum frame size. */ 552 - ret = -EMSGSIZE; 553 - if (len > cf_sk->maxframe && cf_sk->sk.sk_protocol != CAIFPROTO_RFM) 554 - goto err; 555 - 556 - buffer_size = len + cf_sk->headroom + cf_sk->tailroom; 557 - 558 - ret = -ENOMEM; 559 - skb = sock_alloc_send_skb(sk, buffer_size, noblock, &ret); 560 - 561 - if (!skb || skb_tailroom(skb) < buffer_size) 562 - goto err; 563 - 564 - skb_reserve(skb, cf_sk->headroom); 565 - 566 - ret = memcpy_from_msg(skb_put(skb, len), msg, len); 567 - 568 - if (ret) 569 - goto err; 570 - ret = transmit_skb(skb, cf_sk, noblock, timeo); 571 - if (ret < 0) 572 - /* skb is already freed */ 573 - return ret; 574 - 575 - return len; 576 - err: 577 - kfree_skb(skb); 578 - return ret; 579 - } 580 - 581 - /* 582 - * Copied from unix_stream_sendmsg and adapted to CAIF: 583 - * Changed removed permission handling and added waiting for flow on 584 - * and other minor adaptations. 585 - */ 586 - static int caif_stream_sendmsg(struct socket *sock, struct msghdr *msg, 587 - size_t len) 588 - { 589 - struct sock *sk = sock->sk; 590 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 591 - int err, size; 592 - struct sk_buff *skb; 593 - int sent = 0; 594 - long timeo; 595 - 596 - err = -EOPNOTSUPP; 597 - if (unlikely(msg->msg_flags&MSG_OOB)) 598 - goto out_err; 599 - 600 - if (unlikely(msg->msg_namelen)) 601 - goto out_err; 602 - 603 - timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); 604 - timeo = caif_wait_for_flow_on(cf_sk, 1, timeo, &err); 605 - 606 - if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN)) 607 - goto pipe_err; 608 - 609 - while (sent < len) { 610 - 611 - size = len-sent; 612 - 613 - if (size > cf_sk->maxframe) 614 - size = cf_sk->maxframe; 615 - 616 - /* If size is more than half of sndbuf, chop up message */ 617 - if (size > ((sk->sk_sndbuf >> 1) - 64)) 618 - size = (sk->sk_sndbuf >> 1) - 64; 619 - 620 - if (size > SKB_MAX_ALLOC) 621 - size = SKB_MAX_ALLOC; 622 - 623 - skb = sock_alloc_send_skb(sk, 624 - size + cf_sk->headroom + 625 - cf_sk->tailroom, 626 - msg->msg_flags&MSG_DONTWAIT, 627 - &err); 628 - if (skb == NULL) 629 - goto out_err; 630 - 631 - skb_reserve(skb, cf_sk->headroom); 632 - /* 633 - * If you pass two values to the sock_alloc_send_skb 634 - * it tries to grab the large buffer with GFP_NOFS 635 - * (which can fail easily), and if it fails grab the 636 - * fallback size buffer which is under a page and will 637 - * succeed. [Alan] 638 - */ 639 - size = min_t(int, size, skb_tailroom(skb)); 640 - 641 - err = memcpy_from_msg(skb_put(skb, size), msg, size); 642 - if (err) { 643 - kfree_skb(skb); 644 - goto out_err; 645 - } 646 - err = transmit_skb(skb, cf_sk, 647 - msg->msg_flags&MSG_DONTWAIT, timeo); 648 - if (err < 0) 649 - /* skb is already freed */ 650 - goto pipe_err; 651 - 652 - sent += size; 653 - } 654 - 655 - return sent; 656 - 657 - pipe_err: 658 - if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL)) 659 - send_sig(SIGPIPE, current, 0); 660 - err = -EPIPE; 661 - out_err: 662 - return sent ? : err; 663 - } 664 - 665 - static int setsockopt(struct socket *sock, int lvl, int opt, sockptr_t ov, 666 - unsigned int ol) 667 - { 668 - struct sock *sk = sock->sk; 669 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 670 - int linksel; 671 - 672 - if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) 673 - return -ENOPROTOOPT; 674 - 675 - switch (opt) { 676 - case CAIFSO_LINK_SELECT: 677 - if (ol < sizeof(int)) 678 - return -EINVAL; 679 - if (lvl != SOL_CAIF) 680 - goto bad_sol; 681 - if (copy_from_sockptr(&linksel, ov, sizeof(int))) 682 - return -EINVAL; 683 - lock_sock(&(cf_sk->sk)); 684 - cf_sk->conn_req.link_selector = linksel; 685 - release_sock(&cf_sk->sk); 686 - return 0; 687 - 688 - case CAIFSO_REQ_PARAM: 689 - if (lvl != SOL_CAIF) 690 - goto bad_sol; 691 - if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) 692 - return -ENOPROTOOPT; 693 - lock_sock(&(cf_sk->sk)); 694 - if (ol > sizeof(cf_sk->conn_req.param.data) || 695 - copy_from_sockptr(&cf_sk->conn_req.param.data, ov, ol)) { 696 - release_sock(&cf_sk->sk); 697 - return -EINVAL; 698 - } 699 - cf_sk->conn_req.param.size = ol; 700 - release_sock(&cf_sk->sk); 701 - return 0; 702 - 703 - default: 704 - return -ENOPROTOOPT; 705 - } 706 - 707 - return 0; 708 - bad_sol: 709 - return -ENOPROTOOPT; 710 - 711 - } 712 - 713 - /* 714 - * caif_connect() - Connect a CAIF Socket 715 - * Copied and modified af_irda.c:irda_connect(). 716 - * 717 - * Note : by consulting "errno", the user space caller may learn the cause 718 - * of the failure. Most of them are visible in the function, others may come 719 - * from subroutines called and are listed here : 720 - * o -EAFNOSUPPORT: bad socket family or type. 721 - * o -ESOCKTNOSUPPORT: bad socket type or protocol 722 - * o -EINVAL: bad socket address, or CAIF link type 723 - * o -ECONNREFUSED: remote end refused the connection. 724 - * o -EINPROGRESS: connect request sent but timed out (or non-blocking) 725 - * o -EISCONN: already connected. 726 - * o -ETIMEDOUT: Connection timed out (send timeout) 727 - * o -ENODEV: No link layer to send request 728 - * o -ECONNRESET: Received Shutdown indication or lost link layer 729 - * o -ENOMEM: Out of memory 730 - * 731 - * State Strategy: 732 - * o sk_state: holds the CAIF_* protocol state, it's updated by 733 - * caif_ctrl_cb. 734 - * o sock->state: holds the SS_* socket state and is updated by connect and 735 - * disconnect. 736 - */ 737 - static int caif_connect(struct socket *sock, struct sockaddr_unsized *uaddr, 738 - int addr_len, int flags) 739 - { 740 - struct sock *sk = sock->sk; 741 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 742 - long timeo; 743 - int err; 744 - int ifindex, headroom, tailroom; 745 - unsigned int mtu; 746 - struct net_device *dev; 747 - 748 - lock_sock(sk); 749 - 750 - err = -EINVAL; 751 - if (addr_len < offsetofend(struct sockaddr, sa_family)) 752 - goto out; 753 - 754 - err = -EAFNOSUPPORT; 755 - if (uaddr->sa_family != AF_CAIF) 756 - goto out; 757 - 758 - switch (sock->state) { 759 - case SS_UNCONNECTED: 760 - /* Normal case, a fresh connect */ 761 - caif_assert(sk->sk_state == CAIF_DISCONNECTED); 762 - break; 763 - case SS_CONNECTING: 764 - switch (sk->sk_state) { 765 - case CAIF_CONNECTED: 766 - sock->state = SS_CONNECTED; 767 - err = -EISCONN; 768 - goto out; 769 - case CAIF_DISCONNECTED: 770 - /* Reconnect allowed */ 771 - break; 772 - case CAIF_CONNECTING: 773 - err = -EALREADY; 774 - if (flags & O_NONBLOCK) 775 - goto out; 776 - goto wait_connect; 777 - } 778 - break; 779 - case SS_CONNECTED: 780 - caif_assert(sk->sk_state == CAIF_CONNECTED || 781 - sk->sk_state == CAIF_DISCONNECTED); 782 - if (sk->sk_shutdown & SHUTDOWN_MASK) { 783 - /* Allow re-connect after SHUTDOWN_IND */ 784 - caif_disconnect_client(sock_net(sk), &cf_sk->layer); 785 - caif_free_client(&cf_sk->layer); 786 - break; 787 - } 788 - /* No reconnect on a seqpacket socket */ 789 - err = -EISCONN; 790 - goto out; 791 - case SS_DISCONNECTING: 792 - case SS_FREE: 793 - caif_assert(1); /*Should never happen */ 794 - break; 795 - } 796 - sk->sk_state = CAIF_DISCONNECTED; 797 - sock->state = SS_UNCONNECTED; 798 - sk_stream_kill_queues(&cf_sk->sk); 799 - 800 - err = -EINVAL; 801 - if (addr_len != sizeof(struct sockaddr_caif)) 802 - goto out; 803 - 804 - memcpy(&cf_sk->conn_req.sockaddr, uaddr, 805 - sizeof(struct sockaddr_caif)); 806 - 807 - /* Move to connecting socket, start sending Connect Requests */ 808 - sock->state = SS_CONNECTING; 809 - sk->sk_state = CAIF_CONNECTING; 810 - 811 - /* Check priority value comming from socket */ 812 - /* if priority value is out of range it will be ajusted */ 813 - if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) 814 - cf_sk->conn_req.priority = CAIF_PRIO_MAX; 815 - else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN) 816 - cf_sk->conn_req.priority = CAIF_PRIO_MIN; 817 - else 818 - cf_sk->conn_req.priority = cf_sk->sk.sk_priority; 819 - 820 - /*ifindex = id of the interface.*/ 821 - cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if; 822 - 823 - cf_sk->layer.receive = caif_sktrecv_cb; 824 - 825 - err = caif_connect_client(sock_net(sk), &cf_sk->conn_req, 826 - &cf_sk->layer, &ifindex, &headroom, &tailroom); 827 - 828 - if (err < 0) { 829 - cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 830 - cf_sk->sk.sk_state = CAIF_DISCONNECTED; 831 - goto out; 832 - } 833 - 834 - err = -ENODEV; 835 - rcu_read_lock(); 836 - dev = dev_get_by_index_rcu(sock_net(sk), ifindex); 837 - if (!dev) { 838 - rcu_read_unlock(); 839 - goto out; 840 - } 841 - cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); 842 - mtu = dev->mtu; 843 - rcu_read_unlock(); 844 - 845 - cf_sk->tailroom = tailroom; 846 - cf_sk->maxframe = mtu - (headroom + tailroom); 847 - if (cf_sk->maxframe < 1) { 848 - pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); 849 - err = -ENODEV; 850 - goto out; 851 - } 852 - 853 - err = -EINPROGRESS; 854 - wait_connect: 855 - 856 - if (sk->sk_state != CAIF_CONNECTED && (flags & O_NONBLOCK)) 857 - goto out; 858 - 859 - timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); 860 - 861 - release_sock(sk); 862 - err = -ERESTARTSYS; 863 - timeo = wait_event_interruptible_timeout(*sk_sleep(sk), 864 - sk->sk_state != CAIF_CONNECTING, 865 - timeo); 866 - lock_sock(sk); 867 - if (timeo < 0) 868 - goto out; /* -ERESTARTSYS */ 869 - 870 - err = -ETIMEDOUT; 871 - if (timeo == 0 && sk->sk_state != CAIF_CONNECTED) 872 - goto out; 873 - if (sk->sk_state != CAIF_CONNECTED) { 874 - sock->state = SS_UNCONNECTED; 875 - err = sock_error(sk); 876 - if (!err) 877 - err = -ECONNREFUSED; 878 - goto out; 879 - } 880 - sock->state = SS_CONNECTED; 881 - err = 0; 882 - out: 883 - release_sock(sk); 884 - return err; 885 - } 886 - 887 - /* 888 - * caif_release() - Disconnect a CAIF Socket 889 - * Copied and modified af_irda.c:irda_release(). 890 - */ 891 - static int caif_release(struct socket *sock) 892 - { 893 - struct sock *sk = sock->sk; 894 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 895 - 896 - if (!sk) 897 - return 0; 898 - 899 - set_tx_flow_off(cf_sk); 900 - 901 - /* 902 - * Ensure that packets are not queued after this point in time. 903 - * caif_queue_rcv_skb checks SOCK_DEAD holding the queue lock, 904 - * this ensures no packets when sock is dead. 905 - */ 906 - spin_lock_bh(&sk->sk_receive_queue.lock); 907 - sock_set_flag(sk, SOCK_DEAD); 908 - spin_unlock_bh(&sk->sk_receive_queue.lock); 909 - sock->sk = NULL; 910 - 911 - WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir)); 912 - debugfs_remove_recursive(cf_sk->debugfs_socket_dir); 913 - 914 - lock_sock(&(cf_sk->sk)); 915 - sk->sk_state = CAIF_DISCONNECTED; 916 - sk->sk_shutdown = SHUTDOWN_MASK; 917 - 918 - caif_disconnect_client(sock_net(sk), &cf_sk->layer); 919 - cf_sk->sk.sk_socket->state = SS_DISCONNECTING; 920 - wake_up_interruptible_poll(sk_sleep(sk), EPOLLERR|EPOLLHUP); 921 - 922 - sock_orphan(sk); 923 - sk_stream_kill_queues(&cf_sk->sk); 924 - release_sock(sk); 925 - sock_put(sk); 926 - return 0; 927 - } 928 - 929 - /* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */ 930 - static __poll_t caif_poll(struct file *file, 931 - struct socket *sock, poll_table *wait) 932 - { 933 - struct sock *sk = sock->sk; 934 - __poll_t mask; 935 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 936 - 937 - sock_poll_wait(file, sock, wait); 938 - mask = 0; 939 - 940 - /* exceptional events? */ 941 - if (sk->sk_err) 942 - mask |= EPOLLERR; 943 - if (sk->sk_shutdown == SHUTDOWN_MASK) 944 - mask |= EPOLLHUP; 945 - if (sk->sk_shutdown & RCV_SHUTDOWN) 946 - mask |= EPOLLRDHUP; 947 - 948 - /* readable? */ 949 - if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || 950 - (sk->sk_shutdown & RCV_SHUTDOWN)) 951 - mask |= EPOLLIN | EPOLLRDNORM; 952 - 953 - /* 954 - * we set writable also when the other side has shut down the 955 - * connection. This prevents stuck sockets. 956 - */ 957 - if (sock_writeable(sk) && tx_flow_is_on(cf_sk)) 958 - mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; 959 - 960 - return mask; 961 - } 962 - 963 - static const struct proto_ops caif_seqpacket_ops = { 964 - .family = PF_CAIF, 965 - .owner = THIS_MODULE, 966 - .release = caif_release, 967 - .bind = sock_no_bind, 968 - .connect = caif_connect, 969 - .socketpair = sock_no_socketpair, 970 - .accept = sock_no_accept, 971 - .getname = sock_no_getname, 972 - .poll = caif_poll, 973 - .ioctl = sock_no_ioctl, 974 - .listen = sock_no_listen, 975 - .shutdown = sock_no_shutdown, 976 - .setsockopt = setsockopt, 977 - .sendmsg = caif_seqpkt_sendmsg, 978 - .recvmsg = caif_seqpkt_recvmsg, 979 - .mmap = sock_no_mmap, 980 - }; 981 - 982 - static const struct proto_ops caif_stream_ops = { 983 - .family = PF_CAIF, 984 - .owner = THIS_MODULE, 985 - .release = caif_release, 986 - .bind = sock_no_bind, 987 - .connect = caif_connect, 988 - .socketpair = sock_no_socketpair, 989 - .accept = sock_no_accept, 990 - .getname = sock_no_getname, 991 - .poll = caif_poll, 992 - .ioctl = sock_no_ioctl, 993 - .listen = sock_no_listen, 994 - .shutdown = sock_no_shutdown, 995 - .setsockopt = setsockopt, 996 - .sendmsg = caif_stream_sendmsg, 997 - .recvmsg = caif_stream_recvmsg, 998 - .mmap = sock_no_mmap, 999 - }; 1000 - 1001 - /* This function is called when a socket is finally destroyed. */ 1002 - static void caif_sock_destructor(struct sock *sk) 1003 - { 1004 - struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); 1005 - caif_assert(!refcount_read(&sk->sk_wmem_alloc)); 1006 - caif_assert(sk_unhashed(sk)); 1007 - caif_assert(!sk->sk_socket); 1008 - if (!sock_flag(sk, SOCK_DEAD)) { 1009 - pr_debug("Attempt to release alive CAIF socket: %p\n", sk); 1010 - return; 1011 - } 1012 - sk_stream_kill_queues(&cf_sk->sk); 1013 - WARN_ON_ONCE(sk->sk_forward_alloc); 1014 - caif_free_client(&cf_sk->layer); 1015 - } 1016 - 1017 - static int caif_create(struct net *net, struct socket *sock, int protocol, 1018 - int kern) 1019 - { 1020 - struct sock *sk = NULL; 1021 - struct caifsock *cf_sk = NULL; 1022 - static struct proto prot = {.name = "PF_CAIF", 1023 - .owner = THIS_MODULE, 1024 - .obj_size = sizeof(struct caifsock), 1025 - .useroffset = offsetof(struct caifsock, conn_req.param), 1026 - .usersize = sizeof_field(struct caifsock, conn_req.param) 1027 - }; 1028 - 1029 - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_NET_ADMIN)) 1030 - return -EPERM; 1031 - /* 1032 - * The sock->type specifies the socket type to use. 1033 - * The CAIF socket is a packet stream in the sense 1034 - * that it is packet based. CAIF trusts the reliability 1035 - * of the link, no resending is implemented. 1036 - */ 1037 - if (sock->type == SOCK_SEQPACKET) 1038 - sock->ops = &caif_seqpacket_ops; 1039 - else if (sock->type == SOCK_STREAM) 1040 - sock->ops = &caif_stream_ops; 1041 - else 1042 - return -ESOCKTNOSUPPORT; 1043 - 1044 - if (protocol < 0 || protocol >= CAIFPROTO_MAX) 1045 - return -EPROTONOSUPPORT; 1046 - /* 1047 - * Set the socket state to unconnected. The socket state 1048 - * is really not used at all in the net/core or socket.c but the 1049 - * initialization makes sure that sock->state is not uninitialized. 1050 - */ 1051 - sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot, kern); 1052 - if (!sk) 1053 - return -ENOMEM; 1054 - 1055 - cf_sk = container_of(sk, struct caifsock, sk); 1056 - 1057 - /* Store the protocol */ 1058 - sk->sk_protocol = (unsigned char) protocol; 1059 - 1060 - /* Initialize default priority for well-known cases */ 1061 - switch (protocol) { 1062 - case CAIFPROTO_AT: 1063 - sk->sk_priority = TC_PRIO_CONTROL; 1064 - break; 1065 - case CAIFPROTO_RFM: 1066 - sk->sk_priority = TC_PRIO_INTERACTIVE_BULK; 1067 - break; 1068 - default: 1069 - sk->sk_priority = TC_PRIO_BESTEFFORT; 1070 - } 1071 - 1072 - /* 1073 - * Lock in order to try to stop someone from opening the socket 1074 - * too early. 1075 - */ 1076 - lock_sock(&(cf_sk->sk)); 1077 - 1078 - /* Initialize the nozero default sock structure data. */ 1079 - sock_init_data(sock, sk); 1080 - sk->sk_destruct = caif_sock_destructor; 1081 - 1082 - mutex_init(&cf_sk->readlock); /* single task reading lock */ 1083 - cf_sk->layer.ctrlcmd = caif_ctrl_cb; 1084 - cf_sk->sk.sk_socket->state = SS_UNCONNECTED; 1085 - cf_sk->sk.sk_state = CAIF_DISCONNECTED; 1086 - 1087 - set_tx_flow_off(cf_sk); 1088 - set_rx_flow_on(cf_sk); 1089 - 1090 - /* Set default options on configuration */ 1091 - cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; 1092 - cf_sk->conn_req.protocol = protocol; 1093 - release_sock(&cf_sk->sk); 1094 - return 0; 1095 - } 1096 - 1097 - 1098 - static const struct net_proto_family caif_family_ops = { 1099 - .family = PF_CAIF, 1100 - .create = caif_create, 1101 - .owner = THIS_MODULE, 1102 - }; 1103 - 1104 - static int __init caif_sktinit_module(void) 1105 - { 1106 - return sock_register(&caif_family_ops); 1107 - } 1108 - 1109 - static void __exit caif_sktexit_module(void) 1110 - { 1111 - sock_unregister(PF_CAIF); 1112 - } 1113 - module_init(caif_sktinit_module); 1114 - module_exit(caif_sktexit_module);
-216
net/caif/caif_usb.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * CAIF USB handler 4 - * Copyright (C) ST-Ericsson AB 2011 5 - * Author: Sjur Brendeland 6 - */ 7 - 8 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 9 - 10 - #include <linux/module.h> 11 - #include <linux/netdevice.h> 12 - #include <linux/slab.h> 13 - #include <linux/mii.h> 14 - #include <linux/usb.h> 15 - #include <linux/usb/usbnet.h> 16 - #include <linux/etherdevice.h> 17 - #include <net/netns/generic.h> 18 - #include <net/caif/caif_dev.h> 19 - #include <net/caif/caif_layer.h> 20 - #include <net/caif/cfpkt.h> 21 - #include <net/caif/cfcnfg.h> 22 - 23 - MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol USB support"); 24 - MODULE_LICENSE("GPL"); 25 - 26 - #define CFUSB_PAD_DESCR_SZ 1 /* Alignment descriptor length */ 27 - #define CFUSB_ALIGNMENT 4 /* Number of bytes to align. */ 28 - #define CFUSB_MAX_HEADLEN (CFUSB_PAD_DESCR_SZ + CFUSB_ALIGNMENT-1) 29 - #define STE_USB_VID 0x04cc /* USB Product ID for ST-Ericsson */ 30 - #define STE_USB_PID_CAIF 0x230f /* Product id for CAIF Modems */ 31 - 32 - struct cfusbl { 33 - struct cflayer layer; 34 - u8 tx_eth_hdr[ETH_HLEN]; 35 - }; 36 - 37 - static bool pack_added; 38 - 39 - static int cfusbl_receive(struct cflayer *layr, struct cfpkt *pkt) 40 - { 41 - u8 hpad; 42 - 43 - /* Remove padding. */ 44 - cfpkt_extr_head(pkt, &hpad, 1); 45 - cfpkt_extr_head(pkt, NULL, hpad); 46 - return layr->up->receive(layr->up, pkt); 47 - } 48 - 49 - static int cfusbl_transmit(struct cflayer *layr, struct cfpkt *pkt) 50 - { 51 - struct caif_payload_info *info; 52 - u8 hpad; 53 - u8 zeros[CFUSB_ALIGNMENT]; 54 - struct sk_buff *skb; 55 - struct cfusbl *usbl = container_of(layr, struct cfusbl, layer); 56 - 57 - skb = cfpkt_tonative(pkt); 58 - 59 - skb_reset_network_header(skb); 60 - skb->protocol = htons(ETH_P_IP); 61 - 62 - info = cfpkt_info(pkt); 63 - hpad = (info->hdr_len + CFUSB_PAD_DESCR_SZ) & (CFUSB_ALIGNMENT - 1); 64 - 65 - if (skb_headroom(skb) < ETH_HLEN + CFUSB_PAD_DESCR_SZ + hpad) { 66 - pr_warn("Headroom too small\n"); 67 - kfree_skb(skb); 68 - return -EIO; 69 - } 70 - memset(zeros, 0, hpad); 71 - 72 - cfpkt_add_head(pkt, zeros, hpad); 73 - cfpkt_add_head(pkt, &hpad, 1); 74 - cfpkt_add_head(pkt, usbl->tx_eth_hdr, sizeof(usbl->tx_eth_hdr)); 75 - return layr->dn->transmit(layr->dn, pkt); 76 - } 77 - 78 - static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 79 - int phyid) 80 - { 81 - if (layr->up && layr->up->ctrlcmd) 82 - layr->up->ctrlcmd(layr->up, ctrl, layr->id); 83 - } 84 - 85 - static struct cflayer *cfusbl_create(int phyid, const u8 ethaddr[ETH_ALEN], 86 - u8 braddr[ETH_ALEN]) 87 - { 88 - struct cfusbl *this = kmalloc_obj(struct cfusbl, GFP_ATOMIC); 89 - 90 - if (!this) 91 - return NULL; 92 - 93 - caif_assert(offsetof(struct cfusbl, layer) == 0); 94 - 95 - memset(&this->layer, 0, sizeof(this->layer)); 96 - this->layer.receive = cfusbl_receive; 97 - this->layer.transmit = cfusbl_transmit; 98 - this->layer.ctrlcmd = cfusbl_ctrlcmd; 99 - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "usb%d", phyid); 100 - this->layer.id = phyid; 101 - 102 - /* 103 - * Construct TX ethernet header: 104 - * 0-5 destination address 105 - * 5-11 source address 106 - * 12-13 protocol type 107 - */ 108 - ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], braddr); 109 - ether_addr_copy(&this->tx_eth_hdr[ETH_ALEN], ethaddr); 110 - this->tx_eth_hdr[12] = cpu_to_be16(ETH_P_802_EX1) & 0xff; 111 - this->tx_eth_hdr[13] = (cpu_to_be16(ETH_P_802_EX1) >> 8) & 0xff; 112 - pr_debug("caif ethernet TX-header dst:%pM src:%pM type:%02x%02x\n", 113 - this->tx_eth_hdr, this->tx_eth_hdr + ETH_ALEN, 114 - this->tx_eth_hdr[12], this->tx_eth_hdr[13]); 115 - 116 - return (struct cflayer *) this; 117 - } 118 - 119 - static void cfusbl_release(struct cflayer *layer) 120 - { 121 - kfree(layer); 122 - } 123 - 124 - static struct packet_type caif_usb_type __read_mostly = { 125 - .type = cpu_to_be16(ETH_P_802_EX1), 126 - }; 127 - 128 - static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, 129 - void *ptr) 130 - { 131 - struct net_device *dev = netdev_notifier_info_to_dev(ptr); 132 - struct caif_dev_common common; 133 - struct cflayer *layer, *link_support; 134 - struct usbnet *usbnet; 135 - struct usb_device *usbdev; 136 - int res; 137 - 138 - if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED) 139 - return 0; 140 - 141 - /* Check whether we have a NCM device, and find its VID/PID. */ 142 - if (!(dev->dev.parent && dev->dev.parent->driver && 143 - strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0)) 144 - return 0; 145 - 146 - usbnet = netdev_priv(dev); 147 - usbdev = usbnet->udev; 148 - 149 - pr_debug("USB CDC NCM device VID:0x%4x PID:0x%4x\n", 150 - le16_to_cpu(usbdev->descriptor.idVendor), 151 - le16_to_cpu(usbdev->descriptor.idProduct)); 152 - 153 - /* Check for VID/PID that supports CAIF */ 154 - if (!(le16_to_cpu(usbdev->descriptor.idVendor) == STE_USB_VID && 155 - le16_to_cpu(usbdev->descriptor.idProduct) == STE_USB_PID_CAIF)) 156 - return 0; 157 - 158 - if (what == NETDEV_UNREGISTER) 159 - module_put(THIS_MODULE); 160 - 161 - if (what != NETDEV_REGISTER) 162 - return 0; 163 - 164 - __module_get(THIS_MODULE); 165 - 166 - memset(&common, 0, sizeof(common)); 167 - common.use_frag = false; 168 - common.use_fcs = false; 169 - common.use_stx = false; 170 - common.link_select = CAIF_LINK_HIGH_BANDW; 171 - common.flowctrl = NULL; 172 - 173 - link_support = cfusbl_create(dev->ifindex, dev->dev_addr, 174 - dev->broadcast); 175 - 176 - if (!link_support) 177 - return -ENOMEM; 178 - 179 - if (dev->num_tx_queues > 1) 180 - pr_warn("USB device uses more than one tx queue\n"); 181 - 182 - res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, 183 - &layer, &caif_usb_type.func); 184 - if (res) 185 - goto err; 186 - 187 - if (!pack_added) 188 - dev_add_pack(&caif_usb_type); 189 - pack_added = true; 190 - 191 - strscpy(layer->name, dev->name, sizeof(layer->name)); 192 - 193 - return 0; 194 - err: 195 - cfusbl_release(link_support); 196 - return res; 197 - } 198 - 199 - static struct notifier_block caif_device_notifier = { 200 - .notifier_call = cfusbl_device_notify, 201 - .priority = 0, 202 - }; 203 - 204 - static int __init cfusbl_init(void) 205 - { 206 - return register_netdevice_notifier(&caif_device_notifier); 207 - } 208 - 209 - static void __exit cfusbl_exit(void) 210 - { 211 - unregister_netdevice_notifier(&caif_device_notifier); 212 - dev_remove_pack(&caif_usb_type); 213 - } 214 - 215 - module_init(cfusbl_init); 216 - module_exit(cfusbl_exit);
-612
net/caif/cfcnfg.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/kernel.h> 10 - #include <linux/stddef.h> 11 - #include <linux/slab.h> 12 - #include <linux/netdevice.h> 13 - #include <linux/module.h> 14 - #include <net/caif/caif_layer.h> 15 - #include <net/caif/cfpkt.h> 16 - #include <net/caif/cfcnfg.h> 17 - #include <net/caif/cfctrl.h> 18 - #include <net/caif/cfmuxl.h> 19 - #include <net/caif/cffrml.h> 20 - #include <net/caif/cfserl.h> 21 - #include <net/caif/cfsrvl.h> 22 - #include <net/caif/caif_dev.h> 23 - 24 - #define container_obj(layr) container_of(layr, struct cfcnfg, layer) 25 - 26 - /* Information about CAIF physical interfaces held by Config Module in order 27 - * to manage physical interfaces 28 - */ 29 - struct cfcnfg_phyinfo { 30 - struct list_head node; 31 - bool up; 32 - 33 - /* Pointer to the layer below the MUX (framing layer) */ 34 - struct cflayer *frm_layer; 35 - /* Pointer to the lowest actual physical layer */ 36 - struct cflayer *phy_layer; 37 - /* Unique identifier of the physical interface */ 38 - unsigned int id; 39 - /* Preference of the physical in interface */ 40 - enum cfcnfg_phy_preference pref; 41 - 42 - /* Information about the physical device */ 43 - struct dev_info dev_info; 44 - 45 - /* Interface index */ 46 - int ifindex; 47 - 48 - /* Protocol head room added for CAIF link layer */ 49 - int head_room; 50 - 51 - /* Use Start of frame checksum */ 52 - bool use_fcs; 53 - }; 54 - 55 - struct cfcnfg { 56 - struct cflayer layer; 57 - struct cflayer *ctrl; 58 - struct cflayer *mux; 59 - struct list_head phys; 60 - struct mutex lock; 61 - }; 62 - 63 - static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, 64 - enum cfctrl_srv serv, u8 phyid, 65 - struct cflayer *adapt_layer); 66 - static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id); 67 - static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, 68 - struct cflayer *adapt_layer); 69 - static void cfctrl_resp_func(void); 70 - static void cfctrl_enum_resp(void); 71 - 72 - struct cfcnfg *cfcnfg_create(void) 73 - { 74 - struct cfcnfg *this; 75 - struct cfctrl_rsp *resp; 76 - 77 - might_sleep(); 78 - 79 - /* Initiate this layer */ 80 - this = kzalloc_obj(struct cfcnfg, GFP_ATOMIC); 81 - if (!this) 82 - return NULL; 83 - this->mux = cfmuxl_create(); 84 - if (!this->mux) 85 - goto out_of_mem; 86 - this->ctrl = cfctrl_create(); 87 - if (!this->ctrl) 88 - goto out_of_mem; 89 - /* Initiate response functions */ 90 - resp = cfctrl_get_respfuncs(this->ctrl); 91 - resp->enum_rsp = cfctrl_enum_resp; 92 - resp->linkerror_ind = cfctrl_resp_func; 93 - resp->linkdestroy_rsp = cfcnfg_linkdestroy_rsp; 94 - resp->sleep_rsp = cfctrl_resp_func; 95 - resp->wake_rsp = cfctrl_resp_func; 96 - resp->restart_rsp = cfctrl_resp_func; 97 - resp->radioset_rsp = cfctrl_resp_func; 98 - resp->linksetup_rsp = cfcnfg_linkup_rsp; 99 - resp->reject_rsp = cfcnfg_reject_rsp; 100 - INIT_LIST_HEAD(&this->phys); 101 - 102 - cfmuxl_set_uplayer(this->mux, this->ctrl, 0); 103 - layer_set_dn(this->ctrl, this->mux); 104 - layer_set_up(this->ctrl, this); 105 - mutex_init(&this->lock); 106 - 107 - return this; 108 - out_of_mem: 109 - synchronize_rcu(); 110 - 111 - kfree(this->mux); 112 - kfree(this->ctrl); 113 - kfree(this); 114 - return NULL; 115 - } 116 - 117 - void cfcnfg_remove(struct cfcnfg *cfg) 118 - { 119 - might_sleep(); 120 - if (cfg) { 121 - synchronize_rcu(); 122 - 123 - kfree(cfg->mux); 124 - cfctrl_remove(cfg->ctrl); 125 - kfree(cfg); 126 - } 127 - } 128 - 129 - static void cfctrl_resp_func(void) 130 - { 131 - } 132 - 133 - static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo_rcu(struct cfcnfg *cnfg, 134 - u8 phyid) 135 - { 136 - struct cfcnfg_phyinfo *phy; 137 - 138 - list_for_each_entry_rcu(phy, &cnfg->phys, node) 139 - if (phy->id == phyid) 140 - return phy; 141 - return NULL; 142 - } 143 - 144 - static void cfctrl_enum_resp(void) 145 - { 146 - } 147 - 148 - static struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, 149 - enum cfcnfg_phy_preference phy_pref) 150 - { 151 - /* Try to match with specified preference */ 152 - struct cfcnfg_phyinfo *phy; 153 - 154 - list_for_each_entry_rcu(phy, &cnfg->phys, node) { 155 - if (phy->up && phy->pref == phy_pref && 156 - phy->frm_layer != NULL) 157 - 158 - return &phy->dev_info; 159 - } 160 - 161 - /* Otherwise just return something */ 162 - list_for_each_entry_rcu(phy, &cnfg->phys, node) 163 - if (phy->up) 164 - return &phy->dev_info; 165 - 166 - return NULL; 167 - } 168 - 169 - static int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) 170 - { 171 - struct cfcnfg_phyinfo *phy; 172 - 173 - list_for_each_entry_rcu(phy, &cnfg->phys, node) 174 - if (phy->ifindex == ifi && phy->up) 175 - return phy->id; 176 - return -ENODEV; 177 - } 178 - 179 - int caif_disconnect_client(struct net *net, struct cflayer *adap_layer) 180 - { 181 - u8 channel_id; 182 - struct cfcnfg *cfg = get_cfcnfg(net); 183 - 184 - caif_assert(adap_layer != NULL); 185 - cfctrl_cancel_req(cfg->ctrl, adap_layer); 186 - channel_id = adap_layer->id; 187 - if (channel_id != 0) { 188 - struct cflayer *servl; 189 - servl = cfmuxl_remove_uplayer(cfg->mux, channel_id); 190 - cfctrl_linkdown_req(cfg->ctrl, channel_id, adap_layer); 191 - if (servl != NULL) 192 - layer_set_up(servl, NULL); 193 - } else 194 - pr_debug("nothing to disconnect\n"); 195 - 196 - /* Do RCU sync before initiating cleanup */ 197 - synchronize_rcu(); 198 - if (adap_layer->ctrlcmd != NULL) 199 - adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0); 200 - return 0; 201 - 202 - } 203 - EXPORT_SYMBOL(caif_disconnect_client); 204 - 205 - static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) 206 - { 207 - } 208 - 209 - static const int protohead[CFCTRL_SRV_MASK] = { 210 - [CFCTRL_SRV_VEI] = 4, 211 - [CFCTRL_SRV_DATAGRAM] = 7, 212 - [CFCTRL_SRV_UTIL] = 4, 213 - [CFCTRL_SRV_RFM] = 3, 214 - [CFCTRL_SRV_DBG] = 3, 215 - }; 216 - 217 - 218 - static int caif_connect_req_to_link_param(struct cfcnfg *cnfg, 219 - struct caif_connect_request *s, 220 - struct cfctrl_link_param *l) 221 - { 222 - struct dev_info *dev_info; 223 - enum cfcnfg_phy_preference pref; 224 - int res; 225 - 226 - memset(l, 0, sizeof(*l)); 227 - /* In caif protocol low value is high priority */ 228 - l->priority = CAIF_PRIO_MAX - s->priority + 1; 229 - 230 - if (s->ifindex != 0) { 231 - res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); 232 - if (res < 0) 233 - return res; 234 - l->phyid = res; 235 - } else { 236 - switch (s->link_selector) { 237 - case CAIF_LINK_HIGH_BANDW: 238 - pref = CFPHYPREF_HIGH_BW; 239 - break; 240 - case CAIF_LINK_LOW_LATENCY: 241 - pref = CFPHYPREF_LOW_LAT; 242 - break; 243 - default: 244 - return -EINVAL; 245 - } 246 - dev_info = cfcnfg_get_phyid(cnfg, pref); 247 - if (dev_info == NULL) 248 - return -ENODEV; 249 - l->phyid = dev_info->id; 250 - } 251 - switch (s->protocol) { 252 - case CAIFPROTO_AT: 253 - l->linktype = CFCTRL_SRV_VEI; 254 - l->endpoint = (s->sockaddr.u.at.type >> 2) & 0x3; 255 - l->chtype = s->sockaddr.u.at.type & 0x3; 256 - break; 257 - case CAIFPROTO_DATAGRAM: 258 - l->linktype = CFCTRL_SRV_DATAGRAM; 259 - l->chtype = 0x00; 260 - l->u.datagram.connid = s->sockaddr.u.dgm.connection_id; 261 - break; 262 - case CAIFPROTO_DATAGRAM_LOOP: 263 - l->linktype = CFCTRL_SRV_DATAGRAM; 264 - l->chtype = 0x03; 265 - l->endpoint = 0x00; 266 - l->u.datagram.connid = s->sockaddr.u.dgm.connection_id; 267 - break; 268 - case CAIFPROTO_RFM: 269 - l->linktype = CFCTRL_SRV_RFM; 270 - l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; 271 - strscpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, 272 - sizeof(l->u.rfm.volume)); 273 - break; 274 - case CAIFPROTO_UTIL: 275 - l->linktype = CFCTRL_SRV_UTIL; 276 - l->endpoint = 0x00; 277 - l->chtype = 0x00; 278 - strscpy(l->u.utility.name, s->sockaddr.u.util.service, 279 - sizeof(l->u.utility.name)); 280 - caif_assert(sizeof(l->u.utility.name) > 10); 281 - l->u.utility.paramlen = s->param.size; 282 - if (l->u.utility.paramlen > sizeof(l->u.utility.params)) 283 - l->u.utility.paramlen = sizeof(l->u.utility.params); 284 - 285 - memcpy(l->u.utility.params, s->param.data, 286 - l->u.utility.paramlen); 287 - 288 - break; 289 - case CAIFPROTO_DEBUG: 290 - l->linktype = CFCTRL_SRV_DBG; 291 - l->endpoint = s->sockaddr.u.dbg.service; 292 - l->chtype = s->sockaddr.u.dbg.type; 293 - break; 294 - default: 295 - return -EINVAL; 296 - } 297 - return 0; 298 - } 299 - 300 - int caif_connect_client(struct net *net, struct caif_connect_request *conn_req, 301 - struct cflayer *adap_layer, int *ifindex, 302 - int *proto_head, int *proto_tail) 303 - { 304 - struct cflayer *frml; 305 - struct cfcnfg_phyinfo *phy; 306 - int err; 307 - struct cfctrl_link_param param; 308 - struct cfcnfg *cfg = get_cfcnfg(net); 309 - 310 - rcu_read_lock(); 311 - err = caif_connect_req_to_link_param(cfg, conn_req, &param); 312 - if (err) 313 - goto unlock; 314 - 315 - phy = cfcnfg_get_phyinfo_rcu(cfg, param.phyid); 316 - if (!phy) { 317 - err = -ENODEV; 318 - goto unlock; 319 - } 320 - err = -EINVAL; 321 - 322 - if (adap_layer == NULL) { 323 - pr_err("adap_layer is zero\n"); 324 - goto unlock; 325 - } 326 - if (adap_layer->receive == NULL) { 327 - pr_err("adap_layer->receive is NULL\n"); 328 - goto unlock; 329 - } 330 - if (adap_layer->ctrlcmd == NULL) { 331 - pr_err("adap_layer->ctrlcmd == NULL\n"); 332 - goto unlock; 333 - } 334 - 335 - err = -ENODEV; 336 - frml = phy->frm_layer; 337 - if (frml == NULL) { 338 - pr_err("Specified PHY type does not exist!\n"); 339 - goto unlock; 340 - } 341 - caif_assert(param.phyid == phy->id); 342 - caif_assert(phy->frm_layer->id == 343 - param.phyid); 344 - caif_assert(phy->phy_layer->id == 345 - param.phyid); 346 - 347 - *ifindex = phy->ifindex; 348 - *proto_tail = 2; 349 - *proto_head = protohead[param.linktype] + phy->head_room; 350 - 351 - rcu_read_unlock(); 352 - 353 - /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ 354 - cfctrl_enum_req(cfg->ctrl, param.phyid); 355 - return cfctrl_linkup_request(cfg->ctrl, &param, adap_layer); 356 - 357 - unlock: 358 - rcu_read_unlock(); 359 - return err; 360 - } 361 - EXPORT_SYMBOL(caif_connect_client); 362 - 363 - static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, 364 - struct cflayer *adapt_layer) 365 - { 366 - if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) 367 - adapt_layer->ctrlcmd(adapt_layer, 368 - CAIF_CTRLCMD_INIT_FAIL_RSP, 0); 369 - } 370 - 371 - static void 372 - cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, 373 - u8 phyid, struct cflayer *adapt_layer) 374 - { 375 - struct cfcnfg *cnfg = container_obj(layer); 376 - struct cflayer *servicel = NULL; 377 - struct cfcnfg_phyinfo *phyinfo; 378 - struct net_device *netdev; 379 - 380 - if (channel_id == 0) { 381 - pr_warn("received channel_id zero\n"); 382 - if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) 383 - adapt_layer->ctrlcmd(adapt_layer, 384 - CAIF_CTRLCMD_INIT_FAIL_RSP, 0); 385 - return; 386 - } 387 - 388 - rcu_read_lock(); 389 - 390 - if (adapt_layer == NULL) { 391 - pr_debug("link setup response but no client exist, send linkdown back\n"); 392 - cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL); 393 - goto unlock; 394 - } 395 - 396 - caif_assert(cnfg != NULL); 397 - caif_assert(phyid != 0); 398 - 399 - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid); 400 - if (phyinfo == NULL) { 401 - pr_err("ERROR: Link Layer Device disappeared while connecting\n"); 402 - goto unlock; 403 - } 404 - 405 - caif_assert(phyinfo != NULL); 406 - caif_assert(phyinfo->id == phyid); 407 - caif_assert(phyinfo->phy_layer != NULL); 408 - caif_assert(phyinfo->phy_layer->id == phyid); 409 - 410 - adapt_layer->id = channel_id; 411 - 412 - switch (serv) { 413 - case CFCTRL_SRV_VEI: 414 - servicel = cfvei_create(channel_id, &phyinfo->dev_info); 415 - break; 416 - case CFCTRL_SRV_DATAGRAM: 417 - servicel = cfdgml_create(channel_id, 418 - &phyinfo->dev_info); 419 - break; 420 - case CFCTRL_SRV_RFM: 421 - netdev = phyinfo->dev_info.dev; 422 - servicel = cfrfml_create(channel_id, &phyinfo->dev_info, 423 - netdev->mtu); 424 - break; 425 - case CFCTRL_SRV_UTIL: 426 - servicel = cfutill_create(channel_id, &phyinfo->dev_info); 427 - break; 428 - case CFCTRL_SRV_VIDEO: 429 - servicel = cfvidl_create(channel_id, &phyinfo->dev_info); 430 - break; 431 - case CFCTRL_SRV_DBG: 432 - servicel = cfdbgl_create(channel_id, &phyinfo->dev_info); 433 - break; 434 - default: 435 - pr_err("Protocol error. Link setup response - unknown channel type\n"); 436 - goto unlock; 437 - } 438 - if (!servicel) 439 - goto unlock; 440 - layer_set_dn(servicel, cnfg->mux); 441 - cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id); 442 - layer_set_up(servicel, adapt_layer); 443 - layer_set_dn(adapt_layer, servicel); 444 - 445 - rcu_read_unlock(); 446 - 447 - servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0); 448 - return; 449 - unlock: 450 - rcu_read_unlock(); 451 - } 452 - 453 - int 454 - cfcnfg_add_phy_layer(struct cfcnfg *cnfg, 455 - struct net_device *dev, struct cflayer *phy_layer, 456 - enum cfcnfg_phy_preference pref, 457 - struct cflayer *link_support, 458 - bool fcs, int head_room) 459 - { 460 - struct cflayer *frml; 461 - struct cfcnfg_phyinfo *phyinfo = NULL; 462 - int i, res = 0; 463 - u8 phyid; 464 - 465 - mutex_lock(&cnfg->lock); 466 - 467 - /* CAIF protocol allow maximum 6 link-layers */ 468 - for (i = 0; i < 7; i++) { 469 - phyid = (dev->ifindex + i) & 0x7; 470 - if (phyid == 0) 471 - continue; 472 - if (cfcnfg_get_phyinfo_rcu(cnfg, phyid) == NULL) 473 - goto got_phyid; 474 - } 475 - pr_warn("Too many CAIF Link Layers (max 6)\n"); 476 - res = -EEXIST; 477 - goto out; 478 - 479 - got_phyid: 480 - phyinfo = kzalloc_obj(struct cfcnfg_phyinfo, GFP_ATOMIC); 481 - if (!phyinfo) { 482 - res = -ENOMEM; 483 - goto out; 484 - } 485 - 486 - phy_layer->id = phyid; 487 - phyinfo->pref = pref; 488 - phyinfo->id = phyid; 489 - phyinfo->dev_info.id = phyid; 490 - phyinfo->dev_info.dev = dev; 491 - phyinfo->phy_layer = phy_layer; 492 - phyinfo->ifindex = dev->ifindex; 493 - phyinfo->head_room = head_room; 494 - phyinfo->use_fcs = fcs; 495 - 496 - frml = cffrml_create(phyid, fcs); 497 - 498 - if (!frml) { 499 - res = -ENOMEM; 500 - goto out_err; 501 - } 502 - phyinfo->frm_layer = frml; 503 - layer_set_up(frml, cnfg->mux); 504 - 505 - if (link_support != NULL) { 506 - link_support->id = phyid; 507 - layer_set_dn(frml, link_support); 508 - layer_set_up(link_support, frml); 509 - layer_set_dn(link_support, phy_layer); 510 - layer_set_up(phy_layer, link_support); 511 - } else { 512 - layer_set_dn(frml, phy_layer); 513 - layer_set_up(phy_layer, frml); 514 - } 515 - 516 - list_add_rcu(&phyinfo->node, &cnfg->phys); 517 - out: 518 - mutex_unlock(&cnfg->lock); 519 - return res; 520 - 521 - out_err: 522 - kfree(phyinfo); 523 - mutex_unlock(&cnfg->lock); 524 - return res; 525 - } 526 - EXPORT_SYMBOL(cfcnfg_add_phy_layer); 527 - 528 - int cfcnfg_set_phy_state(struct cfcnfg *cnfg, struct cflayer *phy_layer, 529 - bool up) 530 - { 531 - struct cfcnfg_phyinfo *phyinfo; 532 - 533 - rcu_read_lock(); 534 - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phy_layer->id); 535 - if (phyinfo == NULL) { 536 - rcu_read_unlock(); 537 - return -ENODEV; 538 - } 539 - 540 - if (phyinfo->up == up) { 541 - rcu_read_unlock(); 542 - return 0; 543 - } 544 - phyinfo->up = up; 545 - 546 - if (up) { 547 - cffrml_hold(phyinfo->frm_layer); 548 - cfmuxl_set_dnlayer(cnfg->mux, phyinfo->frm_layer, 549 - phy_layer->id); 550 - } else { 551 - cfmuxl_remove_dnlayer(cnfg->mux, phy_layer->id); 552 - cffrml_put(phyinfo->frm_layer); 553 - } 554 - 555 - rcu_read_unlock(); 556 - return 0; 557 - } 558 - EXPORT_SYMBOL(cfcnfg_set_phy_state); 559 - 560 - int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer) 561 - { 562 - struct cflayer *frml, *frml_dn; 563 - u16 phyid; 564 - struct cfcnfg_phyinfo *phyinfo; 565 - 566 - might_sleep(); 567 - 568 - mutex_lock(&cnfg->lock); 569 - 570 - phyid = phy_layer->id; 571 - phyinfo = cfcnfg_get_phyinfo_rcu(cnfg, phyid); 572 - 573 - if (phyinfo == NULL) { 574 - mutex_unlock(&cnfg->lock); 575 - return 0; 576 - } 577 - caif_assert(phyid == phyinfo->id); 578 - caif_assert(phy_layer == phyinfo->phy_layer); 579 - caif_assert(phy_layer->id == phyid); 580 - caif_assert(phyinfo->frm_layer->id == phyid); 581 - 582 - list_del_rcu(&phyinfo->node); 583 - synchronize_rcu(); 584 - 585 - /* Fail if reference count is not zero */ 586 - if (cffrml_refcnt_read(phyinfo->frm_layer) != 0) { 587 - pr_info("Wait for device inuse\n"); 588 - list_add_rcu(&phyinfo->node, &cnfg->phys); 589 - mutex_unlock(&cnfg->lock); 590 - return -EAGAIN; 591 - } 592 - 593 - frml = phyinfo->frm_layer; 594 - frml_dn = frml->dn; 595 - cffrml_set_uplayer(frml, NULL); 596 - cffrml_set_dnlayer(frml, NULL); 597 - if (phy_layer != frml_dn) { 598 - layer_set_up(frml_dn, NULL); 599 - layer_set_dn(frml_dn, NULL); 600 - } 601 - layer_set_up(phy_layer, NULL); 602 - 603 - if (phyinfo->phy_layer != frml_dn) 604 - kfree(frml_dn); 605 - 606 - cffrml_free(frml); 607 - kfree(phyinfo); 608 - mutex_unlock(&cnfg->lock); 609 - 610 - return 0; 611 - } 612 - EXPORT_SYMBOL(cfcnfg_del_phy_layer);
-631
net/caif/cfctrl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/spinlock.h> 11 - #include <linux/slab.h> 12 - #include <linux/pkt_sched.h> 13 - #include <net/caif/caif_layer.h> 14 - #include <net/caif/cfpkt.h> 15 - #include <net/caif/cfctrl.h> 16 - 17 - #define container_obj(layr) container_of(layr, struct cfctrl, serv.layer) 18 - #define UTILITY_NAME_LENGTH 16 19 - #define CFPKT_CTRL_PKT_LEN 20 20 - 21 - #ifdef CAIF_NO_LOOP 22 - static int handle_loop(struct cfctrl *ctrl, 23 - int cmd, struct cfpkt *pkt){ 24 - return -1; 25 - } 26 - #else 27 - static int handle_loop(struct cfctrl *ctrl, 28 - int cmd, struct cfpkt *pkt); 29 - #endif 30 - static int cfctrl_recv(struct cflayer *layr, struct cfpkt *pkt); 31 - static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 32 - int phyid); 33 - 34 - 35 - struct cflayer *cfctrl_create(void) 36 - { 37 - struct dev_info dev_info; 38 - struct cfctrl *this = 39 - kzalloc_obj(struct cfctrl, GFP_ATOMIC); 40 - if (!this) 41 - return NULL; 42 - caif_assert(offsetof(struct cfctrl, serv.layer) == 0); 43 - memset(&dev_info, 0, sizeof(dev_info)); 44 - dev_info.id = 0xff; 45 - cfsrvl_init(&this->serv, 0, &dev_info, false); 46 - atomic_set(&this->req_seq_no, 1); 47 - atomic_set(&this->rsp_seq_no, 1); 48 - this->serv.layer.receive = cfctrl_recv; 49 - sprintf(this->serv.layer.name, "ctrl"); 50 - this->serv.layer.ctrlcmd = cfctrl_ctrlcmd; 51 - #ifndef CAIF_NO_LOOP 52 - spin_lock_init(&this->loop_linkid_lock); 53 - this->loop_linkid = 1; 54 - #endif 55 - spin_lock_init(&this->info_list_lock); 56 - INIT_LIST_HEAD(&this->list); 57 - return &this->serv.layer; 58 - } 59 - 60 - void cfctrl_remove(struct cflayer *layer) 61 - { 62 - struct cfctrl_request_info *p, *tmp; 63 - struct cfctrl *ctrl = container_obj(layer); 64 - 65 - spin_lock_bh(&ctrl->info_list_lock); 66 - list_for_each_entry_safe(p, tmp, &ctrl->list, list) { 67 - list_del(&p->list); 68 - kfree(p); 69 - } 70 - spin_unlock_bh(&ctrl->info_list_lock); 71 - kfree(layer); 72 - } 73 - 74 - static bool param_eq(const struct cfctrl_link_param *p1, 75 - const struct cfctrl_link_param *p2) 76 - { 77 - bool eq = 78 - p1->linktype == p2->linktype && 79 - p1->priority == p2->priority && 80 - p1->phyid == p2->phyid && 81 - p1->endpoint == p2->endpoint && p1->chtype == p2->chtype; 82 - 83 - if (!eq) 84 - return false; 85 - 86 - switch (p1->linktype) { 87 - case CFCTRL_SRV_VEI: 88 - return true; 89 - case CFCTRL_SRV_DATAGRAM: 90 - return p1->u.datagram.connid == p2->u.datagram.connid; 91 - case CFCTRL_SRV_RFM: 92 - return 93 - p1->u.rfm.connid == p2->u.rfm.connid && 94 - strcmp(p1->u.rfm.volume, p2->u.rfm.volume) == 0; 95 - case CFCTRL_SRV_UTIL: 96 - return 97 - p1->u.utility.fifosize_kb == p2->u.utility.fifosize_kb 98 - && p1->u.utility.fifosize_bufs == 99 - p2->u.utility.fifosize_bufs 100 - && strcmp(p1->u.utility.name, p2->u.utility.name) == 0 101 - && p1->u.utility.paramlen == p2->u.utility.paramlen 102 - && memcmp(p1->u.utility.params, p2->u.utility.params, 103 - p1->u.utility.paramlen) == 0; 104 - 105 - case CFCTRL_SRV_VIDEO: 106 - return p1->u.video.connid == p2->u.video.connid; 107 - case CFCTRL_SRV_DBG: 108 - return true; 109 - case CFCTRL_SRV_DECM: 110 - return false; 111 - default: 112 - return false; 113 - } 114 - return false; 115 - } 116 - 117 - static bool cfctrl_req_eq(const struct cfctrl_request_info *r1, 118 - const struct cfctrl_request_info *r2) 119 - { 120 - if (r1->cmd != r2->cmd) 121 - return false; 122 - if (r1->cmd == CFCTRL_CMD_LINK_SETUP) 123 - return param_eq(&r1->param, &r2->param); 124 - else 125 - return r1->channel_id == r2->channel_id; 126 - } 127 - 128 - /* Insert request at the end */ 129 - static void cfctrl_insert_req(struct cfctrl *ctrl, 130 - struct cfctrl_request_info *req) 131 - { 132 - spin_lock_bh(&ctrl->info_list_lock); 133 - atomic_inc(&ctrl->req_seq_no); 134 - req->sequence_no = atomic_read(&ctrl->req_seq_no); 135 - list_add_tail(&req->list, &ctrl->list); 136 - spin_unlock_bh(&ctrl->info_list_lock); 137 - } 138 - 139 - /* Compare and remove request */ 140 - static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, 141 - struct cfctrl_request_info *req) 142 - { 143 - struct cfctrl_request_info *p, *tmp, *first; 144 - 145 - first = list_first_entry(&ctrl->list, struct cfctrl_request_info, list); 146 - 147 - list_for_each_entry_safe(p, tmp, &ctrl->list, list) { 148 - if (cfctrl_req_eq(req, p)) { 149 - if (p != first) 150 - pr_warn("Requests are not received in order\n"); 151 - 152 - atomic_set(&ctrl->rsp_seq_no, 153 - p->sequence_no); 154 - list_del(&p->list); 155 - goto out; 156 - } 157 - } 158 - p = NULL; 159 - out: 160 - return p; 161 - } 162 - 163 - struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer) 164 - { 165 - struct cfctrl *this = container_obj(layer); 166 - return &this->res; 167 - } 168 - 169 - static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) 170 - { 171 - info->hdr_len = 0; 172 - info->channel_id = cfctrl->serv.layer.id; 173 - info->dev_info = &cfctrl->serv.dev_info; 174 - } 175 - 176 - void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) 177 - { 178 - struct cfpkt *pkt; 179 - struct cfctrl *cfctrl = container_obj(layer); 180 - struct cflayer *dn = cfctrl->serv.layer.dn; 181 - 182 - if (!dn) { 183 - pr_debug("not able to send enum request\n"); 184 - return; 185 - } 186 - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); 187 - if (!pkt) 188 - return; 189 - caif_assert(offsetof(struct cfctrl, serv.layer) == 0); 190 - init_info(cfpkt_info(pkt), cfctrl); 191 - cfpkt_info(pkt)->dev_info->id = physlinkid; 192 - cfctrl->serv.dev_info.id = physlinkid; 193 - cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM); 194 - cfpkt_addbdy(pkt, physlinkid); 195 - cfpkt_set_prio(pkt, TC_PRIO_CONTROL); 196 - dn->transmit(dn, pkt); 197 - } 198 - 199 - int cfctrl_linkup_request(struct cflayer *layer, 200 - struct cfctrl_link_param *param, 201 - struct cflayer *user_layer) 202 - { 203 - struct cfctrl *cfctrl = container_obj(layer); 204 - struct cflayer *dn = cfctrl->serv.layer.dn; 205 - char utility_name[UTILITY_NAME_LENGTH]; 206 - struct cfctrl_request_info *req; 207 - struct cfpkt *pkt; 208 - u32 tmp32; 209 - u16 tmp16; 210 - u8 tmp8; 211 - int ret; 212 - 213 - if (!dn) { 214 - pr_debug("not able to send linkup request\n"); 215 - return -ENODEV; 216 - } 217 - 218 - if (cfctrl_cancel_req(layer, user_layer) > 0) { 219 - /* Slight Paranoia, check if already connecting */ 220 - pr_err("Duplicate connect request for same client\n"); 221 - WARN_ON(1); 222 - return -EALREADY; 223 - } 224 - 225 - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); 226 - if (!pkt) 227 - return -ENOMEM; 228 - cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); 229 - cfpkt_addbdy(pkt, (param->chtype << 4) | param->linktype); 230 - cfpkt_addbdy(pkt, (param->priority << 3) | param->phyid); 231 - cfpkt_addbdy(pkt, param->endpoint & 0x03); 232 - 233 - switch (param->linktype) { 234 - case CFCTRL_SRV_VEI: 235 - break; 236 - case CFCTRL_SRV_VIDEO: 237 - cfpkt_addbdy(pkt, (u8) param->u.video.connid); 238 - break; 239 - case CFCTRL_SRV_DBG: 240 - break; 241 - case CFCTRL_SRV_DATAGRAM: 242 - tmp32 = cpu_to_le32(param->u.datagram.connid); 243 - cfpkt_add_body(pkt, &tmp32, 4); 244 - break; 245 - case CFCTRL_SRV_RFM: 246 - /* Construct a frame, convert DatagramConnectionID to network 247 - * format long and copy it out... 248 - */ 249 - tmp32 = cpu_to_le32(param->u.rfm.connid); 250 - cfpkt_add_body(pkt, &tmp32, 4); 251 - /* Add volume name, including zero termination... */ 252 - cfpkt_add_body(pkt, param->u.rfm.volume, 253 - strlen(param->u.rfm.volume) + 1); 254 - break; 255 - case CFCTRL_SRV_UTIL: 256 - tmp16 = cpu_to_le16(param->u.utility.fifosize_kb); 257 - cfpkt_add_body(pkt, &tmp16, 2); 258 - tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); 259 - cfpkt_add_body(pkt, &tmp16, 2); 260 - strscpy_pad(utility_name, param->u.utility.name); 261 - cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH); 262 - tmp8 = param->u.utility.paramlen; 263 - cfpkt_add_body(pkt, &tmp8, 1); 264 - cfpkt_add_body(pkt, param->u.utility.params, 265 - param->u.utility.paramlen); 266 - break; 267 - default: 268 - pr_warn("Request setup of bad link type = %d\n", 269 - param->linktype); 270 - cfpkt_destroy(pkt); 271 - return -EINVAL; 272 - } 273 - req = kzalloc_obj(*req); 274 - if (!req) { 275 - cfpkt_destroy(pkt); 276 - return -ENOMEM; 277 - } 278 - 279 - req->client_layer = user_layer; 280 - req->cmd = CFCTRL_CMD_LINK_SETUP; 281 - req->param = *param; 282 - cfctrl_insert_req(cfctrl, req); 283 - init_info(cfpkt_info(pkt), cfctrl); 284 - /* 285 - * NOTE:Always send linkup and linkdown request on the same 286 - * device as the payload. Otherwise old queued up payload 287 - * might arrive with the newly allocated channel ID. 288 - */ 289 - cfpkt_info(pkt)->dev_info->id = param->phyid; 290 - cfpkt_set_prio(pkt, TC_PRIO_CONTROL); 291 - ret = 292 - dn->transmit(dn, pkt); 293 - if (ret < 0) { 294 - int count; 295 - 296 - count = cfctrl_cancel_req(&cfctrl->serv.layer, 297 - user_layer); 298 - if (count != 1) { 299 - pr_err("Could not remove request (%d)", count); 300 - return -ENODEV; 301 - } 302 - } 303 - return 0; 304 - } 305 - 306 - int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, 307 - struct cflayer *client) 308 - { 309 - int ret; 310 - struct cfpkt *pkt; 311 - struct cfctrl *cfctrl = container_obj(layer); 312 - struct cflayer *dn = cfctrl->serv.layer.dn; 313 - 314 - if (!dn) { 315 - pr_debug("not able to send link-down request\n"); 316 - return -ENODEV; 317 - } 318 - pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); 319 - if (!pkt) 320 - return -ENOMEM; 321 - cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); 322 - cfpkt_addbdy(pkt, channelid); 323 - init_info(cfpkt_info(pkt), cfctrl); 324 - cfpkt_set_prio(pkt, TC_PRIO_CONTROL); 325 - ret = 326 - dn->transmit(dn, pkt); 327 - #ifndef CAIF_NO_LOOP 328 - cfctrl->loop_linkused[channelid] = 0; 329 - #endif 330 - return ret; 331 - } 332 - 333 - int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) 334 - { 335 - struct cfctrl_request_info *p, *tmp; 336 - struct cfctrl *ctrl = container_obj(layr); 337 - int found = 0; 338 - spin_lock_bh(&ctrl->info_list_lock); 339 - 340 - list_for_each_entry_safe(p, tmp, &ctrl->list, list) { 341 - if (p->client_layer == adap_layer) { 342 - list_del(&p->list); 343 - kfree(p); 344 - found++; 345 - } 346 - } 347 - 348 - spin_unlock_bh(&ctrl->info_list_lock); 349 - return found; 350 - } 351 - 352 - static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp) 353 - { 354 - u8 len; 355 - u8 linkid = 0; 356 - enum cfctrl_srv serv; 357 - enum cfctrl_srv servtype; 358 - u8 endpoint; 359 - u8 physlinkid; 360 - u8 prio; 361 - u8 tmp; 362 - u8 *cp; 363 - int i; 364 - struct cfctrl_link_param linkparam; 365 - struct cfctrl_request_info rsp, *req; 366 - 367 - memset(&linkparam, 0, sizeof(linkparam)); 368 - 369 - tmp = cfpkt_extr_head_u8(pkt); 370 - 371 - serv = tmp & CFCTRL_SRV_MASK; 372 - linkparam.linktype = serv; 373 - 374 - servtype = tmp >> 4; 375 - linkparam.chtype = servtype; 376 - 377 - tmp = cfpkt_extr_head_u8(pkt); 378 - physlinkid = tmp & 0x07; 379 - prio = tmp >> 3; 380 - 381 - linkparam.priority = prio; 382 - linkparam.phyid = physlinkid; 383 - endpoint = cfpkt_extr_head_u8(pkt); 384 - linkparam.endpoint = endpoint & 0x03; 385 - 386 - switch (serv) { 387 - case CFCTRL_SRV_VEI: 388 - case CFCTRL_SRV_DBG: 389 - if (CFCTRL_ERR_BIT & cmdrsp) 390 - break; 391 - /* Link ID */ 392 - linkid = cfpkt_extr_head_u8(pkt); 393 - break; 394 - case CFCTRL_SRV_VIDEO: 395 - tmp = cfpkt_extr_head_u8(pkt); 396 - linkparam.u.video.connid = tmp; 397 - if (CFCTRL_ERR_BIT & cmdrsp) 398 - break; 399 - /* Link ID */ 400 - linkid = cfpkt_extr_head_u8(pkt); 401 - break; 402 - 403 - case CFCTRL_SRV_DATAGRAM: 404 - linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt); 405 - if (CFCTRL_ERR_BIT & cmdrsp) 406 - break; 407 - /* Link ID */ 408 - linkid = cfpkt_extr_head_u8(pkt); 409 - break; 410 - case CFCTRL_SRV_RFM: 411 - /* Construct a frame, convert 412 - * DatagramConnectionID 413 - * to network format long and copy it out... 414 - */ 415 - linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt); 416 - cp = (u8 *) linkparam.u.rfm.volume; 417 - for (tmp = cfpkt_extr_head_u8(pkt); 418 - cfpkt_more(pkt) && tmp != '\0'; 419 - tmp = cfpkt_extr_head_u8(pkt)) 420 - *cp++ = tmp; 421 - *cp = '\0'; 422 - 423 - if (CFCTRL_ERR_BIT & cmdrsp) 424 - break; 425 - /* Link ID */ 426 - linkid = cfpkt_extr_head_u8(pkt); 427 - 428 - break; 429 - case CFCTRL_SRV_UTIL: 430 - /* Construct a frame, convert 431 - * DatagramConnectionID 432 - * to network format long and copy it out... 433 - */ 434 - /* Fifosize KB */ 435 - linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt); 436 - /* Fifosize bufs */ 437 - linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt); 438 - /* name */ 439 - cp = (u8 *) linkparam.u.utility.name; 440 - caif_assert(sizeof(linkparam.u.utility.name) 441 - >= UTILITY_NAME_LENGTH); 442 - for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) { 443 - tmp = cfpkt_extr_head_u8(pkt); 444 - *cp++ = tmp; 445 - } 446 - /* Length */ 447 - len = cfpkt_extr_head_u8(pkt); 448 - linkparam.u.utility.paramlen = len; 449 - /* Param Data */ 450 - cp = linkparam.u.utility.params; 451 - while (cfpkt_more(pkt) && len--) { 452 - tmp = cfpkt_extr_head_u8(pkt); 453 - *cp++ = tmp; 454 - } 455 - if (CFCTRL_ERR_BIT & cmdrsp) 456 - break; 457 - /* Link ID */ 458 - linkid = cfpkt_extr_head_u8(pkt); 459 - /* Length */ 460 - len = cfpkt_extr_head_u8(pkt); 461 - /* Param Data */ 462 - cfpkt_extr_head(pkt, NULL, len); 463 - break; 464 - default: 465 - pr_warn("Request setup, invalid type (%d)\n", serv); 466 - return -1; 467 - } 468 - 469 - rsp.cmd = CFCTRL_CMD_LINK_SETUP; 470 - rsp.param = linkparam; 471 - spin_lock_bh(&cfctrl->info_list_lock); 472 - req = cfctrl_remove_req(cfctrl, &rsp); 473 - 474 - if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || 475 - cfpkt_erroneous(pkt)) { 476 - pr_err("Invalid O/E bit or parse error " 477 - "on CAIF control channel\n"); 478 - cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, 479 - req ? req->client_layer : NULL); 480 - } else { 481 - cfctrl->res.linksetup_rsp(cfctrl->serv.layer.up, linkid, 482 - serv, physlinkid, 483 - req ? req->client_layer : NULL); 484 - } 485 - 486 - kfree(req); 487 - 488 - spin_unlock_bh(&cfctrl->info_list_lock); 489 - 490 - return 0; 491 - } 492 - 493 - static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) 494 - { 495 - u8 cmdrsp; 496 - u8 cmd; 497 - int ret = 0; 498 - u8 linkid = 0; 499 - struct cfctrl *cfctrl = container_obj(layer); 500 - 501 - cmdrsp = cfpkt_extr_head_u8(pkt); 502 - cmd = cmdrsp & CFCTRL_CMD_MASK; 503 - if (cmd != CFCTRL_CMD_LINK_ERR 504 - && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp) 505 - && CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) { 506 - if (handle_loop(cfctrl, cmd, pkt) != 0) 507 - cmdrsp |= CFCTRL_ERR_BIT; 508 - } 509 - 510 - switch (cmd) { 511 - case CFCTRL_CMD_LINK_SETUP: 512 - ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp); 513 - break; 514 - case CFCTRL_CMD_LINK_DESTROY: 515 - linkid = cfpkt_extr_head_u8(pkt); 516 - cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); 517 - break; 518 - case CFCTRL_CMD_LINK_ERR: 519 - pr_err("Frame Error Indication received\n"); 520 - cfctrl->res.linkerror_ind(); 521 - break; 522 - case CFCTRL_CMD_ENUM: 523 - cfctrl->res.enum_rsp(); 524 - break; 525 - case CFCTRL_CMD_SLEEP: 526 - cfctrl->res.sleep_rsp(); 527 - break; 528 - case CFCTRL_CMD_WAKE: 529 - cfctrl->res.wake_rsp(); 530 - break; 531 - case CFCTRL_CMD_LINK_RECONF: 532 - cfctrl->res.restart_rsp(); 533 - break; 534 - case CFCTRL_CMD_RADIO_SET: 535 - cfctrl->res.radioset_rsp(); 536 - break; 537 - default: 538 - pr_err("Unrecognized Control Frame\n"); 539 - ret = -1; 540 - goto error; 541 - } 542 - error: 543 - cfpkt_destroy(pkt); 544 - return ret; 545 - } 546 - 547 - static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 548 - int phyid) 549 - { 550 - struct cfctrl *this = container_obj(layr); 551 - switch (ctrl) { 552 - case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: 553 - case CAIF_CTRLCMD_FLOW_OFF_IND: 554 - spin_lock_bh(&this->info_list_lock); 555 - if (!list_empty(&this->list)) 556 - pr_debug("Received flow off in control layer\n"); 557 - spin_unlock_bh(&this->info_list_lock); 558 - break; 559 - case _CAIF_CTRLCMD_PHYIF_DOWN_IND: { 560 - struct cfctrl_request_info *p, *tmp; 561 - 562 - /* Find all connect request and report failure */ 563 - spin_lock_bh(&this->info_list_lock); 564 - list_for_each_entry_safe(p, tmp, &this->list, list) { 565 - if (p->param.phyid == phyid) { 566 - list_del(&p->list); 567 - p->client_layer->ctrlcmd(p->client_layer, 568 - CAIF_CTRLCMD_INIT_FAIL_RSP, 569 - phyid); 570 - kfree(p); 571 - } 572 - } 573 - spin_unlock_bh(&this->info_list_lock); 574 - break; 575 - } 576 - default: 577 - break; 578 - } 579 - } 580 - 581 - #ifndef CAIF_NO_LOOP 582 - static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) 583 - { 584 - static int last_linkid; 585 - static int dec; 586 - u8 linkid, linktype, tmp; 587 - switch (cmd) { 588 - case CFCTRL_CMD_LINK_SETUP: 589 - spin_lock_bh(&ctrl->loop_linkid_lock); 590 - if (!dec) { 591 - for (linkid = last_linkid + 1; linkid < 254; linkid++) 592 - if (!ctrl->loop_linkused[linkid]) 593 - goto found; 594 - } 595 - dec = 1; 596 - for (linkid = last_linkid - 1; linkid > 1; linkid--) 597 - if (!ctrl->loop_linkused[linkid]) 598 - goto found; 599 - spin_unlock_bh(&ctrl->loop_linkid_lock); 600 - return -1; 601 - found: 602 - if (linkid < 10) 603 - dec = 0; 604 - 605 - if (!ctrl->loop_linkused[linkid]) 606 - ctrl->loop_linkused[linkid] = 1; 607 - 608 - last_linkid = linkid; 609 - 610 - cfpkt_add_trail(pkt, &linkid, 1); 611 - spin_unlock_bh(&ctrl->loop_linkid_lock); 612 - cfpkt_peek_head(pkt, &linktype, 1); 613 - if (linktype == CFCTRL_SRV_UTIL) { 614 - tmp = 0x01; 615 - cfpkt_add_trail(pkt, &tmp, 1); 616 - cfpkt_add_trail(pkt, &tmp, 1); 617 - } 618 - break; 619 - 620 - case CFCTRL_CMD_LINK_DESTROY: 621 - spin_lock_bh(&ctrl->loop_linkid_lock); 622 - cfpkt_peek_head(pkt, &linkid, 1); 623 - ctrl->loop_linkused[linkid] = 0; 624 - spin_unlock_bh(&ctrl->loop_linkid_lock); 625 - break; 626 - default: 627 - break; 628 - } 629 - return 0; 630 - } 631 - #endif
-55
net/caif/cfdbgl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/slab.h> 11 - #include <net/caif/caif_layer.h> 12 - #include <net/caif/cfsrvl.h> 13 - #include <net/caif/cfpkt.h> 14 - 15 - #define container_obj(layr) ((struct cfsrvl *) layr) 16 - 17 - static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); 18 - static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); 19 - 20 - struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info) 21 - { 22 - struct cfsrvl *dbg = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); 23 - if (!dbg) 24 - return NULL; 25 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 26 - cfsrvl_init(dbg, channel_id, dev_info, false); 27 - dbg->layer.receive = cfdbgl_receive; 28 - dbg->layer.transmit = cfdbgl_transmit; 29 - snprintf(dbg->layer.name, CAIF_LAYER_NAME_SZ, "dbg%d", channel_id); 30 - return &dbg->layer; 31 - } 32 - 33 - static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) 34 - { 35 - return layr->up->receive(layr->up, pkt); 36 - } 37 - 38 - static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) 39 - { 40 - struct cfsrvl *service = container_obj(layr); 41 - struct caif_payload_info *info; 42 - int ret; 43 - 44 - if (!cfsrvl_ready(service, &ret)) { 45 - cfpkt_destroy(pkt); 46 - return ret; 47 - } 48 - 49 - /* Add info for MUX-layer to route the packet out */ 50 - info = cfpkt_info(pkt); 51 - info->channel_id = service->layer.id; 52 - info->dev_info = &service->dev_info; 53 - 54 - return layr->dn->transmit(layr->dn, pkt); 55 - }
-113
net/caif/cfdgml.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/spinlock.h> 11 - #include <linux/slab.h> 12 - #include <net/caif/caif_layer.h> 13 - #include <net/caif/cfsrvl.h> 14 - #include <net/caif/cfpkt.h> 15 - 16 - 17 - #define container_obj(layr) ((struct cfsrvl *) layr) 18 - 19 - #define DGM_CMD_BIT 0x80 20 - #define DGM_FLOW_OFF 0x81 21 - #define DGM_FLOW_ON 0x80 22 - #define DGM_MTU 1500 23 - 24 - static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt); 25 - static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt); 26 - 27 - struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info) 28 - { 29 - struct cfsrvl *dgm = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); 30 - if (!dgm) 31 - return NULL; 32 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 33 - cfsrvl_init(dgm, channel_id, dev_info, true); 34 - dgm->layer.receive = cfdgml_receive; 35 - dgm->layer.transmit = cfdgml_transmit; 36 - snprintf(dgm->layer.name, CAIF_LAYER_NAME_SZ, "dgm%d", channel_id); 37 - return &dgm->layer; 38 - } 39 - 40 - static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) 41 - { 42 - u8 cmd = -1; 43 - u8 dgmhdr[3]; 44 - int ret; 45 - caif_assert(layr->up != NULL); 46 - caif_assert(layr->receive != NULL); 47 - caif_assert(layr->ctrlcmd != NULL); 48 - 49 - if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { 50 - pr_err("Packet is erroneous!\n"); 51 - cfpkt_destroy(pkt); 52 - return -EPROTO; 53 - } 54 - 55 - if ((cmd & DGM_CMD_BIT) == 0) { 56 - if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) { 57 - pr_err("Packet is erroneous!\n"); 58 - cfpkt_destroy(pkt); 59 - return -EPROTO; 60 - } 61 - ret = layr->up->receive(layr->up, pkt); 62 - return ret; 63 - } 64 - 65 - switch (cmd) { 66 - case DGM_FLOW_OFF: /* FLOW OFF */ 67 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0); 68 - cfpkt_destroy(pkt); 69 - return 0; 70 - case DGM_FLOW_ON: /* FLOW ON */ 71 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0); 72 - cfpkt_destroy(pkt); 73 - return 0; 74 - default: 75 - cfpkt_destroy(pkt); 76 - pr_info("Unknown datagram control %d (0x%x)\n", cmd, cmd); 77 - return -EPROTO; 78 - } 79 - } 80 - 81 - static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) 82 - { 83 - u8 packet_type; 84 - u32 zero = 0; 85 - struct caif_payload_info *info; 86 - struct cfsrvl *service = container_obj(layr); 87 - int ret; 88 - 89 - if (!cfsrvl_ready(service, &ret)) { 90 - cfpkt_destroy(pkt); 91 - return ret; 92 - } 93 - 94 - /* STE Modem cannot handle more than 1500 bytes datagrams */ 95 - if (cfpkt_getlen(pkt) > DGM_MTU) { 96 - cfpkt_destroy(pkt); 97 - return -EMSGSIZE; 98 - } 99 - 100 - cfpkt_add_head(pkt, &zero, 3); 101 - packet_type = 0x08; /* B9 set - UNCLASSIFIED */ 102 - cfpkt_add_head(pkt, &packet_type, 1); 103 - 104 - /* Add info for MUX-layer to route the packet out. */ 105 - info = cfpkt_info(pkt); 106 - info->channel_id = service->layer.id; 107 - /* To optimize alignment, we add up the size of CAIF header 108 - * before payload. 109 - */ 110 - info->hdr_len = 4; 111 - info->dev_info = &service->dev_info; 112 - return layr->dn->transmit(layr->dn, pkt); 113 - }
-204
net/caif/cffrml.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * CAIF Framing Layer. 4 - * 5 - * Copyright (C) ST-Ericsson AB 2010 6 - * Author: Sjur Brendeland 7 - */ 8 - 9 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 10 - 11 - #include <linux/stddef.h> 12 - #include <linux/spinlock.h> 13 - #include <linux/slab.h> 14 - #include <linux/crc-ccitt.h> 15 - #include <linux/netdevice.h> 16 - #include <net/caif/caif_layer.h> 17 - #include <net/caif/cfpkt.h> 18 - #include <net/caif/cffrml.h> 19 - 20 - #define container_obj(layr) container_of(layr, struct cffrml, layer) 21 - 22 - struct cffrml { 23 - struct cflayer layer; 24 - bool dofcs; /* !< FCS active */ 25 - int __percpu *pcpu_refcnt; 26 - }; 27 - 28 - static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt); 29 - static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt); 30 - static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 31 - int phyid); 32 - 33 - static u32 cffrml_rcv_error; 34 - static u32 cffrml_rcv_checsum_error; 35 - struct cflayer *cffrml_create(u16 phyid, bool use_fcs) 36 - { 37 - struct cffrml *this = kzalloc_obj(struct cffrml, GFP_ATOMIC); 38 - if (!this) 39 - return NULL; 40 - this->pcpu_refcnt = alloc_percpu(int); 41 - if (this->pcpu_refcnt == NULL) { 42 - kfree(this); 43 - return NULL; 44 - } 45 - 46 - caif_assert(offsetof(struct cffrml, layer) == 0); 47 - 48 - this->layer.receive = cffrml_receive; 49 - this->layer.transmit = cffrml_transmit; 50 - this->layer.ctrlcmd = cffrml_ctrlcmd; 51 - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "frm%d", phyid); 52 - this->dofcs = use_fcs; 53 - this->layer.id = phyid; 54 - return (struct cflayer *) this; 55 - } 56 - 57 - void cffrml_free(struct cflayer *layer) 58 - { 59 - struct cffrml *this = container_obj(layer); 60 - free_percpu(this->pcpu_refcnt); 61 - kfree(layer); 62 - } 63 - 64 - void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up) 65 - { 66 - this->up = up; 67 - } 68 - 69 - void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn) 70 - { 71 - this->dn = dn; 72 - } 73 - 74 - static u16 cffrml_checksum(u16 chks, void *buf, u16 len) 75 - { 76 - /* FIXME: FCS should be moved to glue in order to use OS-Specific 77 - * solutions 78 - */ 79 - return crc_ccitt(chks, buf, len); 80 - } 81 - 82 - static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) 83 - { 84 - u16 tmp; 85 - u16 len; 86 - u16 hdrchks; 87 - int pktchks; 88 - struct cffrml *this; 89 - this = container_obj(layr); 90 - 91 - cfpkt_extr_head(pkt, &tmp, 2); 92 - len = le16_to_cpu(tmp); 93 - 94 - /* Subtract for FCS on length if FCS is not used. */ 95 - if (!this->dofcs) { 96 - if (len < 2) { 97 - ++cffrml_rcv_error; 98 - pr_err("Invalid frame length (%d)\n", len); 99 - cfpkt_destroy(pkt); 100 - return -EPROTO; 101 - } 102 - len -= 2; 103 - } 104 - 105 - if (cfpkt_setlen(pkt, len) < 0) { 106 - ++cffrml_rcv_error; 107 - pr_err("Framing length error (%d)\n", len); 108 - cfpkt_destroy(pkt); 109 - return -EPROTO; 110 - } 111 - /* 112 - * Don't do extract if FCS is false, rather do setlen - then we don't 113 - * get a cache-miss. 114 - */ 115 - if (this->dofcs) { 116 - cfpkt_extr_trail(pkt, &tmp, 2); 117 - hdrchks = le16_to_cpu(tmp); 118 - pktchks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); 119 - if (pktchks != hdrchks) { 120 - cfpkt_add_trail(pkt, &tmp, 2); 121 - ++cffrml_rcv_error; 122 - ++cffrml_rcv_checsum_error; 123 - pr_info("Frame checksum error (0x%x != 0x%x)\n", 124 - hdrchks, pktchks); 125 - return -EILSEQ; 126 - } 127 - } 128 - if (cfpkt_erroneous(pkt)) { 129 - ++cffrml_rcv_error; 130 - pr_err("Packet is erroneous!\n"); 131 - cfpkt_destroy(pkt); 132 - return -EPROTO; 133 - } 134 - 135 - if (layr->up == NULL) { 136 - pr_err("Layr up is missing!\n"); 137 - cfpkt_destroy(pkt); 138 - return -EINVAL; 139 - } 140 - 141 - return layr->up->receive(layr->up, pkt); 142 - } 143 - 144 - static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) 145 - { 146 - u16 chks; 147 - u16 len; 148 - __le16 data; 149 - 150 - struct cffrml *this = container_obj(layr); 151 - if (this->dofcs) { 152 - chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); 153 - data = cpu_to_le16(chks); 154 - cfpkt_add_trail(pkt, &data, 2); 155 - } else { 156 - cfpkt_pad_trail(pkt, 2); 157 - } 158 - len = cfpkt_getlen(pkt); 159 - data = cpu_to_le16(len); 160 - cfpkt_add_head(pkt, &data, 2); 161 - cfpkt_info(pkt)->hdr_len += 2; 162 - if (cfpkt_erroneous(pkt)) { 163 - pr_err("Packet is erroneous!\n"); 164 - cfpkt_destroy(pkt); 165 - return -EPROTO; 166 - } 167 - 168 - if (layr->dn == NULL) { 169 - cfpkt_destroy(pkt); 170 - return -ENODEV; 171 - 172 - } 173 - return layr->dn->transmit(layr->dn, pkt); 174 - } 175 - 176 - static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 177 - int phyid) 178 - { 179 - if (layr->up && layr->up->ctrlcmd) 180 - layr->up->ctrlcmd(layr->up, ctrl, layr->id); 181 - } 182 - 183 - void cffrml_put(struct cflayer *layr) 184 - { 185 - struct cffrml *this = container_obj(layr); 186 - if (layr != NULL && this->pcpu_refcnt != NULL) 187 - this_cpu_dec(*this->pcpu_refcnt); 188 - } 189 - 190 - void cffrml_hold(struct cflayer *layr) 191 - { 192 - struct cffrml *this = container_obj(layr); 193 - if (layr != NULL && this->pcpu_refcnt != NULL) 194 - this_cpu_inc(*this->pcpu_refcnt); 195 - } 196 - 197 - int cffrml_refcnt_read(struct cflayer *layr) 198 - { 199 - int i, refcnt = 0; 200 - struct cffrml *this = container_obj(layr); 201 - for_each_possible_cpu(i) 202 - refcnt += *per_cpu_ptr(this->pcpu_refcnt, i); 203 - return refcnt; 204 - }
-267
net/caif/cfmuxl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/spinlock.h> 11 - #include <linux/slab.h> 12 - #include <linux/rculist.h> 13 - #include <net/caif/cfpkt.h> 14 - #include <net/caif/cfmuxl.h> 15 - #include <net/caif/cfsrvl.h> 16 - #include <net/caif/cffrml.h> 17 - 18 - #define container_obj(layr) container_of(layr, struct cfmuxl, layer) 19 - 20 - #define CAIF_CTRL_CHANNEL 0 21 - #define UP_CACHE_SIZE 8 22 - #define DN_CACHE_SIZE 8 23 - 24 - struct cfmuxl { 25 - struct cflayer layer; 26 - struct list_head srvl_list; 27 - struct list_head frml_list; 28 - struct cflayer *up_cache[UP_CACHE_SIZE]; 29 - struct cflayer *dn_cache[DN_CACHE_SIZE]; 30 - /* 31 - * Set when inserting or removing downwards layers. 32 - */ 33 - spinlock_t transmit_lock; 34 - 35 - /* 36 - * Set when inserting or removing upwards layers. 37 - */ 38 - spinlock_t receive_lock; 39 - 40 - }; 41 - 42 - static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt); 43 - static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt); 44 - static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 45 - int phyid); 46 - static struct cflayer *get_up(struct cfmuxl *muxl, u16 id); 47 - 48 - struct cflayer *cfmuxl_create(void) 49 - { 50 - struct cfmuxl *this = kzalloc_obj(struct cfmuxl, GFP_ATOMIC); 51 - 52 - if (!this) 53 - return NULL; 54 - this->layer.receive = cfmuxl_receive; 55 - this->layer.transmit = cfmuxl_transmit; 56 - this->layer.ctrlcmd = cfmuxl_ctrlcmd; 57 - INIT_LIST_HEAD(&this->srvl_list); 58 - INIT_LIST_HEAD(&this->frml_list); 59 - spin_lock_init(&this->transmit_lock); 60 - spin_lock_init(&this->receive_lock); 61 - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "mux"); 62 - return &this->layer; 63 - } 64 - 65 - int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid) 66 - { 67 - struct cfmuxl *muxl = (struct cfmuxl *) layr; 68 - 69 - spin_lock_bh(&muxl->transmit_lock); 70 - list_add_rcu(&dn->node, &muxl->frml_list); 71 - spin_unlock_bh(&muxl->transmit_lock); 72 - return 0; 73 - } 74 - 75 - static struct cflayer *get_from_id(struct list_head *list, u16 id) 76 - { 77 - struct cflayer *lyr; 78 - list_for_each_entry_rcu(lyr, list, node) { 79 - if (lyr->id == id) 80 - return lyr; 81 - } 82 - 83 - return NULL; 84 - } 85 - 86 - int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) 87 - { 88 - struct cfmuxl *muxl = container_obj(layr); 89 - struct cflayer *old; 90 - 91 - spin_lock_bh(&muxl->receive_lock); 92 - 93 - /* Two entries with same id is wrong, so remove old layer from mux */ 94 - old = get_from_id(&muxl->srvl_list, linkid); 95 - if (old != NULL) 96 - list_del_rcu(&old->node); 97 - 98 - list_add_rcu(&up->node, &muxl->srvl_list); 99 - spin_unlock_bh(&muxl->receive_lock); 100 - 101 - return 0; 102 - } 103 - 104 - struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid) 105 - { 106 - struct cfmuxl *muxl = container_obj(layr); 107 - struct cflayer *dn; 108 - int idx = phyid % DN_CACHE_SIZE; 109 - 110 - spin_lock_bh(&muxl->transmit_lock); 111 - RCU_INIT_POINTER(muxl->dn_cache[idx], NULL); 112 - dn = get_from_id(&muxl->frml_list, phyid); 113 - if (dn == NULL) 114 - goto out; 115 - 116 - list_del_rcu(&dn->node); 117 - caif_assert(dn != NULL); 118 - out: 119 - spin_unlock_bh(&muxl->transmit_lock); 120 - return dn; 121 - } 122 - 123 - static struct cflayer *get_up(struct cfmuxl *muxl, u16 id) 124 - { 125 - struct cflayer *up; 126 - int idx = id % UP_CACHE_SIZE; 127 - up = rcu_dereference(muxl->up_cache[idx]); 128 - if (up == NULL || up->id != id) { 129 - spin_lock_bh(&muxl->receive_lock); 130 - up = get_from_id(&muxl->srvl_list, id); 131 - rcu_assign_pointer(muxl->up_cache[idx], up); 132 - spin_unlock_bh(&muxl->receive_lock); 133 - } 134 - return up; 135 - } 136 - 137 - static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info) 138 - { 139 - struct cflayer *dn; 140 - int idx = dev_info->id % DN_CACHE_SIZE; 141 - dn = rcu_dereference(muxl->dn_cache[idx]); 142 - if (dn == NULL || dn->id != dev_info->id) { 143 - spin_lock_bh(&muxl->transmit_lock); 144 - dn = get_from_id(&muxl->frml_list, dev_info->id); 145 - rcu_assign_pointer(muxl->dn_cache[idx], dn); 146 - spin_unlock_bh(&muxl->transmit_lock); 147 - } 148 - return dn; 149 - } 150 - 151 - struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id) 152 - { 153 - struct cflayer *up; 154 - struct cfmuxl *muxl = container_obj(layr); 155 - int idx = id % UP_CACHE_SIZE; 156 - 157 - if (id == 0) { 158 - pr_warn("Trying to remove control layer\n"); 159 - return NULL; 160 - } 161 - 162 - spin_lock_bh(&muxl->receive_lock); 163 - up = get_from_id(&muxl->srvl_list, id); 164 - if (up == NULL) 165 - goto out; 166 - 167 - RCU_INIT_POINTER(muxl->up_cache[idx], NULL); 168 - list_del_rcu(&up->node); 169 - out: 170 - spin_unlock_bh(&muxl->receive_lock); 171 - return up; 172 - } 173 - 174 - static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) 175 - { 176 - int ret; 177 - struct cfmuxl *muxl = container_obj(layr); 178 - u8 id; 179 - struct cflayer *up; 180 - if (cfpkt_extr_head(pkt, &id, 1) < 0) { 181 - pr_err("erroneous Caif Packet\n"); 182 - cfpkt_destroy(pkt); 183 - return -EPROTO; 184 - } 185 - rcu_read_lock(); 186 - up = get_up(muxl, id); 187 - 188 - if (up == NULL) { 189 - pr_debug("Received data on unknown link ID = %d (0x%x)" 190 - " up == NULL", id, id); 191 - cfpkt_destroy(pkt); 192 - /* 193 - * Don't return ERROR, since modem misbehaves and sends out 194 - * flow on before linksetup response. 195 - */ 196 - 197 - rcu_read_unlock(); 198 - return /* CFGLU_EPROT; */ 0; 199 - } 200 - 201 - /* We can't hold rcu_lock during receive, so take a ref count instead */ 202 - cfsrvl_get(up); 203 - rcu_read_unlock(); 204 - 205 - ret = up->receive(up, pkt); 206 - 207 - cfsrvl_put(up); 208 - return ret; 209 - } 210 - 211 - static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) 212 - { 213 - struct cfmuxl *muxl = container_obj(layr); 214 - int err; 215 - u8 linkid; 216 - struct cflayer *dn; 217 - struct caif_payload_info *info = cfpkt_info(pkt); 218 - BUG_ON(!info); 219 - 220 - rcu_read_lock(); 221 - 222 - dn = get_dn(muxl, info->dev_info); 223 - if (dn == NULL) { 224 - pr_debug("Send data on unknown phy ID = %d (0x%x)\n", 225 - info->dev_info->id, info->dev_info->id); 226 - rcu_read_unlock(); 227 - cfpkt_destroy(pkt); 228 - return -ENOTCONN; 229 - } 230 - 231 - info->hdr_len += 1; 232 - linkid = info->channel_id; 233 - cfpkt_add_head(pkt, &linkid, 1); 234 - 235 - /* We can't hold rcu_lock during receive, so take a ref count instead */ 236 - cffrml_hold(dn); 237 - 238 - rcu_read_unlock(); 239 - 240 - err = dn->transmit(dn, pkt); 241 - 242 - cffrml_put(dn); 243 - return err; 244 - } 245 - 246 - static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 247 - int phyid) 248 - { 249 - struct cfmuxl *muxl = container_obj(layr); 250 - struct cflayer *layer; 251 - 252 - rcu_read_lock(); 253 - list_for_each_entry_rcu(layer, &muxl->srvl_list, node) { 254 - 255 - if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { 256 - 257 - if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND || 258 - ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && 259 - layer->id != 0) 260 - cfmuxl_remove_uplayer(layr, layer->id); 261 - 262 - /* NOTE: ctrlcmd is not allowed to block */ 263 - layer->ctrlcmd(layer, ctrl, phyid); 264 - } 265 - } 266 - rcu_read_unlock(); 267 - }
-373
net/caif/cfpkt_skbuff.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/string.h> 10 - #include <linux/skbuff.h> 11 - #include <linux/export.h> 12 - #include <net/caif/cfpkt.h> 13 - 14 - #define PKT_PREFIX 48 15 - #define PKT_POSTFIX 2 16 - #define PKT_LEN_WHEN_EXTENDING 128 17 - #define PKT_ERROR(pkt, errmsg) \ 18 - do { \ 19 - cfpkt_priv(pkt)->erronous = true; \ 20 - skb_reset_tail_pointer(&pkt->skb); \ 21 - pr_warn(errmsg); \ 22 - } while (0) 23 - 24 - /* 25 - * net/caif/ is generic and does not 26 - * understand SKB, so we do this typecast 27 - */ 28 - struct cfpkt { 29 - struct sk_buff skb; 30 - }; 31 - 32 - /* Private data inside SKB */ 33 - struct cfpkt_priv_data { 34 - struct dev_info dev_info; 35 - bool erronous; 36 - }; 37 - 38 - static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt) 39 - { 40 - return (struct cfpkt_priv_data *) pkt->skb.cb; 41 - } 42 - 43 - static inline bool is_erronous(struct cfpkt *pkt) 44 - { 45 - return cfpkt_priv(pkt)->erronous; 46 - } 47 - 48 - static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt) 49 - { 50 - return &pkt->skb; 51 - } 52 - 53 - static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb) 54 - { 55 - return (struct cfpkt *) skb; 56 - } 57 - 58 - struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt) 59 - { 60 - struct cfpkt *pkt = skb_to_pkt(nativepkt); 61 - cfpkt_priv(pkt)->erronous = false; 62 - return pkt; 63 - } 64 - EXPORT_SYMBOL(cfpkt_fromnative); 65 - 66 - void *cfpkt_tonative(struct cfpkt *pkt) 67 - { 68 - return (void *) pkt; 69 - } 70 - EXPORT_SYMBOL(cfpkt_tonative); 71 - 72 - static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx) 73 - { 74 - struct sk_buff *skb; 75 - 76 - skb = alloc_skb(len + pfx, GFP_ATOMIC); 77 - if (unlikely(skb == NULL)) 78 - return NULL; 79 - 80 - skb_reserve(skb, pfx); 81 - return skb_to_pkt(skb); 82 - } 83 - 84 - inline struct cfpkt *cfpkt_create(u16 len) 85 - { 86 - return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); 87 - } 88 - 89 - void cfpkt_destroy(struct cfpkt *pkt) 90 - { 91 - struct sk_buff *skb = pkt_to_skb(pkt); 92 - kfree_skb(skb); 93 - } 94 - 95 - inline bool cfpkt_more(struct cfpkt *pkt) 96 - { 97 - struct sk_buff *skb = pkt_to_skb(pkt); 98 - return skb->len > 0; 99 - } 100 - 101 - int cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len) 102 - { 103 - struct sk_buff *skb = pkt_to_skb(pkt); 104 - if (skb_headlen(skb) >= len) { 105 - memcpy(data, skb->data, len); 106 - return 0; 107 - } 108 - return !cfpkt_extr_head(pkt, data, len) && 109 - !cfpkt_add_head(pkt, data, len); 110 - } 111 - 112 - int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len) 113 - { 114 - struct sk_buff *skb = pkt_to_skb(pkt); 115 - u8 *from; 116 - if (unlikely(is_erronous(pkt))) 117 - return -EPROTO; 118 - 119 - if (unlikely(len > skb->len)) { 120 - PKT_ERROR(pkt, "read beyond end of packet\n"); 121 - return -EPROTO; 122 - } 123 - 124 - if (unlikely(len > skb_headlen(skb))) { 125 - if (unlikely(skb_linearize(skb) != 0)) { 126 - PKT_ERROR(pkt, "linearize failed\n"); 127 - return -EPROTO; 128 - } 129 - } 130 - from = skb_pull(skb, len); 131 - from -= len; 132 - if (data) 133 - memcpy(data, from, len); 134 - return 0; 135 - } 136 - EXPORT_SYMBOL(cfpkt_extr_head); 137 - 138 - int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len) 139 - { 140 - struct sk_buff *skb = pkt_to_skb(pkt); 141 - u8 *data = dta; 142 - u8 *from; 143 - if (unlikely(is_erronous(pkt))) 144 - return -EPROTO; 145 - 146 - if (unlikely(skb_linearize(skb) != 0)) { 147 - PKT_ERROR(pkt, "linearize failed\n"); 148 - return -EPROTO; 149 - } 150 - if (unlikely(skb->data + len > skb_tail_pointer(skb))) { 151 - PKT_ERROR(pkt, "read beyond end of packet\n"); 152 - return -EPROTO; 153 - } 154 - from = skb_tail_pointer(skb) - len; 155 - skb_trim(skb, skb->len - len); 156 - memcpy(data, from, len); 157 - return 0; 158 - } 159 - 160 - int cfpkt_pad_trail(struct cfpkt *pkt, u16 len) 161 - { 162 - return cfpkt_add_body(pkt, NULL, len); 163 - } 164 - 165 - int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) 166 - { 167 - struct sk_buff *skb = pkt_to_skb(pkt); 168 - struct sk_buff *lastskb; 169 - u8 *to; 170 - u16 addlen = 0; 171 - 172 - 173 - if (unlikely(is_erronous(pkt))) 174 - return -EPROTO; 175 - 176 - lastskb = skb; 177 - 178 - /* Check whether we need to add space at the tail */ 179 - if (unlikely(skb_tailroom(skb) < len)) { 180 - if (likely(len < PKT_LEN_WHEN_EXTENDING)) 181 - addlen = PKT_LEN_WHEN_EXTENDING; 182 - else 183 - addlen = len; 184 - } 185 - 186 - /* Check whether we need to change the SKB before writing to the tail */ 187 - if (unlikely((addlen > 0) || skb_cloned(skb) || skb_shared(skb))) { 188 - 189 - /* Make sure data is writable */ 190 - if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) { 191 - PKT_ERROR(pkt, "cow failed\n"); 192 - return -EPROTO; 193 - } 194 - } 195 - 196 - /* All set to put the last SKB and optionally write data there. */ 197 - to = pskb_put(skb, lastskb, len); 198 - if (likely(data)) 199 - memcpy(to, data, len); 200 - return 0; 201 - } 202 - 203 - inline int cfpkt_addbdy(struct cfpkt *pkt, u8 data) 204 - { 205 - return cfpkt_add_body(pkt, &data, 1); 206 - } 207 - 208 - int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) 209 - { 210 - struct sk_buff *skb = pkt_to_skb(pkt); 211 - struct sk_buff *lastskb; 212 - u8 *to; 213 - const u8 *data = data2; 214 - int ret; 215 - if (unlikely(is_erronous(pkt))) 216 - return -EPROTO; 217 - if (unlikely(skb_headroom(skb) < len)) { 218 - PKT_ERROR(pkt, "no headroom\n"); 219 - return -EPROTO; 220 - } 221 - 222 - /* Make sure data is writable */ 223 - ret = skb_cow_data(skb, 0, &lastskb); 224 - if (unlikely(ret < 0)) { 225 - PKT_ERROR(pkt, "cow failed\n"); 226 - return ret; 227 - } 228 - 229 - to = skb_push(skb, len); 230 - memcpy(to, data, len); 231 - return 0; 232 - } 233 - EXPORT_SYMBOL(cfpkt_add_head); 234 - 235 - inline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len) 236 - { 237 - return cfpkt_add_body(pkt, data, len); 238 - } 239 - 240 - inline u16 cfpkt_getlen(struct cfpkt *pkt) 241 - { 242 - struct sk_buff *skb = pkt_to_skb(pkt); 243 - return skb->len; 244 - } 245 - 246 - int cfpkt_iterate(struct cfpkt *pkt, 247 - u16 (*iter_func)(u16, void *, u16), 248 - u16 data) 249 - { 250 - /* 251 - * Don't care about the performance hit of linearizing, 252 - * Checksum should not be used on high-speed interfaces anyway. 253 - */ 254 - if (unlikely(is_erronous(pkt))) 255 - return -EPROTO; 256 - if (unlikely(skb_linearize(&pkt->skb) != 0)) { 257 - PKT_ERROR(pkt, "linearize failed\n"); 258 - return -EPROTO; 259 - } 260 - return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt)); 261 - } 262 - 263 - int cfpkt_setlen(struct cfpkt *pkt, u16 len) 264 - { 265 - struct sk_buff *skb = pkt_to_skb(pkt); 266 - 267 - 268 - if (unlikely(is_erronous(pkt))) 269 - return -EPROTO; 270 - 271 - if (likely(len <= skb->len)) { 272 - if (unlikely(skb->data_len)) 273 - ___pskb_trim(skb, len); 274 - else 275 - skb_trim(skb, len); 276 - 277 - return cfpkt_getlen(pkt); 278 - } 279 - 280 - /* Need to expand SKB */ 281 - if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len))) 282 - PKT_ERROR(pkt, "skb_pad_trail failed\n"); 283 - 284 - return cfpkt_getlen(pkt); 285 - } 286 - 287 - struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, 288 - struct cfpkt *addpkt, 289 - u16 expectlen) 290 - { 291 - struct sk_buff *dst = pkt_to_skb(dstpkt); 292 - struct sk_buff *add = pkt_to_skb(addpkt); 293 - u16 addlen = skb_headlen(add); 294 - u16 neededtailspace; 295 - struct sk_buff *tmp; 296 - u16 dstlen; 297 - u16 createlen; 298 - if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) { 299 - return dstpkt; 300 - } 301 - 302 - neededtailspace = max(expectlen, addlen); 303 - 304 - if (dst->tail + neededtailspace > dst->end) { 305 - /* Create a dumplicate of 'dst' with more tail space */ 306 - struct cfpkt *tmppkt; 307 - dstlen = skb_headlen(dst); 308 - createlen = dstlen + neededtailspace; 309 - tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX); 310 - if (tmppkt == NULL) 311 - return NULL; 312 - tmp = pkt_to_skb(tmppkt); 313 - skb_put_data(tmp, dst->data, dstlen); 314 - cfpkt_destroy(dstpkt); 315 - dst = tmp; 316 - } 317 - skb_put_data(dst, add->data, skb_headlen(add)); 318 - cfpkt_destroy(addpkt); 319 - return skb_to_pkt(dst); 320 - } 321 - 322 - struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) 323 - { 324 - struct sk_buff *skb2; 325 - struct sk_buff *skb = pkt_to_skb(pkt); 326 - struct cfpkt *tmppkt; 327 - u8 *split = skb->data + pos; 328 - u16 len2nd = skb_tail_pointer(skb) - split; 329 - 330 - if (unlikely(is_erronous(pkt))) 331 - return NULL; 332 - 333 - if (skb->data + pos > skb_tail_pointer(skb)) { 334 - PKT_ERROR(pkt, "trying to split beyond end of packet\n"); 335 - return NULL; 336 - } 337 - 338 - /* Create a new packet for the second part of the data */ 339 - tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX, 340 - PKT_PREFIX); 341 - if (tmppkt == NULL) 342 - return NULL; 343 - skb2 = pkt_to_skb(tmppkt); 344 - 345 - 346 - if (skb2 == NULL) 347 - return NULL; 348 - 349 - skb_put_data(skb2, split, len2nd); 350 - 351 - /* Reduce the length of the original packet */ 352 - skb_trim(skb, pos); 353 - 354 - skb2->priority = skb->priority; 355 - return skb_to_pkt(skb2); 356 - } 357 - 358 - bool cfpkt_erroneous(struct cfpkt *pkt) 359 - { 360 - return cfpkt_priv(pkt)->erronous; 361 - } 362 - 363 - struct caif_payload_info *cfpkt_info(struct cfpkt *pkt) 364 - { 365 - return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb; 366 - } 367 - EXPORT_SYMBOL(cfpkt_info); 368 - 369 - void cfpkt_set_prio(struct cfpkt *pkt, int prio) 370 - { 371 - pkt_to_skb(pkt)->priority = prio; 372 - } 373 - EXPORT_SYMBOL(cfpkt_set_prio);
-299
net/caif/cfrfml.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/spinlock.h> 11 - #include <linux/slab.h> 12 - #include <linux/unaligned.h> 13 - #include <net/caif/caif_layer.h> 14 - #include <net/caif/cfsrvl.h> 15 - #include <net/caif/cfpkt.h> 16 - 17 - #define container_obj(layr) container_of(layr, struct cfrfml, serv.layer) 18 - #define RFM_SEGMENTATION_BIT 0x01 19 - #define RFM_HEAD_SIZE 7 20 - 21 - static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt); 22 - static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt); 23 - 24 - struct cfrfml { 25 - struct cfsrvl serv; 26 - struct cfpkt *incomplete_frm; 27 - int fragment_size; 28 - u8 seghead[6]; 29 - u16 pdu_size; 30 - /* Protects serialized processing of packets */ 31 - spinlock_t sync; 32 - }; 33 - 34 - static void cfrfml_release(struct cflayer *layer) 35 - { 36 - struct cfsrvl *srvl = container_of(layer, struct cfsrvl, layer); 37 - struct cfrfml *rfml = container_obj(&srvl->layer); 38 - 39 - if (rfml->incomplete_frm) 40 - cfpkt_destroy(rfml->incomplete_frm); 41 - 42 - kfree(srvl); 43 - } 44 - 45 - struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info, 46 - int mtu_size) 47 - { 48 - int tmp; 49 - struct cfrfml *this = kzalloc_obj(struct cfrfml, GFP_ATOMIC); 50 - 51 - if (!this) 52 - return NULL; 53 - 54 - cfsrvl_init(&this->serv, channel_id, dev_info, false); 55 - this->serv.release = cfrfml_release; 56 - this->serv.layer.receive = cfrfml_receive; 57 - this->serv.layer.transmit = cfrfml_transmit; 58 - 59 - /* Round down to closest multiple of 16 */ 60 - tmp = (mtu_size - RFM_HEAD_SIZE - 6) / 16; 61 - tmp *= 16; 62 - 63 - this->fragment_size = tmp; 64 - spin_lock_init(&this->sync); 65 - snprintf(this->serv.layer.name, CAIF_LAYER_NAME_SZ, 66 - "rfm%d", channel_id); 67 - 68 - return &this->serv.layer; 69 - } 70 - 71 - static struct cfpkt *rfm_append(struct cfrfml *rfml, char *seghead, 72 - struct cfpkt *pkt, int *err) 73 - { 74 - struct cfpkt *tmppkt; 75 - *err = -EPROTO; 76 - /* n-th but not last segment */ 77 - 78 - if (cfpkt_extr_head(pkt, seghead, 6) < 0) 79 - return NULL; 80 - 81 - /* Verify correct header */ 82 - if (memcmp(seghead, rfml->seghead, 6) != 0) 83 - return NULL; 84 - 85 - tmppkt = cfpkt_append(rfml->incomplete_frm, pkt, 86 - rfml->pdu_size + RFM_HEAD_SIZE); 87 - 88 - /* If cfpkt_append failes input pkts are not freed */ 89 - *err = -ENOMEM; 90 - if (tmppkt == NULL) 91 - return NULL; 92 - 93 - *err = 0; 94 - return tmppkt; 95 - } 96 - 97 - static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) 98 - { 99 - u8 tmp; 100 - bool segmented; 101 - int err; 102 - u8 seghead[6]; 103 - struct cfrfml *rfml; 104 - struct cfpkt *tmppkt = NULL; 105 - 106 - caif_assert(layr->up != NULL); 107 - caif_assert(layr->receive != NULL); 108 - rfml = container_obj(layr); 109 - spin_lock(&rfml->sync); 110 - 111 - err = -EPROTO; 112 - if (cfpkt_extr_head(pkt, &tmp, 1) < 0) 113 - goto out; 114 - segmented = tmp & RFM_SEGMENTATION_BIT; 115 - 116 - if (segmented) { 117 - if (rfml->incomplete_frm == NULL) { 118 - /* Initial Segment */ 119 - if (cfpkt_peek_head(pkt, rfml->seghead, 6) != 0) 120 - goto out; 121 - 122 - rfml->pdu_size = get_unaligned_le16(rfml->seghead+4); 123 - 124 - if (cfpkt_erroneous(pkt)) 125 - goto out; 126 - rfml->incomplete_frm = pkt; 127 - pkt = NULL; 128 - } else { 129 - 130 - tmppkt = rfm_append(rfml, seghead, pkt, &err); 131 - if (tmppkt == NULL) 132 - goto out; 133 - 134 - if (cfpkt_erroneous(tmppkt)) 135 - goto out; 136 - 137 - rfml->incomplete_frm = tmppkt; 138 - 139 - 140 - if (cfpkt_erroneous(tmppkt)) 141 - goto out; 142 - } 143 - err = 0; 144 - goto out; 145 - } 146 - 147 - if (rfml->incomplete_frm) { 148 - 149 - /* Last Segment */ 150 - tmppkt = rfm_append(rfml, seghead, pkt, &err); 151 - if (tmppkt == NULL) 152 - goto out; 153 - 154 - if (cfpkt_erroneous(tmppkt)) 155 - goto out; 156 - 157 - rfml->incomplete_frm = NULL; 158 - pkt = tmppkt; 159 - tmppkt = NULL; 160 - 161 - /* Verify that length is correct */ 162 - err = -EPROTO; 163 - if (rfml->pdu_size != cfpkt_getlen(pkt) - RFM_HEAD_SIZE + 1) 164 - goto out; 165 - } 166 - 167 - err = rfml->serv.layer.up->receive(rfml->serv.layer.up, pkt); 168 - 169 - out: 170 - 171 - if (err != 0) { 172 - if (tmppkt) 173 - cfpkt_destroy(tmppkt); 174 - if (pkt) 175 - cfpkt_destroy(pkt); 176 - if (rfml->incomplete_frm) 177 - cfpkt_destroy(rfml->incomplete_frm); 178 - rfml->incomplete_frm = NULL; 179 - 180 - pr_info("Connection error %d triggered on RFM link\n", err); 181 - 182 - /* Trigger connection error upon failure.*/ 183 - layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 184 - rfml->serv.dev_info.id); 185 - } 186 - spin_unlock(&rfml->sync); 187 - 188 - if (unlikely(err == -EAGAIN)) 189 - /* It is not possible to recover after drop of a fragment */ 190 - err = -EIO; 191 - 192 - return err; 193 - } 194 - 195 - 196 - static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) 197 - { 198 - caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size + RFM_HEAD_SIZE); 199 - 200 - /* Add info for MUX-layer to route the packet out. */ 201 - cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; 202 - 203 - /* 204 - * To optimize alignment, we add up the size of CAIF header before 205 - * payload. 206 - */ 207 - cfpkt_info(pkt)->hdr_len = RFM_HEAD_SIZE; 208 - cfpkt_info(pkt)->dev_info = &rfml->serv.dev_info; 209 - 210 - return rfml->serv.layer.dn->transmit(rfml->serv.layer.dn, pkt); 211 - } 212 - 213 - static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) 214 - { 215 - int err; 216 - u8 seg; 217 - u8 head[6]; 218 - struct cfpkt *rearpkt = NULL; 219 - struct cfpkt *frontpkt = pkt; 220 - struct cfrfml *rfml = container_obj(layr); 221 - 222 - caif_assert(layr->dn != NULL); 223 - caif_assert(layr->dn->transmit != NULL); 224 - 225 - if (!cfsrvl_ready(&rfml->serv, &err)) 226 - goto out; 227 - 228 - err = -EPROTO; 229 - if (cfpkt_getlen(pkt) <= RFM_HEAD_SIZE-1) 230 - goto out; 231 - 232 - err = 0; 233 - if (cfpkt_getlen(pkt) > rfml->fragment_size + RFM_HEAD_SIZE) 234 - err = cfpkt_peek_head(pkt, head, 6); 235 - 236 - if (err != 0) 237 - goto out; 238 - 239 - while (cfpkt_getlen(frontpkt) > rfml->fragment_size + RFM_HEAD_SIZE) { 240 - 241 - seg = 1; 242 - err = -EPROTO; 243 - 244 - if (cfpkt_add_head(frontpkt, &seg, 1) < 0) 245 - goto out; 246 - /* 247 - * On OOM error cfpkt_split returns NULL. 248 - * 249 - * NOTE: Segmented pdu is not correctly aligned. 250 - * This has negative performance impact. 251 - */ 252 - 253 - rearpkt = cfpkt_split(frontpkt, rfml->fragment_size); 254 - if (rearpkt == NULL) 255 - goto out; 256 - 257 - err = cfrfml_transmit_segment(rfml, frontpkt); 258 - 259 - if (err != 0) { 260 - frontpkt = NULL; 261 - goto out; 262 - } 263 - 264 - frontpkt = rearpkt; 265 - rearpkt = NULL; 266 - 267 - err = -EPROTO; 268 - if (cfpkt_add_head(frontpkt, head, 6) < 0) 269 - goto out; 270 - 271 - } 272 - 273 - seg = 0; 274 - err = -EPROTO; 275 - 276 - if (cfpkt_add_head(frontpkt, &seg, 1) < 0) 277 - goto out; 278 - 279 - err = cfrfml_transmit_segment(rfml, frontpkt); 280 - 281 - frontpkt = NULL; 282 - out: 283 - 284 - if (err != 0) { 285 - pr_info("Connection error %d triggered on RFM link\n", err); 286 - /* Trigger connection error upon failure.*/ 287 - 288 - layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 289 - rfml->serv.dev_info.id); 290 - 291 - if (rearpkt) 292 - cfpkt_destroy(rearpkt); 293 - 294 - if (frontpkt) 295 - cfpkt_destroy(frontpkt); 296 - } 297 - 298 - return err; 299 - }
-192
net/caif/cfserl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/spinlock.h> 11 - #include <linux/slab.h> 12 - #include <net/caif/caif_layer.h> 13 - #include <net/caif/cfpkt.h> 14 - #include <net/caif/cfserl.h> 15 - 16 - #define container_obj(layr) ((struct cfserl *) layr) 17 - 18 - #define CFSERL_STX 0x02 19 - #define SERIAL_MINIUM_PACKET_SIZE 4 20 - #define SERIAL_MAX_FRAMESIZE 4096 21 - struct cfserl { 22 - struct cflayer layer; 23 - struct cfpkt *incomplete_frm; 24 - /* Protects parallel processing of incoming packets */ 25 - spinlock_t sync; 26 - bool usestx; 27 - }; 28 - 29 - static int cfserl_receive(struct cflayer *layr, struct cfpkt *pkt); 30 - static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); 31 - static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 32 - int phyid); 33 - 34 - void cfserl_release(struct cflayer *layer) 35 - { 36 - kfree(layer); 37 - } 38 - 39 - struct cflayer *cfserl_create(int instance, bool use_stx) 40 - { 41 - struct cfserl *this = kzalloc_obj(struct cfserl, GFP_ATOMIC); 42 - if (!this) 43 - return NULL; 44 - caif_assert(offsetof(struct cfserl, layer) == 0); 45 - this->layer.receive = cfserl_receive; 46 - this->layer.transmit = cfserl_transmit; 47 - this->layer.ctrlcmd = cfserl_ctrlcmd; 48 - this->usestx = use_stx; 49 - spin_lock_init(&this->sync); 50 - snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "ser1"); 51 - return &this->layer; 52 - } 53 - 54 - static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) 55 - { 56 - struct cfserl *layr = container_obj(l); 57 - u16 pkt_len; 58 - struct cfpkt *pkt = NULL; 59 - struct cfpkt *tail_pkt = NULL; 60 - u8 tmp8; 61 - u16 tmp; 62 - u8 stx = CFSERL_STX; 63 - int ret; 64 - u16 expectlen = 0; 65 - 66 - caif_assert(newpkt != NULL); 67 - spin_lock(&layr->sync); 68 - 69 - if (layr->incomplete_frm != NULL) { 70 - layr->incomplete_frm = 71 - cfpkt_append(layr->incomplete_frm, newpkt, expectlen); 72 - pkt = layr->incomplete_frm; 73 - if (pkt == NULL) { 74 - spin_unlock(&layr->sync); 75 - return -ENOMEM; 76 - } 77 - } else { 78 - pkt = newpkt; 79 - } 80 - layr->incomplete_frm = NULL; 81 - 82 - do { 83 - /* Search for STX at start of pkt if STX is used */ 84 - if (layr->usestx) { 85 - cfpkt_extr_head(pkt, &tmp8, 1); 86 - if (tmp8 != CFSERL_STX) { 87 - while (cfpkt_more(pkt) 88 - && tmp8 != CFSERL_STX) { 89 - cfpkt_extr_head(pkt, &tmp8, 1); 90 - } 91 - if (!cfpkt_more(pkt)) { 92 - cfpkt_destroy(pkt); 93 - layr->incomplete_frm = NULL; 94 - spin_unlock(&layr->sync); 95 - return -EPROTO; 96 - } 97 - } 98 - } 99 - 100 - pkt_len = cfpkt_getlen(pkt); 101 - 102 - /* 103 - * pkt_len is the accumulated length of the packet data 104 - * we have received so far. 105 - * Exit if frame doesn't hold length. 106 - */ 107 - 108 - if (pkt_len < 2) { 109 - if (layr->usestx) 110 - cfpkt_add_head(pkt, &stx, 1); 111 - layr->incomplete_frm = pkt; 112 - spin_unlock(&layr->sync); 113 - return 0; 114 - } 115 - 116 - /* 117 - * Find length of frame. 118 - * expectlen is the length we need for a full frame. 119 - */ 120 - cfpkt_peek_head(pkt, &tmp, 2); 121 - expectlen = le16_to_cpu(tmp) + 2; 122 - /* 123 - * Frame error handling 124 - */ 125 - if (expectlen < SERIAL_MINIUM_PACKET_SIZE 126 - || expectlen > SERIAL_MAX_FRAMESIZE) { 127 - if (!layr->usestx) { 128 - if (pkt != NULL) 129 - cfpkt_destroy(pkt); 130 - layr->incomplete_frm = NULL; 131 - spin_unlock(&layr->sync); 132 - return -EPROTO; 133 - } 134 - continue; 135 - } 136 - 137 - if (pkt_len < expectlen) { 138 - /* Too little received data */ 139 - if (layr->usestx) 140 - cfpkt_add_head(pkt, &stx, 1); 141 - layr->incomplete_frm = pkt; 142 - spin_unlock(&layr->sync); 143 - return 0; 144 - } 145 - 146 - /* 147 - * Enough data for at least one frame. 148 - * Split the frame, if too long 149 - */ 150 - if (pkt_len > expectlen) 151 - tail_pkt = cfpkt_split(pkt, expectlen); 152 - else 153 - tail_pkt = NULL; 154 - 155 - /* Send the first part of packet upwards.*/ 156 - spin_unlock(&layr->sync); 157 - ret = layr->layer.up->receive(layr->layer.up, pkt); 158 - spin_lock(&layr->sync); 159 - if (ret == -EILSEQ) { 160 - if (layr->usestx) { 161 - if (tail_pkt != NULL) 162 - pkt = cfpkt_append(pkt, tail_pkt, 0); 163 - /* Start search for next STX if frame failed */ 164 - continue; 165 - } else { 166 - cfpkt_destroy(pkt); 167 - pkt = NULL; 168 - } 169 - } 170 - 171 - pkt = tail_pkt; 172 - 173 - } while (pkt != NULL); 174 - 175 - spin_unlock(&layr->sync); 176 - return 0; 177 - } 178 - 179 - static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt) 180 - { 181 - struct cfserl *layr = container_obj(layer); 182 - u8 tmp8 = CFSERL_STX; 183 - if (layr->usestx) 184 - cfpkt_add_head(newpkt, &tmp8, 1); 185 - return layer->dn->transmit(layer->dn, newpkt); 186 - } 187 - 188 - static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 189 - int phyid) 190 - { 191 - layr->up->ctrlcmd(layr->up, ctrl, phyid); 192 - }
-224
net/caif/cfsrvl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/kernel.h> 10 - #include <linux/types.h> 11 - #include <linux/errno.h> 12 - #include <linux/slab.h> 13 - #include <linux/module.h> 14 - #include <linux/pkt_sched.h> 15 - #include <net/caif/caif_layer.h> 16 - #include <net/caif/cfsrvl.h> 17 - #include <net/caif/cfpkt.h> 18 - #include <net/caif/caif_dev.h> 19 - 20 - #define SRVL_CTRL_PKT_SIZE 1 21 - #define SRVL_FLOW_OFF 0x81 22 - #define SRVL_FLOW_ON 0x80 23 - #define SRVL_SET_PIN 0x82 24 - 25 - #define container_obj(layr) container_of(layr, struct cfsrvl, layer) 26 - 27 - static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 28 - int phyid) 29 - { 30 - struct cfsrvl *service = container_obj(layr); 31 - 32 - if (layr->up == NULL || layr->up->ctrlcmd == NULL) 33 - return; 34 - 35 - switch (ctrl) { 36 - case CAIF_CTRLCMD_INIT_RSP: 37 - service->open = true; 38 - layr->up->ctrlcmd(layr->up, ctrl, phyid); 39 - break; 40 - case CAIF_CTRLCMD_DEINIT_RSP: 41 - case CAIF_CTRLCMD_INIT_FAIL_RSP: 42 - service->open = false; 43 - layr->up->ctrlcmd(layr->up, ctrl, phyid); 44 - break; 45 - case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: 46 - if (phyid != service->dev_info.id) 47 - break; 48 - if (service->modem_flow_on) 49 - layr->up->ctrlcmd(layr->up, 50 - CAIF_CTRLCMD_FLOW_OFF_IND, phyid); 51 - service->phy_flow_on = false; 52 - break; 53 - case _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND: 54 - if (phyid != service->dev_info.id) 55 - return; 56 - if (service->modem_flow_on) { 57 - layr->up->ctrlcmd(layr->up, 58 - CAIF_CTRLCMD_FLOW_ON_IND, 59 - phyid); 60 - } 61 - service->phy_flow_on = true; 62 - break; 63 - case CAIF_CTRLCMD_FLOW_OFF_IND: 64 - if (service->phy_flow_on) { 65 - layr->up->ctrlcmd(layr->up, 66 - CAIF_CTRLCMD_FLOW_OFF_IND, phyid); 67 - } 68 - service->modem_flow_on = false; 69 - break; 70 - case CAIF_CTRLCMD_FLOW_ON_IND: 71 - if (service->phy_flow_on) { 72 - layr->up->ctrlcmd(layr->up, 73 - CAIF_CTRLCMD_FLOW_ON_IND, phyid); 74 - } 75 - service->modem_flow_on = true; 76 - break; 77 - case _CAIF_CTRLCMD_PHYIF_DOWN_IND: 78 - /* In case interface is down, let's fake a remove shutdown */ 79 - layr->up->ctrlcmd(layr->up, 80 - CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, phyid); 81 - break; 82 - case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: 83 - layr->up->ctrlcmd(layr->up, ctrl, phyid); 84 - break; 85 - default: 86 - pr_warn("Unexpected ctrl in cfsrvl (%d)\n", ctrl); 87 - /* We have both modem and phy flow on, send flow on */ 88 - layr->up->ctrlcmd(layr->up, ctrl, phyid); 89 - service->phy_flow_on = true; 90 - break; 91 - } 92 - } 93 - 94 - static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) 95 - { 96 - struct cfsrvl *service = container_obj(layr); 97 - 98 - caif_assert(layr != NULL); 99 - caif_assert(layr->dn != NULL); 100 - caif_assert(layr->dn->transmit != NULL); 101 - 102 - if (!service->supports_flowctrl) 103 - return 0; 104 - 105 - switch (ctrl) { 106 - case CAIF_MODEMCMD_FLOW_ON_REQ: 107 - { 108 - struct cfpkt *pkt; 109 - struct caif_payload_info *info; 110 - u8 flow_on = SRVL_FLOW_ON; 111 - pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); 112 - if (!pkt) 113 - return -ENOMEM; 114 - 115 - if (cfpkt_add_head(pkt, &flow_on, 1) < 0) { 116 - pr_err("Packet is erroneous!\n"); 117 - cfpkt_destroy(pkt); 118 - return -EPROTO; 119 - } 120 - info = cfpkt_info(pkt); 121 - info->channel_id = service->layer.id; 122 - info->hdr_len = 1; 123 - info->dev_info = &service->dev_info; 124 - cfpkt_set_prio(pkt, TC_PRIO_CONTROL); 125 - return layr->dn->transmit(layr->dn, pkt); 126 - } 127 - case CAIF_MODEMCMD_FLOW_OFF_REQ: 128 - { 129 - struct cfpkt *pkt; 130 - struct caif_payload_info *info; 131 - u8 flow_off = SRVL_FLOW_OFF; 132 - pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); 133 - if (!pkt) 134 - return -ENOMEM; 135 - 136 - if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { 137 - pr_err("Packet is erroneous!\n"); 138 - cfpkt_destroy(pkt); 139 - return -EPROTO; 140 - } 141 - info = cfpkt_info(pkt); 142 - info->channel_id = service->layer.id; 143 - info->hdr_len = 1; 144 - info->dev_info = &service->dev_info; 145 - cfpkt_set_prio(pkt, TC_PRIO_CONTROL); 146 - return layr->dn->transmit(layr->dn, pkt); 147 - } 148 - default: 149 - break; 150 - } 151 - return -EINVAL; 152 - } 153 - 154 - static void cfsrvl_release(struct cflayer *layer) 155 - { 156 - struct cfsrvl *service = container_of(layer, struct cfsrvl, layer); 157 - kfree(service); 158 - } 159 - 160 - void cfsrvl_init(struct cfsrvl *service, 161 - u8 channel_id, 162 - struct dev_info *dev_info, 163 - bool supports_flowctrl) 164 - { 165 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 166 - service->open = false; 167 - service->modem_flow_on = true; 168 - service->phy_flow_on = true; 169 - service->layer.id = channel_id; 170 - service->layer.ctrlcmd = cfservl_ctrlcmd; 171 - service->layer.modemcmd = cfservl_modemcmd; 172 - service->dev_info = *dev_info; 173 - service->supports_flowctrl = supports_flowctrl; 174 - service->release = cfsrvl_release; 175 - } 176 - 177 - bool cfsrvl_ready(struct cfsrvl *service, int *err) 178 - { 179 - if (!service->open) { 180 - *err = -ENOTCONN; 181 - return false; 182 - } 183 - return true; 184 - } 185 - 186 - bool cfsrvl_phyid_match(struct cflayer *layer, int phyid) 187 - { 188 - struct cfsrvl *servl = container_obj(layer); 189 - return servl->dev_info.id == phyid; 190 - } 191 - 192 - void caif_free_client(struct cflayer *adap_layer) 193 - { 194 - struct cflayer *serv_layer; 195 - struct cfsrvl *servl; 196 - 197 - if (!adap_layer) 198 - return; 199 - 200 - serv_layer = adap_layer->dn; 201 - if (!serv_layer) 202 - return; 203 - 204 - layer_set_dn(adap_layer, NULL); 205 - layer_set_up(serv_layer, NULL); 206 - 207 - servl = container_obj(serv_layer); 208 - servl->release(&servl->layer); 209 - } 210 - EXPORT_SYMBOL(caif_free_client); 211 - 212 - void caif_client_register_refcnt(struct cflayer *adapt_layer, 213 - void (*hold)(struct cflayer *lyr), 214 - void (*put)(struct cflayer *lyr)) 215 - { 216 - struct cfsrvl *service; 217 - 218 - if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL)) 219 - return; 220 - service = container_of(adapt_layer->dn, struct cfsrvl, layer); 221 - service->hold = hold; 222 - service->put = put; 223 - } 224 - EXPORT_SYMBOL(caif_client_register_refcnt);
-104
net/caif/cfutill.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/kernel.h> 10 - #include <linux/types.h> 11 - #include <linux/slab.h> 12 - #include <linux/errno.h> 13 - #include <net/caif/caif_layer.h> 14 - #include <net/caif/cfsrvl.h> 15 - #include <net/caif/cfpkt.h> 16 - 17 - #define container_obj(layr) ((struct cfsrvl *) layr) 18 - #define UTIL_PAYLOAD 0x00 19 - #define UTIL_CMD_BIT 0x80 20 - #define UTIL_REMOTE_SHUTDOWN 0x82 21 - #define UTIL_FLOW_OFF 0x81 22 - #define UTIL_FLOW_ON 0x80 23 - 24 - static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt); 25 - static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt); 26 - 27 - struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info) 28 - { 29 - struct cfsrvl *util = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); 30 - if (!util) 31 - return NULL; 32 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 33 - cfsrvl_init(util, channel_id, dev_info, true); 34 - util->layer.receive = cfutill_receive; 35 - util->layer.transmit = cfutill_transmit; 36 - snprintf(util->layer.name, CAIF_LAYER_NAME_SZ, "util1"); 37 - return &util->layer; 38 - } 39 - 40 - static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) 41 - { 42 - u8 cmd = -1; 43 - struct cfsrvl *service = container_obj(layr); 44 - caif_assert(layr != NULL); 45 - caif_assert(layr->up != NULL); 46 - caif_assert(layr->up->receive != NULL); 47 - caif_assert(layr->up->ctrlcmd != NULL); 48 - if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { 49 - pr_err("Packet is erroneous!\n"); 50 - cfpkt_destroy(pkt); 51 - return -EPROTO; 52 - } 53 - 54 - switch (cmd) { 55 - case UTIL_PAYLOAD: 56 - return layr->up->receive(layr->up, pkt); 57 - case UTIL_FLOW_OFF: 58 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0); 59 - cfpkt_destroy(pkt); 60 - return 0; 61 - case UTIL_FLOW_ON: 62 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0); 63 - cfpkt_destroy(pkt); 64 - return 0; 65 - case UTIL_REMOTE_SHUTDOWN: /* Remote Shutdown Request */ 66 - pr_err("REMOTE SHUTDOWN REQUEST RECEIVED\n"); 67 - layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0); 68 - service->open = false; 69 - cfpkt_destroy(pkt); 70 - return 0; 71 - default: 72 - cfpkt_destroy(pkt); 73 - pr_warn("Unknown service control %d (0x%x)\n", cmd, cmd); 74 - return -EPROTO; 75 - } 76 - } 77 - 78 - static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt) 79 - { 80 - u8 zero = 0; 81 - struct caif_payload_info *info; 82 - int ret; 83 - struct cfsrvl *service = container_obj(layr); 84 - caif_assert(layr != NULL); 85 - caif_assert(layr->dn != NULL); 86 - caif_assert(layr->dn->transmit != NULL); 87 - 88 - if (!cfsrvl_ready(service, &ret)) { 89 - cfpkt_destroy(pkt); 90 - return ret; 91 - } 92 - 93 - cfpkt_add_head(pkt, &zero, 1); 94 - /* Add info for MUX-layer to route the packet out. */ 95 - info = cfpkt_info(pkt); 96 - info->channel_id = service->layer.id; 97 - /* 98 - * To optimize alignment, we add up the size of CAIF header before 99 - * payload. 100 - */ 101 - info->hdr_len = 1; 102 - info->dev_info = &service->dev_info; 103 - return layr->dn->transmit(layr->dn, pkt); 104 - }
-101
net/caif/cfveil.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/stddef.h> 10 - #include <linux/slab.h> 11 - #include <net/caif/caif_layer.h> 12 - #include <net/caif/cfsrvl.h> 13 - #include <net/caif/cfpkt.h> 14 - 15 - #define VEI_PAYLOAD 0x00 16 - #define VEI_CMD_BIT 0x80 17 - #define VEI_FLOW_OFF 0x81 18 - #define VEI_FLOW_ON 0x80 19 - #define VEI_SET_PIN 0x82 20 - 21 - #define container_obj(layr) container_of(layr, struct cfsrvl, layer) 22 - 23 - static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt); 24 - static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt); 25 - 26 - struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info) 27 - { 28 - struct cfsrvl *vei = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); 29 - if (!vei) 30 - return NULL; 31 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 32 - cfsrvl_init(vei, channel_id, dev_info, true); 33 - vei->layer.receive = cfvei_receive; 34 - vei->layer.transmit = cfvei_transmit; 35 - snprintf(vei->layer.name, CAIF_LAYER_NAME_SZ, "vei%d", channel_id); 36 - return &vei->layer; 37 - } 38 - 39 - static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) 40 - { 41 - u8 cmd; 42 - int ret; 43 - caif_assert(layr->up != NULL); 44 - caif_assert(layr->receive != NULL); 45 - caif_assert(layr->ctrlcmd != NULL); 46 - 47 - 48 - if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { 49 - pr_err("Packet is erroneous!\n"); 50 - cfpkt_destroy(pkt); 51 - return -EPROTO; 52 - } 53 - switch (cmd) { 54 - case VEI_PAYLOAD: 55 - ret = layr->up->receive(layr->up, pkt); 56 - return ret; 57 - case VEI_FLOW_OFF: 58 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0); 59 - cfpkt_destroy(pkt); 60 - return 0; 61 - case VEI_FLOW_ON: 62 - layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0); 63 - cfpkt_destroy(pkt); 64 - return 0; 65 - case VEI_SET_PIN: /* SET RS232 PIN */ 66 - cfpkt_destroy(pkt); 67 - return 0; 68 - default: /* SET RS232 PIN */ 69 - pr_warn("Unknown VEI control packet %d (0x%x)!\n", cmd, cmd); 70 - cfpkt_destroy(pkt); 71 - return -EPROTO; 72 - } 73 - } 74 - 75 - static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) 76 - { 77 - u8 tmp = 0; 78 - struct caif_payload_info *info; 79 - int ret; 80 - struct cfsrvl *service = container_obj(layr); 81 - if (!cfsrvl_ready(service, &ret)) 82 - goto err; 83 - caif_assert(layr->dn != NULL); 84 - caif_assert(layr->dn->transmit != NULL); 85 - 86 - if (cfpkt_add_head(pkt, &tmp, 1) < 0) { 87 - pr_err("Packet is erroneous!\n"); 88 - ret = -EPROTO; 89 - goto err; 90 - } 91 - 92 - /* Add info-> for MUX-layer to route the packet out. */ 93 - info = cfpkt_info(pkt); 94 - info->channel_id = service->layer.id; 95 - info->hdr_len = 1; 96 - info->dev_info = &service->dev_info; 97 - return layr->dn->transmit(layr->dn, pkt); 98 - err: 99 - cfpkt_destroy(pkt); 100 - return ret; 101 - }
-65
net/caif/cfvidl.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Author: Sjur Brendeland 5 - */ 6 - 7 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 - 9 - #include <linux/kernel.h> 10 - #include <linux/types.h> 11 - #include <linux/slab.h> 12 - #include <linux/errno.h> 13 - #include <net/caif/caif_layer.h> 14 - #include <net/caif/cfsrvl.h> 15 - #include <net/caif/cfpkt.h> 16 - 17 - #define container_obj(layr) ((struct cfsrvl *) layr) 18 - 19 - static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt); 20 - static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt); 21 - 22 - struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) 23 - { 24 - struct cfsrvl *vid = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); 25 - if (!vid) 26 - return NULL; 27 - caif_assert(offsetof(struct cfsrvl, layer) == 0); 28 - 29 - cfsrvl_init(vid, channel_id, dev_info, false); 30 - vid->layer.receive = cfvidl_receive; 31 - vid->layer.transmit = cfvidl_transmit; 32 - snprintf(vid->layer.name, CAIF_LAYER_NAME_SZ, "vid1"); 33 - return &vid->layer; 34 - } 35 - 36 - static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt) 37 - { 38 - u32 videoheader; 39 - if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) { 40 - pr_err("Packet is erroneous!\n"); 41 - cfpkt_destroy(pkt); 42 - return -EPROTO; 43 - } 44 - return layr->up->receive(layr->up, pkt); 45 - } 46 - 47 - static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt) 48 - { 49 - struct cfsrvl *service = container_obj(layr); 50 - struct caif_payload_info *info; 51 - u32 videoheader = 0; 52 - int ret; 53 - 54 - if (!cfsrvl_ready(service, &ret)) { 55 - cfpkt_destroy(pkt); 56 - return ret; 57 - } 58 - 59 - cfpkt_add_head(pkt, &videoheader, 4); 60 - /* Add info for MUX-layer to route the packet out */ 61 - info = cfpkt_info(pkt); 62 - info->channel_id = service->layer.id; 63 - info->dev_info = &service->dev_info; 64 - return layr->dn->transmit(layr->dn, pkt); 65 - }
-531
net/caif/chnl_net.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) ST-Ericsson AB 2010 4 - * Authors: Sjur Brendeland 5 - * Daniel Martensson 6 - */ 7 - 8 - #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 9 - 10 - #include <linux/fs.h> 11 - #include <linux/init.h> 12 - #include <linux/module.h> 13 - #include <linux/netdevice.h> 14 - #include <linux/if_ether.h> 15 - #include <linux/ip.h> 16 - #include <linux/sched.h> 17 - #include <linux/sockios.h> 18 - #include <linux/caif/if_caif.h> 19 - #include <net/rtnetlink.h> 20 - #include <net/caif/caif_layer.h> 21 - #include <net/caif/cfpkt.h> 22 - #include <net/caif/caif_dev.h> 23 - 24 - /* GPRS PDP connection has MTU to 1500 */ 25 - #define GPRS_PDP_MTU 1500 26 - /* 5 sec. connect timeout */ 27 - #define CONNECT_TIMEOUT (5 * HZ) 28 - #define CAIF_NET_DEFAULT_QUEUE_LEN 500 29 - #define UNDEF_CONNID 0xffffffff 30 - 31 - /*This list is protected by the rtnl lock. */ 32 - static LIST_HEAD(chnl_net_list); 33 - 34 - MODULE_DESCRIPTION("ST-Ericsson CAIF modem protocol GPRS network device"); 35 - MODULE_LICENSE("GPL"); 36 - MODULE_ALIAS_RTNL_LINK("caif"); 37 - 38 - enum caif_states { 39 - CAIF_CONNECTED = 1, 40 - CAIF_CONNECTING, 41 - CAIF_DISCONNECTED, 42 - CAIF_SHUTDOWN 43 - }; 44 - 45 - struct chnl_net { 46 - struct cflayer chnl; 47 - struct caif_connect_request conn_req; 48 - struct list_head list_field; 49 - struct net_device *netdev; 50 - wait_queue_head_t netmgmt_wq; 51 - /* Flow status to remember and control the transmission. */ 52 - bool flowenabled; 53 - enum caif_states state; 54 - }; 55 - 56 - static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) 57 - { 58 - struct sk_buff *skb; 59 - struct chnl_net *priv; 60 - int pktlen; 61 - const u8 *ip_version; 62 - u8 buf; 63 - 64 - priv = container_of(layr, struct chnl_net, chnl); 65 - 66 - skb = (struct sk_buff *) cfpkt_tonative(pkt); 67 - 68 - /* Get length of CAIF packet. */ 69 - pktlen = skb->len; 70 - 71 - /* Pass some minimum information and 72 - * send the packet to the net stack. 73 - */ 74 - skb->dev = priv->netdev; 75 - 76 - /* check the version of IP */ 77 - ip_version = skb_header_pointer(skb, 0, 1, &buf); 78 - if (!ip_version) { 79 - kfree_skb(skb); 80 - return -EINVAL; 81 - } 82 - 83 - switch (*ip_version >> 4) { 84 - case 4: 85 - skb->protocol = htons(ETH_P_IP); 86 - break; 87 - case 6: 88 - skb->protocol = htons(ETH_P_IPV6); 89 - break; 90 - default: 91 - kfree_skb(skb); 92 - priv->netdev->stats.rx_errors++; 93 - return -EINVAL; 94 - } 95 - 96 - /* If we change the header in loop mode, the checksum is corrupted. */ 97 - if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) 98 - skb->ip_summed = CHECKSUM_UNNECESSARY; 99 - else 100 - skb->ip_summed = CHECKSUM_NONE; 101 - 102 - netif_rx(skb); 103 - 104 - /* Update statistics. */ 105 - priv->netdev->stats.rx_packets++; 106 - priv->netdev->stats.rx_bytes += pktlen; 107 - 108 - return 0; 109 - } 110 - 111 - static int delete_device(struct chnl_net *dev) 112 - { 113 - ASSERT_RTNL(); 114 - if (dev->netdev) 115 - unregister_netdevice(dev->netdev); 116 - return 0; 117 - } 118 - 119 - static void close_work(struct work_struct *work) 120 - { 121 - struct chnl_net *dev = NULL; 122 - struct list_head *list_node; 123 - struct list_head *_tmp; 124 - 125 - rtnl_lock(); 126 - list_for_each_safe(list_node, _tmp, &chnl_net_list) { 127 - dev = list_entry(list_node, struct chnl_net, list_field); 128 - if (dev->state == CAIF_SHUTDOWN) 129 - dev_close(dev->netdev); 130 - } 131 - rtnl_unlock(); 132 - } 133 - static DECLARE_WORK(close_worker, close_work); 134 - 135 - static void chnl_hold(struct cflayer *lyr) 136 - { 137 - struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl); 138 - dev_hold(priv->netdev); 139 - } 140 - 141 - static void chnl_put(struct cflayer *lyr) 142 - { 143 - struct chnl_net *priv = container_of(lyr, struct chnl_net, chnl); 144 - dev_put(priv->netdev); 145 - } 146 - 147 - static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, 148 - int phyid) 149 - { 150 - struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); 151 - pr_debug("NET flowctrl func called flow: %s\n", 152 - flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : 153 - flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" : 154 - flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" : 155 - flow == CAIF_CTRLCMD_DEINIT_RSP ? "CLOSE/DEINIT" : 156 - flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "OPEN_FAIL" : 157 - flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? 158 - "REMOTE_SHUTDOWN" : "UNKNOWN CTRL COMMAND"); 159 - 160 - 161 - 162 - switch (flow) { 163 - case CAIF_CTRLCMD_FLOW_OFF_IND: 164 - priv->flowenabled = false; 165 - netif_stop_queue(priv->netdev); 166 - break; 167 - case CAIF_CTRLCMD_DEINIT_RSP: 168 - priv->state = CAIF_DISCONNECTED; 169 - break; 170 - case CAIF_CTRLCMD_INIT_FAIL_RSP: 171 - priv->state = CAIF_DISCONNECTED; 172 - wake_up_interruptible(&priv->netmgmt_wq); 173 - break; 174 - case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: 175 - priv->state = CAIF_SHUTDOWN; 176 - netif_tx_disable(priv->netdev); 177 - schedule_work(&close_worker); 178 - break; 179 - case CAIF_CTRLCMD_FLOW_ON_IND: 180 - priv->flowenabled = true; 181 - netif_wake_queue(priv->netdev); 182 - break; 183 - case CAIF_CTRLCMD_INIT_RSP: 184 - caif_client_register_refcnt(&priv->chnl, chnl_hold, chnl_put); 185 - priv->state = CAIF_CONNECTED; 186 - priv->flowenabled = true; 187 - netif_wake_queue(priv->netdev); 188 - wake_up_interruptible(&priv->netmgmt_wq); 189 - break; 190 - default: 191 - break; 192 - } 193 - } 194 - 195 - static netdev_tx_t chnl_net_start_xmit(struct sk_buff *skb, 196 - struct net_device *dev) 197 - { 198 - struct chnl_net *priv; 199 - struct cfpkt *pkt = NULL; 200 - int len; 201 - int result = -1; 202 - /* Get our private data. */ 203 - priv = netdev_priv(dev); 204 - 205 - if (skb->len > priv->netdev->mtu) { 206 - pr_warn("Size of skb exceeded MTU\n"); 207 - kfree_skb(skb); 208 - dev->stats.tx_errors++; 209 - return NETDEV_TX_OK; 210 - } 211 - 212 - if (!priv->flowenabled) { 213 - pr_debug("dropping packets flow off\n"); 214 - kfree_skb(skb); 215 - dev->stats.tx_dropped++; 216 - return NETDEV_TX_OK; 217 - } 218 - 219 - if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) 220 - swap(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); 221 - 222 - /* Store original SKB length. */ 223 - len = skb->len; 224 - 225 - pkt = cfpkt_fromnative(CAIF_DIR_OUT, (void *) skb); 226 - 227 - /* Send the packet down the stack. */ 228 - result = priv->chnl.dn->transmit(priv->chnl.dn, pkt); 229 - if (result) { 230 - dev->stats.tx_dropped++; 231 - return NETDEV_TX_OK; 232 - } 233 - 234 - /* Update statistics. */ 235 - dev->stats.tx_packets++; 236 - dev->stats.tx_bytes += len; 237 - 238 - return NETDEV_TX_OK; 239 - } 240 - 241 - static int chnl_net_open(struct net_device *dev) 242 - { 243 - struct chnl_net *priv = NULL; 244 - int result = -1; 245 - int llifindex, headroom, tailroom, mtu; 246 - struct net_device *lldev; 247 - ASSERT_RTNL(); 248 - priv = netdev_priv(dev); 249 - if (!priv) { 250 - pr_debug("chnl_net_open: no priv\n"); 251 - return -ENODEV; 252 - } 253 - 254 - if (priv->state != CAIF_CONNECTING) { 255 - priv->state = CAIF_CONNECTING; 256 - result = caif_connect_client(dev_net(dev), &priv->conn_req, 257 - &priv->chnl, &llifindex, 258 - &headroom, &tailroom); 259 - if (result != 0) { 260 - pr_debug("err: " 261 - "Unable to register and open device," 262 - " Err:%d\n", 263 - result); 264 - goto error; 265 - } 266 - 267 - lldev = __dev_get_by_index(dev_net(dev), llifindex); 268 - 269 - if (lldev == NULL) { 270 - pr_debug("no interface?\n"); 271 - result = -ENODEV; 272 - goto error; 273 - } 274 - 275 - dev->needed_tailroom = tailroom + lldev->needed_tailroom; 276 - dev->hard_header_len = headroom + lldev->hard_header_len + 277 - lldev->needed_tailroom; 278 - 279 - /* 280 - * MTU, head-room etc is not know before we have a 281 - * CAIF link layer device available. MTU calculation may 282 - * override initial RTNL configuration. 283 - * MTU is minimum of current mtu, link layer mtu pluss 284 - * CAIF head and tail, and PDP GPRS contexts max MTU. 285 - */ 286 - mtu = min_t(int, dev->mtu, lldev->mtu - (headroom + tailroom)); 287 - mtu = min_t(int, GPRS_PDP_MTU, mtu); 288 - dev_set_mtu(dev, mtu); 289 - 290 - if (mtu < 100) { 291 - pr_warn("CAIF Interface MTU too small (%d)\n", mtu); 292 - result = -ENODEV; 293 - goto error; 294 - } 295 - } 296 - 297 - rtnl_unlock(); /* Release RTNL lock during connect wait */ 298 - 299 - result = wait_event_interruptible_timeout(priv->netmgmt_wq, 300 - priv->state != CAIF_CONNECTING, 301 - CONNECT_TIMEOUT); 302 - 303 - rtnl_lock(); 304 - 305 - if (result == -ERESTARTSYS) { 306 - pr_debug("wait_event_interruptible woken by a signal\n"); 307 - result = -ERESTARTSYS; 308 - goto error; 309 - } 310 - 311 - if (result == 0) { 312 - pr_debug("connect timeout\n"); 313 - result = -ETIMEDOUT; 314 - goto error; 315 - } 316 - 317 - if (priv->state != CAIF_CONNECTED) { 318 - pr_debug("connect failed\n"); 319 - result = -ECONNREFUSED; 320 - goto error; 321 - } 322 - pr_debug("CAIF Netdevice connected\n"); 323 - return 0; 324 - 325 - error: 326 - caif_disconnect_client(dev_net(dev), &priv->chnl); 327 - priv->state = CAIF_DISCONNECTED; 328 - pr_debug("state disconnected\n"); 329 - return result; 330 - 331 - } 332 - 333 - static int chnl_net_stop(struct net_device *dev) 334 - { 335 - struct chnl_net *priv; 336 - 337 - ASSERT_RTNL(); 338 - priv = netdev_priv(dev); 339 - priv->state = CAIF_DISCONNECTED; 340 - caif_disconnect_client(dev_net(dev), &priv->chnl); 341 - return 0; 342 - } 343 - 344 - static int chnl_net_init(struct net_device *dev) 345 - { 346 - struct chnl_net *priv; 347 - ASSERT_RTNL(); 348 - priv = netdev_priv(dev); 349 - INIT_LIST_HEAD(&priv->list_field); 350 - return 0; 351 - } 352 - 353 - static void chnl_net_uninit(struct net_device *dev) 354 - { 355 - struct chnl_net *priv; 356 - ASSERT_RTNL(); 357 - priv = netdev_priv(dev); 358 - list_del_init(&priv->list_field); 359 - } 360 - 361 - static const struct net_device_ops netdev_ops = { 362 - .ndo_open = chnl_net_open, 363 - .ndo_stop = chnl_net_stop, 364 - .ndo_init = chnl_net_init, 365 - .ndo_uninit = chnl_net_uninit, 366 - .ndo_start_xmit = chnl_net_start_xmit, 367 - }; 368 - 369 - static void chnl_net_destructor(struct net_device *dev) 370 - { 371 - struct chnl_net *priv = netdev_priv(dev); 372 - caif_free_client(&priv->chnl); 373 - } 374 - 375 - static void ipcaif_net_setup(struct net_device *dev) 376 - { 377 - struct chnl_net *priv; 378 - dev->netdev_ops = &netdev_ops; 379 - dev->needs_free_netdev = true; 380 - dev->priv_destructor = chnl_net_destructor; 381 - dev->flags |= IFF_NOARP; 382 - dev->flags |= IFF_POINTOPOINT; 383 - dev->mtu = GPRS_PDP_MTU; 384 - dev->tx_queue_len = CAIF_NET_DEFAULT_QUEUE_LEN; 385 - 386 - priv = netdev_priv(dev); 387 - priv->chnl.receive = chnl_recv_cb; 388 - priv->chnl.ctrlcmd = chnl_flowctrl_cb; 389 - priv->netdev = dev; 390 - priv->conn_req.protocol = CAIFPROTO_DATAGRAM; 391 - priv->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; 392 - priv->conn_req.priority = CAIF_PRIO_LOW; 393 - /* Insert illegal value */ 394 - priv->conn_req.sockaddr.u.dgm.connection_id = UNDEF_CONNID; 395 - priv->flowenabled = false; 396 - 397 - init_waitqueue_head(&priv->netmgmt_wq); 398 - } 399 - 400 - 401 - static int ipcaif_fill_info(struct sk_buff *skb, const struct net_device *dev) 402 - { 403 - struct chnl_net *priv; 404 - u8 loop; 405 - priv = netdev_priv(dev); 406 - if (nla_put_u32(skb, IFLA_CAIF_IPV4_CONNID, 407 - priv->conn_req.sockaddr.u.dgm.connection_id) || 408 - nla_put_u32(skb, IFLA_CAIF_IPV6_CONNID, 409 - priv->conn_req.sockaddr.u.dgm.connection_id)) 410 - goto nla_put_failure; 411 - loop = priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP; 412 - if (nla_put_u8(skb, IFLA_CAIF_LOOPBACK, loop)) 413 - goto nla_put_failure; 414 - return 0; 415 - nla_put_failure: 416 - return -EMSGSIZE; 417 - 418 - } 419 - 420 - static void caif_netlink_parms(struct nlattr *data[], 421 - struct caif_connect_request *conn_req) 422 - { 423 - if (!data) { 424 - pr_warn("no params data found\n"); 425 - return; 426 - } 427 - if (data[IFLA_CAIF_IPV4_CONNID]) 428 - conn_req->sockaddr.u.dgm.connection_id = 429 - nla_get_u32(data[IFLA_CAIF_IPV4_CONNID]); 430 - if (data[IFLA_CAIF_IPV6_CONNID]) 431 - conn_req->sockaddr.u.dgm.connection_id = 432 - nla_get_u32(data[IFLA_CAIF_IPV6_CONNID]); 433 - if (data[IFLA_CAIF_LOOPBACK]) { 434 - if (nla_get_u8(data[IFLA_CAIF_LOOPBACK])) 435 - conn_req->protocol = CAIFPROTO_DATAGRAM_LOOP; 436 - else 437 - conn_req->protocol = CAIFPROTO_DATAGRAM; 438 - } 439 - } 440 - 441 - static int ipcaif_newlink(struct net_device *dev, 442 - struct rtnl_newlink_params *params, 443 - struct netlink_ext_ack *extack) 444 - { 445 - struct nlattr **data = params->data; 446 - int ret; 447 - struct chnl_net *caifdev; 448 - ASSERT_RTNL(); 449 - caifdev = netdev_priv(dev); 450 - caif_netlink_parms(data, &caifdev->conn_req); 451 - 452 - ret = register_netdevice(dev); 453 - if (ret) 454 - pr_warn("device rtml registration failed\n"); 455 - else 456 - list_add(&caifdev->list_field, &chnl_net_list); 457 - 458 - /* Use ifindex as connection id, and use loopback channel default. */ 459 - if (caifdev->conn_req.sockaddr.u.dgm.connection_id == UNDEF_CONNID) { 460 - caifdev->conn_req.sockaddr.u.dgm.connection_id = dev->ifindex; 461 - caifdev->conn_req.protocol = CAIFPROTO_DATAGRAM_LOOP; 462 - } 463 - return ret; 464 - } 465 - 466 - static int ipcaif_changelink(struct net_device *dev, struct nlattr *tb[], 467 - struct nlattr *data[], 468 - struct netlink_ext_ack *extack) 469 - { 470 - struct chnl_net *caifdev; 471 - ASSERT_RTNL(); 472 - caifdev = netdev_priv(dev); 473 - caif_netlink_parms(data, &caifdev->conn_req); 474 - netdev_state_change(dev); 475 - return 0; 476 - } 477 - 478 - static size_t ipcaif_get_size(const struct net_device *dev) 479 - { 480 - return 481 - /* IFLA_CAIF_IPV4_CONNID */ 482 - nla_total_size(4) + 483 - /* IFLA_CAIF_IPV6_CONNID */ 484 - nla_total_size(4) + 485 - /* IFLA_CAIF_LOOPBACK */ 486 - nla_total_size(2) + 487 - 0; 488 - } 489 - 490 - static const struct nla_policy ipcaif_policy[IFLA_CAIF_MAX + 1] = { 491 - [IFLA_CAIF_IPV4_CONNID] = { .type = NLA_U32 }, 492 - [IFLA_CAIF_IPV6_CONNID] = { .type = NLA_U32 }, 493 - [IFLA_CAIF_LOOPBACK] = { .type = NLA_U8 } 494 - }; 495 - 496 - 497 - static struct rtnl_link_ops ipcaif_link_ops __read_mostly = { 498 - .kind = "caif", 499 - .priv_size = sizeof(struct chnl_net), 500 - .setup = ipcaif_net_setup, 501 - .maxtype = IFLA_CAIF_MAX, 502 - .policy = ipcaif_policy, 503 - .newlink = ipcaif_newlink, 504 - .changelink = ipcaif_changelink, 505 - .get_size = ipcaif_get_size, 506 - .fill_info = ipcaif_fill_info, 507 - 508 - }; 509 - 510 - static int __init chnl_init_module(void) 511 - { 512 - return rtnl_link_register(&ipcaif_link_ops); 513 - } 514 - 515 - static void __exit chnl_exit_module(void) 516 - { 517 - struct chnl_net *dev = NULL; 518 - struct list_head *list_node; 519 - struct list_head *_tmp; 520 - rtnl_link_unregister(&ipcaif_link_ops); 521 - rtnl_lock(); 522 - list_for_each_safe(list_node, _tmp, &chnl_net_list) { 523 - dev = list_entry(list_node, struct chnl_net, list_field); 524 - list_del_init(list_node); 525 - delete_device(dev); 526 - } 527 - rtnl_unlock(); 528 - } 529 - 530 - module_init(chnl_init_module); 531 - module_exit(chnl_exit_module);