util.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /* Copyright(c) 2018-2019 Realtek Corporation
  3. */
  4. #include "main.h"
  5. #include "util.h"
  6. #include "reg.h"
  7. bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target)
  8. {
  9. u32 cnt;
  10. for (cnt = 0; cnt < 1000; cnt++) {
  11. if (rtw_read32_mask(rtwdev, addr, mask) == target)
  12. return true;
  13. udelay(10);
  14. }
  15. return false;
  16. }
  17. EXPORT_SYMBOL(check_hw_ready);
  18. bool ltecoex_read_reg(struct rtw_dev *rtwdev, u16 offset, u32 *val)
  19. {
  20. const struct rtw_chip_info *chip = rtwdev->chip;
  21. const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr;
  22. if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1))
  23. return false;
  24. rtw_write32(rtwdev, ltecoex->ctrl, 0x800F0000 | offset);
  25. *val = rtw_read32(rtwdev, ltecoex->rdata);
  26. return true;
  27. }
  28. bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value)
  29. {
  30. const struct rtw_chip_info *chip = rtwdev->chip;
  31. const struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr;
  32. if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1))
  33. return false;
  34. rtw_write32(rtwdev, ltecoex->wdata, value);
  35. rtw_write32(rtwdev, ltecoex->ctrl, 0xC00F0000 | offset);
  36. return true;
  37. }
  38. void rtw_restore_reg(struct rtw_dev *rtwdev,
  39. struct rtw_backup_info *bckp, u32 num)
  40. {
  41. u8 len;
  42. u32 reg;
  43. u32 val;
  44. int i;
  45. for (i = 0; i < num; i++, bckp++) {
  46. len = bckp->len;
  47. reg = bckp->reg;
  48. val = bckp->val;
  49. switch (len) {
  50. case 1:
  51. rtw_write8(rtwdev, reg, (u8)val);
  52. break;
  53. case 2:
  54. rtw_write16(rtwdev, reg, (u16)val);
  55. break;
  56. case 4:
  57. rtw_write32(rtwdev, reg, (u32)val);
  58. break;
  59. default:
  60. break;
  61. }
  62. }
  63. }
  64. EXPORT_SYMBOL(rtw_restore_reg);
  65. void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
  66. {
  67. if (rate <= DESC_RATE54M)
  68. return;
  69. if (rate >= DESC_RATEVHT1SS_MCS0 &&
  70. rate <= DESC_RATEVHT1SS_MCS9) {
  71. *nss = 1;
  72. *mcs = rate - DESC_RATEVHT1SS_MCS0;
  73. } else if (rate >= DESC_RATEVHT2SS_MCS0 &&
  74. rate <= DESC_RATEVHT2SS_MCS9) {
  75. *nss = 2;
  76. *mcs = rate - DESC_RATEVHT2SS_MCS0;
  77. } else if (rate >= DESC_RATEVHT3SS_MCS0 &&
  78. rate <= DESC_RATEVHT3SS_MCS9) {
  79. *nss = 3;
  80. *mcs = rate - DESC_RATEVHT3SS_MCS0;
  81. } else if (rate >= DESC_RATEVHT4SS_MCS0 &&
  82. rate <= DESC_RATEVHT4SS_MCS9) {
  83. *nss = 4;
  84. *mcs = rate - DESC_RATEVHT4SS_MCS0;
  85. } else if (rate >= DESC_RATEMCS0 &&
  86. rate <= DESC_RATEMCS31) {
  87. *nss = 0;
  88. *mcs = rate - DESC_RATEMCS0;
  89. }
  90. }
  91. struct rtw_stas_entry {
  92. struct list_head list;
  93. struct ieee80211_sta *sta;
  94. };
  95. struct rtw_iter_stas_data {
  96. struct rtw_dev *rtwdev;
  97. struct list_head list;
  98. };
  99. static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
  100. {
  101. struct rtw_iter_stas_data *iter_stas = data;
  102. struct rtw_stas_entry *stas_entry;
  103. stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC);
  104. if (!stas_entry)
  105. return;
  106. stas_entry->sta = sta;
  107. list_add_tail(&stas_entry->list, &iter_stas->list);
  108. }
  109. void rtw_iterate_stas(struct rtw_dev *rtwdev,
  110. void (*iterator)(void *data,
  111. struct ieee80211_sta *sta),
  112. void *data)
  113. {
  114. struct rtw_iter_stas_data iter_data;
  115. struct rtw_stas_entry *sta_entry, *tmp;
  116. /* &rtwdev->mutex makes sure no stations can be removed between
  117. * collecting the stations and iterating over them.
  118. */
  119. lockdep_assert_held(&rtwdev->mutex);
  120. iter_data.rtwdev = rtwdev;
  121. INIT_LIST_HEAD(&iter_data.list);
  122. ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter,
  123. &iter_data);
  124. list_for_each_entry_safe(sta_entry, tmp, &iter_data.list,
  125. list) {
  126. list_del_init(&sta_entry->list);
  127. iterator(data, sta_entry->sta);
  128. kfree(sta_entry);
  129. }
  130. }
  131. struct rtw_vifs_entry {
  132. struct list_head list;
  133. struct ieee80211_vif *vif;
  134. };
  135. struct rtw_iter_vifs_data {
  136. struct rtw_dev *rtwdev;
  137. struct list_head list;
  138. };
  139. static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
  140. {
  141. struct rtw_iter_vifs_data *iter_stas = data;
  142. struct rtw_vifs_entry *vifs_entry;
  143. vifs_entry = kmalloc_obj(*vifs_entry, GFP_ATOMIC);
  144. if (!vifs_entry)
  145. return;
  146. vifs_entry->vif = vif;
  147. list_add_tail(&vifs_entry->list, &iter_stas->list);
  148. }
  149. void rtw_iterate_vifs(struct rtw_dev *rtwdev,
  150. void (*iterator)(void *data, struct ieee80211_vif *vif),
  151. void *data)
  152. {
  153. struct rtw_iter_vifs_data iter_data;
  154. struct rtw_vifs_entry *vif_entry, *tmp;
  155. /* &rtwdev->mutex makes sure no interfaces can be removed between
  156. * collecting the interfaces and iterating over them.
  157. */
  158. lockdep_assert_held(&rtwdev->mutex);
  159. iter_data.rtwdev = rtwdev;
  160. INIT_LIST_HEAD(&iter_data.list);
  161. ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
  162. IEEE80211_IFACE_ITER_NORMAL,
  163. rtw_collect_vif_iter, &iter_data);
  164. list_for_each_entry_safe(vif_entry, tmp, &iter_data.list,
  165. list) {
  166. list_del_init(&vif_entry->list);
  167. iterator(data, vif_entry->vif);
  168. kfree(vif_entry);
  169. }
  170. }