1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2018-2019 Realtek Corporation |
3 | */ |
4 | |
5 | #include <linux/devcoredump.h> |
6 | |
7 | #include "main.h" |
8 | #include "regd.h" |
9 | #include "fw.h" |
10 | #include "ps.h" |
11 | #include "sec.h" |
12 | #include "mac.h" |
13 | #include "coex.h" |
14 | #include "phy.h" |
15 | #include "reg.h" |
16 | #include "efuse.h" |
17 | #include "tx.h" |
18 | #include "debug.h" |
19 | #include "bf.h" |
20 | #include "sar.h" |
21 | #include "sdio.h" |
22 | |
23 | bool rtw_disable_lps_deep_mode; |
24 | EXPORT_SYMBOL(rtw_disable_lps_deep_mode); |
25 | bool rtw_bf_support = true; |
26 | unsigned int rtw_debug_mask; |
27 | EXPORT_SYMBOL(rtw_debug_mask); |
28 | /* EDCCA is enabled during normal behavior. For debugging purpose in |
29 | * a noisy environment, it can be disabled via edcca debugfs. Because |
30 | * all rtw88 devices will probably be affected if environment is noisy, |
31 | * rtw_edcca_enabled is just declared by driver instead of by device. |
32 | * So, turning it off will take effect for all rtw88 devices before |
33 | * there is a tough reason to maintain rtw_edcca_enabled by device. |
34 | */ |
35 | bool rtw_edcca_enabled = true; |
36 | |
37 | module_param_named(disable_lps_deep, rtw_disable_lps_deep_mode, bool, 0644); |
38 | module_param_named(support_bf, rtw_bf_support, bool, 0644); |
39 | module_param_named(debug_mask, rtw_debug_mask, uint, 0644); |
40 | |
41 | MODULE_PARM_DESC(disable_lps_deep, "Set Y to disable Deep PS" ); |
42 | MODULE_PARM_DESC(support_bf, "Set Y to enable beamformee support" ); |
43 | MODULE_PARM_DESC(debug_mask, "Debugging mask" ); |
44 | |
45 | static struct ieee80211_channel rtw_channeltable_2g[] = { |
46 | {.center_freq = 2412, .hw_value = 1,}, |
47 | {.center_freq = 2417, .hw_value = 2,}, |
48 | {.center_freq = 2422, .hw_value = 3,}, |
49 | {.center_freq = 2427, .hw_value = 4,}, |
50 | {.center_freq = 2432, .hw_value = 5,}, |
51 | {.center_freq = 2437, .hw_value = 6,}, |
52 | {.center_freq = 2442, .hw_value = 7,}, |
53 | {.center_freq = 2447, .hw_value = 8,}, |
54 | {.center_freq = 2452, .hw_value = 9,}, |
55 | {.center_freq = 2457, .hw_value = 10,}, |
56 | {.center_freq = 2462, .hw_value = 11,}, |
57 | {.center_freq = 2467, .hw_value = 12,}, |
58 | {.center_freq = 2472, .hw_value = 13,}, |
59 | {.center_freq = 2484, .hw_value = 14,}, |
60 | }; |
61 | |
62 | static struct ieee80211_channel rtw_channeltable_5g[] = { |
63 | {.center_freq = 5180, .hw_value = 36,}, |
64 | {.center_freq = 5200, .hw_value = 40,}, |
65 | {.center_freq = 5220, .hw_value = 44,}, |
66 | {.center_freq = 5240, .hw_value = 48,}, |
67 | {.center_freq = 5260, .hw_value = 52,}, |
68 | {.center_freq = 5280, .hw_value = 56,}, |
69 | {.center_freq = 5300, .hw_value = 60,}, |
70 | {.center_freq = 5320, .hw_value = 64,}, |
71 | {.center_freq = 5500, .hw_value = 100,}, |
72 | {.center_freq = 5520, .hw_value = 104,}, |
73 | {.center_freq = 5540, .hw_value = 108,}, |
74 | {.center_freq = 5560, .hw_value = 112,}, |
75 | {.center_freq = 5580, .hw_value = 116,}, |
76 | {.center_freq = 5600, .hw_value = 120,}, |
77 | {.center_freq = 5620, .hw_value = 124,}, |
78 | {.center_freq = 5640, .hw_value = 128,}, |
79 | {.center_freq = 5660, .hw_value = 132,}, |
80 | {.center_freq = 5680, .hw_value = 136,}, |
81 | {.center_freq = 5700, .hw_value = 140,}, |
82 | {.center_freq = 5720, .hw_value = 144,}, |
83 | {.center_freq = 5745, .hw_value = 149,}, |
84 | {.center_freq = 5765, .hw_value = 153,}, |
85 | {.center_freq = 5785, .hw_value = 157,}, |
86 | {.center_freq = 5805, .hw_value = 161,}, |
87 | {.center_freq = 5825, .hw_value = 165, |
88 | .flags = IEEE80211_CHAN_NO_HT40MINUS}, |
89 | }; |
90 | |
91 | static struct ieee80211_rate rtw_ratetable[] = { |
92 | {.bitrate = 10, .hw_value = 0x00,}, |
93 | {.bitrate = 20, .hw_value = 0x01,}, |
94 | {.bitrate = 55, .hw_value = 0x02,}, |
95 | {.bitrate = 110, .hw_value = 0x03,}, |
96 | {.bitrate = 60, .hw_value = 0x04,}, |
97 | {.bitrate = 90, .hw_value = 0x05,}, |
98 | {.bitrate = 120, .hw_value = 0x06,}, |
99 | {.bitrate = 180, .hw_value = 0x07,}, |
100 | {.bitrate = 240, .hw_value = 0x08,}, |
101 | {.bitrate = 360, .hw_value = 0x09,}, |
102 | {.bitrate = 480, .hw_value = 0x0a,}, |
103 | {.bitrate = 540, .hw_value = 0x0b,}, |
104 | }; |
105 | |
106 | static const struct ieee80211_iface_limit rtw_iface_limits[] = { |
107 | { |
108 | .max = 1, |
109 | .types = BIT(NL80211_IFTYPE_STATION), |
110 | }, |
111 | { |
112 | .max = 1, |
113 | .types = BIT(NL80211_IFTYPE_AP), |
114 | } |
115 | }; |
116 | |
117 | static const struct ieee80211_iface_combination rtw_iface_combs[] = { |
118 | { |
119 | .limits = rtw_iface_limits, |
120 | .n_limits = ARRAY_SIZE(rtw_iface_limits), |
121 | .max_interfaces = 2, |
122 | .num_different_channels = 1, |
123 | } |
124 | }; |
125 | |
126 | u16 rtw_desc_to_bitrate(u8 desc_rate) |
127 | { |
128 | struct ieee80211_rate rate; |
129 | |
130 | if (WARN(desc_rate >= ARRAY_SIZE(rtw_ratetable), "invalid desc rate\n" )) |
131 | return 0; |
132 | |
133 | rate = rtw_ratetable[desc_rate]; |
134 | |
135 | return rate.bitrate; |
136 | } |
137 | |
138 | static struct ieee80211_supported_band rtw_band_2ghz = { |
139 | .band = NL80211_BAND_2GHZ, |
140 | |
141 | .channels = rtw_channeltable_2g, |
142 | .n_channels = ARRAY_SIZE(rtw_channeltable_2g), |
143 | |
144 | .bitrates = rtw_ratetable, |
145 | .n_bitrates = ARRAY_SIZE(rtw_ratetable), |
146 | |
147 | .ht_cap = {0}, |
148 | .vht_cap = {0}, |
149 | }; |
150 | |
151 | static struct ieee80211_supported_band rtw_band_5ghz = { |
152 | .band = NL80211_BAND_5GHZ, |
153 | |
154 | .channels = rtw_channeltable_5g, |
155 | .n_channels = ARRAY_SIZE(rtw_channeltable_5g), |
156 | |
157 | /* 5G has no CCK rates */ |
158 | .bitrates = rtw_ratetable + 4, |
159 | .n_bitrates = ARRAY_SIZE(rtw_ratetable) - 4, |
160 | |
161 | .ht_cap = {0}, |
162 | .vht_cap = {0}, |
163 | }; |
164 | |
165 | struct rtw_watch_dog_iter_data { |
166 | struct rtw_dev *rtwdev; |
167 | struct rtw_vif *rtwvif; |
168 | }; |
169 | |
170 | static void rtw_dynamic_csi_rate(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) |
171 | { |
172 | struct rtw_bf_info *bf_info = &rtwdev->bf_info; |
173 | u8 fix_rate_enable = 0; |
174 | u8 new_csi_rate_idx; |
175 | |
176 | if (rtwvif->bfee.role != RTW_BFEE_SU && |
177 | rtwvif->bfee.role != RTW_BFEE_MU) |
178 | return; |
179 | |
180 | rtw_chip_cfg_csi_rate(rtwdev, rssi: rtwdev->dm_info.min_rssi, |
181 | cur_rate: bf_info->cur_csi_rpt_rate, |
182 | fixrate_en: fix_rate_enable, new_rate: &new_csi_rate_idx); |
183 | |
184 | if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate) |
185 | bf_info->cur_csi_rpt_rate = new_csi_rate_idx; |
186 | } |
187 | |
188 | static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif) |
189 | { |
190 | struct rtw_watch_dog_iter_data *iter_data = data; |
191 | struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; |
192 | |
193 | if (vif->type == NL80211_IFTYPE_STATION) |
194 | if (vif->cfg.assoc) |
195 | iter_data->rtwvif = rtwvif; |
196 | |
197 | rtw_dynamic_csi_rate(rtwdev: iter_data->rtwdev, rtwvif); |
198 | |
199 | rtwvif->stats.tx_unicast = 0; |
200 | rtwvif->stats.rx_unicast = 0; |
201 | rtwvif->stats.tx_cnt = 0; |
202 | rtwvif->stats.rx_cnt = 0; |
203 | } |
204 | |
205 | /* process TX/RX statistics periodically for hardware, |
206 | * the information helps hardware to enhance performance |
207 | */ |
208 | static void rtw_watch_dog_work(struct work_struct *work) |
209 | { |
210 | struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, |
211 | watch_dog_work.work); |
212 | struct rtw_traffic_stats *stats = &rtwdev->stats; |
213 | struct rtw_watch_dog_iter_data data = {}; |
214 | bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); |
215 | bool ps_active; |
216 | |
217 | mutex_lock(&rtwdev->mutex); |
218 | |
219 | if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) |
220 | goto unlock; |
221 | |
222 | ieee80211_queue_delayed_work(hw: rtwdev->hw, dwork: &rtwdev->watch_dog_work, |
223 | RTW_WATCH_DOG_DELAY_TIME); |
224 | |
225 | if (rtwdev->stats.tx_cnt > 100 || rtwdev->stats.rx_cnt > 100) |
226 | set_bit(nr: RTW_FLAG_BUSY_TRAFFIC, addr: rtwdev->flags); |
227 | else |
228 | clear_bit(nr: RTW_FLAG_BUSY_TRAFFIC, addr: rtwdev->flags); |
229 | |
230 | rtw_coex_wl_status_check(rtwdev); |
231 | rtw_coex_query_bt_hid_list(rtwdev); |
232 | |
233 | if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags)) |
234 | rtw_coex_wl_status_change_notify(rtwdev, type: 0); |
235 | |
236 | if (stats->tx_cnt > RTW_LPS_THRESHOLD || |
237 | stats->rx_cnt > RTW_LPS_THRESHOLD) |
238 | ps_active = true; |
239 | else |
240 | ps_active = false; |
241 | |
242 | ewma_tp_add(e: &stats->tx_ewma_tp, |
243 | val: (u32)(stats->tx_unicast >> RTW_TP_SHIFT)); |
244 | ewma_tp_add(e: &stats->rx_ewma_tp, |
245 | val: (u32)(stats->rx_unicast >> RTW_TP_SHIFT)); |
246 | stats->tx_throughput = ewma_tp_read(e: &stats->tx_ewma_tp); |
247 | stats->rx_throughput = ewma_tp_read(e: &stats->rx_ewma_tp); |
248 | |
249 | /* reset tx/rx statictics */ |
250 | stats->tx_unicast = 0; |
251 | stats->rx_unicast = 0; |
252 | stats->tx_cnt = 0; |
253 | stats->rx_cnt = 0; |
254 | |
255 | if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) |
256 | goto unlock; |
257 | |
258 | /* make sure BB/RF is working for dynamic mech */ |
259 | rtw_leave_lps(rtwdev); |
260 | |
261 | rtw_phy_dynamic_mechanism(rtwdev); |
262 | |
263 | data.rtwdev = rtwdev; |
264 | /* rtw_iterate_vifs internally uses an atomic iterator which is needed |
265 | * to avoid taking local->iflist_mtx mutex |
266 | */ |
267 | rtw_iterate_vifs(rtwdev, iterator: rtw_vif_watch_dog_iter, data: &data); |
268 | |
269 | /* fw supports only one station associated to enter lps, if there are |
270 | * more than two stations associated to the AP, then we can not enter |
271 | * lps, because fw does not handle the overlapped beacon interval |
272 | * |
273 | * rtw_recalc_lps() iterate vifs and determine if driver can enter |
274 | * ps by vif->type and vif->cfg.ps, all we need to do here is to |
275 | * get that vif and check if device is having traffic more than the |
276 | * threshold. |
277 | */ |
278 | if (rtwdev->ps_enabled && data.rtwvif && !ps_active && |
279 | !rtwdev->beacon_loss && !rtwdev->ap_active) |
280 | rtw_enter_lps(rtwdev, port_id: data.rtwvif->port); |
281 | |
282 | rtwdev->watch_dog_cnt++; |
283 | |
284 | unlock: |
285 | mutex_unlock(lock: &rtwdev->mutex); |
286 | } |
287 | |
288 | static void rtw_c2h_work(struct work_struct *work) |
289 | { |
290 | struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, c2h_work); |
291 | struct sk_buff *skb, *tmp; |
292 | |
293 | skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { |
294 | skb_unlink(skb, list: &rtwdev->c2h_queue); |
295 | rtw_fw_c2h_cmd_handle(rtwdev, skb); |
296 | dev_kfree_skb_any(skb); |
297 | } |
298 | } |
299 | |
300 | static void rtw_ips_work(struct work_struct *work) |
301 | { |
302 | struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work); |
303 | |
304 | mutex_lock(&rtwdev->mutex); |
305 | if (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE) |
306 | rtw_enter_ips(rtwdev); |
307 | mutex_unlock(lock: &rtwdev->mutex); |
308 | } |
309 | |
310 | static u8 rtw_acquire_macid(struct rtw_dev *rtwdev) |
311 | { |
312 | unsigned long mac_id; |
313 | |
314 | mac_id = find_first_zero_bit(addr: rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); |
315 | if (mac_id < RTW_MAX_MAC_ID_NUM) |
316 | set_bit(nr: mac_id, addr: rtwdev->mac_id_map); |
317 | |
318 | return mac_id; |
319 | } |
320 | |
321 | static void rtw_sta_rc_work(struct work_struct *work) |
322 | { |
323 | struct rtw_sta_info *si = container_of(work, struct rtw_sta_info, |
324 | rc_work); |
325 | struct rtw_dev *rtwdev = si->rtwdev; |
326 | |
327 | mutex_lock(&rtwdev->mutex); |
328 | rtw_update_sta_info(rtwdev, si, reset_ra_mask: true); |
329 | mutex_unlock(lock: &rtwdev->mutex); |
330 | } |
331 | |
332 | int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, |
333 | struct ieee80211_vif *vif) |
334 | { |
335 | struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; |
336 | struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; |
337 | int i; |
338 | |
339 | si->mac_id = rtw_acquire_macid(rtwdev); |
340 | if (si->mac_id >= RTW_MAX_MAC_ID_NUM) |
341 | return -ENOSPC; |
342 | |
343 | if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) |
344 | rtwvif->mac_id = si->mac_id; |
345 | si->rtwdev = rtwdev; |
346 | si->sta = sta; |
347 | si->vif = vif; |
348 | si->init_ra_lv = 1; |
349 | ewma_rssi_init(e: &si->avg_rssi); |
350 | for (i = 0; i < ARRAY_SIZE(sta->txq); i++) |
351 | rtw_txq_init(rtwdev, txq: sta->txq[i]); |
352 | INIT_WORK(&si->rc_work, rtw_sta_rc_work); |
353 | |
354 | rtw_update_sta_info(rtwdev, si, reset_ra_mask: true); |
355 | rtw_fw_media_status_report(rtwdev, mac_id: si->mac_id, conn: true); |
356 | |
357 | rtwdev->sta_cnt++; |
358 | rtwdev->beacon_loss = false; |
359 | rtw_dbg(rtwdev, mask: RTW_DBG_STATE, fmt: "sta %pM joined with macid %d\n" , |
360 | sta->addr, si->mac_id); |
361 | |
362 | return 0; |
363 | } |
364 | |
365 | void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, |
366 | bool fw_exist) |
367 | { |
368 | struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; |
369 | int i; |
370 | |
371 | cancel_work_sync(work: &si->rc_work); |
372 | |
373 | rtw_release_macid(rtwdev, mac_id: si->mac_id); |
374 | if (fw_exist) |
375 | rtw_fw_media_status_report(rtwdev, mac_id: si->mac_id, conn: false); |
376 | |
377 | for (i = 0; i < ARRAY_SIZE(sta->txq); i++) |
378 | rtw_txq_cleanup(rtwdev, txq: sta->txq[i]); |
379 | |
380 | kfree(objp: si->mask); |
381 | |
382 | rtwdev->sta_cnt--; |
383 | rtw_dbg(rtwdev, mask: RTW_DBG_STATE, fmt: "sta %pM with macid %d left\n" , |
384 | sta->addr, si->mac_id); |
385 | } |
386 | |
387 | struct rtw_fwcd_hdr { |
388 | u32 item; |
389 | u32 size; |
390 | u32 padding1; |
391 | u32 padding2; |
392 | } __packed; |
393 | |
394 | static int rtw_fwcd_prep(struct rtw_dev *rtwdev) |
395 | { |
396 | const struct rtw_chip_info *chip = rtwdev->chip; |
397 | struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; |
398 | const struct rtw_fwcd_segs *segs = chip->fwcd_segs; |
399 | u32 prep_size = chip->fw_rxff_size + sizeof(struct rtw_fwcd_hdr); |
400 | u8 i; |
401 | |
402 | if (segs) { |
403 | prep_size += segs->num * sizeof(struct rtw_fwcd_hdr); |
404 | |
405 | for (i = 0; i < segs->num; i++) |
406 | prep_size += segs->segs[i]; |
407 | } |
408 | |
409 | desc->data = vmalloc(size: prep_size); |
410 | if (!desc->data) |
411 | return -ENOMEM; |
412 | |
413 | desc->size = prep_size; |
414 | desc->next = desc->data; |
415 | |
416 | return 0; |
417 | } |
418 | |
419 | static u8 *rtw_fwcd_next(struct rtw_dev *rtwdev, u32 item, u32 size) |
420 | { |
421 | struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; |
422 | struct rtw_fwcd_hdr *hdr; |
423 | u8 *next; |
424 | |
425 | if (!desc->data) { |
426 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "fwcd isn't prepared successfully\n" ); |
427 | return NULL; |
428 | } |
429 | |
430 | next = desc->next + sizeof(struct rtw_fwcd_hdr); |
431 | if (next - desc->data + size > desc->size) { |
432 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "fwcd isn't prepared enough\n" ); |
433 | return NULL; |
434 | } |
435 | |
436 | hdr = (struct rtw_fwcd_hdr *)(desc->next); |
437 | hdr->item = item; |
438 | hdr->size = size; |
439 | hdr->padding1 = 0x01234567; |
440 | hdr->padding2 = 0x89abcdef; |
441 | desc->next = next + size; |
442 | |
443 | return next; |
444 | } |
445 | |
446 | static void rtw_fwcd_dump(struct rtw_dev *rtwdev) |
447 | { |
448 | struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; |
449 | |
450 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "dump fwcd\n" ); |
451 | |
452 | /* Data will be freed after lifetime of device coredump. After calling |
453 | * dev_coredump, data is supposed to be handled by the device coredump |
454 | * framework. Note that a new dump will be discarded if a previous one |
455 | * hasn't been released yet. |
456 | */ |
457 | dev_coredumpv(dev: rtwdev->dev, data: desc->data, datalen: desc->size, GFP_KERNEL); |
458 | } |
459 | |
460 | static void rtw_fwcd_free(struct rtw_dev *rtwdev, bool free_self) |
461 | { |
462 | struct rtw_fwcd_desc *desc = &rtwdev->fw.fwcd_desc; |
463 | |
464 | if (free_self) { |
465 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "free fwcd by self\n" ); |
466 | vfree(addr: desc->data); |
467 | } |
468 | |
469 | desc->data = NULL; |
470 | desc->next = NULL; |
471 | } |
472 | |
473 | static int rtw_fw_dump_crash_log(struct rtw_dev *rtwdev) |
474 | { |
475 | u32 size = rtwdev->chip->fw_rxff_size; |
476 | u32 *buf; |
477 | u8 seq; |
478 | |
479 | buf = (u32 *)rtw_fwcd_next(rtwdev, item: RTW_FWCD_TLV, size); |
480 | if (!buf) |
481 | return -ENOMEM; |
482 | |
483 | if (rtw_fw_dump_fifo(rtwdev, fifo_sel: RTW_FW_FIFO_SEL_RXBUF_FW, addr: 0, size, buffer: buf)) { |
484 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "dump fw fifo fail\n" ); |
485 | return -EINVAL; |
486 | } |
487 | |
488 | if (GET_FW_DUMP_LEN(buf) == 0) { |
489 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, fmt: "fw crash dump's length is 0\n" ); |
490 | return -EINVAL; |
491 | } |
492 | |
493 | seq = GET_FW_DUMP_SEQ(buf); |
494 | if (seq > 0) { |
495 | rtw_dbg(rtwdev, mask: RTW_DBG_FW, |
496 | fmt: "fw crash dump's seq is wrong: %d\n" , seq); |
497 | return -EINVAL; |
498 | } |
499 | |
500 | return 0; |
501 | } |
502 | |
503 | int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, |
504 | u32 fwcd_item) |
505 | { |
506 | u32 rxff = rtwdev->chip->fw_rxff_size; |
507 | u32 dump_size, done_size = 0; |
508 | u8 *buf; |
509 | int ret; |
510 | |
511 | buf = rtw_fwcd_next(rtwdev, item: fwcd_item, size); |
512 | if (!buf) |
513 | return -ENOMEM; |
514 | |
515 | while (size) { |
516 | dump_size = size > rxff ? rxff : size; |
517 | |
518 | ret = rtw_ddma_to_fw_fifo(rtwdev, ocp_src: ocp_src + done_size, |
519 | size: dump_size); |
520 | if (ret) { |
521 | rtw_err(rtwdev, |
522 | "ddma fw 0x%x [+0x%x] to fw fifo fail\n" , |
523 | ocp_src, done_size); |
524 | return ret; |
525 | } |
526 | |
527 | ret = rtw_fw_dump_fifo(rtwdev, fifo_sel: RTW_FW_FIFO_SEL_RXBUF_FW, addr: 0, |
528 | size: dump_size, buffer: (u32 *)(buf + done_size)); |
529 | if (ret) { |
530 | rtw_err(rtwdev, |
531 | "dump fw 0x%x [+0x%x] from fw fifo fail\n" , |
532 | ocp_src, done_size); |
533 | return ret; |
534 | } |
535 | |
536 | size -= dump_size; |
537 | done_size += dump_size; |
538 | } |
539 | |
540 | return 0; |
541 | } |
542 | EXPORT_SYMBOL(rtw_dump_fw); |
543 | |
544 | int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size) |
545 | { |
546 | u8 *buf; |
547 | u32 i; |
548 | |
549 | if (addr & 0x3) { |
550 | WARN(1, "should be 4-byte aligned, addr = 0x%08x\n" , addr); |
551 | return -EINVAL; |
552 | } |
553 | |
554 | buf = rtw_fwcd_next(rtwdev, item: RTW_FWCD_REG, size); |
555 | if (!buf) |
556 | return -ENOMEM; |
557 | |
558 | for (i = 0; i < size; i += 4) |
559 | *(u32 *)(buf + i) = rtw_read32(rtwdev, addr: addr + i); |
560 | |
561 | return 0; |
562 | } |
563 | EXPORT_SYMBOL(rtw_dump_reg); |
564 | |
565 | void rtw_vif_assoc_changed(struct rtw_vif *rtwvif, |
566 | struct ieee80211_bss_conf *conf) |
567 | { |
568 | struct ieee80211_vif *vif = NULL; |
569 | |
570 | if (conf) |
571 | vif = container_of(conf, struct ieee80211_vif, bss_conf); |
572 | |
573 | if (conf && vif->cfg.assoc) { |
574 | rtwvif->aid = vif->cfg.aid; |
575 | rtwvif->net_type = RTW_NET_MGD_LINKED; |
576 | } else { |
577 | rtwvif->aid = 0; |
578 | rtwvif->net_type = RTW_NET_NO_LINK; |
579 | } |
580 | } |
581 | |
582 | static void rtw_reset_key_iter(struct ieee80211_hw *hw, |
583 | struct ieee80211_vif *vif, |
584 | struct ieee80211_sta *sta, |
585 | struct ieee80211_key_conf *key, |
586 | void *data) |
587 | { |
588 | struct rtw_dev *rtwdev = (struct rtw_dev *)data; |
589 | struct rtw_sec_desc *sec = &rtwdev->sec; |
590 | |
591 | rtw_sec_clear_cam(rtwdev, sec, hw_key_idx: key->hw_key_idx); |
592 | } |
593 | |
594 | static void rtw_reset_sta_iter(void *data, struct ieee80211_sta *sta) |
595 | { |
596 | struct rtw_dev *rtwdev = (struct rtw_dev *)data; |
597 | |
598 | if (rtwdev->sta_cnt == 0) { |
599 | rtw_warn(rtwdev, "sta count before reset should not be 0\n" ); |
600 | return; |
601 | } |
602 | rtw_sta_remove(rtwdev, sta, fw_exist: false); |
603 | } |
604 | |
605 | static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
606 | { |
607 | struct rtw_dev *rtwdev = (struct rtw_dev *)data; |
608 | struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; |
609 | |
610 | rtw_bf_disassoc(rtwdev, vif, NULL); |
611 | rtw_vif_assoc_changed(rtwvif, NULL); |
612 | rtw_txq_cleanup(rtwdev, txq: vif->txq); |
613 | } |
614 | |
615 | void rtw_fw_recovery(struct rtw_dev *rtwdev) |
616 | { |
617 | if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) |
618 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->fw_recovery_work); |
619 | } |
620 | |
621 | static void __fw_recovery_work(struct rtw_dev *rtwdev) |
622 | { |
623 | int ret = 0; |
624 | |
625 | set_bit(nr: RTW_FLAG_RESTARTING, addr: rtwdev->flags); |
626 | clear_bit(nr: RTW_FLAG_RESTART_TRIGGERING, addr: rtwdev->flags); |
627 | |
628 | ret = rtw_fwcd_prep(rtwdev); |
629 | if (ret) |
630 | goto free; |
631 | ret = rtw_fw_dump_crash_log(rtwdev); |
632 | if (ret) |
633 | goto free; |
634 | ret = rtw_chip_dump_fw_crash(rtwdev); |
635 | if (ret) |
636 | goto free; |
637 | |
638 | rtw_fwcd_dump(rtwdev); |
639 | free: |
640 | rtw_fwcd_free(rtwdev, free_self: !!ret); |
641 | rtw_write8(rtwdev, REG_MCU_TST_CFG, val: 0); |
642 | |
643 | WARN(1, "firmware crash, start reset and recover\n" ); |
644 | |
645 | rcu_read_lock(); |
646 | rtw_iterate_keys_rcu(rtwdev, NULL, rtw_reset_key_iter, rtwdev); |
647 | rcu_read_unlock(); |
648 | rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev); |
649 | rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev); |
650 | bitmap_zero(dst: rtwdev->hw_port, nbits: RTW_PORT_NUM); |
651 | rtw_enter_ips(rtwdev); |
652 | } |
653 | |
654 | static void rtw_fw_recovery_work(struct work_struct *work) |
655 | { |
656 | struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, |
657 | fw_recovery_work); |
658 | |
659 | mutex_lock(&rtwdev->mutex); |
660 | __fw_recovery_work(rtwdev); |
661 | mutex_unlock(lock: &rtwdev->mutex); |
662 | |
663 | ieee80211_restart_hw(hw: rtwdev->hw); |
664 | } |
665 | |
666 | struct rtw_txq_ba_iter_data { |
667 | }; |
668 | |
669 | static void rtw_txq_ba_iter(void *data, struct ieee80211_sta *sta) |
670 | { |
671 | struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; |
672 | int ret; |
673 | u8 tid; |
674 | |
675 | tid = find_first_bit(addr: si->tid_ba, IEEE80211_NUM_TIDS); |
676 | while (tid != IEEE80211_NUM_TIDS) { |
677 | clear_bit(nr: tid, addr: si->tid_ba); |
678 | ret = ieee80211_start_tx_ba_session(sta, tid, timeout: 0); |
679 | if (ret == -EINVAL) { |
680 | struct ieee80211_txq *txq; |
681 | struct rtw_txq *rtwtxq; |
682 | |
683 | txq = sta->txq[tid]; |
684 | rtwtxq = (struct rtw_txq *)txq->drv_priv; |
685 | set_bit(nr: RTW_TXQ_BLOCK_BA, addr: &rtwtxq->flags); |
686 | } |
687 | |
688 | tid = find_first_bit(addr: si->tid_ba, IEEE80211_NUM_TIDS); |
689 | } |
690 | } |
691 | |
692 | static void rtw_txq_ba_work(struct work_struct *work) |
693 | { |
694 | struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ba_work); |
695 | struct rtw_txq_ba_iter_data data; |
696 | |
697 | rtw_iterate_stas_atomic(rtwdev, rtw_txq_ba_iter, &data); |
698 | } |
699 | |
700 | void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel) |
701 | { |
702 | if (IS_CH_2G_BAND(channel)) |
703 | pkt_stat->band = NL80211_BAND_2GHZ; |
704 | else if (IS_CH_5G_BAND(channel)) |
705 | pkt_stat->band = NL80211_BAND_5GHZ; |
706 | else |
707 | return; |
708 | |
709 | pkt_stat->freq = ieee80211_channel_to_frequency(chan: channel, band: pkt_stat->band); |
710 | } |
711 | EXPORT_SYMBOL(rtw_set_rx_freq_band); |
712 | |
713 | void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period) |
714 | { |
715 | rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_TIMIE); |
716 | rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, val: dtim_period - 1); |
717 | } |
718 | |
719 | void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, |
720 | u8 primary_channel, enum rtw_supported_band band, |
721 | enum rtw_bandwidth bandwidth) |
722 | { |
723 | enum nl80211_band nl_band = rtw_hw_to_nl80211_band(hw_band: band); |
724 | struct rtw_hal *hal = &rtwdev->hal; |
725 | u8 *cch_by_bw = hal->cch_by_bw; |
726 | u32 center_freq, primary_freq; |
727 | enum rtw_sar_bands sar_band; |
728 | u8 primary_channel_idx; |
729 | |
730 | center_freq = ieee80211_channel_to_frequency(chan: center_channel, band: nl_band); |
731 | primary_freq = ieee80211_channel_to_frequency(chan: primary_channel, band: nl_band); |
732 | |
733 | /* assign the center channel used while 20M bw is selected */ |
734 | cch_by_bw[RTW_CHANNEL_WIDTH_20] = primary_channel; |
735 | |
736 | /* assign the center channel used while current bw is selected */ |
737 | cch_by_bw[bandwidth] = center_channel; |
738 | |
739 | switch (bandwidth) { |
740 | case RTW_CHANNEL_WIDTH_20: |
741 | default: |
742 | primary_channel_idx = RTW_SC_DONT_CARE; |
743 | break; |
744 | case RTW_CHANNEL_WIDTH_40: |
745 | if (primary_freq > center_freq) |
746 | primary_channel_idx = RTW_SC_20_UPPER; |
747 | else |
748 | primary_channel_idx = RTW_SC_20_LOWER; |
749 | break; |
750 | case RTW_CHANNEL_WIDTH_80: |
751 | if (primary_freq > center_freq) { |
752 | if (primary_freq - center_freq == 10) |
753 | primary_channel_idx = RTW_SC_20_UPPER; |
754 | else |
755 | primary_channel_idx = RTW_SC_20_UPMOST; |
756 | |
757 | /* assign the center channel used |
758 | * while 40M bw is selected |
759 | */ |
760 | cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel + 4; |
761 | } else { |
762 | if (center_freq - primary_freq == 10) |
763 | primary_channel_idx = RTW_SC_20_LOWER; |
764 | else |
765 | primary_channel_idx = RTW_SC_20_LOWEST; |
766 | |
767 | /* assign the center channel used |
768 | * while 40M bw is selected |
769 | */ |
770 | cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel - 4; |
771 | } |
772 | break; |
773 | } |
774 | |
775 | switch (center_channel) { |
776 | case 1 ... 14: |
777 | sar_band = RTW_SAR_BAND_0; |
778 | break; |
779 | case 36 ... 64: |
780 | sar_band = RTW_SAR_BAND_1; |
781 | break; |
782 | case 100 ... 144: |
783 | sar_band = RTW_SAR_BAND_3; |
784 | break; |
785 | case 149 ... 177: |
786 | sar_band = RTW_SAR_BAND_4; |
787 | break; |
788 | default: |
789 | WARN(1, "unknown ch(%u) to SAR band\n" , center_channel); |
790 | sar_band = RTW_SAR_BAND_0; |
791 | break; |
792 | } |
793 | |
794 | hal->current_primary_channel_index = primary_channel_idx; |
795 | hal->current_band_width = bandwidth; |
796 | hal->primary_channel = primary_channel; |
797 | hal->current_channel = center_channel; |
798 | hal->current_band_type = band; |
799 | hal->sar_band = sar_band; |
800 | } |
801 | |
802 | void rtw_get_channel_params(struct cfg80211_chan_def *chandef, |
803 | struct rtw_channel_params *chan_params) |
804 | { |
805 | struct ieee80211_channel *channel = chandef->chan; |
806 | enum nl80211_chan_width width = chandef->width; |
807 | u32 primary_freq, center_freq; |
808 | u8 center_chan; |
809 | u8 bandwidth = RTW_CHANNEL_WIDTH_20; |
810 | |
811 | center_chan = channel->hw_value; |
812 | primary_freq = channel->center_freq; |
813 | center_freq = chandef->center_freq1; |
814 | |
815 | switch (width) { |
816 | case NL80211_CHAN_WIDTH_20_NOHT: |
817 | case NL80211_CHAN_WIDTH_20: |
818 | bandwidth = RTW_CHANNEL_WIDTH_20; |
819 | break; |
820 | case NL80211_CHAN_WIDTH_40: |
821 | bandwidth = RTW_CHANNEL_WIDTH_40; |
822 | if (primary_freq > center_freq) |
823 | center_chan -= 2; |
824 | else |
825 | center_chan += 2; |
826 | break; |
827 | case NL80211_CHAN_WIDTH_80: |
828 | bandwidth = RTW_CHANNEL_WIDTH_80; |
829 | if (primary_freq > center_freq) { |
830 | if (primary_freq - center_freq == 10) |
831 | center_chan -= 2; |
832 | else |
833 | center_chan -= 6; |
834 | } else { |
835 | if (center_freq - primary_freq == 10) |
836 | center_chan += 2; |
837 | else |
838 | center_chan += 6; |
839 | } |
840 | break; |
841 | default: |
842 | center_chan = 0; |
843 | break; |
844 | } |
845 | |
846 | chan_params->center_chan = center_chan; |
847 | chan_params->bandwidth = bandwidth; |
848 | chan_params->primary_chan = channel->hw_value; |
849 | } |
850 | |
851 | void rtw_set_channel(struct rtw_dev *rtwdev) |
852 | { |
853 | const struct rtw_chip_info *chip = rtwdev->chip; |
854 | struct ieee80211_hw *hw = rtwdev->hw; |
855 | struct rtw_hal *hal = &rtwdev->hal; |
856 | struct rtw_channel_params ch_param; |
857 | u8 center_chan, primary_chan, bandwidth, band; |
858 | |
859 | rtw_get_channel_params(chandef: &hw->conf.chandef, chan_params: &ch_param); |
860 | if (WARN(ch_param.center_chan == 0, "Invalid channel\n" )) |
861 | return; |
862 | |
863 | center_chan = ch_param.center_chan; |
864 | primary_chan = ch_param.primary_chan; |
865 | bandwidth = ch_param.bandwidth; |
866 | band = ch_param.center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; |
867 | |
868 | rtw_update_channel(rtwdev, center_channel: center_chan, primary_channel: primary_chan, band, bandwidth); |
869 | |
870 | if (rtwdev->scan_info.op_chan) |
871 | rtw_store_op_chan(rtwdev, backup: true); |
872 | |
873 | chip->ops->set_channel(rtwdev, center_chan, bandwidth, |
874 | hal->current_primary_channel_index); |
875 | |
876 | if (hal->current_band_type == RTW_BAND_5G) { |
877 | rtw_coex_switchband_notify(rtwdev, type: COEX_SWITCH_TO_5G); |
878 | } else { |
879 | if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) |
880 | rtw_coex_switchband_notify(rtwdev, type: COEX_SWITCH_TO_24G); |
881 | else |
882 | rtw_coex_switchband_notify(rtwdev, type: COEX_SWITCH_TO_24G_NOFORSCAN); |
883 | } |
884 | |
885 | rtw_phy_set_tx_power_level(rtwdev, channel: center_chan); |
886 | |
887 | /* if the channel isn't set for scanning, we will do RF calibration |
888 | * in ieee80211_ops::mgd_prepare_tx(). Performing the calibration |
889 | * during scanning on each channel takes too long. |
890 | */ |
891 | if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) |
892 | rtwdev->need_rfk = true; |
893 | } |
894 | |
895 | void rtw_chip_prepare_tx(struct rtw_dev *rtwdev) |
896 | { |
897 | const struct rtw_chip_info *chip = rtwdev->chip; |
898 | |
899 | if (rtwdev->need_rfk) { |
900 | rtwdev->need_rfk = false; |
901 | chip->ops->phy_calibration(rtwdev); |
902 | } |
903 | } |
904 | |
905 | static void rtw_vif_write_addr(struct rtw_dev *rtwdev, u32 start, u8 *addr) |
906 | { |
907 | int i; |
908 | |
909 | for (i = 0; i < ETH_ALEN; i++) |
910 | rtw_write8(rtwdev, addr: start + i, val: addr[i]); |
911 | } |
912 | |
913 | void rtw_vif_port_config(struct rtw_dev *rtwdev, |
914 | struct rtw_vif *rtwvif, |
915 | u32 config) |
916 | { |
917 | u32 addr, mask; |
918 | |
919 | if (config & PORT_SET_MAC_ADDR) { |
920 | addr = rtwvif->conf->mac_addr.addr; |
921 | rtw_vif_write_addr(rtwdev, start: addr, addr: rtwvif->mac_addr); |
922 | } |
923 | if (config & PORT_SET_BSSID) { |
924 | addr = rtwvif->conf->bssid.addr; |
925 | rtw_vif_write_addr(rtwdev, start: addr, addr: rtwvif->bssid); |
926 | } |
927 | if (config & PORT_SET_NET_TYPE) { |
928 | addr = rtwvif->conf->net_type.addr; |
929 | mask = rtwvif->conf->net_type.mask; |
930 | rtw_write32_mask(rtwdev, addr, mask, data: rtwvif->net_type); |
931 | } |
932 | if (config & PORT_SET_AID) { |
933 | addr = rtwvif->conf->aid.addr; |
934 | mask = rtwvif->conf->aid.mask; |
935 | rtw_write32_mask(rtwdev, addr, mask, data: rtwvif->aid); |
936 | } |
937 | if (config & PORT_SET_BCN_CTRL) { |
938 | addr = rtwvif->conf->bcn_ctrl.addr; |
939 | mask = rtwvif->conf->bcn_ctrl.mask; |
940 | rtw_write8_mask(rtwdev, addr, mask, data: rtwvif->bcn_ctrl); |
941 | } |
942 | } |
943 | |
944 | static u8 hw_bw_cap_to_bitamp(u8 bw_cap) |
945 | { |
946 | u8 bw = 0; |
947 | |
948 | switch (bw_cap) { |
949 | case EFUSE_HW_CAP_IGNORE: |
950 | case EFUSE_HW_CAP_SUPP_BW80: |
951 | bw |= BIT(RTW_CHANNEL_WIDTH_80); |
952 | fallthrough; |
953 | case EFUSE_HW_CAP_SUPP_BW40: |
954 | bw |= BIT(RTW_CHANNEL_WIDTH_40); |
955 | fallthrough; |
956 | default: |
957 | bw |= BIT(RTW_CHANNEL_WIDTH_20); |
958 | break; |
959 | } |
960 | |
961 | return bw; |
962 | } |
963 | |
964 | static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num) |
965 | { |
966 | const struct rtw_chip_info *chip = rtwdev->chip; |
967 | struct rtw_hal *hal = &rtwdev->hal; |
968 | |
969 | if (hw_ant_num == EFUSE_HW_CAP_IGNORE || |
970 | hw_ant_num >= hal->rf_path_num) |
971 | return; |
972 | |
973 | switch (hw_ant_num) { |
974 | case 1: |
975 | hal->rf_type = RF_1T1R; |
976 | hal->rf_path_num = 1; |
977 | if (!chip->fix_rf_phy_num) |
978 | hal->rf_phy_num = hal->rf_path_num; |
979 | hal->antenna_tx = BB_PATH_A; |
980 | hal->antenna_rx = BB_PATH_A; |
981 | break; |
982 | default: |
983 | WARN(1, "invalid hw configuration from efuse\n" ); |
984 | break; |
985 | } |
986 | } |
987 | |
988 | static u64 get_vht_ra_mask(struct ieee80211_sta *sta) |
989 | { |
990 | u64 ra_mask = 0; |
991 | u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); |
992 | u8 vht_mcs_cap; |
993 | int i, nss; |
994 | |
995 | /* 4SS, every two bits for MCS7/8/9 */ |
996 | for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 10) { |
997 | vht_mcs_cap = mcs_map & 0x3; |
998 | switch (vht_mcs_cap) { |
999 | case 2: /* MCS9 */ |
1000 | ra_mask |= 0x3ffULL << nss; |
1001 | break; |
1002 | case 1: /* MCS8 */ |
1003 | ra_mask |= 0x1ffULL << nss; |
1004 | break; |
1005 | case 0: /* MCS7 */ |
1006 | ra_mask |= 0x0ffULL << nss; |
1007 | break; |
1008 | default: |
1009 | break; |
1010 | } |
1011 | } |
1012 | |
1013 | return ra_mask; |
1014 | } |
1015 | |
1016 | static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 tx_num) |
1017 | { |
1018 | u8 rate_id = 0; |
1019 | |
1020 | switch (wireless_set) { |
1021 | case WIRELESS_CCK: |
1022 | rate_id = RTW_RATEID_B_20M; |
1023 | break; |
1024 | case WIRELESS_OFDM: |
1025 | rate_id = RTW_RATEID_G; |
1026 | break; |
1027 | case WIRELESS_CCK | WIRELESS_OFDM: |
1028 | rate_id = RTW_RATEID_BG; |
1029 | break; |
1030 | case WIRELESS_OFDM | WIRELESS_HT: |
1031 | if (tx_num == 1) |
1032 | rate_id = RTW_RATEID_GN_N1SS; |
1033 | else if (tx_num == 2) |
1034 | rate_id = RTW_RATEID_GN_N2SS; |
1035 | else if (tx_num == 3) |
1036 | rate_id = RTW_RATEID_ARFR5_N_3SS; |
1037 | break; |
1038 | case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT: |
1039 | if (bw_mode == RTW_CHANNEL_WIDTH_40) { |
1040 | if (tx_num == 1) |
1041 | rate_id = RTW_RATEID_BGN_40M_1SS; |
1042 | else if (tx_num == 2) |
1043 | rate_id = RTW_RATEID_BGN_40M_2SS; |
1044 | else if (tx_num == 3) |
1045 | rate_id = RTW_RATEID_ARFR5_N_3SS; |
1046 | else if (tx_num == 4) |
1047 | rate_id = RTW_RATEID_ARFR7_N_4SS; |
1048 | } else { |
1049 | if (tx_num == 1) |
1050 | rate_id = RTW_RATEID_BGN_20M_1SS; |
1051 | else if (tx_num == 2) |
1052 | rate_id = RTW_RATEID_BGN_20M_2SS; |
1053 | else if (tx_num == 3) |
1054 | rate_id = RTW_RATEID_ARFR5_N_3SS; |
1055 | else if (tx_num == 4) |
1056 | rate_id = RTW_RATEID_ARFR7_N_4SS; |
1057 | } |
1058 | break; |
1059 | case WIRELESS_OFDM | WIRELESS_VHT: |
1060 | if (tx_num == 1) |
1061 | rate_id = RTW_RATEID_ARFR1_AC_1SS; |
1062 | else if (tx_num == 2) |
1063 | rate_id = RTW_RATEID_ARFR0_AC_2SS; |
1064 | else if (tx_num == 3) |
1065 | rate_id = RTW_RATEID_ARFR4_AC_3SS; |
1066 | else if (tx_num == 4) |
1067 | rate_id = RTW_RATEID_ARFR6_AC_4SS; |
1068 | break; |
1069 | case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_VHT: |
1070 | if (bw_mode >= RTW_CHANNEL_WIDTH_80) { |
1071 | if (tx_num == 1) |
1072 | rate_id = RTW_RATEID_ARFR1_AC_1SS; |
1073 | else if (tx_num == 2) |
1074 | rate_id = RTW_RATEID_ARFR0_AC_2SS; |
1075 | else if (tx_num == 3) |
1076 | rate_id = RTW_RATEID_ARFR4_AC_3SS; |
1077 | else if (tx_num == 4) |
1078 | rate_id = RTW_RATEID_ARFR6_AC_4SS; |
1079 | } else { |
1080 | if (tx_num == 1) |
1081 | rate_id = RTW_RATEID_ARFR2_AC_2G_1SS; |
1082 | else if (tx_num == 2) |
1083 | rate_id = RTW_RATEID_ARFR3_AC_2G_2SS; |
1084 | else if (tx_num == 3) |
1085 | rate_id = RTW_RATEID_ARFR4_AC_3SS; |
1086 | else if (tx_num == 4) |
1087 | rate_id = RTW_RATEID_ARFR6_AC_4SS; |
1088 | } |
1089 | break; |
1090 | default: |
1091 | break; |
1092 | } |
1093 | |
1094 | return rate_id; |
1095 | } |
1096 | |
1097 | #define RA_MASK_CCK_RATES 0x0000f |
1098 | #define RA_MASK_OFDM_RATES 0x00ff0 |
1099 | #define RA_MASK_HT_RATES_1SS (0xff000ULL << 0) |
1100 | #define RA_MASK_HT_RATES_2SS (0xff000ULL << 8) |
1101 | #define RA_MASK_HT_RATES_3SS (0xff000ULL << 16) |
1102 | #define RA_MASK_HT_RATES (RA_MASK_HT_RATES_1SS | \ |
1103 | RA_MASK_HT_RATES_2SS | \ |
1104 | RA_MASK_HT_RATES_3SS) |
1105 | #define RA_MASK_VHT_RATES_1SS (0x3ff000ULL << 0) |
1106 | #define RA_MASK_VHT_RATES_2SS (0x3ff000ULL << 10) |
1107 | #define RA_MASK_VHT_RATES_3SS (0x3ff000ULL << 20) |
1108 | #define RA_MASK_VHT_RATES (RA_MASK_VHT_RATES_1SS | \ |
1109 | RA_MASK_VHT_RATES_2SS | \ |
1110 | RA_MASK_VHT_RATES_3SS) |
1111 | #define RA_MASK_CCK_IN_BG 0x00005 |
1112 | #define RA_MASK_CCK_IN_HT 0x00005 |
1113 | #define RA_MASK_CCK_IN_VHT 0x00005 |
1114 | #define RA_MASK_OFDM_IN_VHT 0x00010 |
1115 | #define RA_MASK_OFDM_IN_HT_2G 0x00010 |
1116 | #define RA_MASK_OFDM_IN_HT_5G 0x00030 |
1117 | |
1118 | static u64 (struct rtw_sta_info *si, u8 wireless_set) |
1119 | { |
1120 | u8 = si->rssi_level; |
1121 | |
1122 | if (wireless_set == WIRELESS_CCK) |
1123 | return 0xffffffffffffffffULL; |
1124 | |
1125 | if (rssi_level == 0) |
1126 | return 0xffffffffffffffffULL; |
1127 | else if (rssi_level == 1) |
1128 | return 0xfffffffffffffff0ULL; |
1129 | else if (rssi_level == 2) |
1130 | return 0xffffffffffffefe0ULL; |
1131 | else if (rssi_level == 3) |
1132 | return 0xffffffffffffcfc0ULL; |
1133 | else if (rssi_level == 4) |
1134 | return 0xffffffffffff8f80ULL; |
1135 | else |
1136 | return 0xffffffffffff0f00ULL; |
1137 | } |
1138 | |
1139 | static u64 rtw_rate_mask_recover(u64 ra_mask, u64 ra_mask_bak) |
1140 | { |
1141 | if ((ra_mask & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)) == 0) |
1142 | ra_mask |= (ra_mask_bak & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); |
1143 | |
1144 | if (ra_mask == 0) |
1145 | ra_mask |= (ra_mask_bak & (RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)); |
1146 | |
1147 | return ra_mask; |
1148 | } |
1149 | |
1150 | static u64 rtw_rate_mask_cfg(struct rtw_dev *rtwdev, struct rtw_sta_info *si, |
1151 | u64 ra_mask, bool is_vht_enable) |
1152 | { |
1153 | struct rtw_hal *hal = &rtwdev->hal; |
1154 | const struct cfg80211_bitrate_mask *mask = si->mask; |
1155 | u64 cfg_mask = GENMASK_ULL(63, 0); |
1156 | u8 band; |
1157 | |
1158 | if (!si->use_cfg_mask) |
1159 | return ra_mask; |
1160 | |
1161 | band = hal->current_band_type; |
1162 | if (band == RTW_BAND_2G) { |
1163 | band = NL80211_BAND_2GHZ; |
1164 | cfg_mask = mask->control[band].legacy; |
1165 | } else if (band == RTW_BAND_5G) { |
1166 | band = NL80211_BAND_5GHZ; |
1167 | cfg_mask = u64_encode_bits(v: mask->control[band].legacy, |
1168 | RA_MASK_OFDM_RATES); |
1169 | } |
1170 | |
1171 | if (!is_vht_enable) { |
1172 | if (ra_mask & RA_MASK_HT_RATES_1SS) |
1173 | cfg_mask |= u64_encode_bits(v: mask->control[band].ht_mcs[0], |
1174 | RA_MASK_HT_RATES_1SS); |
1175 | if (ra_mask & RA_MASK_HT_RATES_2SS) |
1176 | cfg_mask |= u64_encode_bits(v: mask->control[band].ht_mcs[1], |
1177 | RA_MASK_HT_RATES_2SS); |
1178 | } else { |
1179 | if (ra_mask & RA_MASK_VHT_RATES_1SS) |
1180 | cfg_mask |= u64_encode_bits(v: mask->control[band].vht_mcs[0], |
1181 | RA_MASK_VHT_RATES_1SS); |
1182 | if (ra_mask & RA_MASK_VHT_RATES_2SS) |
1183 | cfg_mask |= u64_encode_bits(v: mask->control[band].vht_mcs[1], |
1184 | RA_MASK_VHT_RATES_2SS); |
1185 | } |
1186 | |
1187 | ra_mask &= cfg_mask; |
1188 | |
1189 | return ra_mask; |
1190 | } |
1191 | |
1192 | void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, |
1193 | bool reset_ra_mask) |
1194 | { |
1195 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1196 | struct ieee80211_sta *sta = si->sta; |
1197 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1198 | struct rtw_hal *hal = &rtwdev->hal; |
1199 | u8 wireless_set; |
1200 | u8 bw_mode; |
1201 | u8 rate_id; |
1202 | u8 rf_type = RF_1T1R; |
1203 | u8 stbc_en = 0; |
1204 | u8 ldpc_en = 0; |
1205 | u8 tx_num = 1; |
1206 | u64 ra_mask = 0; |
1207 | u64 ra_mask_bak = 0; |
1208 | bool is_vht_enable = false; |
1209 | bool is_support_sgi = false; |
1210 | |
1211 | if (sta->deflink.vht_cap.vht_supported) { |
1212 | is_vht_enable = true; |
1213 | ra_mask |= get_vht_ra_mask(sta); |
1214 | if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) |
1215 | stbc_en = VHT_STBC_EN; |
1216 | if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) |
1217 | ldpc_en = VHT_LDPC_EN; |
1218 | } else if (sta->deflink.ht_cap.ht_supported) { |
1219 | ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | |
1220 | (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); |
1221 | if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) |
1222 | stbc_en = HT_STBC_EN; |
1223 | if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) |
1224 | ldpc_en = HT_LDPC_EN; |
1225 | } |
1226 | |
1227 | if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss) |
1228 | ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; |
1229 | |
1230 | if (hal->current_band_type == RTW_BAND_5G) { |
1231 | ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4; |
1232 | ra_mask_bak = ra_mask; |
1233 | if (sta->deflink.vht_cap.vht_supported) { |
1234 | ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT; |
1235 | wireless_set = WIRELESS_OFDM | WIRELESS_VHT; |
1236 | } else if (sta->deflink.ht_cap.ht_supported) { |
1237 | ra_mask &= RA_MASK_HT_RATES | RA_MASK_OFDM_IN_HT_5G; |
1238 | wireless_set = WIRELESS_OFDM | WIRELESS_HT; |
1239 | } else { |
1240 | wireless_set = WIRELESS_OFDM; |
1241 | } |
1242 | dm_info->rrsr_val_init = RRSR_INIT_5G; |
1243 | } else if (hal->current_band_type == RTW_BAND_2G) { |
1244 | ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; |
1245 | ra_mask_bak = ra_mask; |
1246 | if (sta->deflink.vht_cap.vht_supported) { |
1247 | ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT | |
1248 | RA_MASK_OFDM_IN_VHT; |
1249 | wireless_set = WIRELESS_CCK | WIRELESS_OFDM | |
1250 | WIRELESS_HT | WIRELESS_VHT; |
1251 | } else if (sta->deflink.ht_cap.ht_supported) { |
1252 | ra_mask &= RA_MASK_HT_RATES | RA_MASK_CCK_IN_HT | |
1253 | RA_MASK_OFDM_IN_HT_2G; |
1254 | wireless_set = WIRELESS_CCK | WIRELESS_OFDM | |
1255 | WIRELESS_HT; |
1256 | } else if (sta->deflink.supp_rates[0] <= 0xf) { |
1257 | wireless_set = WIRELESS_CCK; |
1258 | } else { |
1259 | ra_mask &= RA_MASK_OFDM_RATES | RA_MASK_CCK_IN_BG; |
1260 | wireless_set = WIRELESS_CCK | WIRELESS_OFDM; |
1261 | } |
1262 | dm_info->rrsr_val_init = RRSR_INIT_2G; |
1263 | } else { |
1264 | rtw_err(rtwdev, "Unknown band type\n" ); |
1265 | ra_mask_bak = ra_mask; |
1266 | wireless_set = 0; |
1267 | } |
1268 | |
1269 | switch (sta->deflink.bandwidth) { |
1270 | case IEEE80211_STA_RX_BW_80: |
1271 | bw_mode = RTW_CHANNEL_WIDTH_80; |
1272 | is_support_sgi = sta->deflink.vht_cap.vht_supported && |
1273 | (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); |
1274 | break; |
1275 | case IEEE80211_STA_RX_BW_40: |
1276 | bw_mode = RTW_CHANNEL_WIDTH_40; |
1277 | is_support_sgi = sta->deflink.ht_cap.ht_supported && |
1278 | (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40); |
1279 | break; |
1280 | default: |
1281 | bw_mode = RTW_CHANNEL_WIDTH_20; |
1282 | is_support_sgi = sta->deflink.ht_cap.ht_supported && |
1283 | (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20); |
1284 | break; |
1285 | } |
1286 | |
1287 | if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) { |
1288 | tx_num = 2; |
1289 | rf_type = RF_2T2R; |
1290 | } else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) { |
1291 | tx_num = 2; |
1292 | rf_type = RF_2T2R; |
1293 | } |
1294 | |
1295 | rate_id = get_rate_id(wireless_set, bw_mode, tx_num); |
1296 | |
1297 | ra_mask &= rtw_rate_mask_rssi(si, wireless_set); |
1298 | ra_mask = rtw_rate_mask_recover(ra_mask, ra_mask_bak); |
1299 | ra_mask = rtw_rate_mask_cfg(rtwdev, si, ra_mask, is_vht_enable); |
1300 | |
1301 | si->bw_mode = bw_mode; |
1302 | si->stbc_en = stbc_en; |
1303 | si->ldpc_en = ldpc_en; |
1304 | si->rf_type = rf_type; |
1305 | si->sgi_enable = is_support_sgi; |
1306 | si->vht_enable = is_vht_enable; |
1307 | si->ra_mask = ra_mask; |
1308 | si->rate_id = rate_id; |
1309 | |
1310 | rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); |
1311 | } |
1312 | |
1313 | static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) |
1314 | { |
1315 | const struct rtw_chip_info *chip = rtwdev->chip; |
1316 | struct rtw_fw_state *fw; |
1317 | |
1318 | fw = &rtwdev->fw; |
1319 | wait_for_completion(&fw->completion); |
1320 | if (!fw->firmware) |
1321 | return -EINVAL; |
1322 | |
1323 | if (chip->wow_fw_name) { |
1324 | fw = &rtwdev->wow_fw; |
1325 | wait_for_completion(&fw->completion); |
1326 | if (!fw->firmware) |
1327 | return -EINVAL; |
1328 | } |
1329 | |
1330 | return 0; |
1331 | } |
1332 | |
1333 | static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, |
1334 | struct rtw_fw_state *fw) |
1335 | { |
1336 | const struct rtw_chip_info *chip = rtwdev->chip; |
1337 | |
1338 | if (rtw_disable_lps_deep_mode || !chip->lps_deep_mode_supported || |
1339 | !fw->feature) |
1340 | return LPS_DEEP_MODE_NONE; |
1341 | |
1342 | if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_PG)) && |
1343 | rtw_fw_feature_check(fw, feature: FW_FEATURE_PG)) |
1344 | return LPS_DEEP_MODE_PG; |
1345 | |
1346 | if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_LCLK)) && |
1347 | rtw_fw_feature_check(fw, feature: FW_FEATURE_LCLK)) |
1348 | return LPS_DEEP_MODE_LCLK; |
1349 | |
1350 | return LPS_DEEP_MODE_NONE; |
1351 | } |
1352 | |
1353 | static int rtw_power_on(struct rtw_dev *rtwdev) |
1354 | { |
1355 | const struct rtw_chip_info *chip = rtwdev->chip; |
1356 | struct rtw_fw_state *fw = &rtwdev->fw; |
1357 | bool wifi_only; |
1358 | int ret; |
1359 | |
1360 | ret = rtw_hci_setup(rtwdev); |
1361 | if (ret) { |
1362 | rtw_err(rtwdev, "failed to setup hci\n" ); |
1363 | goto err; |
1364 | } |
1365 | |
1366 | /* power on MAC before firmware downloaded */ |
1367 | ret = rtw_mac_power_on(rtwdev); |
1368 | if (ret) { |
1369 | rtw_err(rtwdev, "failed to power on mac\n" ); |
1370 | goto err; |
1371 | } |
1372 | |
1373 | ret = rtw_wait_firmware_completion(rtwdev); |
1374 | if (ret) { |
1375 | rtw_err(rtwdev, "failed to wait firmware completion\n" ); |
1376 | goto err_off; |
1377 | } |
1378 | |
1379 | ret = rtw_download_firmware(rtwdev, fw); |
1380 | if (ret) { |
1381 | rtw_err(rtwdev, "failed to download firmware\n" ); |
1382 | goto err_off; |
1383 | } |
1384 | |
1385 | /* config mac after firmware downloaded */ |
1386 | ret = rtw_mac_init(rtwdev); |
1387 | if (ret) { |
1388 | rtw_err(rtwdev, "failed to configure mac\n" ); |
1389 | goto err_off; |
1390 | } |
1391 | |
1392 | chip->ops->phy_set_param(rtwdev); |
1393 | |
1394 | ret = rtw_hci_start(rtwdev); |
1395 | if (ret) { |
1396 | rtw_err(rtwdev, "failed to start hci\n" ); |
1397 | goto err_off; |
1398 | } |
1399 | |
1400 | /* send H2C after HCI has started */ |
1401 | rtw_fw_send_general_info(rtwdev); |
1402 | rtw_fw_send_phydm_info(rtwdev); |
1403 | |
1404 | wifi_only = !rtwdev->efuse.btcoex; |
1405 | rtw_coex_power_on_setting(rtwdev); |
1406 | rtw_coex_init_hw_config(rtwdev, wifi_only); |
1407 | |
1408 | return 0; |
1409 | |
1410 | err_off: |
1411 | rtw_mac_power_off(rtwdev); |
1412 | |
1413 | err: |
1414 | return ret; |
1415 | } |
1416 | |
1417 | void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start) |
1418 | { |
1419 | if (!rtw_fw_feature_check(fw: &rtwdev->fw, feature: FW_FEATURE_NOTIFY_SCAN)) |
1420 | return; |
1421 | |
1422 | if (start) { |
1423 | rtw_fw_scan_notify(rtwdev, start: true); |
1424 | } else { |
1425 | reinit_completion(x: &rtwdev->fw_scan_density); |
1426 | rtw_fw_scan_notify(rtwdev, start: false); |
1427 | if (!wait_for_completion_timeout(x: &rtwdev->fw_scan_density, |
1428 | SCAN_NOTIFY_TIMEOUT)) |
1429 | rtw_warn(rtwdev, "firmware failed to report density after scan\n" ); |
1430 | } |
1431 | } |
1432 | |
1433 | void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, |
1434 | const u8 *mac_addr, bool hw_scan) |
1435 | { |
1436 | u32 config = 0; |
1437 | int ret = 0; |
1438 | |
1439 | rtw_leave_lps(rtwdev); |
1440 | |
1441 | if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) { |
1442 | ret = rtw_leave_ips(rtwdev); |
1443 | if (ret) { |
1444 | rtw_err(rtwdev, "failed to leave idle state\n" ); |
1445 | return; |
1446 | } |
1447 | } |
1448 | |
1449 | ether_addr_copy(dst: rtwvif->mac_addr, src: mac_addr); |
1450 | config |= PORT_SET_MAC_ADDR; |
1451 | rtw_vif_port_config(rtwdev, rtwvif, config); |
1452 | |
1453 | rtw_coex_scan_notify(rtwdev, type: COEX_SCAN_START); |
1454 | rtw_core_fw_scan_notify(rtwdev, start: true); |
1455 | |
1456 | set_bit(nr: RTW_FLAG_DIG_DISABLE, addr: rtwdev->flags); |
1457 | set_bit(nr: RTW_FLAG_SCANNING, addr: rtwdev->flags); |
1458 | } |
1459 | |
1460 | void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, |
1461 | bool hw_scan) |
1462 | { |
1463 | struct rtw_vif *rtwvif = vif ? (struct rtw_vif *)vif->drv_priv : NULL; |
1464 | u32 config = 0; |
1465 | |
1466 | if (!rtwvif) |
1467 | return; |
1468 | |
1469 | clear_bit(nr: RTW_FLAG_SCANNING, addr: rtwdev->flags); |
1470 | clear_bit(nr: RTW_FLAG_DIG_DISABLE, addr: rtwdev->flags); |
1471 | |
1472 | rtw_core_fw_scan_notify(rtwdev, start: false); |
1473 | |
1474 | ether_addr_copy(dst: rtwvif->mac_addr, src: vif->addr); |
1475 | config |= PORT_SET_MAC_ADDR; |
1476 | rtw_vif_port_config(rtwdev, rtwvif, config); |
1477 | |
1478 | rtw_coex_scan_notify(rtwdev, type: COEX_SCAN_FINISH); |
1479 | |
1480 | if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE)) |
1481 | ieee80211_queue_work(hw: rtwdev->hw, work: &rtwdev->ips_work); |
1482 | } |
1483 | |
1484 | int rtw_core_start(struct rtw_dev *rtwdev) |
1485 | { |
1486 | int ret; |
1487 | |
1488 | ret = rtw_power_on(rtwdev); |
1489 | if (ret) |
1490 | return ret; |
1491 | |
1492 | rtw_sec_enable_sec_engine(rtwdev); |
1493 | |
1494 | rtwdev->lps_conf.deep_mode = rtw_update_lps_deep_mode(rtwdev, fw: &rtwdev->fw); |
1495 | rtwdev->lps_conf.wow_deep_mode = rtw_update_lps_deep_mode(rtwdev, fw: &rtwdev->wow_fw); |
1496 | |
1497 | /* rcr reset after powered on */ |
1498 | rtw_write32(rtwdev, REG_RCR, val: rtwdev->hal.rcr); |
1499 | |
1500 | ieee80211_queue_delayed_work(hw: rtwdev->hw, dwork: &rtwdev->watch_dog_work, |
1501 | RTW_WATCH_DOG_DELAY_TIME); |
1502 | |
1503 | set_bit(nr: RTW_FLAG_RUNNING, addr: rtwdev->flags); |
1504 | |
1505 | return 0; |
1506 | } |
1507 | |
1508 | static void rtw_power_off(struct rtw_dev *rtwdev) |
1509 | { |
1510 | rtw_hci_stop(rtwdev); |
1511 | rtw_coex_power_off_setting(rtwdev); |
1512 | rtw_mac_power_off(rtwdev); |
1513 | } |
1514 | |
1515 | void rtw_core_stop(struct rtw_dev *rtwdev) |
1516 | { |
1517 | struct rtw_coex *coex = &rtwdev->coex; |
1518 | |
1519 | clear_bit(nr: RTW_FLAG_RUNNING, addr: rtwdev->flags); |
1520 | clear_bit(nr: RTW_FLAG_FW_RUNNING, addr: rtwdev->flags); |
1521 | |
1522 | mutex_unlock(lock: &rtwdev->mutex); |
1523 | |
1524 | cancel_work_sync(work: &rtwdev->c2h_work); |
1525 | cancel_work_sync(work: &rtwdev->update_beacon_work); |
1526 | cancel_delayed_work_sync(dwork: &rtwdev->watch_dog_work); |
1527 | cancel_delayed_work_sync(dwork: &coex->bt_relink_work); |
1528 | cancel_delayed_work_sync(dwork: &coex->bt_reenable_work); |
1529 | cancel_delayed_work_sync(dwork: &coex->defreeze_work); |
1530 | cancel_delayed_work_sync(dwork: &coex->wl_remain_work); |
1531 | cancel_delayed_work_sync(dwork: &coex->bt_remain_work); |
1532 | cancel_delayed_work_sync(dwork: &coex->wl_connecting_work); |
1533 | cancel_delayed_work_sync(dwork: &coex->bt_multi_link_remain_work); |
1534 | cancel_delayed_work_sync(dwork: &coex->wl_ccklock_work); |
1535 | |
1536 | mutex_lock(&rtwdev->mutex); |
1537 | |
1538 | rtw_power_off(rtwdev); |
1539 | } |
1540 | |
1541 | static void rtw_init_ht_cap(struct rtw_dev *rtwdev, |
1542 | struct ieee80211_sta_ht_cap *ht_cap) |
1543 | { |
1544 | const struct rtw_chip_info *chip = rtwdev->chip; |
1545 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1546 | |
1547 | ht_cap->ht_supported = true; |
1548 | ht_cap->cap = 0; |
1549 | ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | |
1550 | IEEE80211_HT_CAP_MAX_AMSDU | |
1551 | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); |
1552 | |
1553 | if (rtw_chip_has_rx_ldpc(rtwdev)) |
1554 | ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; |
1555 | if (rtw_chip_has_tx_stbc(rtwdev)) |
1556 | ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC; |
1557 | |
1558 | if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40)) |
1559 | ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
1560 | IEEE80211_HT_CAP_DSSSCCK40 | |
1561 | IEEE80211_HT_CAP_SGI_40; |
1562 | ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
1563 | ht_cap->ampdu_density = chip->ampdu_density; |
1564 | ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
1565 | if (efuse->hw_cap.nss > 1) { |
1566 | ht_cap->mcs.rx_mask[0] = 0xFF; |
1567 | ht_cap->mcs.rx_mask[1] = 0xFF; |
1568 | ht_cap->mcs.rx_mask[4] = 0x01; |
1569 | ht_cap->mcs.rx_highest = cpu_to_le16(300); |
1570 | } else { |
1571 | ht_cap->mcs.rx_mask[0] = 0xFF; |
1572 | ht_cap->mcs.rx_mask[1] = 0x00; |
1573 | ht_cap->mcs.rx_mask[4] = 0x01; |
1574 | ht_cap->mcs.rx_highest = cpu_to_le16(150); |
1575 | } |
1576 | } |
1577 | |
1578 | static void rtw_init_vht_cap(struct rtw_dev *rtwdev, |
1579 | struct ieee80211_sta_vht_cap *vht_cap) |
1580 | { |
1581 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1582 | u16 mcs_map; |
1583 | __le16 highest; |
1584 | |
1585 | if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE && |
1586 | efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT) |
1587 | return; |
1588 | |
1589 | vht_cap->vht_supported = true; |
1590 | vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | |
1591 | IEEE80211_VHT_CAP_SHORT_GI_80 | |
1592 | IEEE80211_VHT_CAP_RXSTBC_1 | |
1593 | IEEE80211_VHT_CAP_HTC_VHT | |
1594 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | |
1595 | 0; |
1596 | if (rtwdev->hal.rf_path_num > 1) |
1597 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; |
1598 | vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | |
1599 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; |
1600 | vht_cap->cap |= (rtwdev->hal.bfee_sts_cap << |
1601 | IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); |
1602 | |
1603 | if (rtw_chip_has_rx_ldpc(rtwdev)) |
1604 | vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; |
1605 | |
1606 | mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | |
1607 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | |
1608 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | |
1609 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | |
1610 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | |
1611 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | |
1612 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; |
1613 | if (efuse->hw_cap.nss > 1) { |
1614 | highest = cpu_to_le16(780); |
1615 | mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2; |
1616 | } else { |
1617 | highest = cpu_to_le16(390); |
1618 | mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2; |
1619 | } |
1620 | |
1621 | vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); |
1622 | vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); |
1623 | vht_cap->vht_mcs.rx_highest = highest; |
1624 | vht_cap->vht_mcs.tx_highest = highest; |
1625 | } |
1626 | |
1627 | static u16 rtw_get_max_scan_ie_len(struct rtw_dev *rtwdev) |
1628 | { |
1629 | u16 len; |
1630 | |
1631 | len = rtwdev->chip->max_scan_ie_len; |
1632 | |
1633 | if (!rtw_fw_feature_check(fw: &rtwdev->fw, feature: FW_FEATURE_SCAN_OFFLOAD) && |
1634 | rtwdev->chip->id == RTW_CHIP_TYPE_8822C) |
1635 | len = IEEE80211_MAX_DATA_LEN; |
1636 | else if (rtw_fw_feature_ext_check(fw: &rtwdev->fw, feature: FW_FEATURE_EXT_OLD_PAGE_NUM)) |
1637 | len -= RTW_OLD_PROBE_PG_CNT * TX_PAGE_SIZE; |
1638 | |
1639 | return len; |
1640 | } |
1641 | |
1642 | static void rtw_set_supported_band(struct ieee80211_hw *hw, |
1643 | const struct rtw_chip_info *chip) |
1644 | { |
1645 | struct rtw_dev *rtwdev = hw->priv; |
1646 | struct ieee80211_supported_band *sband; |
1647 | |
1648 | if (chip->band & RTW_BAND_2G) { |
1649 | sband = kmemdup(p: &rtw_band_2ghz, size: sizeof(*sband), GFP_KERNEL); |
1650 | if (!sband) |
1651 | goto err_out; |
1652 | if (chip->ht_supported) |
1653 | rtw_init_ht_cap(rtwdev, ht_cap: &sband->ht_cap); |
1654 | hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; |
1655 | } |
1656 | |
1657 | if (chip->band & RTW_BAND_5G) { |
1658 | sband = kmemdup(p: &rtw_band_5ghz, size: sizeof(*sband), GFP_KERNEL); |
1659 | if (!sband) |
1660 | goto err_out; |
1661 | if (chip->ht_supported) |
1662 | rtw_init_ht_cap(rtwdev, ht_cap: &sband->ht_cap); |
1663 | if (chip->vht_supported) |
1664 | rtw_init_vht_cap(rtwdev, vht_cap: &sband->vht_cap); |
1665 | hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; |
1666 | } |
1667 | |
1668 | return; |
1669 | |
1670 | err_out: |
1671 | rtw_err(rtwdev, "failed to set supported band\n" ); |
1672 | } |
1673 | |
1674 | static void rtw_unset_supported_band(struct ieee80211_hw *hw, |
1675 | const struct rtw_chip_info *chip) |
1676 | { |
1677 | kfree(objp: hw->wiphy->bands[NL80211_BAND_2GHZ]); |
1678 | kfree(objp: hw->wiphy->bands[NL80211_BAND_5GHZ]); |
1679 | } |
1680 | |
1681 | static void rtw_vif_smps_iter(void *data, u8 *mac, |
1682 | struct ieee80211_vif *vif) |
1683 | { |
1684 | struct rtw_dev *rtwdev = (struct rtw_dev *)data; |
1685 | |
1686 | if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) |
1687 | return; |
1688 | |
1689 | if (rtwdev->hal.txrx_1ss) |
1690 | ieee80211_request_smps(vif, link_id: 0, smps_mode: IEEE80211_SMPS_STATIC); |
1691 | else |
1692 | ieee80211_request_smps(vif, link_id: 0, smps_mode: IEEE80211_SMPS_OFF); |
1693 | } |
1694 | |
1695 | void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss) |
1696 | { |
1697 | const struct rtw_chip_info *chip = rtwdev->chip; |
1698 | struct rtw_hal *hal = &rtwdev->hal; |
1699 | |
1700 | if (!chip->ops->config_txrx_mode || rtwdev->hal.txrx_1ss == txrx_1ss) |
1701 | return; |
1702 | |
1703 | rtwdev->hal.txrx_1ss = txrx_1ss; |
1704 | if (txrx_1ss) |
1705 | chip->ops->config_txrx_mode(rtwdev, BB_PATH_A, BB_PATH_A, false); |
1706 | else |
1707 | chip->ops->config_txrx_mode(rtwdev, hal->antenna_tx, |
1708 | hal->antenna_rx, false); |
1709 | rtw_iterate_vifs_atomic(rtwdev, rtw_vif_smps_iter, rtwdev); |
1710 | } |
1711 | |
1712 | static void __update_firmware_feature(struct rtw_dev *rtwdev, |
1713 | struct rtw_fw_state *fw) |
1714 | { |
1715 | u32 feature; |
1716 | const struct rtw_fw_hdr *fw_hdr = |
1717 | (const struct rtw_fw_hdr *)fw->firmware->data; |
1718 | |
1719 | feature = le32_to_cpu(fw_hdr->feature); |
1720 | fw->feature = feature & FW_FEATURE_SIG ? feature : 0; |
1721 | |
1722 | if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C && |
1723 | RTW_FW_SUIT_VER_CODE(rtwdev->fw) < RTW_FW_VER_CODE(9, 9, 13)) |
1724 | fw->feature_ext |= FW_FEATURE_EXT_OLD_PAGE_NUM; |
1725 | } |
1726 | |
1727 | static void __update_firmware_info(struct rtw_dev *rtwdev, |
1728 | struct rtw_fw_state *fw) |
1729 | { |
1730 | const struct rtw_fw_hdr *fw_hdr = |
1731 | (const struct rtw_fw_hdr *)fw->firmware->data; |
1732 | |
1733 | fw->h2c_version = le16_to_cpu(fw_hdr->h2c_fmt_ver); |
1734 | fw->version = le16_to_cpu(fw_hdr->version); |
1735 | fw->sub_version = fw_hdr->subversion; |
1736 | fw->sub_index = fw_hdr->subindex; |
1737 | |
1738 | __update_firmware_feature(rtwdev, fw); |
1739 | } |
1740 | |
1741 | static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, |
1742 | struct rtw_fw_state *fw) |
1743 | { |
1744 | struct rtw_fw_hdr_legacy *legacy = |
1745 | (struct rtw_fw_hdr_legacy *)fw->firmware->data; |
1746 | |
1747 | fw->h2c_version = 0; |
1748 | fw->version = le16_to_cpu(legacy->version); |
1749 | fw->sub_version = legacy->subversion1; |
1750 | fw->sub_index = legacy->subversion2; |
1751 | } |
1752 | |
1753 | static void update_firmware_info(struct rtw_dev *rtwdev, |
1754 | struct rtw_fw_state *fw) |
1755 | { |
1756 | if (rtw_chip_wcpu_11n(rtwdev)) |
1757 | __update_firmware_info_legacy(rtwdev, fw); |
1758 | else |
1759 | __update_firmware_info(rtwdev, fw); |
1760 | } |
1761 | |
1762 | static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) |
1763 | { |
1764 | struct rtw_fw_state *fw = context; |
1765 | struct rtw_dev *rtwdev = fw->rtwdev; |
1766 | |
1767 | if (!firmware || !firmware->data) { |
1768 | rtw_err(rtwdev, "failed to request firmware\n" ); |
1769 | complete_all(&fw->completion); |
1770 | return; |
1771 | } |
1772 | |
1773 | fw->firmware = firmware; |
1774 | update_firmware_info(rtwdev, fw); |
1775 | complete_all(&fw->completion); |
1776 | |
1777 | rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n" , |
1778 | fw->type == RTW_WOWLAN_FW ? "WOW " : "" , |
1779 | fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); |
1780 | } |
1781 | |
1782 | static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type) |
1783 | { |
1784 | const char *fw_name; |
1785 | struct rtw_fw_state *fw; |
1786 | int ret; |
1787 | |
1788 | switch (type) { |
1789 | case RTW_WOWLAN_FW: |
1790 | fw = &rtwdev->wow_fw; |
1791 | fw_name = rtwdev->chip->wow_fw_name; |
1792 | break; |
1793 | |
1794 | case RTW_NORMAL_FW: |
1795 | fw = &rtwdev->fw; |
1796 | fw_name = rtwdev->chip->fw_name; |
1797 | break; |
1798 | |
1799 | default: |
1800 | rtw_warn(rtwdev, "unsupported firmware type\n" ); |
1801 | return -ENOENT; |
1802 | } |
1803 | |
1804 | fw->type = type; |
1805 | fw->rtwdev = rtwdev; |
1806 | init_completion(x: &fw->completion); |
1807 | |
1808 | ret = request_firmware_nowait(THIS_MODULE, uevent: true, name: fw_name, device: rtwdev->dev, |
1809 | GFP_KERNEL, context: fw, cont: rtw_load_firmware_cb); |
1810 | if (ret) { |
1811 | rtw_err(rtwdev, "failed to async firmware request\n" ); |
1812 | return ret; |
1813 | } |
1814 | |
1815 | return 0; |
1816 | } |
1817 | |
1818 | static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev) |
1819 | { |
1820 | const struct rtw_chip_info *chip = rtwdev->chip; |
1821 | struct rtw_hal *hal = &rtwdev->hal; |
1822 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1823 | |
1824 | switch (rtw_hci_type(rtwdev)) { |
1825 | case RTW_HCI_TYPE_PCIE: |
1826 | rtwdev->hci.rpwm_addr = 0x03d9; |
1827 | rtwdev->hci.cpwm_addr = 0x03da; |
1828 | break; |
1829 | case RTW_HCI_TYPE_SDIO: |
1830 | rtwdev->hci.rpwm_addr = REG_SDIO_HRPWM1; |
1831 | rtwdev->hci.cpwm_addr = REG_SDIO_HCPWM1_V2; |
1832 | break; |
1833 | case RTW_HCI_TYPE_USB: |
1834 | rtwdev->hci.rpwm_addr = 0xfe58; |
1835 | rtwdev->hci.cpwm_addr = 0xfe57; |
1836 | break; |
1837 | default: |
1838 | rtw_err(rtwdev, "unsupported hci type\n" ); |
1839 | return -EINVAL; |
1840 | } |
1841 | |
1842 | hal->chip_version = rtw_read32(rtwdev, REG_SYS_CFG1); |
1843 | hal->cut_version = BIT_GET_CHIP_VER(hal->chip_version); |
1844 | hal->mp_chip = (hal->chip_version & BIT_RTL_ID) ? 0 : 1; |
1845 | if (hal->chip_version & BIT_RF_TYPE_ID) { |
1846 | hal->rf_type = RF_2T2R; |
1847 | hal->rf_path_num = 2; |
1848 | hal->antenna_tx = BB_PATH_AB; |
1849 | hal->antenna_rx = BB_PATH_AB; |
1850 | } else { |
1851 | hal->rf_type = RF_1T1R; |
1852 | hal->rf_path_num = 1; |
1853 | hal->antenna_tx = BB_PATH_A; |
1854 | hal->antenna_rx = BB_PATH_A; |
1855 | } |
1856 | hal->rf_phy_num = chip->fix_rf_phy_num ? chip->fix_rf_phy_num : |
1857 | hal->rf_path_num; |
1858 | |
1859 | efuse->physical_size = chip->phy_efuse_size; |
1860 | efuse->logical_size = chip->log_efuse_size; |
1861 | efuse->protect_size = chip->ptct_efuse_size; |
1862 | |
1863 | /* default use ack */ |
1864 | rtwdev->hal.rcr |= BIT_VHT_DACK; |
1865 | |
1866 | hal->bfee_sts_cap = 3; |
1867 | |
1868 | return 0; |
1869 | } |
1870 | |
1871 | static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev) |
1872 | { |
1873 | struct rtw_fw_state *fw = &rtwdev->fw; |
1874 | int ret; |
1875 | |
1876 | ret = rtw_hci_setup(rtwdev); |
1877 | if (ret) { |
1878 | rtw_err(rtwdev, "failed to setup hci\n" ); |
1879 | goto err; |
1880 | } |
1881 | |
1882 | ret = rtw_mac_power_on(rtwdev); |
1883 | if (ret) { |
1884 | rtw_err(rtwdev, "failed to power on mac\n" ); |
1885 | goto err; |
1886 | } |
1887 | |
1888 | rtw_write8(rtwdev, REG_C2HEVT, val: C2H_HW_FEATURE_DUMP); |
1889 | |
1890 | wait_for_completion(&fw->completion); |
1891 | if (!fw->firmware) { |
1892 | ret = -EINVAL; |
1893 | rtw_err(rtwdev, "failed to load firmware\n" ); |
1894 | goto err; |
1895 | } |
1896 | |
1897 | ret = rtw_download_firmware(rtwdev, fw); |
1898 | if (ret) { |
1899 | rtw_err(rtwdev, "failed to download firmware\n" ); |
1900 | goto err_off; |
1901 | } |
1902 | |
1903 | return 0; |
1904 | |
1905 | err_off: |
1906 | rtw_mac_power_off(rtwdev); |
1907 | |
1908 | err: |
1909 | return ret; |
1910 | } |
1911 | |
1912 | static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) |
1913 | { |
1914 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1915 | u8 hw_feature[HW_FEATURE_LEN]; |
1916 | u8 id; |
1917 | u8 bw; |
1918 | int i; |
1919 | |
1920 | id = rtw_read8(rtwdev, REG_C2HEVT); |
1921 | if (id != C2H_HW_FEATURE_REPORT) { |
1922 | rtw_err(rtwdev, "failed to read hw feature report\n" ); |
1923 | return -EBUSY; |
1924 | } |
1925 | |
1926 | for (i = 0; i < HW_FEATURE_LEN; i++) |
1927 | hw_feature[i] = rtw_read8(rtwdev, REG_C2HEVT + 2 + i); |
1928 | |
1929 | rtw_write8(rtwdev, REG_C2HEVT, val: 0); |
1930 | |
1931 | bw = GET_EFUSE_HW_CAP_BW(hw_feature); |
1932 | efuse->hw_cap.bw = hw_bw_cap_to_bitamp(bw_cap: bw); |
1933 | efuse->hw_cap.hci = GET_EFUSE_HW_CAP_HCI(hw_feature); |
1934 | efuse->hw_cap.nss = GET_EFUSE_HW_CAP_NSS(hw_feature); |
1935 | efuse->hw_cap.ptcl = GET_EFUSE_HW_CAP_PTCL(hw_feature); |
1936 | efuse->hw_cap.ant_num = GET_EFUSE_HW_CAP_ANT_NUM(hw_feature); |
1937 | |
1938 | rtw_hw_config_rf_ant_num(rtwdev, hw_ant_num: efuse->hw_cap.ant_num); |
1939 | |
1940 | if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE || |
1941 | efuse->hw_cap.nss > rtwdev->hal.rf_path_num) |
1942 | efuse->hw_cap.nss = rtwdev->hal.rf_path_num; |
1943 | |
1944 | rtw_dbg(rtwdev, mask: RTW_DBG_EFUSE, |
1945 | fmt: "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n" , |
1946 | efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, |
1947 | efuse->hw_cap.ant_num, efuse->hw_cap.nss); |
1948 | |
1949 | return 0; |
1950 | } |
1951 | |
1952 | static void rtw_chip_efuse_disable(struct rtw_dev *rtwdev) |
1953 | { |
1954 | rtw_hci_stop(rtwdev); |
1955 | rtw_mac_power_off(rtwdev); |
1956 | } |
1957 | |
1958 | static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev) |
1959 | { |
1960 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1961 | int ret; |
1962 | |
1963 | mutex_lock(&rtwdev->mutex); |
1964 | |
1965 | /* power on mac to read efuse */ |
1966 | ret = rtw_chip_efuse_enable(rtwdev); |
1967 | if (ret) |
1968 | goto out_unlock; |
1969 | |
1970 | ret = rtw_parse_efuse_map(rtwdev); |
1971 | if (ret) |
1972 | goto out_disable; |
1973 | |
1974 | ret = rtw_dump_hw_feature(rtwdev); |
1975 | if (ret) |
1976 | goto out_disable; |
1977 | |
1978 | ret = rtw_check_supported_rfe(rtwdev); |
1979 | if (ret) |
1980 | goto out_disable; |
1981 | |
1982 | if (efuse->crystal_cap == 0xff) |
1983 | efuse->crystal_cap = 0; |
1984 | if (efuse->pa_type_2g == 0xff) |
1985 | efuse->pa_type_2g = 0; |
1986 | if (efuse->pa_type_5g == 0xff) |
1987 | efuse->pa_type_5g = 0; |
1988 | if (efuse->lna_type_2g == 0xff) |
1989 | efuse->lna_type_2g = 0; |
1990 | if (efuse->lna_type_5g == 0xff) |
1991 | efuse->lna_type_5g = 0; |
1992 | if (efuse->channel_plan == 0xff) |
1993 | efuse->channel_plan = 0x7f; |
1994 | if (efuse->rf_board_option == 0xff) |
1995 | efuse->rf_board_option = 0; |
1996 | if (efuse->bt_setting & BIT(0)) |
1997 | efuse->share_ant = true; |
1998 | if (efuse->regd == 0xff) |
1999 | efuse->regd = 0; |
2000 | if (efuse->tx_bb_swing_setting_2g == 0xff) |
2001 | efuse->tx_bb_swing_setting_2g = 0; |
2002 | if (efuse->tx_bb_swing_setting_5g == 0xff) |
2003 | efuse->tx_bb_swing_setting_5g = 0; |
2004 | |
2005 | efuse->btcoex = (efuse->rf_board_option & 0xe0) == 0x20; |
2006 | efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0; |
2007 | efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0; |
2008 | efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0; |
2009 | efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0; |
2010 | |
2011 | if (!is_valid_ether_addr(addr: efuse->addr)) { |
2012 | eth_random_addr(addr: efuse->addr); |
2013 | dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n" ); |
2014 | } |
2015 | |
2016 | out_disable: |
2017 | rtw_chip_efuse_disable(rtwdev); |
2018 | |
2019 | out_unlock: |
2020 | mutex_unlock(lock: &rtwdev->mutex); |
2021 | return ret; |
2022 | } |
2023 | |
2024 | static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) |
2025 | { |
2026 | struct rtw_hal *hal = &rtwdev->hal; |
2027 | const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); |
2028 | |
2029 | if (!rfe_def) |
2030 | return -ENODEV; |
2031 | |
2032 | rtw_phy_setup_phy_cond(rtwdev, pkg: hal->pkg_type); |
2033 | |
2034 | rtw_phy_init_tx_power(rtwdev); |
2035 | rtw_load_table(rtwdev, tbl: rfe_def->phy_pg_tbl); |
2036 | rtw_load_table(rtwdev, tbl: rfe_def->txpwr_lmt_tbl); |
2037 | rtw_phy_tx_power_by_rate_config(hal); |
2038 | rtw_phy_tx_power_limit_config(hal); |
2039 | |
2040 | return 0; |
2041 | } |
2042 | |
2043 | int rtw_chip_info_setup(struct rtw_dev *rtwdev) |
2044 | { |
2045 | int ret; |
2046 | |
2047 | ret = rtw_chip_parameter_setup(rtwdev); |
2048 | if (ret) { |
2049 | rtw_err(rtwdev, "failed to setup chip parameters\n" ); |
2050 | goto err_out; |
2051 | } |
2052 | |
2053 | ret = rtw_chip_efuse_info_setup(rtwdev); |
2054 | if (ret) { |
2055 | rtw_err(rtwdev, "failed to setup chip efuse info\n" ); |
2056 | goto err_out; |
2057 | } |
2058 | |
2059 | ret = rtw_chip_board_info_setup(rtwdev); |
2060 | if (ret) { |
2061 | rtw_err(rtwdev, "failed to setup chip board info\n" ); |
2062 | goto err_out; |
2063 | } |
2064 | |
2065 | return 0; |
2066 | |
2067 | err_out: |
2068 | return ret; |
2069 | } |
2070 | EXPORT_SYMBOL(rtw_chip_info_setup); |
2071 | |
2072 | static void rtw_stats_init(struct rtw_dev *rtwdev) |
2073 | { |
2074 | struct rtw_traffic_stats *stats = &rtwdev->stats; |
2075 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
2076 | int i; |
2077 | |
2078 | ewma_tp_init(e: &stats->tx_ewma_tp); |
2079 | ewma_tp_init(e: &stats->rx_ewma_tp); |
2080 | |
2081 | for (i = 0; i < RTW_EVM_NUM; i++) |
2082 | ewma_evm_init(e: &dm_info->ewma_evm[i]); |
2083 | for (i = 0; i < RTW_SNR_NUM; i++) |
2084 | ewma_snr_init(e: &dm_info->ewma_snr[i]); |
2085 | } |
2086 | |
2087 | int rtw_core_init(struct rtw_dev *rtwdev) |
2088 | { |
2089 | const struct rtw_chip_info *chip = rtwdev->chip; |
2090 | struct rtw_coex *coex = &rtwdev->coex; |
2091 | int ret; |
2092 | |
2093 | INIT_LIST_HEAD(list: &rtwdev->rsvd_page_list); |
2094 | INIT_LIST_HEAD(list: &rtwdev->txqs); |
2095 | |
2096 | timer_setup(&rtwdev->tx_report.purge_timer, |
2097 | rtw_tx_report_purge_timer, 0); |
2098 | rtwdev->tx_wq = alloc_workqueue(fmt: "rtw_tx_wq" , flags: WQ_UNBOUND | WQ_HIGHPRI, max_active: 0); |
2099 | if (!rtwdev->tx_wq) { |
2100 | rtw_warn(rtwdev, "alloc_workqueue rtw_tx_wq failed\n" ); |
2101 | return -ENOMEM; |
2102 | } |
2103 | |
2104 | INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work); |
2105 | INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work); |
2106 | INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work); |
2107 | INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work); |
2108 | INIT_DELAYED_WORK(&coex->wl_remain_work, rtw_coex_wl_remain_work); |
2109 | INIT_DELAYED_WORK(&coex->bt_remain_work, rtw_coex_bt_remain_work); |
2110 | INIT_DELAYED_WORK(&coex->wl_connecting_work, rtw_coex_wl_connecting_work); |
2111 | INIT_DELAYED_WORK(&coex->bt_multi_link_remain_work, |
2112 | rtw_coex_bt_multi_link_remain_work); |
2113 | INIT_DELAYED_WORK(&coex->wl_ccklock_work, rtw_coex_wl_ccklock_work); |
2114 | INIT_WORK(&rtwdev->tx_work, rtw_tx_work); |
2115 | INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work); |
2116 | INIT_WORK(&rtwdev->ips_work, rtw_ips_work); |
2117 | INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work); |
2118 | INIT_WORK(&rtwdev->update_beacon_work, rtw_fw_update_beacon_work); |
2119 | INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work); |
2120 | skb_queue_head_init(list: &rtwdev->c2h_queue); |
2121 | skb_queue_head_init(list: &rtwdev->coex.queue); |
2122 | skb_queue_head_init(list: &rtwdev->tx_report.queue); |
2123 | |
2124 | spin_lock_init(&rtwdev->txq_lock); |
2125 | spin_lock_init(&rtwdev->tx_report.q_lock); |
2126 | |
2127 | mutex_init(&rtwdev->mutex); |
2128 | mutex_init(&rtwdev->hal.tx_power_mutex); |
2129 | |
2130 | init_waitqueue_head(&rtwdev->coex.wait); |
2131 | init_completion(x: &rtwdev->lps_leave_check); |
2132 | init_completion(x: &rtwdev->fw_scan_density); |
2133 | |
2134 | rtwdev->sec.total_cam_num = 32; |
2135 | rtwdev->hal.current_channel = 1; |
2136 | rtwdev->dm_info.fix_rate = U8_MAX; |
2137 | set_bit(RTW_BC_MC_MACID, addr: rtwdev->mac_id_map); |
2138 | |
2139 | rtw_stats_init(rtwdev); |
2140 | |
2141 | /* default rx filter setting */ |
2142 | rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | |
2143 | BIT_PKTCTL_DLEN | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | |
2144 | BIT_AB | BIT_AM | BIT_APM; |
2145 | |
2146 | ret = rtw_load_firmware(rtwdev, type: RTW_NORMAL_FW); |
2147 | if (ret) { |
2148 | rtw_warn(rtwdev, "no firmware loaded\n" ); |
2149 | goto out; |
2150 | } |
2151 | |
2152 | if (chip->wow_fw_name) { |
2153 | ret = rtw_load_firmware(rtwdev, type: RTW_WOWLAN_FW); |
2154 | if (ret) { |
2155 | rtw_warn(rtwdev, "no wow firmware loaded\n" ); |
2156 | wait_for_completion(&rtwdev->fw.completion); |
2157 | if (rtwdev->fw.firmware) |
2158 | release_firmware(fw: rtwdev->fw.firmware); |
2159 | goto out; |
2160 | } |
2161 | } |
2162 | |
2163 | return 0; |
2164 | |
2165 | out: |
2166 | destroy_workqueue(wq: rtwdev->tx_wq); |
2167 | return ret; |
2168 | } |
2169 | EXPORT_SYMBOL(rtw_core_init); |
2170 | |
2171 | void rtw_core_deinit(struct rtw_dev *rtwdev) |
2172 | { |
2173 | struct rtw_fw_state *fw = &rtwdev->fw; |
2174 | struct rtw_fw_state *wow_fw = &rtwdev->wow_fw; |
2175 | struct rtw_rsvd_page *rsvd_pkt, *tmp; |
2176 | unsigned long flags; |
2177 | |
2178 | rtw_wait_firmware_completion(rtwdev); |
2179 | |
2180 | if (fw->firmware) |
2181 | release_firmware(fw: fw->firmware); |
2182 | |
2183 | if (wow_fw->firmware) |
2184 | release_firmware(fw: wow_fw->firmware); |
2185 | |
2186 | destroy_workqueue(wq: rtwdev->tx_wq); |
2187 | timer_delete_sync(timer: &rtwdev->tx_report.purge_timer); |
2188 | spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags); |
2189 | skb_queue_purge(list: &rtwdev->tx_report.queue); |
2190 | spin_unlock_irqrestore(lock: &rtwdev->tx_report.q_lock, flags); |
2191 | skb_queue_purge(list: &rtwdev->coex.queue); |
2192 | skb_queue_purge(list: &rtwdev->c2h_queue); |
2193 | |
2194 | list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, |
2195 | build_list) { |
2196 | list_del(entry: &rsvd_pkt->build_list); |
2197 | kfree(objp: rsvd_pkt); |
2198 | } |
2199 | |
2200 | mutex_destroy(lock: &rtwdev->mutex); |
2201 | mutex_destroy(lock: &rtwdev->hal.tx_power_mutex); |
2202 | } |
2203 | EXPORT_SYMBOL(rtw_core_deinit); |
2204 | |
2205 | int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) |
2206 | { |
2207 | struct rtw_hal *hal = &rtwdev->hal; |
2208 | int max_tx_headroom = 0; |
2209 | int ret; |
2210 | |
2211 | max_tx_headroom = rtwdev->chip->tx_pkt_desc_sz; |
2212 | |
2213 | if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) |
2214 | max_tx_headroom += RTW_SDIO_DATA_PTR_ALIGN; |
2215 | |
2216 | hw->extra_tx_headroom = max_tx_headroom; |
2217 | hw->queues = IEEE80211_NUM_ACS; |
2218 | hw->txq_data_size = sizeof(struct rtw_txq); |
2219 | hw->sta_data_size = sizeof(struct rtw_sta_info); |
2220 | hw->vif_data_size = sizeof(struct rtw_vif); |
2221 | |
2222 | ieee80211_hw_set(hw, SIGNAL_DBM); |
2223 | ieee80211_hw_set(hw, RX_INCLUDES_FCS); |
2224 | ieee80211_hw_set(hw, AMPDU_AGGREGATION); |
2225 | ieee80211_hw_set(hw, MFP_CAPABLE); |
2226 | ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); |
2227 | ieee80211_hw_set(hw, SUPPORTS_PS); |
2228 | ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); |
2229 | ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); |
2230 | ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); |
2231 | ieee80211_hw_set(hw, HAS_RATE_CONTROL); |
2232 | ieee80211_hw_set(hw, TX_AMSDU); |
2233 | ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); |
2234 | |
2235 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
2236 | BIT(NL80211_IFTYPE_AP) | |
2237 | BIT(NL80211_IFTYPE_ADHOC) | |
2238 | BIT(NL80211_IFTYPE_MESH_POINT); |
2239 | hw->wiphy->available_antennas_tx = hal->antenna_tx; |
2240 | hw->wiphy->available_antennas_rx = hal->antenna_rx; |
2241 | |
2242 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | |
2243 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP; |
2244 | |
2245 | hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; |
2246 | hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; |
2247 | hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); |
2248 | |
2249 | if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { |
2250 | hw->wiphy->iface_combinations = rtw_iface_combs; |
2251 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); |
2252 | } |
2253 | |
2254 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); |
2255 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_SCAN_RANDOM_SN); |
2256 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_SET_SCAN_DWELL); |
2257 | |
2258 | #ifdef CONFIG_PM |
2259 | hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; |
2260 | hw->wiphy->max_sched_scan_ssids = rtwdev->chip->max_sched_scan_ssids; |
2261 | #endif |
2262 | rtw_set_supported_band(hw, chip: rtwdev->chip); |
2263 | SET_IEEE80211_PERM_ADDR(hw, addr: rtwdev->efuse.addr); |
2264 | |
2265 | hw->wiphy->sar_capa = &rtw_sar_capa; |
2266 | |
2267 | ret = rtw_regd_init(rtwdev); |
2268 | if (ret) { |
2269 | rtw_err(rtwdev, "failed to init regd\n" ); |
2270 | return ret; |
2271 | } |
2272 | |
2273 | ret = ieee80211_register_hw(hw); |
2274 | if (ret) { |
2275 | rtw_err(rtwdev, "failed to register hw\n" ); |
2276 | return ret; |
2277 | } |
2278 | |
2279 | ret = rtw_regd_hint(rtwdev); |
2280 | if (ret) { |
2281 | rtw_err(rtwdev, "failed to hint regd\n" ); |
2282 | return ret; |
2283 | } |
2284 | |
2285 | rtw_debugfs_init(rtwdev); |
2286 | |
2287 | rtwdev->bf_info.bfer_mu_cnt = 0; |
2288 | rtwdev->bf_info.bfer_su_cnt = 0; |
2289 | |
2290 | return 0; |
2291 | } |
2292 | EXPORT_SYMBOL(rtw_register_hw); |
2293 | |
2294 | void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) |
2295 | { |
2296 | const struct rtw_chip_info *chip = rtwdev->chip; |
2297 | |
2298 | ieee80211_unregister_hw(hw); |
2299 | rtw_unset_supported_band(hw, chip); |
2300 | } |
2301 | EXPORT_SYMBOL(rtw_unregister_hw); |
2302 | |
2303 | static |
2304 | void rtw_swap_reg_nbytes(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, |
2305 | const struct rtw_hw_reg *reg2, u8 nbytes) |
2306 | { |
2307 | u8 i; |
2308 | |
2309 | for (i = 0; i < nbytes; i++) { |
2310 | u8 v1 = rtw_read8(rtwdev, addr: reg1->addr + i); |
2311 | u8 v2 = rtw_read8(rtwdev, addr: reg2->addr + i); |
2312 | |
2313 | rtw_write8(rtwdev, addr: reg1->addr + i, val: v2); |
2314 | rtw_write8(rtwdev, addr: reg2->addr + i, val: v1); |
2315 | } |
2316 | } |
2317 | |
2318 | static |
2319 | void rtw_swap_reg_mask(struct rtw_dev *rtwdev, const struct rtw_hw_reg *reg1, |
2320 | const struct rtw_hw_reg *reg2) |
2321 | { |
2322 | u32 v1, v2; |
2323 | |
2324 | v1 = rtw_read32_mask(rtwdev, addr: reg1->addr, mask: reg1->mask); |
2325 | v2 = rtw_read32_mask(rtwdev, addr: reg2->addr, mask: reg2->mask); |
2326 | rtw_write32_mask(rtwdev, addr: reg2->addr, mask: reg2->mask, data: v1); |
2327 | rtw_write32_mask(rtwdev, addr: reg1->addr, mask: reg1->mask, data: v2); |
2328 | } |
2329 | |
2330 | struct rtw_iter_port_switch_data { |
2331 | struct rtw_dev *rtwdev; |
2332 | struct rtw_vif *rtwvif_ap; |
2333 | }; |
2334 | |
2335 | static void rtw_port_switch_iter(void *data, struct ieee80211_vif *vif) |
2336 | { |
2337 | struct rtw_iter_port_switch_data *iter_data = data; |
2338 | struct rtw_dev *rtwdev = iter_data->rtwdev; |
2339 | struct rtw_vif *rtwvif_target = (struct rtw_vif *)vif->drv_priv; |
2340 | struct rtw_vif *rtwvif_ap = iter_data->rtwvif_ap; |
2341 | const struct rtw_hw_reg *reg1, *reg2; |
2342 | |
2343 | if (rtwvif_target->port != RTW_PORT_0) |
2344 | return; |
2345 | |
2346 | rtw_dbg(rtwdev, mask: RTW_DBG_STATE, fmt: "AP port switch from %d -> %d\n" , |
2347 | rtwvif_ap->port, rtwvif_target->port); |
2348 | |
2349 | /* Leave LPS so the value swapped are not in PS mode */ |
2350 | rtw_leave_lps(rtwdev); |
2351 | |
2352 | reg1 = &rtwvif_ap->conf->net_type; |
2353 | reg2 = &rtwvif_target->conf->net_type; |
2354 | rtw_swap_reg_mask(rtwdev, reg1, reg2); |
2355 | |
2356 | reg1 = &rtwvif_ap->conf->mac_addr; |
2357 | reg2 = &rtwvif_target->conf->mac_addr; |
2358 | rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); |
2359 | |
2360 | reg1 = &rtwvif_ap->conf->bssid; |
2361 | reg2 = &rtwvif_target->conf->bssid; |
2362 | rtw_swap_reg_nbytes(rtwdev, reg1, reg2, ETH_ALEN); |
2363 | |
2364 | reg1 = &rtwvif_ap->conf->bcn_ctrl; |
2365 | reg2 = &rtwvif_target->conf->bcn_ctrl; |
2366 | rtw_swap_reg_nbytes(rtwdev, reg1, reg2, nbytes: 1); |
2367 | |
2368 | swap(rtwvif_target->port, rtwvif_ap->port); |
2369 | swap(rtwvif_target->conf, rtwvif_ap->conf); |
2370 | |
2371 | rtw_fw_default_port(rtwdev, rtwvif: rtwvif_target); |
2372 | } |
2373 | |
2374 | void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) |
2375 | { |
2376 | struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; |
2377 | struct rtw_iter_port_switch_data iter_data; |
2378 | |
2379 | if (vif->type != NL80211_IFTYPE_AP || rtwvif->port == RTW_PORT_0) |
2380 | return; |
2381 | |
2382 | iter_data.rtwdev = rtwdev; |
2383 | iter_data.rtwvif_ap = rtwvif; |
2384 | rtw_iterate_vifs(rtwdev, iterator: rtw_port_switch_iter, data: &iter_data); |
2385 | } |
2386 | |
2387 | static void rtw_check_sta_active_iter(void *data, struct ieee80211_vif *vif) |
2388 | { |
2389 | struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; |
2390 | bool *active = data; |
2391 | |
2392 | if (*active) |
2393 | return; |
2394 | |
2395 | if (vif->type != NL80211_IFTYPE_STATION) |
2396 | return; |
2397 | |
2398 | if (vif->cfg.assoc || !is_zero_ether_addr(addr: rtwvif->bssid)) |
2399 | *active = true; |
2400 | } |
2401 | |
2402 | bool rtw_core_check_sta_active(struct rtw_dev *rtwdev) |
2403 | { |
2404 | bool sta_active = false; |
2405 | |
2406 | rtw_iterate_vifs(rtwdev, iterator: rtw_check_sta_active_iter, data: &sta_active); |
2407 | |
2408 | return rtwdev->ap_active || sta_active; |
2409 | } |
2410 | |
2411 | void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) |
2412 | { |
2413 | if (!rtwdev->ap_active) |
2414 | return; |
2415 | |
2416 | if (enable) { |
2417 | rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); |
2418 | rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); |
2419 | } else { |
2420 | rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); |
2421 | rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); |
2422 | } |
2423 | } |
2424 | |
2425 | MODULE_AUTHOR("Realtek Corporation" ); |
2426 | MODULE_DESCRIPTION("Realtek 802.11ac wireless core module" ); |
2427 | MODULE_LICENSE("Dual BSD/GPL" ); |
2428 | |