chan.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /* Copyright(c) 2020-2022 Realtek Corporation
  3. */
  4. #include "chan.h"
  5. #include "debug.h"
  6. static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
  7. u8 center_chan)
  8. {
  9. switch (band) {
  10. default:
  11. case RTW89_BAND_2G:
  12. switch (center_chan) {
  13. default:
  14. case 1 ... 14:
  15. return RTW89_CH_2G;
  16. }
  17. case RTW89_BAND_5G:
  18. switch (center_chan) {
  19. default:
  20. case 36 ... 64:
  21. return RTW89_CH_5G_BAND_1;
  22. case 100 ... 144:
  23. return RTW89_CH_5G_BAND_3;
  24. case 149 ... 177:
  25. return RTW89_CH_5G_BAND_4;
  26. }
  27. case RTW89_BAND_6G:
  28. switch (center_chan) {
  29. default:
  30. case 1 ... 29:
  31. return RTW89_CH_6G_BAND_IDX0;
  32. case 33 ... 61:
  33. return RTW89_CH_6G_BAND_IDX1;
  34. case 65 ... 93:
  35. return RTW89_CH_6G_BAND_IDX2;
  36. case 97 ... 125:
  37. return RTW89_CH_6G_BAND_IDX3;
  38. case 129 ... 157:
  39. return RTW89_CH_6G_BAND_IDX4;
  40. case 161 ... 189:
  41. return RTW89_CH_6G_BAND_IDX5;
  42. case 193 ... 221:
  43. return RTW89_CH_6G_BAND_IDX6;
  44. case 225 ... 253:
  45. return RTW89_CH_6G_BAND_IDX7;
  46. }
  47. }
  48. }
  49. static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw,
  50. u32 center_freq,
  51. u32 primary_freq)
  52. {
  53. u8 primary_chan_idx;
  54. u32 offset;
  55. switch (bw) {
  56. default:
  57. case RTW89_CHANNEL_WIDTH_20:
  58. primary_chan_idx = RTW89_SC_DONT_CARE;
  59. break;
  60. case RTW89_CHANNEL_WIDTH_40:
  61. if (primary_freq > center_freq)
  62. primary_chan_idx = RTW89_SC_20_UPPER;
  63. else
  64. primary_chan_idx = RTW89_SC_20_LOWER;
  65. break;
  66. case RTW89_CHANNEL_WIDTH_80:
  67. case RTW89_CHANNEL_WIDTH_160:
  68. if (primary_freq > center_freq) {
  69. offset = (primary_freq - center_freq - 10) / 20;
  70. primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
  71. } else {
  72. offset = (center_freq - primary_freq - 10) / 20;
  73. primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
  74. }
  75. break;
  76. }
  77. return primary_chan_idx;
  78. }
  79. void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
  80. enum rtw89_band band, enum rtw89_bandwidth bandwidth)
  81. {
  82. enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
  83. u32 center_freq, primary_freq;
  84. memset(chan, 0, sizeof(*chan));
  85. chan->channel = center_chan;
  86. chan->primary_channel = primary_chan;
  87. chan->band_type = band;
  88. chan->band_width = bandwidth;
  89. center_freq = ieee80211_channel_to_frequency(center_chan, nl_band);
  90. primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band);
  91. chan->freq = center_freq;
  92. chan->subband_type = rtw89_get_subband_type(band, center_chan);
  93. chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq,
  94. primary_freq);
  95. }
  96. bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
  97. enum rtw89_sub_entity_idx idx,
  98. const struct rtw89_chan *new)
  99. {
  100. struct rtw89_hal *hal = &rtwdev->hal;
  101. struct rtw89_chan *chan = &hal->chan[idx];
  102. struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
  103. bool band_changed;
  104. rcd->prev_primary_channel = chan->primary_channel;
  105. rcd->prev_band_type = chan->band_type;
  106. band_changed = new->band_type != chan->band_type;
  107. *chan = *new;
  108. return band_changed;
  109. }
  110. static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
  111. enum rtw89_sub_entity_idx idx,
  112. const struct cfg80211_chan_def *chandef,
  113. bool from_stack)
  114. {
  115. struct rtw89_hal *hal = &rtwdev->hal;
  116. hal->chandef[idx] = *chandef;
  117. if (from_stack)
  118. set_bit(idx, hal->entity_map);
  119. }
  120. void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
  121. enum rtw89_sub_entity_idx idx,
  122. const struct cfg80211_chan_def *chandef)
  123. {
  124. __rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
  125. }
  126. static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
  127. {
  128. struct cfg80211_chan_def chandef = {0};
  129. rtw89_get_default_chandef(&chandef);
  130. __rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, &chandef, false);
  131. }
  132. void rtw89_entity_init(struct rtw89_dev *rtwdev)
  133. {
  134. struct rtw89_hal *hal = &rtwdev->hal;
  135. bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  136. rtw89_config_default_chandef(rtwdev);
  137. }
  138. enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
  139. {
  140. struct rtw89_hal *hal = &rtwdev->hal;
  141. enum rtw89_entity_mode mode;
  142. u8 weight;
  143. weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  144. switch (weight) {
  145. default:
  146. rtw89_warn(rtwdev, "unknown ent chan weight: %d\n", weight);
  147. bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  148. fallthrough;
  149. case 0:
  150. rtw89_config_default_chandef(rtwdev);
  151. fallthrough;
  152. case 1:
  153. mode = RTW89_ENTITY_MODE_SCC;
  154. break;
  155. }
  156. rtw89_set_entity_mode(rtwdev, mode);
  157. return mode;
  158. }
  159. int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
  160. struct ieee80211_chanctx_conf *ctx)
  161. {
  162. struct rtw89_hal *hal = &rtwdev->hal;
  163. struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  164. const struct rtw89_chip_info *chip = rtwdev->chip;
  165. u8 idx;
  166. idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  167. if (idx >= chip->support_chanctx_num)
  168. return -ENOENT;
  169. rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
  170. rtw89_set_channel(rtwdev);
  171. cfg->idx = idx;
  172. return 0;
  173. }
  174. void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
  175. struct ieee80211_chanctx_conf *ctx)
  176. {
  177. struct rtw89_hal *hal = &rtwdev->hal;
  178. struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  179. clear_bit(cfg->idx, hal->entity_map);
  180. rtw89_set_channel(rtwdev);
  181. }
  182. void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
  183. struct ieee80211_chanctx_conf *ctx,
  184. u32 changed)
  185. {
  186. struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  187. u8 idx = cfg->idx;
  188. if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
  189. rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
  190. rtw89_set_channel(rtwdev);
  191. }
  192. }
  193. int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
  194. struct rtw89_vif *rtwvif,
  195. struct ieee80211_chanctx_conf *ctx)
  196. {
  197. return 0;
  198. }
  199. void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
  200. struct rtw89_vif *rtwvif,
  201. struct ieee80211_chanctx_conf *ctx)
  202. {
  203. }