wlan_cfg80211_coex.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /**
  17. * DOC: defines driver functions interfacing with linux kernel
  18. */
  19. #include <wmi_unified_param.h>
  20. #include <wlan_osif_request_manager.h>
  21. #include <osif_sync.h>
  22. #include <wlan_objmgr_psoc_obj_i.h>
  23. #include <wlan_coex_main.h>
  24. #include <wlan_coex_ucfg_api.h>
  25. #include <wlan_cfg80211_coex.h>
  26. const struct nla_policy
  27. btc_chain_mode_policy[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX + 1] = {
  28. [QCA_VENDOR_ATTR_BTC_CHAIN_MODE] = {.type = NLA_U32},
  29. [QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART] = {.type = NLA_FLAG},
  30. };
  31. static int
  32. __wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
  33. uint8_t mode, bool do_restart)
  34. {
  35. QDF_STATUS status;
  36. uint8_t cur_mode;
  37. int err;
  38. struct wlan_objmgr_psoc *psoc;
  39. struct wlan_objmgr_vdev *vdev_tmp;
  40. int vdev_id;
  41. struct coex_psoc_obj *coex_obj;
  42. if (!vdev) {
  43. coex_err("Null vdev");
  44. return -EINVAL;
  45. }
  46. psoc = wlan_vdev_get_psoc(vdev);
  47. if (!psoc) {
  48. coex_err("NULL psoc");
  49. return -EINVAL;
  50. }
  51. coex_obj = wlan_psoc_get_coex_obj(psoc);
  52. if (!coex_obj)
  53. return -EINVAL;
  54. status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &cur_mode);
  55. if (QDF_IS_STATUS_ERROR(status)) {
  56. coex_err("failed to get cur BTC chain mode, status %d", status);
  57. return -EFAULT;
  58. }
  59. if (cur_mode == mode)
  60. return -EALREADY;
  61. status = ucfg_coex_psoc_set_btc_chain_mode(psoc, mode);
  62. if (!QDF_IS_STATUS_SUCCESS(status)) {
  63. coex_err("unable to set BTC chain mode to %d", mode);
  64. return -EFAULT;
  65. }
  66. wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev_tmp) {
  67. status = ucfg_coex_send_btc_chain_mode(vdev_tmp, mode);
  68. err = qdf_status_to_os_return(status);
  69. if (err) {
  70. coex_err("Failed to set btc chain mode to %d for vdev %d",
  71. mode, vdev_id);
  72. return err;
  73. }
  74. coex_debug("Set btc chain mode to %d for vdev %d",
  75. mode, vdev_id);
  76. if (!do_restart)
  77. continue;
  78. wlan_coex_config_updated(vdev_tmp, COEX_CONFIG_BTC_CHAIN_MODE);
  79. }
  80. return 0;
  81. }
  82. /**
  83. * wlan_hdd_cfg80211_set_btc_chain_mode() - set btc chain mode
  84. * @wiphy: pointer to wireless wiphy structure.
  85. * @wdev: pointer to wireless_dev structure.
  86. * @data: pointer to btc chain mode command parameters.
  87. * @data_len: the length in byte of btc chain mode command parameters.
  88. *
  89. * Return: An error code or 0 on success.
  90. */
  91. int wlan_cfg80211_coex_set_btc_chain_mode(struct wlan_objmgr_vdev *vdev,
  92. const void *data, int data_len)
  93. {
  94. struct nlattr *tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX + 1];
  95. uint32_t mode;
  96. bool restart;
  97. if (wlan_cfg80211_nla_parse(tb, QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX,
  98. data, data_len, btc_chain_mode_policy)) {
  99. coex_err("Invalid btc chain mode ATTR");
  100. return -EINVAL;
  101. }
  102. if (!tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE]) {
  103. coex_err("btc chain mode - no attr mode");
  104. return -EINVAL;
  105. }
  106. mode = nla_get_u32(tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE]);
  107. if (mode < QCA_BTC_CHAIN_SHARED || mode > QCA_BTC_CHAIN_SEPARATED) {
  108. coex_err("Invalid btc chain mode %d", mode);
  109. return -EINVAL;
  110. }
  111. restart = nla_get_flag(tb[QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART]);
  112. coex_debug("vdev_id %u mode %u restart %u",
  113. wlan_vdev_get_id(vdev), mode, restart);
  114. return __wlan_cfg80211_coex_set_btc_chain_mode(vdev, mode, restart);
  115. }