1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2020-2022 Realtek Corporation 3 */ 4 5 #include "chan.h" 6 #include "debug.h" 7 #include "fw.h" 8 #include "ps.h" 9 #include "util.h" 10 11 static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band, 12 u8 center_chan) 13 { 14 switch (band) { 15 default: 16 case RTW89_BAND_2G: 17 switch (center_chan) { 18 default: 19 case 1 ... 14: 20 return RTW89_CH_2G; 21 } 22 case RTW89_BAND_5G: 23 switch (center_chan) { 24 default: 25 case 36 ... 64: 26 return RTW89_CH_5G_BAND_1; 27 case 100 ... 144: 28 return RTW89_CH_5G_BAND_3; 29 case 149 ... 177: 30 return RTW89_CH_5G_BAND_4; 31 } 32 case RTW89_BAND_6G: 33 switch (center_chan) { 34 default: 35 case 1 ... 29: 36 return RTW89_CH_6G_BAND_IDX0; 37 case 33 ... 61: 38 return RTW89_CH_6G_BAND_IDX1; 39 case 65 ... 93: 40 return RTW89_CH_6G_BAND_IDX2; 41 case 97 ... 125: 42 return RTW89_CH_6G_BAND_IDX3; 43 case 129 ... 157: 44 return RTW89_CH_6G_BAND_IDX4; 45 case 161 ... 189: 46 return RTW89_CH_6G_BAND_IDX5; 47 case 193 ... 221: 48 return RTW89_CH_6G_BAND_IDX6; 49 case 225 ... 253: 50 return RTW89_CH_6G_BAND_IDX7; 51 } 52 } 53 } 54 55 static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw, 56 u32 center_freq, 57 u32 primary_freq) 58 { 59 u8 primary_chan_idx; 60 u32 offset; 61 62 switch (bw) { 63 default: 64 case RTW89_CHANNEL_WIDTH_20: 65 primary_chan_idx = RTW89_SC_DONT_CARE; 66 break; 67 case RTW89_CHANNEL_WIDTH_40: 68 if (primary_freq > center_freq) 69 primary_chan_idx = RTW89_SC_20_UPPER; 70 else 71 primary_chan_idx = RTW89_SC_20_LOWER; 72 break; 73 case RTW89_CHANNEL_WIDTH_80: 74 case RTW89_CHANNEL_WIDTH_160: 75 if (primary_freq > center_freq) { 76 offset = (primary_freq - center_freq - 10) / 20; 77 primary_chan_idx = RTW89_SC_20_UPPER + offset * 2; 78 } else { 79 offset = (center_freq - primary_freq - 10) / 20; 80 primary_chan_idx = RTW89_SC_20_LOWER + offset * 2; 81 } 82 break; 83 } 84 85 return primary_chan_idx; 86 } 87 88 void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan, 89 enum rtw89_band band, enum rtw89_bandwidth bandwidth) 90 { 91 enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); 92 u32 center_freq, primary_freq; 93 94 memset(chan, 0, sizeof(*chan)); 95 chan->channel = center_chan; 96 chan->primary_channel = primary_chan; 97 chan->band_type = band; 98 chan->band_width = bandwidth; 99 100 center_freq = ieee80211_channel_to_frequency(center_chan, nl_band); 101 primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band); 102 103 chan->freq = center_freq; 104 chan->subband_type = rtw89_get_subband_type(band, center_chan); 105 chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq, 106 primary_freq); 107 } 108 109 bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev, 110 enum rtw89_sub_entity_idx idx, 111 const struct rtw89_chan *new) 112 { 113 struct rtw89_hal *hal = &rtwdev->hal; 114 struct rtw89_chan *chan = &hal->sub[idx].chan; 115 struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd; 116 bool band_changed; 117 118 rcd->prev_primary_channel = chan->primary_channel; 119 rcd->prev_band_type = chan->band_type; 120 band_changed = new->band_type != chan->band_type; 121 rcd->band_changed = band_changed; 122 123 *chan = *new; 124 return band_changed; 125 } 126 127 static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, 128 enum rtw89_sub_entity_idx idx, 129 const struct cfg80211_chan_def *chandef, 130 bool from_stack) 131 { 132 struct rtw89_hal *hal = &rtwdev->hal; 133 134 hal->sub[idx].chandef = *chandef; 135 136 if (from_stack) 137 set_bit(idx, hal->entity_map); 138 } 139 140 void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, 141 enum rtw89_sub_entity_idx idx, 142 const struct cfg80211_chan_def *chandef) 143 { 144 __rtw89_config_entity_chandef(rtwdev, idx, chandef, true); 145 } 146 147 void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev, 148 enum rtw89_sub_entity_idx idx, 149 const struct cfg80211_chan_def *chandef) 150 { 151 struct rtw89_hal *hal = &rtwdev->hal; 152 enum rtw89_sub_entity_idx cur; 153 154 if (chandef) { 155 cur = atomic_cmpxchg(&hal->roc_entity_idx, 156 RTW89_SUB_ENTITY_IDLE, idx); 157 if (cur != RTW89_SUB_ENTITY_IDLE) { 158 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 159 "ROC still processing on entity %d\n", idx); 160 return; 161 } 162 163 hal->roc_chandef = *chandef; 164 } else { 165 cur = atomic_cmpxchg(&hal->roc_entity_idx, idx, 166 RTW89_SUB_ENTITY_IDLE); 167 if (cur == idx) 168 return; 169 170 if (cur == RTW89_SUB_ENTITY_IDLE) 171 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 172 "ROC already finished on entity %d\n", idx); 173 else 174 rtw89_debug(rtwdev, RTW89_DBG_TXRX, 175 "ROC is processing on entity %d\n", cur); 176 } 177 } 178 179 static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev) 180 { 181 struct cfg80211_chan_def chandef = {0}; 182 183 rtw89_get_default_chandef(&chandef); 184 __rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, &chandef, false); 185 } 186 187 void rtw89_entity_init(struct rtw89_dev *rtwdev) 188 { 189 struct rtw89_hal *hal = &rtwdev->hal; 190 191 bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY); 192 atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE); 193 rtw89_config_default_chandef(rtwdev); 194 } 195 196 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev) 197 { 198 struct rtw89_hal *hal = &rtwdev->hal; 199 const struct cfg80211_chan_def *chandef; 200 enum rtw89_entity_mode mode; 201 struct rtw89_chan chan; 202 u8 weight; 203 u8 last; 204 u8 idx; 205 206 weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY); 207 switch (weight) { 208 default: 209 rtw89_warn(rtwdev, "unknown ent chan weight: %d\n", weight); 210 bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY); 211 fallthrough; 212 case 0: 213 rtw89_config_default_chandef(rtwdev); 214 fallthrough; 215 case 1: 216 last = RTW89_SUB_ENTITY_0; 217 mode = RTW89_ENTITY_MODE_SCC; 218 break; 219 case 2: 220 last = RTW89_SUB_ENTITY_1; 221 mode = rtw89_get_entity_mode(rtwdev); 222 if (mode == RTW89_ENTITY_MODE_MCC) 223 break; 224 225 mode = RTW89_ENTITY_MODE_MCC_PREPARE; 226 break; 227 } 228 229 for (idx = 0; idx <= last; idx++) { 230 chandef = rtw89_chandef_get(rtwdev, idx); 231 rtw89_get_channel_params(chandef, &chan); 232 if (chan.channel == 0) { 233 WARN(1, "Invalid channel on chanctx %d\n", idx); 234 return RTW89_ENTITY_MODE_INVALID; 235 } 236 237 rtw89_assign_entity_chan(rtwdev, idx, &chan); 238 } 239 240 rtw89_set_entity_mode(rtwdev, mode); 241 return mode; 242 } 243 244 static void rtw89_chanctx_notify(struct rtw89_dev *rtwdev, 245 enum rtw89_chanctx_state state) 246 { 247 const struct rtw89_chip_info *chip = rtwdev->chip; 248 const struct rtw89_chanctx_listener *listener = chip->chanctx_listener; 249 int i; 250 251 if (!listener) 252 return; 253 254 for (i = 0; i < NUM_OF_RTW89_CHANCTX_CALLBACKS; i++) { 255 if (!listener->callbacks[i]) 256 continue; 257 258 rtw89_debug(rtwdev, RTW89_DBG_CHAN, 259 "chanctx notify listener: cb %d, state %d\n", 260 i, state); 261 262 listener->callbacks[i](rtwdev, state); 263 } 264 } 265 266 static int rtw89_mcc_start(struct rtw89_dev *rtwdev) 267 { 268 if (rtwdev->scanning) 269 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); 270 271 rtw89_leave_lps(rtwdev); 272 273 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC start\n"); 274 rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_START); 275 return 0; 276 } 277 278 static void rtw89_mcc_stop(struct rtw89_dev *rtwdev) 279 { 280 rtw89_debug(rtwdev, RTW89_DBG_CHAN, "MCC stop\n"); 281 rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP); 282 } 283 284 void rtw89_chanctx_work(struct work_struct *work) 285 { 286 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 287 chanctx_work.work); 288 enum rtw89_entity_mode mode; 289 int ret; 290 291 mutex_lock(&rtwdev->mutex); 292 293 mode = rtw89_get_entity_mode(rtwdev); 294 switch (mode) { 295 case RTW89_ENTITY_MODE_MCC_PREPARE: 296 rtw89_set_entity_mode(rtwdev, RTW89_ENTITY_MODE_MCC); 297 rtw89_set_channel(rtwdev); 298 299 ret = rtw89_mcc_start(rtwdev); 300 if (ret) 301 rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret); 302 break; 303 default: 304 break; 305 } 306 307 mutex_unlock(&rtwdev->mutex); 308 } 309 310 void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev) 311 { 312 enum rtw89_entity_mode mode; 313 u32 delay; 314 315 mode = rtw89_get_entity_mode(rtwdev); 316 switch (mode) { 317 default: 318 return; 319 case RTW89_ENTITY_MODE_MCC_PREPARE: 320 delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE); 321 break; 322 } 323 324 rtw89_debug(rtwdev, RTW89_DBG_CHAN, 325 "queue chanctx work for mode %d with delay %d us\n", 326 mode, delay); 327 ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work, 328 usecs_to_jiffies(delay)); 329 } 330 331 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, 332 struct ieee80211_chanctx_conf *ctx) 333 { 334 struct rtw89_hal *hal = &rtwdev->hal; 335 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; 336 const struct rtw89_chip_info *chip = rtwdev->chip; 337 u8 idx; 338 339 idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY); 340 if (idx >= chip->support_chanctx_num) 341 return -ENOENT; 342 343 rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); 344 rtw89_set_channel(rtwdev); 345 cfg->idx = idx; 346 hal->sub[idx].cfg = cfg; 347 return 0; 348 } 349 350 void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev, 351 struct ieee80211_chanctx_conf *ctx) 352 { 353 struct rtw89_hal *hal = &rtwdev->hal; 354 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; 355 enum rtw89_entity_mode mode; 356 struct rtw89_vif *rtwvif; 357 u8 drop, roll; 358 359 drop = cfg->idx; 360 if (drop != RTW89_SUB_ENTITY_0) 361 goto out; 362 363 roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1); 364 365 /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */ 366 if (roll == NUM_OF_RTW89_SUB_ENTITY) 367 goto out; 368 369 /* RTW89_SUB_ENTITY_0 is going to release, and another exists. 370 * Make another roll down to RTW89_SUB_ENTITY_0 to replace. 371 */ 372 hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0; 373 hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll]; 374 375 rtw89_for_each_rtwvif(rtwdev, rtwvif) { 376 if (rtwvif->sub_entity_idx == roll) 377 rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; 378 } 379 380 atomic_cmpxchg(&hal->roc_entity_idx, roll, RTW89_SUB_ENTITY_0); 381 382 drop = roll; 383 384 out: 385 mode = rtw89_get_entity_mode(rtwdev); 386 switch (mode) { 387 case RTW89_ENTITY_MODE_MCC: 388 rtw89_mcc_stop(rtwdev); 389 break; 390 default: 391 break; 392 } 393 394 clear_bit(drop, hal->entity_map); 395 rtw89_set_channel(rtwdev); 396 } 397 398 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev, 399 struct ieee80211_chanctx_conf *ctx, 400 u32 changed) 401 { 402 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; 403 u8 idx = cfg->idx; 404 405 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) { 406 rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); 407 rtw89_set_channel(rtwdev); 408 } 409 } 410 411 int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, 412 struct rtw89_vif *rtwvif, 413 struct ieee80211_chanctx_conf *ctx) 414 { 415 struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; 416 417 rtwvif->sub_entity_idx = cfg->idx; 418 return 0; 419 } 420 421 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, 422 struct rtw89_vif *rtwvif, 423 struct ieee80211_chanctx_conf *ctx) 424 { 425 rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; 426 } 427