100-wifi-ath11k-use-unique-QRTR-instance-ID.patch 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. From 534a5f99d589cfa6b244b4433c192b6a278a67ff Mon Sep 17 00:00:00 2001
  2. From: Robert Marko <robimarko@gmail.com>
  3. Date: Sat, 5 Nov 2022 20:15:40 +0100
  4. Subject: [PATCH] wifi: ath11k: use unique QRTR instance ID
  5. Currently, trying to use AHB + PCI/MHI cards or multiple PCI/MHI cards
  6. will cause a clash in the QRTR instance node ID and prevent the driver
  7. from talking via QMI to the card and thus initializing it with:
  8. [ 9.836329] ath11k c000000.wifi: host capability request failed: 1 90
  9. [ 9.842047] ath11k c000000.wifi: failed to send qmi host cap: -22
  10. So, in order to allow for this combination of cards, especially AHB + PCI
  11. cards like IPQ8074 + QCN9074 (Used by me and tested on) set the desired
  12. QRTR instance ID offset by calculating a unique one based on PCI domain
  13. and bus ID-s and writing it to bits 7-0 of BHI_ERRDBG2 MHI register by
  14. using the SBL state callback that is added as part of the series.
  15. We also have to make sure that new QRTR offset is added on top of the
  16. default QRTR instance ID-s that are currently used in the driver.
  17. This finally allows using AHB + PCI or multiple PCI cards on the same
  18. system.
  19. Since this is not supported on QCA6390 and like, its limited to QCN9074
  20. which is known to support changing QRTR instance ID.
  21. Before:
  22. root@libreCMC:/# qrtr-lookup
  23. Service Version Instance Node Port
  24. 1054 1 0 7 1 <unknown>
  25. 69 1 2 7 3 ATH10k WLAN firmware service
  26. After:
  27. root@libreCMC:/# qrtr-lookup
  28. Service Version Instance Node Port
  29. 1054 1 0 7 1 <unknown>
  30. 69 1 2 7 3 ATH10k WLAN firmware service
  31. 15 1 0 8 1 Test service
  32. 69 1 8 8 2 ATH10k WLAN firmware service
  33. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
  34. Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
  35. Signed-off-by: Robert Marko <robimarko@gmail.com>
  36. ---
  37. drivers/net/wireless/ath/ath11k/mhi.c | 49 ++++++++++++++++++---------
  38. drivers/net/wireless/ath/ath11k/mhi.h | 3 ++
  39. drivers/net/wireless/ath/ath11k/pci.c | 9 ++++-
  40. 3 files changed, 44 insertions(+), 17 deletions(-)
  41. --- a/drivers/net/wireless/ath/ath11k/mhi.c
  42. +++ b/drivers/net/wireless/ath/ath11k/mhi.c
  43. @@ -294,6 +294,34 @@ static void ath11k_mhi_op_runtime_put(st
  44. {
  45. }
  46. +static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
  47. + void __iomem *addr,
  48. + u32 *out)
  49. +{
  50. + *out = readl(addr);
  51. +
  52. + return 0;
  53. +}
  54. +
  55. +static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
  56. + void __iomem *addr,
  57. + u32 val)
  58. +{
  59. + writel(val, addr);
  60. +}
  61. +
  62. +static void ath11k_mhi_qrtr_instance_set(struct mhi_controller *mhi_cntrl)
  63. +{
  64. + struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
  65. +
  66. + if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
  67. + ath11k_mhi_op_write_reg(mhi_cntrl,
  68. + mhi_cntrl->bhi + BHI_ERRDBG2,
  69. + FIELD_PREP(QRTR_INSTANCE_MASK,
  70. + ab->qmi.service_ins_id - ab->hw_params.qmi_service_ins_id));
  71. + }
  72. +}
  73. +
  74. static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason)
  75. {
  76. switch (reason) {
  77. @@ -315,6 +343,8 @@ static char *ath11k_mhi_op_callback_to_s
  78. return "MHI_CB_FATAL_ERROR";
  79. case MHI_CB_BW_REQ:
  80. return "MHI_CB_BW_REQ";
  81. + case MHI_CB_EE_SBL_MODE:
  82. + return "MHI_CB_EE_SBL_MODE";
  83. default:
  84. return "UNKNOWN";
  85. }
  86. @@ -336,27 +366,14 @@ static void ath11k_mhi_op_status_cb(stru
  87. if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
  88. queue_work(ab->workqueue_aux, &ab->reset_work);
  89. break;
  90. + case MHI_CB_EE_SBL_MODE:
  91. + ath11k_mhi_qrtr_instance_set(mhi_cntrl);
  92. + break;
  93. default:
  94. break;
  95. }
  96. }
  97. -static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
  98. - void __iomem *addr,
  99. - u32 *out)
  100. -{
  101. - *out = readl(addr);
  102. -
  103. - return 0;
  104. -}
  105. -
  106. -static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
  107. - void __iomem *addr,
  108. - u32 val)
  109. -{
  110. - writel(val, addr);
  111. -}
  112. -
  113. static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl)
  114. {
  115. struct device_node *np;
  116. --- a/drivers/net/wireless/ath/ath11k/mhi.h
  117. +++ b/drivers/net/wireless/ath/ath11k/mhi.h
  118. @@ -16,6 +16,9 @@
  119. #define MHICTRL 0x38
  120. #define MHICTRL_RESET_MASK 0x2
  121. +#define BHI_ERRDBG2 0x38
  122. +#define QRTR_INSTANCE_MASK GENMASK(7, 0)
  123. +
  124. int ath11k_mhi_start(struct ath11k_pci *ar_pci);
  125. void ath11k_mhi_stop(struct ath11k_pci *ar_pci);
  126. int ath11k_mhi_register(struct ath11k_pci *ar_pci);
  127. --- a/drivers/net/wireless/ath/ath11k/pci.c
  128. +++ b/drivers/net/wireless/ath/ath11k/pci.c
  129. @@ -370,13 +370,20 @@ static void ath11k_pci_sw_reset(struct a
  130. static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
  131. {
  132. struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
  133. + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
  134. + struct pci_bus *bus = ab_pci->pdev->bus;
  135. cfg->tgt_ce = ab->hw_params.target_ce_config;
  136. cfg->tgt_ce_len = ab->hw_params.target_ce_count;
  137. cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
  138. cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
  139. - ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
  140. +
  141. + if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) {
  142. + ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id +
  143. + (((pci_domain_nr(bus) & 0xF) << 4) | (bus->number & 0xF));
  144. + } else
  145. + ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
  146. ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,
  147. &cfg->shadow_reg_v2_len);