A framer is a component in charge of an E1/T1 line interface.
Connected usually to a TDM bus, it converts TDM frames to/from E1/T1
frames. It also provides information related to the E1/T1 line.
The framer framework provides a set of APIs for the framer drivers
(framer provider) to create/destroy a framer and APIs for the framer
users (framer consumer) to obtain a reference to the framer, and
use the framer.
This basic implementation provides a framer abstraction for:
- power on/off the framer
- get the framer status (line state)
- be notified on framer status changes
- get/set the framer configuration
Signed-off-by: Herve Codina
Reviewed-by: Christophe Leroy
Signed-off-by: Christophe Leroy
---
drivers/net/wan/Kconfig| 2 +
drivers/net/wan/Makefile | 2 +
drivers/net/wan/framer/Kconfig | 23 +
drivers/net/wan/framer/Makefile| 6 +
drivers/net/wan/framer/framer-core.c | 887 +
include/linux/framer/framer-provider.h | 194 ++
include/linux/framer/framer.h | 205 ++
7 files changed, 1319 insertions(+)
create mode 100644 drivers/net/wan/framer/Kconfig
create mode 100644 drivers/net/wan/framer/Makefile
create mode 100644 drivers/net/wan/framer/framer-core.c
create mode 100644 include/linux/framer/framer-provider.h
create mode 100644 include/linux/framer/framer.h
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8de99f4b647b..31ab2136cdf1 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -95,6 +95,8 @@ config HDLC_X25
comment "X.25/LAPB support is disabled"
depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
+source "drivers/net/wan/framer/Kconfig"
+
config PCI200SYN
tristate "Goramo PCI200SYN support"
depends on HDLC && PCI
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index f338f4830626..00e9b7ee1e01 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_HDLC_FR) += hdlc_fr.o
obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o
obj-$(CONFIG_HDLC_X25) += hdlc_x25.o
+obj-y += framer/
+
obj-$(CONFIG_FARSYNC) += farsync.o
obj-$(CONFIG_LAPBETHER)+= lapbether.o
diff --git a/drivers/net/wan/framer/Kconfig b/drivers/net/wan/framer/Kconfig
new file mode 100644
index ..37df9a96ab42
--- /dev/null
+++ b/drivers/net/wan/framer/Kconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# FRAMER
+#
+
+menu "Framer Subsystem"
+
+config GENERIC_FRAMER
+ bool "Framer Core"
+ help
+ Generic Framer support.
+ A framer is a component in charge of an E1/T1 line interface.
+ Connected usually to a TDM bus, it converts TDM frames to/from E1/T1
+ frames. It also provides information related to the E1/T1 line.
+ Used with HDLC, the network can be reached through the E1/T1 line.
+
+ This framework is designed to provide a generic interface for framer
+ devices present in the kernel. This layer will have the generic
+ API by which framer drivers can create framer using the framer
+ framework and framer users can obtain reference to the framer.
+ All the users of this framework should select this config.
+
+endmenu
diff --git a/drivers/net/wan/framer/Makefile b/drivers/net/wan/framer/Makefile
new file mode 100644
index ..78dbd8e563d0
--- /dev/null
+++ b/drivers/net/wan/framer/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the framer drivers.
+#
+
+obj-$(CONFIG_GENERIC_FRAMER) += framer-core.o
diff --git a/drivers/net/wan/framer/framer-core.c
b/drivers/net/wan/framer/framer-core.c
new file mode 100644
index ..a8f34ba993e4
--- /dev/null
+++ b/drivers/net/wan/framer/framer-core.c
@@ -0,0 +1,887 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Generic Framer framework.
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static struct class *framer_class;
+static DEFINE_MUTEX(framer_provider_mutex);
+static LIST_HEAD(framer_provider_list);
+static DEFINE_IDA(framer_ida);
+
+#define dev_to_framer(a) (container_of((a), struct framer, dev))
+
+int framer_pm_runtime_get(struct framer *framer)
+{
+ int ret;
+
+ if (!pm_runtime_enabled(>dev))
+ return -EOPNOTSUPP;
+
+ ret = pm_runtime_get(>dev);
+ if (ret < 0 && ret != -EINPROGRESS)
+ pm_runtime_put_noidle(>dev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(framer_pm_runtime_get);
+
+int framer_pm_runtime_get_sync(struct framer *framer)
+{
+ int ret;
+
+ if (!pm_runtime_enabled(>dev))
+ return -EOPNOTSUPP;
+
+ ret = pm_runtime_get_sync(>dev);
+ if (ret < 0)
+