net: iosm: wwan port control device
authorM Chetan Kumar <m.chetan.kumar@intel.com>
Sun, 13 Jun 2021 12:50:14 +0000 (18:20 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sun, 13 Jun 2021 20:49:38 +0000 (13:49 -0700)
Implements wwan port for MBIM & AT protocol communication

Signed-off-by: M Chetan Kumar <m.chetan.kumar@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/wwan/iosm/iosm_ipc_port.c [new file with mode: 0644]
drivers/net/wwan/iosm/iosm_ipc_port.h [new file with mode: 0644]

diff --git a/drivers/net/wwan/iosm/iosm_ipc_port.c b/drivers/net/wwan/iosm/iosm_ipc_port.c
new file mode 100644 (file)
index 0000000..beb9448
--- /dev/null
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020-21 Intel Corporation.
+ */
+
+#include "iosm_ipc_chnl_cfg.h"
+#include "iosm_ipc_imem_ops.h"
+#include "iosm_ipc_port.h"
+
+/* open logical channel for control communication */
+static int ipc_port_ctrl_start(struct wwan_port *port)
+{
+       struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
+       int ret = 0;
+
+       ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem,
+                                                  ipc_port->chl_id,
+                                                  IPC_HP_CDEV_OPEN);
+       if (!ipc_port->channel)
+               ret = -EIO;
+
+       return ret;
+}
+
+/* close logical channel */
+static void ipc_port_ctrl_stop(struct wwan_port *port)
+{
+       struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
+
+       ipc_imem_sys_cdev_close(ipc_port);
+}
+
+/* transfer control data to modem */
+static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
+{
+       struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
+
+       return ipc_imem_sys_cdev_write(ipc_port, skb);
+}
+
+static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
+       .start = ipc_port_ctrl_start,
+       .stop = ipc_port_ctrl_stop,
+       .tx = ipc_port_ctrl_tx,
+};
+
+/* Port init func */
+struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
+                               struct ipc_chnl_cfg ipc_port_cfg)
+{
+       struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL);
+       enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type;
+       enum ipc_channel_id chl_id = ipc_port_cfg.id;
+
+       if (!ipc_port)
+               return NULL;
+
+       ipc_port->dev = ipc_imem->dev;
+       ipc_port->pcie = ipc_imem->pcie;
+
+       ipc_port->port_type = port_type;
+       ipc_port->chl_id = chl_id;
+       ipc_port->ipc_imem = ipc_imem;
+
+       ipc_port->iosm_port = wwan_create_port(ipc_port->dev, port_type,
+                                              &ipc_wwan_ctrl_ops, ipc_port);
+
+       return ipc_port;
+}
+
+/* Port deinit func */
+void ipc_port_deinit(struct iosm_cdev *port[])
+{
+       struct iosm_cdev *ipc_port;
+       u8 ctrl_chl_nr;
+
+       for (ctrl_chl_nr = 0; ctrl_chl_nr < IPC_MEM_MAX_CHANNELS;
+            ctrl_chl_nr++) {
+               if (port[ctrl_chl_nr]) {
+                       ipc_port = port[ctrl_chl_nr];
+                       wwan_remove_port(ipc_port->iosm_port);
+                       kfree(ipc_port);
+               }
+       }
+}
diff --git a/drivers/net/wwan/iosm/iosm_ipc_port.h b/drivers/net/wwan/iosm/iosm_ipc_port.h
new file mode 100644 (file)
index 0000000..11bc8ed
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2020-21 Intel Corporation.
+ */
+
+#ifndef IOSM_IPC_PORT_H
+#define IOSM_IPC_PORT_H
+
+#include <linux/wwan.h>
+
+#include "iosm_ipc_imem_ops.h"
+
+/**
+ * struct iosm_cdev - State of the char driver layer.
+ * @iosm_port:         Pointer of type wwan_port
+ * @ipc_imem:          imem instance
+ * @dev:               Pointer to device struct
+ * @pcie:              PCIe component
+ * @port_type:         WWAN port type
+ * @channel:           Channel instance
+ * @chl_id:            Channel Indentifier
+ */
+struct iosm_cdev {
+       struct wwan_port *iosm_port;
+       struct iosm_imem *ipc_imem;
+       struct device *dev;
+       struct iosm_pcie *pcie;
+       enum wwan_port_type port_type;
+       struct ipc_mem_channel *channel;
+       enum ipc_channel_id chl_id;
+};
+
+/**
+ * ipc_port_init - Allocate IPC port & register to wwan subsystem for AT/MBIM
+ *                communication.
+ * @ipc_imem:          Pointer to iosm_imem structure
+ * @ipc_port_cfg:      IPC Port Config
+ *
+ * Returns: 0 on success & NULL on failure
+ */
+struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
+                               struct ipc_chnl_cfg ipc_port_cfg);
+
+/**
+ * ipc_port_deinit - Free IPC port & unregister port with wwan subsystem.
+ * @ipc_port:  Array of pointer to the ipc port data-struct
+ */
+void ipc_port_deinit(struct iosm_cdev *ipc_port[]);
+
+#endif