Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2020-21 Intel Corporation.
0004  */
0005 
0006 #include "iosm_ipc_chnl_cfg.h"
0007 #include "iosm_ipc_imem_ops.h"
0008 #include "iosm_ipc_port.h"
0009 
0010 /* open logical channel for control communication */
0011 static int ipc_port_ctrl_start(struct wwan_port *port)
0012 {
0013     struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
0014     int ret = 0;
0015 
0016     ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem,
0017                            ipc_port->chl_id,
0018                            IPC_HP_CDEV_OPEN);
0019     if (!ipc_port->channel)
0020         ret = -EIO;
0021 
0022     return ret;
0023 }
0024 
0025 /* close logical channel */
0026 static void ipc_port_ctrl_stop(struct wwan_port *port)
0027 {
0028     struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
0029 
0030     ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
0031 }
0032 
0033 /* transfer control data to modem */
0034 static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
0035 {
0036     struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
0037 
0038     return ipc_imem_sys_cdev_write(ipc_port, skb);
0039 }
0040 
0041 static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
0042     .start = ipc_port_ctrl_start,
0043     .stop = ipc_port_ctrl_stop,
0044     .tx = ipc_port_ctrl_tx,
0045 };
0046 
0047 /* Port init func */
0048 struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
0049                 struct ipc_chnl_cfg ipc_port_cfg)
0050 {
0051     struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL);
0052     enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type;
0053     enum ipc_channel_id chl_id = ipc_port_cfg.id;
0054 
0055     if (!ipc_port)
0056         return NULL;
0057 
0058     ipc_port->dev = ipc_imem->dev;
0059     ipc_port->pcie = ipc_imem->pcie;
0060 
0061     ipc_port->port_type = port_type;
0062     ipc_port->chl_id = chl_id;
0063     ipc_port->ipc_imem = ipc_imem;
0064 
0065     ipc_port->iosm_port = wwan_create_port(ipc_port->dev, port_type,
0066                            &ipc_wwan_ctrl_ops, ipc_port);
0067 
0068     return ipc_port;
0069 }
0070 
0071 /* Port deinit func */
0072 void ipc_port_deinit(struct iosm_cdev *port[])
0073 {
0074     struct iosm_cdev *ipc_port;
0075     u8 ctrl_chl_nr;
0076 
0077     for (ctrl_chl_nr = 0; ctrl_chl_nr < IPC_MEM_MAX_CHANNELS;
0078          ctrl_chl_nr++) {
0079         if (port[ctrl_chl_nr]) {
0080             ipc_port = port[ctrl_chl_nr];
0081             wwan_remove_port(ipc_port->iosm_port);
0082             kfree(ipc_port);
0083         }
0084     }
0085 }