iosm_ipc_port.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2020-21 Intel Corporation.
  4. */
  5. #include "iosm_ipc_chnl_cfg.h"
  6. #include "iosm_ipc_imem_ops.h"
  7. #include "iosm_ipc_port.h"
  8. /* open logical channel for control communication */
  9. static int ipc_port_ctrl_start(struct wwan_port *port)
  10. {
  11. struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
  12. int ret = 0;
  13. ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem,
  14. ipc_port->chl_id,
  15. IPC_HP_CDEV_OPEN);
  16. if (!ipc_port->channel)
  17. ret = -EIO;
  18. return ret;
  19. }
  20. /* close logical channel */
  21. static void ipc_port_ctrl_stop(struct wwan_port *port)
  22. {
  23. struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
  24. ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
  25. }
  26. /* transfer control data to modem */
  27. static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
  28. {
  29. struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
  30. return ipc_imem_sys_cdev_write(ipc_port, skb);
  31. }
  32. static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
  33. .start = ipc_port_ctrl_start,
  34. .stop = ipc_port_ctrl_stop,
  35. .tx = ipc_port_ctrl_tx,
  36. };
  37. /* Port init func */
  38. struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
  39. struct ipc_chnl_cfg ipc_port_cfg)
  40. {
  41. struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL);
  42. enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type;
  43. enum ipc_channel_id chl_id = ipc_port_cfg.id;
  44. if (!ipc_port)
  45. return NULL;
  46. ipc_port->dev = ipc_imem->dev;
  47. ipc_port->pcie = ipc_imem->pcie;
  48. ipc_port->port_type = port_type;
  49. ipc_port->chl_id = chl_id;
  50. ipc_port->ipc_imem = ipc_imem;
  51. ipc_port->iosm_port = wwan_create_port(ipc_port->dev, port_type,
  52. &ipc_wwan_ctrl_ops, NULL,
  53. ipc_port);
  54. return ipc_port;
  55. }
  56. /* Port deinit func */
  57. void ipc_port_deinit(struct iosm_cdev *port[])
  58. {
  59. struct iosm_cdev *ipc_port;
  60. u8 ctrl_chl_nr;
  61. for (ctrl_chl_nr = 0; ctrl_chl_nr < IPC_MEM_MAX_CHANNELS;
  62. ctrl_chl_nr++) {
  63. if (port[ctrl_chl_nr]) {
  64. ipc_port = port[ctrl_chl_nr];
  65. wwan_remove_port(ipc_port->iosm_port);
  66. kfree(ipc_port);
  67. }
  68. }
  69. }