Commit 9a44c1cc authored by Loic Poulain's avatar Loic Poulain Committed by David S. Miller

net: Add a WWAN subsystem

This change introduces initial support for a WWAN framework. Given the
complexity and heterogeneity of existing WWAN hardwares and interfaces,
there is no strict definition of what a WWAN device is and how it should
be represented. It's often a collection of multiple devices that perform
the global WWAN feature (netdev, tty, chardev, etc).

One usual way to expose modem controls and configuration is via high
level protocols such as the well known AT command protocol, MBIM or
QMI. The USB modems started to expose them as character devices, and
user daemons such as ModemManager learnt to use them.

This initial version adds the concept of WWAN port, which is a logical
pipe to a modem control protocol. The protocols are rawly exposed to
user via character device, allowing straigthforward support in existing
tools (ModemManager, ofono...). The WWAN core takes care of the generic
part, including character device management, and relies on port driver
operations to receive/submit protocol data.

Since the different devices exposing protocols for a same WWAN hardware
do not necessarily know about each others (e.g. two different USB
interfaces, PCI/MHI channel devices...) and can be created/removed in
different orders, the WWAN core ensures that all WAN ports contributing
to the 'whole' WWAN feature are grouped under the same virtual WWAN
device, relying on the provided parent device (e.g. mhi controller,
USB device). It's a 'trick' I copied from Johannes's earlier WWAN
subsystem proposal.

This initial version is purposely minimalist, it's essentially moving
the generic part of the previously proposed mhi_wwan_ctrl driver inside
a common WWAN framework, but the implementation is open and flexible
enough to allow extension for further drivers.
Signed-off-by: default avatarLoic Poulain <loic.poulain@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4ad29b1a
...@@ -502,6 +502,8 @@ source "drivers/net/wan/Kconfig" ...@@ -502,6 +502,8 @@ source "drivers/net/wan/Kconfig"
source "drivers/net/ieee802154/Kconfig" source "drivers/net/ieee802154/Kconfig"
source "drivers/net/wwan/Kconfig"
config XEN_NETDEV_FRONTEND config XEN_NETDEV_FRONTEND
tristate "Xen network device frontend driver" tristate "Xen network device frontend driver"
depends on XEN depends on XEN
......
...@@ -68,6 +68,7 @@ obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o ...@@ -68,6 +68,7 @@ obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o
obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_WAN) += wan/
obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_WLAN) += wireless/
obj-$(CONFIG_IEEE802154) += ieee802154/ obj-$(CONFIG_IEEE802154) += ieee802154/
obj-$(CONFIG_WWAN) += wwan/
obj-$(CONFIG_VMXNET3) += vmxnet3/ obj-$(CONFIG_VMXNET3) += vmxnet3/
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
......
# SPDX-License-Identifier: GPL-2.0-only
#
# Wireless WAN device configuration
#
menuconfig WWAN
bool "Wireless WAN"
help
This section contains Wireless WAN configuration for WWAN framework
and drivers.
if WWAN
config WWAN_CORE
tristate "WWAN Driver Core"
help
Say Y here if you want to use the WWAN driver core. This driver
provides a common framework for WWAN drivers.
To compile this driver as a module, choose M here: the module will be
called wwan.
endif # WWAN
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the Linux WWAN device drivers.
#
obj-$(CONFIG_WWAN_CORE) += wwan.o
wwan-objs += wwan_core.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2021, Linaro Ltd <loic.poulain@linaro.org> */
#ifndef __WWAN_H
#define __WWAN_H
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
/**
* enum wwan_port_type - WWAN port types
* @WWAN_PORT_AT: AT commands
* @WWAN_PORT_MBIM: Mobile Broadband Interface Model control
* @WWAN_PORT_QMI: Qcom modem/MSM interface for modem control
* @WWAN_PORT_QCDM: Qcom Modem diagnostic interface
* @WWAN_PORT_FIREHOSE: XML based command protocol
* @WWAN_PORT_MAX: Number of supported port types
*/
enum wwan_port_type {
WWAN_PORT_AT,
WWAN_PORT_MBIM,
WWAN_PORT_QMI,
WWAN_PORT_QCDM,
WWAN_PORT_FIREHOSE,
WWAN_PORT_MAX,
};
struct wwan_port;
/** struct wwan_port_ops - The WWAN port operations
* @start: The routine for starting the WWAN port device.
* @stop: The routine for stopping the WWAN port device.
* @tx: The routine that sends WWAN port protocol data to the device.
*
* The wwan_port_ops structure contains a list of low-level operations
* that control a WWAN port device. All functions are mandatory.
*/
struct wwan_port_ops {
int (*start)(struct wwan_port *port);
void (*stop)(struct wwan_port *port);
int (*tx)(struct wwan_port *port, struct sk_buff *skb);
};
/**
* wwan_create_port - Add a new WWAN port
* @parent: Device to use as parent and shared by all WWAN ports
* @type: WWAN port type
* @ops: WWAN port operations
* @drvdata: Pointer to caller driver data
*
* Allocate and register a new WWAN port. The port will be automatically exposed
* to user as a character device and attached to the right virtual WWAN device,
* based on the parent pointer. The parent pointer is the device shared by all
* components of a same WWAN modem (e.g. USB dev, PCI dev, MHI controller...).
*
* drvdata will be placed in the WWAN port device driver data and can be
* retrieved with wwan_port_get_drvdata().
*
* This function must be balanced with a call to wwan_remove_port().
*
* Returns a valid pointer to wwan_port on success or PTR_ERR on failure
*/
struct wwan_port *wwan_create_port(struct device *parent,
enum wwan_port_type type,
const struct wwan_port_ops *ops,
void *drvdata);
/**
* wwan_remove_port - Remove a WWAN port
* @port: WWAN port to remove
*
* Remove a previously created port.
*/
void wwan_remove_port(struct wwan_port *port);
/**
* wwan_port_rx - Receive data from the WWAN port
* @port: WWAN port for which data is received
* @skb: Pointer to the rx buffer
*
* A port driver calls this function upon data reception (MBIM, AT...).
*/
void wwan_port_rx(struct wwan_port *port, struct sk_buff *skb);
/**
* wwan_port_txoff - Stop TX on WWAN port
* @port: WWAN port for which TX must be stopped
*
* Used for TX flow control, a port driver calls this function to indicate TX
* is temporary unavailable (e.g. due to ring buffer fullness).
*/
void wwan_port_txoff(struct wwan_port *port);
/**
* wwan_port_txon - Restart TX on WWAN port
* @port: WWAN port for which TX must be restarted
*
* Used for TX flow control, a port driver calls this function to indicate TX
* is available again.
*/
void wwan_port_txon(struct wwan_port *port);
/**
* wwan_port_get_drvdata - Retrieve driver data from a WWAN port
* @port: Related WWAN port
*/
void *wwan_port_get_drvdata(struct wwan_port *port);
#endif /* __WWAN_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment