Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'wireless-next-2024-04-03' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Kalle Valo says:

====================
wireless-next patches for v6.10

The first "new features" pull request for v6.10 with changes both in
stack and in drivers. The big thing in this pull request is that
wireless subsystem is now almost free of sparse warnings. There's only
one warning left in ath11k which was introduced in v6.9-rc1 and will
be fixed via the wireless tree.

Realtek drivers continue to improve, now we have support for RTL8922AE
and RTL8723CS devices. ath11k also has long waited support for P2P.

This time we have a small conflict in iwlwifi, Stephen has an example
merge resolution which should help with fixing the conflict:

https://lore.kernel.org/all/20240326100945.765b8caf@canb.auug.org.au/

Major changes:

rtw89
* RTL8922AE Wi-Fi 7 PCI device support

rtw88
* RTL8723CS SDIO device support

iwlwifi
* don't support puncturing in 5 GHz
* support monitor mode on passive channels
* BZ-W device support
* P2P with HE/EHT support

ath11k
* P2P support for QCA6390, WCN6855 and QCA2066

* tag 'wireless-next-2024-04-03' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (122 commits)
wifi: mt76: mt7915: workaround dubious x | !y warning
wifi: mwl8k: Avoid -Wflex-array-member-not-at-end warnings
wifi: ti: Avoid a hundred -Wflex-array-member-not-at-end warnings
wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask
net: rfkill: gpio: Convert to platform remove callback returning void
wifi: mac80211: use kvcalloc() for codel vars
wifi: iwlwifi: reconfigure TLC during HW restart
wifi: iwlwifi: mvm: don't change BA sessions during restart
wifi: iwlwifi: mvm: select STA mask only for active links
wifi: iwlwifi: mvm: set wider BW OFDMA ignore correctly
wifi: iwlwifi: Add support for LARI_CONFIG_CHANGE_CMD cmd v9
wifi: iwlwifi: mvm: Declare HE/EHT capabilities support for P2P interfaces
wifi: iwlwifi: mvm: Remove outdated comment
wifi: iwlwifi: add support for BZ_W
wifi: iwlwifi: Print a specific device name.
wifi: iwlwifi: remove wrong CRF_IDs
wifi: iwlwifi: remove devices that never came out
wifi: iwlwifi: mvm: mark EMLSR disabled in cleanup iterator
wifi: iwlwifi: mvm: fix active link counting during recovery
wifi: iwlwifi: mvm: assign link STA ID lookups during restart
...
====================

Link: https://lore.kernel.org/r/20240403093625.CF515C433C7@smtp.kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+7816 -1820
+1
Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
··· 44 44 - brcm,bcm4366-fmac 45 45 - cypress,cyw4373-fmac 46 46 - cypress,cyw43012-fmac 47 + - infineon,cyw43439-fmac 47 48 - const: brcm,bcm4329-fmac 48 49 - enum: 49 50 - brcm,bcm4329-fmac
+2 -4
drivers/bcma/host_soc.c
··· 240 240 return err; 241 241 } 242 242 243 - static int bcma_host_soc_remove(struct platform_device *pdev) 243 + static void bcma_host_soc_remove(struct platform_device *pdev) 244 244 { 245 245 struct bcma_bus *bus = platform_get_drvdata(pdev); 246 246 247 247 bcma_bus_unregister(bus); 248 248 iounmap(bus->mmio); 249 249 platform_set_drvdata(pdev, NULL); 250 - 251 - return 0; 252 250 } 253 251 254 252 static const struct of_device_id bcma_host_soc_of_match[] = { ··· 261 263 .of_match_table = bcma_host_soc_of_match, 262 264 }, 263 265 .probe = bcma_host_soc_probe, 264 - .remove = bcma_host_soc_remove, 266 + .remove_new = bcma_host_soc_remove, 265 267 }; 266 268 267 269 int __init bcma_host_soc_register_driver(void)
+1 -1
drivers/net/wireless/ath/ath10k/thermal.c
··· 100 100 spin_unlock_bh(&ar->data_lock); 101 101 102 102 /* display in millidegree celsius */ 103 - ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000); 103 + ret = sysfs_emit(buf, "%d\n", temperature * 1000); 104 104 out: 105 105 mutex_unlock(&ar->conf_mutex); 106 106 return ret;
+23 -3
drivers/net/wireless/ath/ath10k/wmi.c
··· 1763 1763 1764 1764 int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) 1765 1765 { 1766 - unsigned long time_left; 1766 + unsigned long time_left, i; 1767 1767 1768 1768 time_left = wait_for_completion_timeout(&ar->wmi.service_ready, 1769 1769 WMI_SERVICE_READY_TIMEOUT_HZ); 1770 - if (!time_left) 1771 - return -ETIMEDOUT; 1770 + if (!time_left) { 1771 + /* Sometimes the PCI HIF doesn't receive interrupt 1772 + * for the service ready message even if the buffer 1773 + * was completed. PCIe sniffer shows that it's 1774 + * because the corresponding CE ring doesn't fires 1775 + * it. Workaround here by polling CE rings once. 1776 + */ 1777 + ath10k_warn(ar, "failed to receive service ready completion, polling..\n"); 1778 + 1779 + for (i = 0; i < CE_COUNT; i++) 1780 + ath10k_hif_send_complete_check(ar, i, 1); 1781 + 1782 + time_left = wait_for_completion_timeout(&ar->wmi.service_ready, 1783 + WMI_SERVICE_READY_TIMEOUT_HZ); 1784 + if (!time_left) { 1785 + ath10k_warn(ar, "polling timed out\n"); 1786 + return -ETIMEDOUT; 1787 + } 1788 + 1789 + ath10k_warn(ar, "service ready completion received, continuing normally\n"); 1790 + } 1791 + 1772 1792 return 0; 1773 1793 } 1774 1794
+2 -1
drivers/net/wireless/ath/ath11k/Makefile
··· 18 18 dbring.o \ 19 19 hw.o \ 20 20 pcic.o \ 21 - fw.o 21 + fw.o \ 22 + p2p.o 22 23 23 24 ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o 24 25 ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o
+16 -4
drivers/net/wireless/ath/ath11k/core.c
··· 247 247 }, 248 248 249 249 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 250 - BIT(NL80211_IFTYPE_AP), 250 + BIT(NL80211_IFTYPE_AP) | 251 + BIT(NL80211_IFTYPE_P2P_DEVICE) | 252 + BIT(NL80211_IFTYPE_P2P_CLIENT) | 253 + BIT(NL80211_IFTYPE_P2P_GO), 251 254 .supports_monitor = false, 252 255 .full_monitor_mode = false, 253 256 .supports_shadow_regs = true, ··· 419 416 }, 420 417 421 418 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 422 - BIT(NL80211_IFTYPE_AP), 419 + BIT(NL80211_IFTYPE_AP) | 420 + BIT(NL80211_IFTYPE_P2P_DEVICE) | 421 + BIT(NL80211_IFTYPE_P2P_CLIENT) | 422 + BIT(NL80211_IFTYPE_P2P_GO), 423 423 .supports_monitor = false, 424 424 .full_monitor_mode = false, 425 425 .supports_shadow_regs = true, ··· 507 501 }, 508 502 509 503 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 510 - BIT(NL80211_IFTYPE_AP), 504 + BIT(NL80211_IFTYPE_AP) | 505 + BIT(NL80211_IFTYPE_P2P_DEVICE) | 506 + BIT(NL80211_IFTYPE_P2P_CLIENT) | 507 + BIT(NL80211_IFTYPE_P2P_GO), 511 508 .supports_monitor = false, 512 509 .supports_shadow_regs = true, 513 510 .idle_ps = true, ··· 759 750 }, 760 751 761 752 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 762 - BIT(NL80211_IFTYPE_AP), 753 + BIT(NL80211_IFTYPE_AP) | 754 + BIT(NL80211_IFTYPE_P2P_DEVICE) | 755 + BIT(NL80211_IFTYPE_P2P_CLIENT) | 756 + BIT(NL80211_IFTYPE_P2P_GO), 763 757 .supports_monitor = false, 764 758 .full_monitor_mode = false, 765 759 .supports_shadow_regs = true,
+2 -2
drivers/net/wireless/ath/ath11k/debugfs.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #include <linux/vmalloc.h> ··· 980 980 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, 981 981 &fops_simulate_fw_crash); 982 982 983 - debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab, 983 + debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab, 984 984 &fops_soc_dp_stats); 985 985 986 986 if (ab->hw_params.sram_dump.start != 0)
+136 -39
drivers/net/wireless/ath/ath11k/mac.c
··· 1231 1231 1232 1232 enable_ps = arvif->ps; 1233 1233 1234 - if (!arvif->is_started) { 1235 - /* mac80211 can update vif powersave state while disconnected. 1236 - * Firmware doesn't behave nicely and consumes more power than 1237 - * necessary if PS is disabled on a non-started vdev. Hence 1238 - * force-enable PS for non-running vdevs. 1239 - */ 1240 - psmode = WMI_STA_PS_MODE_ENABLED; 1241 - } else if (enable_ps) { 1234 + if (enable_ps) { 1242 1235 psmode = WMI_STA_PS_MODE_ENABLED; 1243 1236 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1244 1237 ··· 1423 1430 return false; 1424 1431 } 1425 1432 1426 - static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif, 1427 - struct sk_buff *bcn) 1433 + static int ath11k_mac_setup_bcn_p2p_ie(struct ath11k_vif *arvif, 1434 + struct sk_buff *bcn) 1428 1435 { 1436 + struct ath11k *ar = arvif->ar; 1429 1437 struct ieee80211_mgmt *mgmt; 1438 + const u8 *p2p_ie; 1439 + int ret; 1440 + 1441 + mgmt = (void *)bcn->data; 1442 + p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, 1443 + mgmt->u.beacon.variable, 1444 + bcn->len - (mgmt->u.beacon.variable - 1445 + bcn->data)); 1446 + if (!p2p_ie) 1447 + return -ENOENT; 1448 + 1449 + ret = ath11k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie); 1450 + if (ret) { 1451 + ath11k_warn(ar->ab, "failed to submit P2P GO bcn ie for vdev %i: %d\n", 1452 + arvif->vdev_id, ret); 1453 + return ret; 1454 + } 1455 + 1456 + return ret; 1457 + } 1458 + 1459 + static int ath11k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui, 1460 + u8 oui_type, size_t ie_offset) 1461 + { 1462 + size_t len; 1463 + const u8 *next, *end; 1464 + u8 *ie; 1465 + 1466 + if (WARN_ON(skb->len < ie_offset)) 1467 + return -EINVAL; 1468 + 1469 + ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, 1470 + skb->data + ie_offset, 1471 + skb->len - ie_offset); 1472 + if (!ie) 1473 + return -ENOENT; 1474 + 1475 + len = ie[1] + 2; 1476 + end = skb->data + skb->len; 1477 + next = ie + len; 1478 + 1479 + if (WARN_ON(next > end)) 1480 + return -EINVAL; 1481 + 1482 + memmove(ie, next, end - next); 1483 + skb_trim(skb, skb->len - len); 1484 + 1485 + return 0; 1486 + } 1487 + 1488 + static int ath11k_mac_set_vif_params(struct ath11k_vif *arvif, 1489 + struct sk_buff *bcn) 1490 + { 1491 + struct ath11k_base *ab = arvif->ar->ab; 1492 + struct ieee80211_mgmt *mgmt; 1493 + int ret = 0; 1430 1494 u8 *ies; 1431 1495 1432 1496 ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); ··· 1501 1451 arvif->wpaie_present = true; 1502 1452 else 1503 1453 arvif->wpaie_present = false; 1454 + 1455 + if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) 1456 + return ret; 1457 + 1458 + ret = ath11k_mac_setup_bcn_p2p_ie(arvif, bcn); 1459 + if (ret) { 1460 + ath11k_warn(ab, "failed to setup P2P GO bcn ie: %d\n", 1461 + ret); 1462 + return ret; 1463 + } 1464 + 1465 + /* P2P IE is inserted by firmware automatically (as 1466 + * configured above) so remove it from the base beacon 1467 + * template to avoid duplicate P2P IEs in beacon frames. 1468 + */ 1469 + ret = ath11k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, 1470 + WLAN_OUI_TYPE_WFA_P2P, 1471 + offsetof(struct ieee80211_mgmt, 1472 + u.beacon.variable)); 1473 + if (ret) { 1474 + ath11k_warn(ab, "failed to remove P2P vendor ie: %d\n", 1475 + ret); 1476 + return ret; 1477 + } 1478 + 1479 + return ret; 1504 1480 } 1505 1481 1506 1482 static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif) ··· 1548 1472 return -EPERM; 1549 1473 } 1550 1474 1551 - if (tx_arvif == arvif) 1552 - ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb); 1553 - else 1475 + if (tx_arvif == arvif) { 1476 + if (ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb)) 1477 + return -EINVAL; 1478 + } else { 1554 1479 arvif->wpaie_present = tx_arvif->wpaie_present; 1480 + } 1555 1481 1556 1482 for (i = 0; i < beacons->cnt; i++) { 1557 1483 if (tx_arvif != arvif && !nontx_vif_params_set) ··· 1612 1534 return -EPERM; 1613 1535 } 1614 1536 1615 - if (tx_arvif == arvif) 1616 - ath11k_mac_set_vif_params(tx_arvif, bcn); 1617 - else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) 1537 + if (tx_arvif == arvif) { 1538 + if (ath11k_mac_set_vif_params(tx_arvif, bcn)) 1539 + return -EINVAL; 1540 + } else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) { 1618 1541 return -EINVAL; 1542 + } 1619 1543 1620 1544 ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0); 1621 1545 kfree_skb(bcn); ··· 4075 3995 ath11k_wmi_start_scan_init(ar, arg); 4076 3996 arg->vdev_id = arvif->vdev_id; 4077 3997 arg->scan_id = ATH11K_SCAN_ID; 3998 + 3999 + if (ar->ab->hw_params.single_pdev_only) 4000 + arg->scan_f_filter_prb_req = 1; 4078 4001 4079 4002 if (req->ie_len) { 4080 4003 arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); ··· 6653 6570 case NL80211_IFTYPE_UNSPECIFIED: 6654 6571 case NL80211_IFTYPE_STATION: 6655 6572 arvif->vdev_type = WMI_VDEV_TYPE_STA; 6573 + if (vif->p2p) 6574 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT; 6656 6575 break; 6657 6576 case NL80211_IFTYPE_MESH_POINT: 6658 6577 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH_11S; 6659 6578 fallthrough; 6660 6579 case NL80211_IFTYPE_AP: 6661 6580 arvif->vdev_type = WMI_VDEV_TYPE_AP; 6581 + if (vif->p2p) 6582 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO; 6662 6583 break; 6663 6584 case NL80211_IFTYPE_MONITOR: 6664 6585 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; 6665 6586 ar->monitor_vdev_id = bit; 6666 6587 break; 6588 + case NL80211_IFTYPE_P2P_DEVICE: 6589 + arvif->vdev_type = WMI_VDEV_TYPE_STA; 6590 + arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; 6591 + break; 6592 + 6667 6593 default: 6668 6594 WARN_ON(1); 6669 6595 break; ··· 9345 9253 arg->dwell_time_passive = scan_time_msec; 9346 9254 arg->max_scan_time = scan_time_msec; 9347 9255 arg->scan_f_passive = 1; 9348 - arg->scan_f_filter_prb_req = 1; 9349 9256 arg->burst_duration = duration; 9257 + 9258 + if (!ar->ab->hw_params.single_pdev_only) 9259 + arg->scan_f_filter_prb_req = 1; 9350 9260 9351 9261 ret = ath11k_start_scan(ar, arg); 9352 9262 if (ret) { ··· 9951 9857 struct ieee80211_iface_combination *combinations; 9952 9858 struct ieee80211_iface_limit *limits; 9953 9859 int n_limits; 9860 + bool p2p; 9861 + 9862 + p2p = ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_P2P_DEVICE); 9954 9863 9955 9864 combinations = kzalloc(sizeof(*combinations), GFP_KERNEL); 9956 9865 if (!combinations) 9957 9866 return -ENOMEM; 9958 9867 9959 - n_limits = 2; 9868 + if (p2p) 9869 + n_limits = 3; 9870 + else 9871 + n_limits = 2; 9960 9872 9961 9873 limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL); 9962 9874 if (!limits) { ··· 9970 9870 return -ENOMEM; 9971 9871 } 9972 9872 9873 + limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9874 + limits[1].types |= BIT(NL80211_IFTYPE_AP); 9875 + if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9876 + ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9877 + limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9878 + 9879 + combinations[0].limits = limits; 9880 + combinations[0].n_limits = n_limits; 9881 + combinations[0].beacon_int_infra_match = true; 9882 + combinations[0].beacon_int_min_gcd = 100; 9883 + 9973 9884 if (ab->hw_params.support_dual_stations) { 9974 9885 limits[0].max = 2; 9975 - limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9976 - 9977 9886 limits[1].max = 1; 9978 - limits[1].types |= BIT(NL80211_IFTYPE_AP); 9979 - if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9980 - ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9981 - limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9982 9887 9983 - combinations[0].limits = limits; 9984 - combinations[0].n_limits = 2; 9985 9888 combinations[0].max_interfaces = ab->hw_params.num_vdevs; 9986 9889 combinations[0].num_different_channels = 2; 9987 - combinations[0].beacon_int_infra_match = true; 9988 - combinations[0].beacon_int_min_gcd = 100; 9989 9890 } else { 9990 9891 limits[0].max = 1; 9991 - limits[0].types |= BIT(NL80211_IFTYPE_STATION); 9992 - 9993 9892 limits[1].max = 16; 9994 - limits[1].types |= BIT(NL80211_IFTYPE_AP); 9995 9893 9996 - if (IS_ENABLED(CONFIG_MAC80211_MESH) && 9997 - ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) 9998 - limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT); 9999 - 10000 - combinations[0].limits = limits; 10001 - combinations[0].n_limits = 2; 10002 9894 combinations[0].max_interfaces = 16; 10003 9895 combinations[0].num_different_channels = 1; 10004 - combinations[0].beacon_int_infra_match = true; 10005 - combinations[0].beacon_int_min_gcd = 100; 10006 9896 combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 10007 9897 BIT(NL80211_CHAN_WIDTH_20) | 10008 9898 BIT(NL80211_CHAN_WIDTH_40) | 10009 9899 BIT(NL80211_CHAN_WIDTH_80) | 10010 9900 BIT(NL80211_CHAN_WIDTH_80P80) | 10011 9901 BIT(NL80211_CHAN_WIDTH_160); 9902 + } 9903 + 9904 + if (p2p) { 9905 + limits[1].types |= BIT(NL80211_IFTYPE_P2P_CLIENT) | 9906 + BIT(NL80211_IFTYPE_P2P_GO); 9907 + limits[2].max = 1; 9908 + limits[2].types |= BIT(NL80211_IFTYPE_P2P_DEVICE); 10012 9909 } 10013 9910 10014 9911 ar->hw->wiphy->iface_combinations = combinations;
+14 -3
drivers/net/wireless/ath/ath11k/mhi.c
··· 19 19 20 20 #define MHI_TIMEOUT_DEFAULT_MS 20000 21 21 #define RDDM_DUMP_SIZE 0x420000 22 + #define MHI_CB_INVALID 0xff 22 23 23 24 static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = { 24 25 { ··· 159 158 160 159 ath11k_dbg(ab, ATH11K_DBG_PCI, "mhistatus 0x%x\n", val); 161 160 162 - /* Observed on QCA6390 that after SOC_GLOBAL_RESET, MHISTATUS 163 - * has SYSERR bit set and thus need to set MHICTRL_RESET 164 - * to clear SYSERR. 161 + /* After SOC_GLOBAL_RESET, MHISTATUS may still have SYSERR bit set 162 + * and thus need to set MHICTRL_RESET to clear SYSERR. 165 163 */ 166 164 ath11k_pcic_write32(ab, MHICTRL, MHICTRL_RESET_MASK); 167 165 ··· 269 269 enum mhi_callback cb) 270 270 { 271 271 struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev); 272 + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); 272 273 273 274 ath11k_dbg(ab, ATH11K_DBG_BOOT, "notify status reason %s\n", 274 275 ath11k_mhi_op_callback_to_str(cb)); ··· 280 279 break; 281 280 case MHI_CB_EE_RDDM: 282 281 ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n"); 282 + if (ab_pci->mhi_pre_cb == MHI_CB_EE_RDDM) { 283 + ath11k_dbg(ab, ATH11K_DBG_BOOT, 284 + "do not queue again for consecutive RDDM event\n"); 285 + break; 286 + } 287 + 283 288 if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) 284 289 queue_work(ab->workqueue_aux, &ab->reset_work); 290 + 285 291 break; 286 292 default: 287 293 break; 288 294 } 295 + 296 + ab_pci->mhi_pre_cb = cb; 289 297 } 290 298 291 299 static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, ··· 407 397 goto free_controller; 408 398 } 409 399 400 + ab_pci->mhi_pre_cb = MHI_CB_INVALID; 410 401 ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config); 411 402 if (ret) { 412 403 ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
+149
drivers/net/wireless/ath/ath11k/p2p.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 + /* 3 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #include "core.h" 7 + #include "wmi.h" 8 + #include "mac.h" 9 + #include "p2p.h" 10 + 11 + static void ath11k_p2p_noa_ie_fill(u8 *data, size_t len, 12 + const struct ath11k_wmi_p2p_noa_info *noa) 13 + { 14 + struct ieee80211_p2p_noa_attr *noa_attr; 15 + u8 noa_descriptors, ctwindow; 16 + bool oppps; 17 + __le16 *noa_attr_len; 18 + u16 attr_len; 19 + int i; 20 + 21 + ctwindow = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_CTWIN_TU); 22 + oppps = u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS); 23 + noa_descriptors = u32_get_bits(noa->noa_attr, 24 + WMI_P2P_NOA_INFO_DESC_NUM); 25 + 26 + /* P2P IE */ 27 + data[0] = WLAN_EID_VENDOR_SPECIFIC; 28 + data[1] = len - 2; 29 + data[2] = (WLAN_OUI_WFA >> 16) & 0xff; 30 + data[3] = (WLAN_OUI_WFA >> 8) & 0xff; 31 + data[4] = (WLAN_OUI_WFA >> 0) & 0xff; 32 + data[5] = WLAN_OUI_TYPE_WFA_P2P; 33 + 34 + /* NOA ATTR */ 35 + data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE; 36 + noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */ 37 + noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9]; 38 + 39 + noa_attr->index = u32_get_bits(noa->noa_attr, 40 + WMI_P2P_NOA_INFO_INDEX); 41 + noa_attr->oppps_ctwindow = ctwindow; 42 + if (oppps) 43 + noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT; 44 + 45 + for (i = 0; i < noa_descriptors; i++) { 46 + noa_attr->desc[i].count = noa->descriptors[i].type_count; 47 + noa_attr->desc[i].duration = 48 + cpu_to_le32(noa->descriptors[i].duration); 49 + noa_attr->desc[i].interval = 50 + cpu_to_le32(noa->descriptors[i].interval); 51 + noa_attr->desc[i].start_time = 52 + cpu_to_le32(noa->descriptors[i].start_time); 53 + } 54 + 55 + attr_len = 2; /* index + oppps_ctwindow */ 56 + attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc); 57 + *noa_attr_len = __cpu_to_le16(attr_len); 58 + } 59 + 60 + static size_t 61 + ath11k_p2p_noa_ie_len_compute(const struct ath11k_wmi_p2p_noa_info *noa) 62 + { 63 + size_t len = 0; 64 + u8 noa_descriptors = u32_get_bits(noa->noa_attr, 65 + WMI_P2P_NOA_INFO_DESC_NUM); 66 + 67 + if (!(noa_descriptors) && 68 + !(u32_get_bits(noa->noa_attr, WMI_P2P_NOA_INFO_OPP_PS))) 69 + return 0; 70 + 71 + len += 1 + 1 + 4; /* EID + len + OUI */ 72 + len += 1 + 2; /* noa attr + attr len */ 73 + len += 1 + 1; /* index + oppps_ctwindow */ 74 + len += noa_descriptors * 75 + sizeof(struct ieee80211_p2p_noa_desc); 76 + 77 + return len; 78 + } 79 + 80 + static void ath11k_p2p_noa_ie_assign(struct ath11k_vif *arvif, void *ie, 81 + size_t len) 82 + { 83 + struct ath11k *ar = arvif->ar; 84 + 85 + lockdep_assert_held(&ar->data_lock); 86 + 87 + kfree(arvif->u.ap.noa_data); 88 + 89 + arvif->u.ap.noa_data = ie; 90 + arvif->u.ap.noa_len = len; 91 + } 92 + 93 + static void __ath11k_p2p_noa_update(struct ath11k_vif *arvif, 94 + const struct ath11k_wmi_p2p_noa_info *noa) 95 + { 96 + struct ath11k *ar = arvif->ar; 97 + void *ie; 98 + size_t len; 99 + 100 + lockdep_assert_held(&ar->data_lock); 101 + 102 + ath11k_p2p_noa_ie_assign(arvif, NULL, 0); 103 + 104 + len = ath11k_p2p_noa_ie_len_compute(noa); 105 + if (!len) 106 + return; 107 + 108 + ie = kmalloc(len, GFP_ATOMIC); 109 + if (!ie) 110 + return; 111 + 112 + ath11k_p2p_noa_ie_fill(ie, len, noa); 113 + ath11k_p2p_noa_ie_assign(arvif, ie, len); } 114 + 115 + void ath11k_p2p_noa_update(struct ath11k_vif *arvif, 116 + const struct ath11k_wmi_p2p_noa_info *noa) 117 + { 118 + struct ath11k *ar = arvif->ar; 119 + 120 + spin_lock_bh(&ar->data_lock); 121 + __ath11k_p2p_noa_update(arvif, noa); 122 + spin_unlock_bh(&ar->data_lock); 123 + } 124 + 125 + static void ath11k_p2p_noa_update_vdev_iter(void *data, u8 *mac, 126 + struct ieee80211_vif *vif) 127 + { 128 + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); 129 + struct ath11k_p2p_noa_arg *arg = data; 130 + 131 + if (arvif->vdev_id != arg->vdev_id) 132 + return; 133 + 134 + ath11k_p2p_noa_update(arvif, arg->noa); 135 + } 136 + 137 + void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id, 138 + const struct ath11k_wmi_p2p_noa_info *noa) 139 + { 140 + struct ath11k_p2p_noa_arg arg = { 141 + .vdev_id = vdev_id, 142 + .noa = noa, 143 + }; 144 + 145 + ieee80211_iterate_active_interfaces_atomic(ar->hw, 146 + IEEE80211_IFACE_ITER_NORMAL, 147 + ath11k_p2p_noa_update_vdev_iter, 148 + &arg); 149 + }
+22
drivers/net/wireless/ath/ath11k/p2p.h
··· 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 + /* 3 + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef ATH11K_P2P_H 7 + #define ATH11K_P2P_H 8 + 9 + #include "wmi.h" 10 + 11 + struct ath11k_wmi_p2p_noa_info; 12 + 13 + struct ath11k_p2p_noa_arg { 14 + u32 vdev_id; 15 + const struct ath11k_wmi_p2p_noa_info *noa; 16 + }; 17 + 18 + void ath11k_p2p_noa_update(struct ath11k_vif *arvif, 19 + const struct ath11k_wmi_p2p_noa_info *noa); 20 + void ath11k_p2p_noa_update_by_vdev_id(struct ath11k *ar, u32 vdev_id, 21 + const struct ath11k_wmi_p2p_noa_info *noa); 22 + #endif
+1
drivers/net/wireless/ath/ath11k/pci.h
··· 64 64 char amss_path[100]; 65 65 struct mhi_controller *mhi_ctrl; 66 66 const struct ath11k_msi_config *msi_config; 67 + enum mhi_callback mhi_pre_cb; 67 68 u32 register_window; 68 69 69 70 /* protects register_window above */
+1 -1
drivers/net/wireless/ath/ath11k/thermal.c
··· 101 101 spin_unlock_bh(&ar->data_lock); 102 102 103 103 /* display in millidegree Celsius */ 104 - ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000); 104 + ret = sysfs_emit(buf, "%d\n", temperature * 1000); 105 105 out: 106 106 mutex_unlock(&ar->conf_mutex); 107 107 return ret;
+106 -1
drivers/net/wireless/ath/ath11k/wmi.c
··· 20 20 #include "hw.h" 21 21 #include "peer.h" 22 22 #include "testmode.h" 23 + #include "p2p.h" 23 24 24 25 struct wmi_tlv_policy { 25 26 size_t min_len; ··· 155 154 .min_len = sizeof(struct wmi_per_chain_rssi_stats) }, 156 155 [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = { 157 156 .min_len = sizeof(struct wmi_twt_add_dialog_event) }, 157 + [WMI_TAG_P2P_NOA_INFO] = { 158 + .min_len = sizeof(struct ath11k_wmi_p2p_noa_info) }, 159 + [WMI_TAG_P2P_NOA_EVENT] = { 160 + .min_len = sizeof(struct wmi_p2p_noa_event) }, 158 161 }; 159 162 160 163 #define PRIMAP(_hw_mode_) \ ··· 986 981 FIELD_PREP(WMI_TLV_LEN, 0); 987 982 988 983 /* Note: This is a nested TLV containing: 989 - * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. 984 + * [wmi_tlv][ath11k_wmi_p2p_noa_descriptor][wmi_tlv].. 990 985 */ 991 986 992 987 ptr += sizeof(*tlv); ··· 1705 1700 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, 1706 1701 "cmd bcn offload ctrl vdev id %d ctrl_op %d\n", 1707 1702 vdev_id, bcn_ctrl_op); 1703 + 1704 + return ret; 1705 + } 1706 + 1707 + int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id, 1708 + const u8 *p2p_ie) 1709 + { 1710 + struct ath11k_pdev_wmi *wmi = ar->wmi; 1711 + struct wmi_p2p_go_set_beacon_ie_cmd *cmd; 1712 + size_t p2p_ie_len, aligned_len; 1713 + struct wmi_tlv *tlv; 1714 + struct sk_buff *skb; 1715 + int ret, len; 1716 + 1717 + p2p_ie_len = p2p_ie[1] + 2; 1718 + aligned_len = roundup(p2p_ie_len, 4); 1719 + 1720 + len = sizeof(*cmd) + TLV_HDR_SIZE + aligned_len; 1721 + 1722 + skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); 1723 + if (!skb) 1724 + return -ENOMEM; 1725 + 1726 + cmd = (struct wmi_p2p_go_set_beacon_ie_cmd *)skb->data; 1727 + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_P2P_GO_SET_BEACON_IE) | 1728 + FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); 1729 + cmd->vdev_id = vdev_id; 1730 + cmd->ie_buf_len = p2p_ie_len; 1731 + 1732 + tlv = (struct wmi_tlv *)cmd->tlv; 1733 + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | 1734 + FIELD_PREP(WMI_TLV_LEN, aligned_len); 1735 + memcpy(tlv->value, p2p_ie, p2p_ie_len); 1736 + 1737 + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_P2P_GO_SET_BEACON_IE); 1738 + if (ret) { 1739 + ath11k_warn(ar->ab, "failed to send WMI_P2P_GO_SET_BEACON_IE\n"); 1740 + dev_kfree_skb(skb); 1741 + } 1708 1742 1709 1743 return ret; 1710 1744 } ··· 8650 8606 kfree(tb); 8651 8607 } 8652 8608 8609 + static int ath11k_wmi_p2p_noa_event(struct ath11k_base *ab, 8610 + struct sk_buff *skb) 8611 + { 8612 + const void **tb; 8613 + const struct wmi_p2p_noa_event *ev; 8614 + const struct ath11k_wmi_p2p_noa_info *noa; 8615 + struct ath11k *ar; 8616 + int ret, vdev_id; 8617 + u8 noa_descriptors; 8618 + 8619 + tb = ath11k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC); 8620 + if (IS_ERR(tb)) { 8621 + ret = PTR_ERR(tb); 8622 + ath11k_warn(ab, "failed to parse tlv: %d\n", ret); 8623 + return ret; 8624 + } 8625 + 8626 + ev = tb[WMI_TAG_P2P_NOA_EVENT]; 8627 + noa = tb[WMI_TAG_P2P_NOA_INFO]; 8628 + 8629 + if (!ev || !noa) { 8630 + ret = -EPROTO; 8631 + goto out; 8632 + } 8633 + 8634 + vdev_id = ev->vdev_id; 8635 + noa_descriptors = u32_get_bits(noa->noa_attr, 8636 + WMI_P2P_NOA_INFO_DESC_NUM); 8637 + 8638 + if (noa_descriptors > WMI_P2P_MAX_NOA_DESCRIPTORS) { 8639 + ath11k_warn(ab, "invalid descriptor num %d in P2P NoA event\n", 8640 + noa_descriptors); 8641 + return -EINVAL; 8642 + goto out; 8643 + } 8644 + 8645 + ath11k_dbg(ab, ATH11K_DBG_WMI, 8646 + "wmi tlv p2p noa vdev_id %i descriptors %u\n", 8647 + vdev_id, noa_descriptors); 8648 + 8649 + rcu_read_lock(); 8650 + ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id); 8651 + if (!ar) { 8652 + ath11k_warn(ab, "invalid vdev id %d in P2P NoA event\n", 8653 + vdev_id); 8654 + ret = -EINVAL; 8655 + goto unlock; 8656 + } 8657 + 8658 + ath11k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa); 8659 + 8660 + unlock: 8661 + rcu_read_unlock(); 8662 + out: 8663 + kfree(tb); 8664 + return 0; 8665 + } 8666 + 8653 8667 static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) 8654 8668 { 8655 8669 struct wmi_cmd_hdr *cmd_hdr; ··· 8834 8732 break; 8835 8733 case WMI_GTK_OFFLOAD_STATUS_EVENTID: 8836 8734 ath11k_wmi_gtk_offload_status_event(ab, skb); 8735 + break; 8736 + case WMI_P2P_NOA_EVENTID: 8737 + ath11k_wmi_p2p_noa_event(ab, skb); 8837 8738 break; 8838 8739 default: 8839 8740 ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
+42 -36
drivers/net/wireless/ath/ath11k/wmi.h
··· 1 1 /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 5 */ 6 6 7 7 #ifndef ATH11K_WMI_H ··· 60 60 #define WLAN_SCAN_MAX_HINT_BSSID 10 61 61 #define MAX_RNR_BSS 5 62 62 63 - #define WLAN_SCAN_MAX_HINT_S_SSID 10 64 - #define WLAN_SCAN_MAX_HINT_BSSID 10 65 - #define MAX_RNR_BSS 5 66 - 67 63 #define WLAN_SCAN_PARAMS_MAX_SSID 16 68 64 #define WLAN_SCAN_PARAMS_MAX_BSSID 4 69 - #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 65 + #define WLAN_SCAN_PARAMS_MAX_IE_LEN 512 70 66 71 67 #define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 72 68 ··· 3440 3444 const u8 *bssid; 3441 3445 }; 3442 3446 3443 - struct wmi_start_scan_arg { 3444 - u32 scan_id; 3445 - u32 scan_req_id; 3446 - u32 vdev_id; 3447 - u32 scan_priority; 3448 - u32 notify_scan_events; 3449 - u32 dwell_time_active; 3450 - u32 dwell_time_passive; 3451 - u32 min_rest_time; 3452 - u32 max_rest_time; 3453 - u32 repeat_probe_time; 3454 - u32 probe_spacing_time; 3455 - u32 idle_time; 3456 - u32 max_scan_time; 3457 - u32 probe_delay; 3458 - u32 scan_ctrl_flags; 3459 - 3460 - u32 ie_len; 3461 - u32 n_channels; 3462 - u32 n_ssids; 3463 - u32 n_bssids; 3464 - 3465 - u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; 3466 - u32 channels[64]; 3467 - struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; 3468 - struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; 3469 - }; 3470 - 3471 3447 #define WMI_SCAN_STOP_ONE 0x00000000 3472 3448 #define WMI_SCN_STOP_VAP_ALL 0x01000000 3473 3449 #define WMI_SCAN_STOP_ALL 0x04000000 ··· 3598 3630 u8 data[]; 3599 3631 } __packed; 3600 3632 3633 + #define WMI_P2P_MAX_NOA_DESCRIPTORS 4 3634 + 3635 + struct wmi_p2p_noa_event { 3636 + u32 vdev_id; 3637 + } __packed; 3638 + 3639 + struct ath11k_wmi_p2p_noa_descriptor { 3640 + u32 type_count; /* 255: continuous schedule, 0: reserved */ 3641 + u32 duration; /* Absent period duration in micro seconds */ 3642 + u32 interval; /* Absent period interval in micro seconds */ 3643 + u32 start_time; /* 32 bit tsf time when in starts */ 3644 + } __packed; 3645 + 3646 + #define WMI_P2P_NOA_INFO_CHANGED_FLAG BIT(0) 3647 + #define WMI_P2P_NOA_INFO_INDEX GENMASK(15, 8) 3648 + #define WMI_P2P_NOA_INFO_OPP_PS BIT(16) 3649 + #define WMI_P2P_NOA_INFO_CTWIN_TU GENMASK(23, 17) 3650 + #define WMI_P2P_NOA_INFO_DESC_NUM GENMASK(31, 24) 3651 + 3652 + struct ath11k_wmi_p2p_noa_info { 3653 + /* Bit 0 - Flag to indicate an update in NOA schedule 3654 + * Bits 7-1 - Reserved 3655 + * Bits 15-8 - Index (identifies the instance of NOA sub element) 3656 + * Bit 16 - Opp PS state of the AP 3657 + * Bits 23-17 - Ctwindow in TUs 3658 + * Bits 31-24 - Number of NOA descriptors 3659 + */ 3660 + u32 noa_attr; 3661 + struct ath11k_wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS]; 3662 + } __packed; 3663 + 3601 3664 #define WMI_BEACON_TX_BUFFER_SIZE 512 3602 3665 3603 3666 #define WMI_EMA_TMPL_IDX_SHIFT 8 ··· 3650 3651 u32 mu_edca_ie_offset; 3651 3652 u32 feature_enable_bitmap; 3652 3653 u32 ema_params; 3654 + } __packed; 3655 + 3656 + struct wmi_p2p_go_set_beacon_ie_cmd { 3657 + u32 tlv_header; 3658 + u32 vdev_id; 3659 + u32 ie_buf_len; 3660 + u8 tlv[]; 3653 3661 } __packed; 3654 3662 3655 3663 struct wmi_key_seq_counter { ··· 5746 5740 u32 value; 5747 5741 } __packed; 5748 5742 5749 - #define WMI_MAX_MEM_REQS 32 5750 - 5751 5743 #define MAX_RADIOS 3 5752 5744 5753 5745 #define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ) ··· 6353 6349 struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); 6354 6350 int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, 6355 6351 struct sk_buff *frame); 6352 + int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id, 6353 + const u8 *p2p_ie); 6356 6354 int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, 6357 6355 struct ieee80211_mutable_offsets *offs, 6358 6356 struct sk_buff *bcn, u32 ema_param);
+19 -12
drivers/net/wireless/ath/ath12k/dp.c
··· 960 960 if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { 961 961 struct ath12k_dp *dp = &ab->dp; 962 962 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; 963 + LIST_HEAD(list); 963 964 964 - ath12k_dp_rx_bufs_replenish(ab, rx_ring, 0); 965 + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); 965 966 } 966 967 967 968 /* TODO: Implement handler for other interrupts */ ··· 1147 1146 1148 1147 static void ath12k_dp_cc_cleanup(struct ath12k_base *ab) 1149 1148 { 1150 - struct ath12k_rx_desc_info *desc_info, *tmp; 1149 + struct ath12k_rx_desc_info *desc_info; 1151 1150 struct ath12k_tx_desc_info *tx_desc_info, *tmp1; 1152 1151 struct ath12k_dp *dp = &ab->dp; 1153 1152 struct sk_buff *skb; 1154 - int i; 1153 + int i, j; 1155 1154 u32 pool_id, tx_spt_page; 1156 1155 1157 1156 if (!dp->spt_info) ··· 1160 1159 /* RX Descriptor cleanup */ 1161 1160 spin_lock_bh(&dp->rx_desc_lock); 1162 1161 1163 - list_for_each_entry_safe(desc_info, tmp, &dp->rx_desc_used_list, list) { 1164 - list_del(&desc_info->list); 1165 - skb = desc_info->skb; 1162 + for (i = 0; i < ATH12K_NUM_RX_SPT_PAGES; i++) { 1163 + desc_info = dp->spt_info->rxbaddr[i]; 1166 1164 1167 - if (!skb) 1168 - continue; 1165 + for (j = 0; j < ATH12K_MAX_SPT_ENTRIES; j++) { 1166 + if (!desc_info[j].in_use) { 1167 + list_del(&desc_info[j].list); 1168 + continue; 1169 + } 1169 1170 1170 - dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr, 1171 - skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); 1172 - dev_kfree_skb_any(skb); 1171 + skb = desc_info[j].skb; 1172 + if (!skb) 1173 + continue; 1174 + 1175 + dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr, 1176 + skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); 1177 + dev_kfree_skb_any(skb); 1178 + } 1173 1179 } 1174 1180 1175 1181 for (i = 0; i < ATH12K_NUM_RX_SPT_PAGES; i++) { ··· 1452 1444 u32 cmem_base; 1453 1445 1454 1446 INIT_LIST_HEAD(&dp->rx_desc_free_list); 1455 - INIT_LIST_HEAD(&dp->rx_desc_used_list); 1456 1447 spin_lock_init(&dp->rx_desc_lock); 1457 1448 1458 1449 for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++) {
+3 -4
drivers/net/wireless/ath/ath12k/dp.h
··· 282 282 struct sk_buff *skb; 283 283 u32 cookie; 284 284 u32 magic; 285 + u8 in_use : 1, 286 + reserved : 7; 285 287 }; 286 288 287 289 struct ath12k_tx_desc_info { ··· 349 347 struct ath12k_spt_info *spt_info; 350 348 u32 num_spt_pages; 351 349 struct list_head rx_desc_free_list; 352 - struct list_head rx_desc_used_list; 353 - /* protects the free and used desc list */ 350 + /* protects the free desc list */ 354 351 spinlock_t rx_desc_lock; 355 352 356 353 struct list_head tx_desc_free_list[ATH12K_HW_MAX_QUEUES]; ··· 377 376 378 377 /* peer meta data */ 379 378 #define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 2) 380 - 381 - #define HTT_TX_WBM_COMP_STATUS_OFFSET 8 382 379 383 380 /* HTT tx completion is overlaid in wbm_release_ring */ 384 381 #define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13)
+90 -50
drivers/net/wireless/ath/ath12k/dp_rx.c
··· 261 261 return -ETIMEDOUT; 262 262 } 263 263 264 + static size_t ath12k_dp_list_cut_nodes(struct list_head *list, 265 + struct list_head *head, 266 + size_t count) 267 + { 268 + struct list_head *cur; 269 + struct ath12k_rx_desc_info *rx_desc; 270 + size_t nodes = 0; 271 + 272 + if (!count) { 273 + INIT_LIST_HEAD(list); 274 + goto out; 275 + } 276 + 277 + list_for_each(cur, head) { 278 + if (!count) 279 + break; 280 + 281 + rx_desc = list_entry(cur, struct ath12k_rx_desc_info, list); 282 + rx_desc->in_use = true; 283 + 284 + count--; 285 + nodes++; 286 + } 287 + 288 + list_cut_before(list, head, cur); 289 + out: 290 + return nodes; 291 + } 292 + 293 + static void ath12k_dp_rx_enqueue_free(struct ath12k_dp *dp, 294 + struct list_head *used_list) 295 + { 296 + struct ath12k_rx_desc_info *rx_desc, *safe; 297 + 298 + /* Reset the use flag */ 299 + list_for_each_entry_safe(rx_desc, safe, used_list, list) 300 + rx_desc->in_use = false; 301 + 302 + spin_lock_bh(&dp->rx_desc_lock); 303 + list_splice_tail(used_list, &dp->rx_desc_free_list); 304 + spin_unlock_bh(&dp->rx_desc_lock); 305 + } 306 + 264 307 /* Returns number of Rx buffers replenished */ 265 308 int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, 266 309 struct dp_rxdma_ring *rx_ring, 310 + struct list_head *used_list, 267 311 int req_entries) 268 312 { 269 313 struct ath12k_buffer_addr *desc; ··· 336 292 req_entries = min(num_free, req_entries); 337 293 num_remain = req_entries; 338 294 295 + if (!num_remain) 296 + goto out; 297 + 298 + /* Get the descriptor from free list */ 299 + if (list_empty(used_list)) { 300 + spin_lock_bh(&dp->rx_desc_lock); 301 + req_entries = ath12k_dp_list_cut_nodes(used_list, 302 + &dp->rx_desc_free_list, 303 + num_remain); 304 + spin_unlock_bh(&dp->rx_desc_lock); 305 + num_remain = req_entries; 306 + } 307 + 339 308 while (num_remain > 0) { 340 309 skb = dev_alloc_skb(DP_RX_BUFFER_SIZE + 341 310 DP_RX_BUFFER_ALIGN_SIZE); ··· 368 311 if (dma_mapping_error(ab->dev, paddr)) 369 312 goto fail_free_skb; 370 313 371 - spin_lock_bh(&dp->rx_desc_lock); 372 - 373 - /* Get desc from free list and store in used list 374 - * for cleanup purposes 375 - * 376 - * TODO: pass the removed descs rather than 377 - * add/read to optimize 378 - */ 379 - rx_desc = list_first_entry_or_null(&dp->rx_desc_free_list, 314 + rx_desc = list_first_entry_or_null(used_list, 380 315 struct ath12k_rx_desc_info, 381 316 list); 382 - if (!rx_desc) { 383 - spin_unlock_bh(&dp->rx_desc_lock); 317 + if (!rx_desc) 384 318 goto fail_dma_unmap; 385 - } 386 319 387 320 rx_desc->skb = skb; 388 321 cookie = rx_desc->cookie; 389 - list_del(&rx_desc->list); 390 - list_add_tail(&rx_desc->list, &dp->rx_desc_used_list); 391 - 392 - spin_unlock_bh(&dp->rx_desc_lock); 393 322 394 323 desc = ath12k_hal_srng_src_get_next_entry(ab, srng); 395 324 if (!desc) 396 - goto fail_buf_unassign; 325 + goto fail_dma_unmap; 397 326 327 + list_del(&rx_desc->list); 398 328 ATH12K_SKB_RXCB(skb)->paddr = paddr; 399 329 400 330 num_remain--; ··· 389 345 ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); 390 346 } 391 347 392 - ath12k_hal_srng_access_end(ab, srng); 348 + goto out; 393 349 394 - spin_unlock_bh(&srng->lock); 395 - 396 - return req_entries - num_remain; 397 - 398 - fail_buf_unassign: 399 - spin_lock_bh(&dp->rx_desc_lock); 400 - list_del(&rx_desc->list); 401 - list_add_tail(&rx_desc->list, &dp->rx_desc_free_list); 402 - rx_desc->skb = NULL; 403 - spin_unlock_bh(&dp->rx_desc_lock); 404 350 fail_dma_unmap: 405 351 dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb), 406 352 DMA_FROM_DEVICE); 407 353 fail_free_skb: 408 354 dev_kfree_skb_any(skb); 409 - 355 + out: 410 356 ath12k_hal_srng_access_end(ab, srng); 357 + 358 + if (!list_empty(used_list)) 359 + ath12k_dp_rx_enqueue_free(dp, used_list); 411 360 412 361 spin_unlock_bh(&srng->lock); 413 362 ··· 459 422 static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab, 460 423 struct dp_rxdma_ring *rx_ring) 461 424 { 462 - int num_entries; 425 + LIST_HEAD(list); 463 426 464 - num_entries = rx_ring->refill_buf_ring.size / 465 - ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF); 427 + rx_ring->bufs_max = rx_ring->refill_buf_ring.size / 428 + ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF); 466 429 467 - rx_ring->bufs_max = num_entries; 468 - ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_entries); 430 + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); 469 431 470 432 return 0; 471 433 } ··· 2621 2585 int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, 2622 2586 struct napi_struct *napi, int budget) 2623 2587 { 2588 + LIST_HEAD(rx_desc_used_list); 2624 2589 struct ath12k_rx_desc_info *desc_info; 2625 2590 struct ath12k_dp *dp = &ab->dp; 2626 2591 struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; ··· 2674 2637 msdu = desc_info->skb; 2675 2638 desc_info->skb = NULL; 2676 2639 2677 - spin_lock_bh(&dp->rx_desc_lock); 2678 - list_move_tail(&desc_info->list, &dp->rx_desc_free_list); 2679 - spin_unlock_bh(&dp->rx_desc_lock); 2640 + list_add_tail(&desc_info->list, &rx_desc_used_list); 2680 2641 2681 2642 rxcb = ATH12K_SKB_RXCB(msdu); 2682 2643 dma_unmap_single(ab->dev, rxcb->paddr, ··· 2735 2700 if (!total_msdu_reaped) 2736 2701 goto exit; 2737 2702 2738 - ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped); 2703 + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list, 2704 + num_buffs_reaped); 2739 2705 2740 2706 ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, 2741 2707 ring_id); ··· 3057 3021 } 3058 3022 3059 3023 desc_info->skb = defrag_skb; 3024 + desc_info->in_use = true; 3060 3025 3061 3026 list_del(&desc_info->list); 3062 - list_add_tail(&desc_info->list, &dp->rx_desc_used_list); 3063 3027 spin_unlock_bh(&dp->rx_desc_lock); 3064 3028 3065 3029 ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; ··· 3121 3085 3122 3086 err_free_desc: 3123 3087 spin_lock_bh(&dp->rx_desc_lock); 3124 - list_del(&desc_info->list); 3125 - list_add_tail(&desc_info->list, &dp->rx_desc_free_list); 3088 + desc_info->in_use = false; 3126 3089 desc_info->skb = NULL; 3090 + list_add_tail(&desc_info->list, &dp->rx_desc_free_list); 3127 3091 spin_unlock_bh(&dp->rx_desc_lock); 3128 3092 err_unmap_dma: 3129 3093 dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), ··· 3340 3304 3341 3305 static int 3342 3306 ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, 3307 + struct list_head *used_list, 3343 3308 bool drop, u32 cookie) 3344 3309 { 3345 3310 struct ath12k_base *ab = ar->ab; ··· 3370 3333 3371 3334 msdu = desc_info->skb; 3372 3335 desc_info->skb = NULL; 3373 - spin_lock_bh(&ab->dp.rx_desc_lock); 3374 - list_move_tail(&desc_info->list, &ab->dp.rx_desc_free_list); 3375 - spin_unlock_bh(&ab->dp.rx_desc_lock); 3336 + 3337 + list_add_tail(&desc_info->list, used_list); 3376 3338 3377 3339 rxcb = ATH12K_SKB_RXCB(msdu); 3378 3340 dma_unmap_single(ar->ab->dev, rxcb->paddr, ··· 3427 3391 struct hal_reo_dest_ring *reo_desc; 3428 3392 struct dp_rxdma_ring *rx_ring; 3429 3393 struct dp_srng *reo_except; 3394 + LIST_HEAD(rx_desc_used_list); 3430 3395 u32 desc_bank, num_msdus; 3431 3396 struct hal_srng *srng; 3432 3397 struct ath12k_dp *dp; ··· 3495 3458 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); 3496 3459 ar = ab->pdevs[pdev_id].ar; 3497 3460 3498 - if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, drop, 3461 + if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, 3462 + &rx_desc_used_list, 3463 + drop, 3499 3464 msdu_cookies[i])) 3500 3465 tot_n_bufs_reaped++; 3501 3466 } ··· 3517 3478 3518 3479 rx_ring = &dp->rx_refill_buf_ring; 3519 3480 3520 - ath12k_dp_rx_bufs_replenish(ab, rx_ring, tot_n_bufs_reaped); 3481 + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list, 3482 + tot_n_bufs_reaped); 3521 3483 3522 3484 return tot_n_bufs_reaped; 3523 3485 } ··· 3735 3695 int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, 3736 3696 struct napi_struct *napi, int budget) 3737 3697 { 3698 + LIST_HEAD(rx_desc_used_list); 3738 3699 struct ath12k *ar; 3739 3700 struct ath12k_dp *dp = &ab->dp; 3740 3701 struct dp_rxdma_ring *rx_ring; ··· 3789 3748 msdu = desc_info->skb; 3790 3749 desc_info->skb = NULL; 3791 3750 3792 - spin_lock_bh(&dp->rx_desc_lock); 3793 - list_move_tail(&desc_info->list, &dp->rx_desc_free_list); 3794 - spin_unlock_bh(&dp->rx_desc_lock); 3751 + list_add_tail(&desc_info->list, &rx_desc_used_list); 3795 3752 3796 3753 rxcb = ATH12K_SKB_RXCB(msdu); 3797 3754 dma_unmap_single(ab->dev, rxcb->paddr, ··· 3825 3786 if (!num_buffs_reaped) 3826 3787 goto done; 3827 3788 3828 - ath12k_dp_rx_bufs_replenish(ab, rx_ring, num_buffs_reaped); 3789 + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list, 3790 + num_buffs_reaped); 3829 3791 3830 3792 rcu_read_lock(); 3831 3793 while ((msdu = __skb_dequeue(&msdu_list))) {
+1
drivers/net/wireless/ath/ath12k/dp_rx.h
··· 118 118 int budget); 119 119 int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, 120 120 struct dp_rxdma_ring *rx_ring, 121 + struct list_head *used_list, 121 122 int req_entries); 122 123 int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar); 123 124 int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id);
+1 -1
drivers/net/wireless/ath/ath12k/dp_tx.c
··· 414 414 struct ath12k_dp_htt_wbm_tx_status ts = {0}; 415 415 enum hal_wbm_htt_tx_comp_status wbm_status; 416 416 417 - status_desc = desc + HTT_TX_WBM_COMP_STATUS_OFFSET; 417 + status_desc = desc; 418 418 419 419 wbm_status = le32_get_bits(status_desc->info0, 420 420 HTT_TX_WBM_COMP_INFO0_STATUS);
+1 -1
drivers/net/wireless/ath/ath12k/wmi.c
··· 1900 1900 if (arg->bw_160) 1901 1901 cmd->peer_flags |= cpu_to_le32(WMI_PEER_160MHZ); 1902 1902 if (arg->bw_320) 1903 - cmd->peer_flags |= cpu_to_le32(WMI_PEER_EXT_320MHZ); 1903 + cmd->peer_flags_ext |= cpu_to_le32(WMI_PEER_EXT_320MHZ); 1904 1904 1905 1905 /* Typically if STBC is enabled for VHT it should be enabled 1906 1906 * for HT as well
-34
drivers/net/wireless/ath/ath12k/wmi.h
··· 164 164 #define WLAN_SCAN_MAX_HINT_BSSID 10 165 165 #define MAX_RNR_BSS 5 166 166 167 - #define WLAN_SCAN_MAX_HINT_S_SSID 10 168 - #define WLAN_SCAN_MAX_HINT_BSSID 10 169 - #define MAX_RNR_BSS 5 170 - 171 167 #define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 172 168 173 169 #define WMI_BA_MODE_BUFFER_SIZE_256 3 ··· 3353 3357 const u8 *bssid; 3354 3358 }; 3355 3359 3356 - struct wmi_start_scan_arg { 3357 - u32 scan_id; 3358 - u32 scan_req_id; 3359 - u32 vdev_id; 3360 - u32 scan_priority; 3361 - u32 notify_scan_events; 3362 - u32 dwell_time_active; 3363 - u32 dwell_time_passive; 3364 - u32 min_rest_time; 3365 - u32 max_rest_time; 3366 - u32 repeat_probe_time; 3367 - u32 probe_spacing_time; 3368 - u32 idle_time; 3369 - u32 max_scan_time; 3370 - u32 probe_delay; 3371 - u32 scan_ctrl_flags; 3372 - 3373 - u32 ie_len; 3374 - u32 n_channels; 3375 - u32 n_ssids; 3376 - u32 n_bssids; 3377 - 3378 - u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; 3379 - u32 channels[64]; 3380 - struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; 3381 - struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; 3382 - }; 3383 - 3384 3360 #define WMI_SCAN_STOP_ONE 0x00000000 3385 3361 #define WMI_SCAN_STOP_VAP_ALL 0x01000000 3386 3362 #define WMI_SCAN_STOP_ALL 0x04000000 ··· 4743 4775 __le32 vdev_id; 4744 4776 __le32 buf_len; 4745 4777 } __packed; 4746 - 4747 - #define WMI_MAX_MEM_REQS 32 4748 4778 4749 4779 #define MAX_RADIOS 3 4750 4780
+1 -2
drivers/net/wireless/ath/ath6kl/htc_mbox.c
··· 364 364 packet->buf -= HTC_HDR_LENGTH; 365 365 hdr = (struct htc_frame_hdr *)packet->buf; 366 366 367 - /* Endianess? */ 368 - put_unaligned((u16)packet->act_len, &hdr->payld_len); 367 + put_unaligned_le16(packet->act_len, &hdr->payld_len); 369 368 hdr->flags = flags; 370 369 hdr->eid = packet->endpoint; 371 370 hdr->ctrl[0] = ctrl0;
+1 -2
drivers/net/wireless/ath/ath6kl/htc_pipe.c
··· 237 237 238 238 packet->info.tx.flags |= HTC_FLAGS_TX_FIXUP_NETBUF; 239 239 240 - /* Endianess? */ 241 - put_unaligned((u16) payload_len, &htc_hdr->payld_len); 240 + put_unaligned_le16(payload_len, &htc_hdr->payld_len); 242 241 htc_hdr->flags = packet->info.tx.flags; 243 242 htc_hdr->eid = (u8) packet->endpoint; 244 243 htc_hdr->ctrl[0] = 0;
+1
drivers/net/wireless/ath/ath9k/ath9k.h
··· 39 39 extern int ath9k_led_blink; 40 40 extern bool is_ath9k_unloaded; 41 41 extern int ath9k_use_chanctx; 42 + extern int ath9k_use_msi; 42 43 43 44 /*************************/ 44 45 /* Descriptor Management */
+1 -1
drivers/net/wireless/ath/ath9k/eeprom_4k.c
··· 76 76 static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size, 77 77 struct modal_eep_4k_header *modal_hdr) 78 78 { 79 - PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); 79 + PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0])); 80 80 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); 81 81 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); 82 82 PR_EEP("Switch Settle", modal_hdr->switchSettling);
+2 -2
drivers/net/wireless/ath/ath9k/eeprom_9287.c
··· 79 79 static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size, 80 80 struct modal_eep_ar9287_header *modal_hdr) 81 81 { 82 - PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); 83 - PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1])); 82 + PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0])); 83 + PR_EEP("Chain1 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[1])); 84 84 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); 85 85 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); 86 86 PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
+3 -3
drivers/net/wireless/ath/ath9k/eeprom_def.c
··· 135 135 static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size, 136 136 struct modal_eep_header *modal_hdr) 137 137 { 138 - PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0])); 139 - PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1])); 140 - PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2])); 138 + PR_EEP("Chain0 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[0])); 139 + PR_EEP("Chain1 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[1])); 140 + PR_EEP("Chain2 Ant. Control", le32_to_cpu(modal_hdr->antCtrlChain[2])); 141 141 PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon)); 142 142 PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]); 143 143 PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
-2
drivers/net/wireless/ath/ath9k/pci.c
··· 21 21 #include <linux/module.h> 22 22 #include "ath9k.h" 23 23 24 - extern int ath9k_use_msi; 25 - 26 24 static const struct pci_device_id ath_pci_id_table[] = { 27 25 { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ 28 26 { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+8 -2
drivers/net/wireless/ath/ath9k/xmit.c
··· 1674 1674 ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val) 1675 1675 { 1676 1676 struct ieee80211_hdr *hdr; 1677 - u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1678 - u16 mask_val = mask * val; 1677 + __le16 mask, mask_val; 1678 + 1679 + mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1680 + 1681 + if (val) 1682 + mask_val = mask; 1683 + else 1684 + mask_val = 0; 1679 1685 1680 1686 hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; 1681 1687 if ((hdr->frame_control & mask) != mask_val) {
+2 -2
drivers/net/wireless/ath/wcn36xx/main.c
··· 756 756 if (sta->deflink.vht_cap.vht_supported) { 757 757 sta_priv->supported_rates.op_rate_mode = STA_11ac; 758 758 sta_priv->supported_rates.vht_rx_mcs_map = 759 - sta->deflink.vht_cap.vht_mcs.rx_mcs_map; 759 + le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map); 760 760 sta_priv->supported_rates.vht_tx_mcs_map = 761 - sta->deflink.vht_cap.vht_mcs.tx_mcs_map; 761 + le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map); 762 762 } 763 763 } 764 764
+2 -2
drivers/net/wireless/ath/wcn36xx/txrx.c
··· 318 318 memset(&status, 0, sizeof(status)); 319 319 320 320 bd = (struct wcn36xx_rx_bd *)skb->data; 321 - buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); 321 + buff_to_be(bd, sizeof(*bd)/sizeof(u32)); 322 322 wcn36xx_dbg_dump(WCN36XX_DBG_RX_DUMP, 323 323 "BD <<< ", (char *)bd, 324 324 sizeof(struct wcn36xx_rx_bd)); ··· 692 692 /* MGMT and CTRL frames are handeld here*/ 693 693 wcn36xx_set_tx_mgmt(&bd, wcn, &vif_priv, skb, bcast); 694 694 695 - buff_to_be((u32 *)&bd, sizeof(bd)/sizeof(u32)); 695 + buff_to_be(&bd, sizeof(bd)/sizeof(u32)); 696 696 bd.tx_bd_sign = 0xbdbdbdbd; 697 697 698 698 ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low);
+5 -2
drivers/net/wireless/ath/wcn36xx/wcn36xx.h
··· 100 100 #define RF_IRIS_WCN3660 0x3660 101 101 #define RF_IRIS_WCN3680 0x3680 102 102 103 - static inline void buff_to_be(u32 *buf, size_t len) 103 + static inline void buff_to_be(void *buf, size_t len) 104 104 { 105 + __be32 *to = buf; 106 + u32 *from = buf; 105 107 int i; 108 + 106 109 for (i = 0; i < len; i++) 107 - buf[i] = cpu_to_be32(buf[i]); 110 + to[i] = cpu_to_be32(from[i]); 108 111 } 109 112 110 113 struct nv_data {
+2 -2
drivers/net/wireless/ath/wil6210/cfg80211.c
··· 2735 2735 return 0; 2736 2736 } 2737 2737 2738 - combo = conc->combos; 2738 + combo = (const struct wil_fw_concurrency_combo *)(conc + 1); 2739 2739 n_combos = le16_to_cpu(conc->n_combos); 2740 2740 for (i = 0; i < n_combos; i++) { 2741 2741 total_limits += combo->n_limits; ··· 2751 2751 return -ENOMEM; 2752 2752 iface_limit = (struct ieee80211_iface_limit *)(iface_combinations + 2753 2753 n_combos); 2754 - combo = conc->combos; 2754 + combo = (const struct wil_fw_concurrency_combo *)(conc + 1); 2755 2755 for (i = 0; i < n_combos; i++) { 2756 2756 iface_combinations[i].max_interfaces = combo->max_interfaces; 2757 2757 iface_combinations[i].num_different_channels =
-1
drivers/net/wireless/ath/wil6210/fw.h
··· 93 93 /* number of concurrency combinations that follow */ 94 94 __le16 n_combos; 95 95 /* keep last - combinations, variable size by n_combos */ 96 - struct wil_fw_concurrency_combo combos[]; 97 96 } __packed; 98 97 99 98 /* brd file info encoded inside a comment record */
+2 -2
drivers/net/wireless/ath/wil6210/fw_inc.c
··· 212 212 } 213 213 214 214 n_combos = le16_to_cpu(rec->n_combos); 215 - remain = size - offsetof(struct wil_fw_record_concurrency, combos); 216 - combo = rec->combos; 215 + remain = size - sizeof(struct wil_fw_record_concurrency); 216 + combo = (const struct wil_fw_concurrency_combo *)(rec + 1); 217 217 for (i = 0; i < n_combos; i++) { 218 218 if (remain < sizeof(*combo)) 219 219 goto out_short;
+4 -9
drivers/net/wireless/broadcom/b43/sysfs.c
··· 53 53 54 54 switch (wldev->phy.g->interfmode) { 55 55 case B43_INTERFMODE_NONE: 56 - count = 57 - snprintf(buf, PAGE_SIZE, 58 - "0 (No Interference Mitigation)\n"); 56 + count = sysfs_emit(buf, "0 (No Interference Mitigation)\n"); 59 57 break; 60 58 case B43_INTERFMODE_NONWLAN: 61 - count = 62 - snprintf(buf, PAGE_SIZE, 63 - "1 (Non-WLAN Interference Mitigation)\n"); 59 + count = sysfs_emit(buf, 60 + "1 (Non-WLAN Interference Mitigation)\n"); 64 61 break; 65 62 case B43_INTERFMODE_MANUALWLAN: 66 - count = 67 - snprintf(buf, PAGE_SIZE, 68 - "2 (WLAN Interference Mitigation)\n"); 63 + count = sysfs_emit(buf, "2 (WLAN Interference Mitigation)\n"); 69 64 break; 70 65 default: 71 66 B43_WARN_ON(1);
+6 -10
drivers/net/wireless/broadcom/b43legacy/sysfs.c
··· 75 75 76 76 switch (wldev->phy.interfmode) { 77 77 case B43legacy_INTERFMODE_NONE: 78 - count = snprintf(buf, PAGE_SIZE, "0 (No Interference" 79 - " Mitigation)\n"); 78 + count = sysfs_emit(buf, "0 (No Interference Mitigation)\n"); 80 79 break; 81 80 case B43legacy_INTERFMODE_NONWLAN: 82 - count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference" 83 - " Mitigation)\n"); 81 + count = sysfs_emit(buf, 82 + "1 (Non-WLAN Interference Mitigation)\n"); 84 83 break; 85 84 case B43legacy_INTERFMODE_MANUALWLAN: 86 - count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference" 87 - " Mitigation)\n"); 85 + count = sysfs_emit(buf, "2 (WLAN Interference Mitigation)\n"); 88 86 break; 89 87 default: 90 88 B43legacy_WARN_ON(1); ··· 153 155 mutex_lock(&wldev->wl->mutex); 154 156 155 157 if (wldev->short_preamble) 156 - count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble" 157 - " enabled)\n"); 158 + count = sysfs_emit(buf, "1 (Short Preamble enabled)\n"); 158 159 else 159 - count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble" 160 - " disabled)\n"); 160 + count = sysfs_emit(buf, "0 (Short Preamble disabled)\n"); 161 161 162 162 mutex_unlock(&wldev->wl->mutex); 163 163
+10 -5
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
··· 1675 1675 #define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de 1676 1676 #define BRCMF_RANDOM_SEED_LENGTH 0x100 1677 1677 1678 + static noinline_for_stack void 1679 + brcmf_pcie_provide_random_bytes(struct brcmf_pciedev_info *devinfo, u32 address) 1680 + { 1681 + u8 randbuf[BRCMF_RANDOM_SEED_LENGTH]; 1682 + 1683 + get_random_bytes(randbuf, BRCMF_RANDOM_SEED_LENGTH); 1684 + memcpy_toio(devinfo->tcm + address, randbuf, BRCMF_RANDOM_SEED_LENGTH); 1685 + } 1686 + 1678 1687 static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, 1679 1688 const struct firmware *fw, void *nvram, 1680 1689 u32 nvram_len) ··· 1726 1717 .length = cpu_to_le32(rand_len), 1727 1718 .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), 1728 1719 }; 1729 - void *randbuf; 1730 1720 1731 1721 /* Some Apple chips/firmwares expect a buffer of random 1732 1722 * data to be present before NVRAM ··· 1737 1729 sizeof(footer)); 1738 1730 1739 1731 address -= rand_len; 1740 - randbuf = kzalloc(rand_len, GFP_KERNEL); 1741 - get_random_bytes(randbuf, rand_len); 1742 - memcpy_toio(devinfo->tcm + address, randbuf, rand_len); 1743 - kfree(randbuf); 1732 + brcmf_pcie_provide_random_bytes(devinfo, address); 1744 1733 } 1745 1734 } else { 1746 1735 brcmf_dbg(PCIE, "No matching NVRAM file found %s\n",
+2
drivers/net/wireless/intel/iwlwifi/cfg/bz.c
··· 149 149 }; 150 150 151 151 const char iwl_bz_name[] = "Intel(R) TBD Bz device"; 152 + const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz"; 153 + const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz"; 152 154 const char iwl_mtp_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz"; 153 155 154 156 const struct iwl_cfg iwl_cfg_bz = {
+54 -3
drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2015-2017 Intel Deutschland GmbH 6 6 */ ··· 843 843 u8 reserved2[2]; 844 844 } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */ 845 845 846 + /* MAX MLO keys of non-active links that can arrive in the notification */ 847 + #define WOWLAN_MAX_MLO_KEYS 18 848 + 849 + /** 850 + * enum iwl_wowlan_mlo_gtk_type - GTK types 851 + * @WOWLAN_MLO_GTK_KEY_TYPE_GTK: GTK 852 + * @WOWLAN_MLO_GTK_KEY_TYPE_IGTK: IGTK 853 + * @WOWLAN_MLO_GTK_KEY_TYPE_BIGTK: BIGTK 854 + * @WOWLAN_MLO_GTK_KEY_NUM_TYPES: number of key types 855 + */ 856 + enum iwl_wowlan_mlo_gtk_type { 857 + WOWLAN_MLO_GTK_KEY_TYPE_GTK, 858 + WOWLAN_MLO_GTK_KEY_TYPE_IGTK, 859 + WOWLAN_MLO_GTK_KEY_TYPE_BIGTK, 860 + WOWLAN_MLO_GTK_KEY_NUM_TYPES 861 + }; /* WOWLAN_MLO_GTK_KEY_TYPE_API_E_VER_1 */ 862 + 863 + /** 864 + * enum iwl_wowlan_mlo_gtk_flag - MLO GTK flags 865 + * @WOWLAN_MLO_GTK_FLAG_KEY_LEN_MSK: 0 for len 16, 1 for len 32 866 + * @WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK: key id (ranges from 0 to 7) 867 + * @WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK: spec link id of the key 868 + * @WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK: &enum iwl_wowlan_mlo_gtk_type 869 + * @WOWLAN_MLO_GTK_FLAG_LAST_KEY_MSK: is this the last given key per 870 + * key-type / link-id - the currently used key 871 + */ 872 + enum iwl_wowlan_mlo_gtk_flag { 873 + WOWLAN_MLO_GTK_FLAG_KEY_LEN_MSK = 0x0001, 874 + WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK = 0x000E, 875 + WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK = 0x00F0, 876 + WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK = 0x0300, 877 + WOWLAN_MLO_GTK_FLAG_LAST_KEY_MSK = 0x0400 878 + }; /* WOWLAN_MLO_GTK_FLAG_API_E_VER_1 */ 879 + 880 + /** 881 + * struct iwl_wowlan_mlo_gtk - MLO GTK info 882 + * @key: key material 883 + * @flags: &enum iwl_wowlan_mlo_gtk_flag 884 + * @pn: packet number 885 + */ 886 + struct iwl_wowlan_mlo_gtk { 887 + u8 key[WOWLAN_KEY_MAX_SIZE]; 888 + __le16 flags; 889 + u8 pn[6]; 890 + } __packed; /* WOWLAN_MLO_GTK_KEY_API_S_VER_1 */ 891 + 846 892 /** 847 893 * struct iwl_wowlan_info_notif - WoWLAN information notification 848 894 * @gtk: GTK data ··· 905 859 * @tid_tear_down: bit mask of tids whose BA sessions were closed 906 860 * in suspend state 907 861 * @station_id: station id 862 + * @num_mlo_link_keys: number of &struct iwl_wowlan_mlo_gtk structs 863 + * following this notif, or reserved in version < 4 908 864 * @reserved2: reserved 865 + * @mlo_gtks: array of GTKs of size num_mlo_link_keys for version >= 4 909 866 */ 910 867 struct iwl_wowlan_info_notif { 911 868 struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM]; ··· 924 875 __le32 received_beacons; 925 876 u8 tid_tear_down; 926 877 u8 station_id; 927 - u8 reserved2[2]; 928 - } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3 */ 878 + u8 num_mlo_link_keys; 879 + u8 reserved2; 880 + struct iwl_wowlan_mlo_gtk mlo_gtks[]; 881 + } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3, _VER_4 */ 929 882 930 883 /** 931 884 * struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification
+4 -1
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
··· 609 609 610 610 /** 611 611 * struct iwl_lari_config_change_cmd_v7 - change LARI configuration 612 - * This structure is used also for lari cmd version 8. 612 + * This structure is used also for lari cmd version 8 and 9. 613 613 * @config_bitmap: Bitmap of the config commands. Each bit will trigger a 614 614 * different predefined FW config operation. 615 615 * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. ··· 619 619 * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits 620 620 * per country, one to indicate whether to override and the other to 621 621 * indicate allow/disallow unii4 channels. 622 + * For LARI cmd version 4 to 8 - bits 0:3 are supported. 623 + * For LARI cmd version 9 - bits 0:5 are supported. 622 624 * @chan_state_active_bitmap: Bitmap to enable different bands per country 623 625 * or region. 624 626 * Each bit represents a country or region, and a band to activate ··· 644 642 } __packed; 645 643 /* LARI_CHANGE_CONF_CMD_S_VER_7 */ 646 644 /* LARI_CHANGE_CONF_CMD_S_VER_8 */ 645 + /* LARI_CHANGE_CONF_CMD_S_VER_9 */ 647 646 648 647 /* Activate UNII-1 (5.2GHz) for World Wide */ 649 648 #define ACTIVATE_5G2_IN_WW_MASK BIT(4)
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
··· 3 3 * Copyright (C) 2012-2014 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 - * Copyright (C) 2021-2023 Intel Corporation 6 + * Copyright (C) 2021-2024 Intel Corporation 7 7 */ 8 8 #ifndef __iwl_fw_api_offload_h__ 9 9 #define __iwl_fw_api_offload_h__ ··· 20 20 /** 21 21 * @WOWLAN_INFO_NOTIFICATION: Notification in 22 22 * &struct iwl_wowlan_info_notif_v1, &struct iwl_wowlan_info_notif_v2, 23 - * or iwl_wowlan_info_notif 23 + * or &struct iwl_wowlan_info_notif 24 24 */ 25 25 WOWLAN_INFO_NOTIFICATION = 0xFD, 26 26
+30
drivers/net/wireless/intel/iwlwifi/fw/api/power.h
··· 385 385 __le32 timer_period; 386 386 __le32 flags; 387 387 } __packed; /* TX_REDUCED_POWER_API_S_VER_7 */ 388 + 389 + /** 390 + * struct iwl_dev_tx_power_cmd_v8 - TX power reduction command version 8 391 + * @per_chain: per chain restrictions 392 + * @enable_ack_reduction: enable or disable close range ack TX power 393 + * reduction. 394 + * @per_chain_restriction_changed: is per_chain_restriction has changed 395 + * from last command. used if set_mode is 396 + * IWL_TX_POWER_MODE_SET_SAR_TIMER. 397 + * note: if not changed, the command is used for keep alive only. 398 + * @reserved: reserved (padding) 399 + * @timer_period: timer in milliseconds. if expires FW will change to default 400 + * BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER 401 + * @flags: reduce power flags. 402 + * @tpc_vlp_backoff_level: user backoff of UNII5,7 VLP channels in USA. 403 + * Not in use. 404 + */ 405 + struct iwl_dev_tx_power_cmd_v8 { 406 + __le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; 407 + u8 enable_ack_reduction; 408 + u8 per_chain_restriction_changed; 409 + u8 reserved[2]; 410 + __le32 timer_period; 411 + __le32 flags; 412 + __le32 tpc_vlp_backoff_level; 413 + } __packed; /* TX_REDUCED_POWER_API_S_VER_8 */ 414 + 388 415 /** 389 416 * struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion) 390 417 * @common: common part of the command ··· 419 392 * @v4: version 4 part of the command 420 393 * @v5: version 5 part of the command 421 394 * @v6: version 6 part of the command 395 + * @v7: version 7 part of the command 396 + * @v8: version 8 part of the command 422 397 */ 423 398 struct iwl_dev_tx_power_cmd { 424 399 struct iwl_dev_tx_power_common common; ··· 430 401 struct iwl_dev_tx_power_cmd_v5 v5; 431 402 struct iwl_dev_tx_power_cmd_v6 v6; 432 403 struct iwl_dev_tx_power_cmd_v7 v7; 404 + struct iwl_dev_tx_power_cmd_v8 v8; 433 405 }; 434 406 }; 435 407
+1
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
··· 3084 3084 if (!test_bit(wk_idx, &fwrt->dump.active_wks)) 3085 3085 return; 3086 3086 3087 + /* also checks 'desc' for pre-ini mode, since that shadows in union */ 3087 3088 if (!dump_data->trig) { 3088 3089 IWL_ERR(fwrt, "dump trigger data is not set\n"); 3089 3090 goto out;
+3
drivers/net/wireless/intel/iwlwifi/fw/file.h
··· 395 395 * @IWL_UCODE_TLV_CAPA_SPP_AMSDU_SUPPORT: Support SPP (signaling and payload 396 396 * protected) A-MSDU. 397 397 * @IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT: Support secure LTF measurement. 398 + * @IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS: Support monitor mode on otherwise 399 + * passive channels 398 400 * 399 401 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used 400 402 */ ··· 496 494 IWL_UCODE_TLV_CAPA_SNIFF_VALIDATE_SUPPORT = (__force iwl_ucode_tlv_capa_t)116, 497 495 IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT = (__force iwl_ucode_tlv_capa_t)117, 498 496 IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT = (__force iwl_ucode_tlv_capa_t)121, 497 + IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS = (__force iwl_ucode_tlv_capa_t)122, 499 498 NUM_IWL_UCODE_TLV_CAPA 500 499 /* 501 500 * This construction make both sparse (which cannot increment the previous
+18 -1
drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2023 Intel Corporation 3 + * Copyright (C) 2023-2024 Intel Corporation 4 4 */ 5 5 6 6 #ifndef __fw_regulatory_h__ ··· 131 131 DSM_VALUE_INDONESIA_RESERVED, 132 132 DSM_VALUE_INDONESIA_MAX 133 133 }; 134 + 135 + enum iwl_dsm_unii4_bitmap { 136 + DSM_VALUE_UNII4_US_OVERRIDE_MSK = BIT(0), 137 + DSM_VALUE_UNII4_US_EN_MSK = BIT(1), 138 + DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK = BIT(2), 139 + DSM_VALUE_UNII4_ETSI_EN_MSK = BIT(3), 140 + DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK = BIT(4), 141 + DSM_VALUE_UNII4_CANADA_EN_MSK = BIT(5), 142 + }; 143 + 144 + #define DSM_UNII4_ALLOW_BITMAP_CMD_V8 (DSM_VALUE_UNII4_US_OVERRIDE_MSK | \ 145 + DSM_VALUE_UNII4_US_EN_MSK | \ 146 + DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK | \ 147 + DSM_VALUE_UNII4_ETSI_EN_MSK) 148 + #define DSM_UNII4_ALLOW_BITMAP (DSM_UNII4_ALLOW_BITMAP_CMD_V8 | \ 149 + DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | \ 150 + DSM_VALUE_UNII4_CANADA_EN_MSK) 134 151 135 152 enum iwl_dsm_values_rfi { 136 153 DSM_VALUE_RFI_DLVR_DISABLE = BIT(0),
+5
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
··· 46 46 * struct iwl_fwrt_dump_data - dump data 47 47 * @trig: trigger the worker was scheduled upon 48 48 * @fw_pkt: packet received from FW 49 + * 50 + * Note that the decision which part of the union is used 51 + * is based on iwl_trans_dbg_ini_valid(): the 'trig' part 52 + * is used if it is %true, the 'desc' part otherwise. 49 53 */ 50 54 struct iwl_fwrt_dump_data { 51 55 union { ··· 58 54 struct iwl_rx_packet *fw_pkt; 59 55 }; 60 56 struct { 57 + /* must be first to be same as 'trig' */ 61 58 const struct iwl_fw_dump_desc *desc; 62 59 bool monitor_only; 63 60 };
+5 -2
drivers/net/wireless/intel/iwlwifi/iwl-config.h
··· 11 11 #include <linux/netdevice.h> 12 12 #include <linux/ieee80211.h> 13 13 #include <linux/nl80211.h> 14 + #include <linux/mod_devicetable.h> 14 15 #include "iwl-csr.h" 15 16 #include "iwl-drv.h" 16 17 ··· 422 421 #define IWL_CFG_MAC_TYPE_SC 0x48 423 422 #define IWL_CFG_MAC_TYPE_SC2 0x49 424 423 #define IWL_CFG_MAC_TYPE_SC2F 0x4A 424 + #define IWL_CFG_MAC_TYPE_BZ_W 0x4B 425 425 426 426 #define IWL_CFG_RF_TYPE_TH 0x105 427 427 #define IWL_CFG_RF_TYPE_TH1 0x108 ··· 431 429 #define IWL_CFG_RF_TYPE_HR2 0x10A 432 430 #define IWL_CFG_RF_TYPE_HR1 0x10C 433 431 #define IWL_CFG_RF_TYPE_GF 0x10D 434 - #define IWL_CFG_RF_TYPE_MR 0x110 435 - #define IWL_CFG_RF_TYPE_MS 0x111 436 432 #define IWL_CFG_RF_TYPE_FM 0x112 437 433 #define IWL_CFG_RF_TYPE_WH 0x113 438 434 ··· 484 484 iwl_pci_find_dev_info(u16 device, u16 subsystem_device, 485 485 u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, 486 486 u8 jacket, u8 rf_id, u8 no_160, u8 cores, u8 rf_step); 487 + extern const struct pci_device_id iwl_hw_card_ids[]; 487 488 #endif 488 489 489 490 /* ··· 542 541 extern const char iwl_ax231_name[]; 543 542 extern const char iwl_ax411_name[]; 544 543 extern const char iwl_bz_name[]; 544 + extern const char iwl_fm_name[]; 545 + extern const char iwl_gl_name[]; 545 546 extern const char iwl_mtp_name[]; 546 547 extern const char iwl_sc_name[]; 547 548 extern const char iwl_sc2_name[];
-6
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
··· 192 192 case IWL_CFG_RF_TYPE_GF: 193 193 rf = "gf"; 194 194 break; 195 - case IWL_CFG_RF_TYPE_MR: 196 - rf = "mr"; 197 - break; 198 - case IWL_CFG_RF_TYPE_MS: 199 - rf = "ms"; 200 - break; 201 195 case IWL_CFG_RF_TYPE_FM: 202 196 rf = "fm"; 203 197 break;
+15 -13
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 392 392 return NL80211_BAND_2GHZ; 393 393 } 394 394 395 - static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, 395 + static int iwl_init_channel_map(struct iwl_trans *trans, 396 + const struct iwl_fw *fw, 396 397 struct iwl_nvm_data *data, 397 398 const void * const nvm_ch_flags, 398 399 u32 sbands_flags, bool v4) 399 400 { 401 + const struct iwl_cfg *cfg = trans->cfg; 402 + struct device *dev = trans->dev; 400 403 int ch_idx; 401 404 int n_channels = 0; 402 405 struct ieee80211_channel *channel; ··· 481 478 else 482 479 channel->flags = 0; 483 480 484 - /* TODO: Don't put limitations on UHB devices as we still don't 485 - * have NVM for them 486 - */ 487 - if (cfg->uhb_supported) 488 - channel->flags = 0; 481 + if (fw_has_capa(&fw->ucode_capa, 482 + IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS)) 483 + channel->flags |= IEEE80211_CHAN_CAN_MONITOR; 484 + 489 485 iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, 490 486 channel->hw_value, ch_flags); 491 487 IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n", ··· 599 597 600 598 static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = { 601 599 { 602 - .types_mask = BIT(NL80211_IFTYPE_STATION), 600 + .types_mask = BIT(NL80211_IFTYPE_STATION) | 601 + BIT(NL80211_IFTYPE_P2P_CLIENT), 603 602 .he_cap = { 604 603 .has_he = true, 605 604 .he_cap_elem = { ··· 756 753 }, 757 754 }, 758 755 { 759 - .types_mask = BIT(NL80211_IFTYPE_AP), 756 + .types_mask = BIT(NL80211_IFTYPE_AP) | 757 + BIT(NL80211_IFTYPE_P2P_GO), 760 758 .he_cap = { 761 759 .has_he = true, 762 760 .he_cap_elem = { ··· 910 906 u8 tx_chains, u8 rx_chains, 911 907 const struct iwl_fw *fw) 912 908 { 913 - bool is_ap = iftype_data->types_mask & BIT(NL80211_IFTYPE_AP); 909 + bool is_ap = iftype_data->types_mask & (BIT(NL80211_IFTYPE_AP) | 910 + BIT(NL80211_IFTYPE_P2P_GO)); 914 911 bool no_320; 915 912 916 913 no_320 = (!trans->trans_cfg->integrated && ··· 1028 1023 1029 1024 switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { 1030 1025 case IWL_CFG_RF_TYPE_GF: 1031 - case IWL_CFG_RF_TYPE_MR: 1032 - case IWL_CFG_RF_TYPE_MS: 1033 1026 case IWL_CFG_RF_TYPE_FM: 1034 1027 case IWL_CFG_RF_TYPE_WH: 1035 1028 iftype_data->he_cap.he_cap_elem.phy_cap_info[9] |= ··· 1179 1176 const struct iwl_fw *fw) 1180 1177 { 1181 1178 struct device *dev = trans->dev; 1182 - const struct iwl_cfg *cfg = trans->cfg; 1183 1179 int n_channels; 1184 1180 int n_used = 0; 1185 1181 struct ieee80211_supported_band *sband; 1186 1182 1187 - n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags, 1183 + n_channels = iwl_init_channel_map(trans, fw, data, nvm_ch_flags, 1188 1184 sbands_flags, v4); 1189 1185 sband = &data->bands[NL80211_BAND_2GHZ]; 1190 1186 sband->band = NL80211_BAND_2GHZ;
+4 -5
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 2 /* 3 - * Copyright (C) 2005-2014, 2018-2023 Intel Corporation 3 + * Copyright (C) 2005-2014, 2018-2024 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2016 Intel Deutschland GmbH 6 6 */ ··· 371 371 #define CNVI_AUX_MISC_CHIP 0xA200B0 372 372 #define CNVI_AUX_MISC_CHIP_MAC_STEP(_val) (((_val) & 0xf000000) >> 24) 373 373 #define CNVI_AUX_MISC_CHIP_PROD_TYPE(_val) ((_val) & 0xfff) 374 + #define CNVI_AUX_MISC_CHIP_PROD_TYPE_GL 0x910 374 375 #define CNVI_AUX_MISC_CHIP_PROD_TYPE_BZ_U 0x930 376 + #define CNVI_AUX_MISC_CHIP_PROD_TYPE_BZ_I 0x900 377 + #define CNVI_AUX_MISC_CHIP_PROD_TYPE_BZ_W 0x901 375 378 376 379 #define CNVR_AUX_MISC_CHIP 0xA2B800 377 380 #define CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM 0xA29890 ··· 456 453 #define REG_CRF_ID_TYPE_HR_NONE_CDB_1X1 0x501 457 454 #define REG_CRF_ID_TYPE_HR_NONE_CDB_CCP 0x532 458 455 #define REG_CRF_ID_TYPE_GF 0x410 459 - #define REG_CRF_ID_TYPE_GF_TC 0xF08 460 - #define REG_CRF_ID_TYPE_MR 0x810 461 456 #define REG_CRF_ID_TYPE_FM 0x910 462 - #define REG_CRF_ID_TYPE_FMI 0x930 463 - #define REG_CRF_ID_TYPE_FMR 0x900 464 457 #define REG_CRF_ID_TYPE_WHP 0xA10 465 458 466 459 #define HPM_DEBUG 0xA03440
+9 -12
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
··· 219 219 220 220 static inline 221 221 void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm, 222 - struct ieee80211_vif *vif, 222 + struct iwl_mvm_vif_link_info *link_info, 223 223 bool enable, int rssi) 224 224 { 225 - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 226 - 227 - mvmvif->bf_data.last_bt_coex_event = rssi; 228 - mvmvif->bf_data.bt_coex_max_thold = 225 + link_info->bf_data.last_bt_coex_event = rssi; 226 + link_info->bf_data.bt_coex_max_thold = 229 227 enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0; 230 - mvmvif->bf_data.bt_coex_min_thold = 228 + link_info->bf_data.bt_coex_min_thold = 231 229 enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0; 232 230 } 233 231 ··· 410 412 smps_mode, link_id); 411 413 iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, 412 414 false); 413 - /* FIXME: should this be per link? */ 414 - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); 415 + iwl_mvm_bt_coex_enable_rssi_event(mvm, link_info, false, 416 + 0); 415 417 } 416 418 return; 417 419 } ··· 506 508 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF || 507 509 !vif->cfg.assoc) { 508 510 iwl_mvm_bt_coex_reduced_txp(mvm, link_info->ap_sta_id, false); 509 - /* FIXME: should this be per link? */ 510 - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); 511 + iwl_mvm_bt_coex_enable_rssi_event(mvm, link_info, false, 0); 511 512 return; 512 513 } 513 514 514 515 /* try to get the avg rssi from fw */ 515 - ave_rssi = mvmvif->bf_data.ave_beacon_signal; 516 + ave_rssi = link_info->bf_data.ave_beacon_signal; 516 517 517 518 /* if the RSSI isn't valid, fake it is very low */ 518 519 if (!ave_rssi) ··· 527 530 } 528 531 529 532 /* Begin to monitor the RSSI: it may influence the reduced Tx power */ 530 - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, true, ave_rssi); 533 + iwl_mvm_bt_coex_enable_rssi_event(mvm, link_info, true, ave_rssi); 531 534 } 532 535 533 536 /* must be called under rcu_read_lock */
+206 -6
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
··· 1152 1152 if (ret) 1153 1153 return ret; 1154 1154 1155 - return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0); 1155 + return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0, 1156 + mvm_link->ap_sta_id); 1156 1157 } 1157 1158 1158 1159 static int ··· 1472 1471 1473 1472 struct iwl_multicast_key_data igtk; 1474 1473 struct iwl_multicast_key_data bigtk[WOWLAN_BIGTK_KEYS_NUM]; 1474 + 1475 + int num_mlo_keys; 1476 + struct iwl_wowlan_mlo_gtk mlo_keys[WOWLAN_MAX_MLO_KEYS]; 1475 1477 1476 1478 u8 *wake_packet; 1477 1479 }; ··· 1834 1830 void *_data) 1835 1831 { 1836 1832 struct iwl_mvm_d3_gtk_iter_data *data = _data; 1833 + int link_id = vif->active_links ? __ffs(vif->active_links) : -1; 1834 + 1835 + if (link_id >= 0 && key->link_id >= 0 && link_id != key->link_id) 1836 + return; 1837 1837 1838 1838 if (data->unhandled_cipher) 1839 1839 return; ··· 1926 1918 struct iwl_mvm_d3_gtk_iter_data *data = _data; 1927 1919 struct iwl_wowlan_status_data *status = data->status; 1928 1920 s8 keyidx; 1921 + int link_id = vif->active_links ? __ffs(vif->active_links) : -1; 1922 + 1923 + if (link_id >= 0 && key->link_id >= 0 && link_id != key->link_id) 1924 + return; 1929 1925 1930 1926 if (data->unhandled_cipher) 1931 1927 return; ··· 1983 1971 &status->bigtk[idx]); 1984 1972 } 1985 1973 } 1974 + } 1975 + 1976 + struct iwl_mvm_d3_mlo_old_keys { 1977 + u32 cipher[IEEE80211_MLD_MAX_NUM_LINKS][WOWLAN_MLO_GTK_KEY_NUM_TYPES]; 1978 + struct ieee80211_key_conf *key[IEEE80211_MLD_MAX_NUM_LINKS][8]; 1979 + }; 1980 + 1981 + static void iwl_mvm_mlo_key_ciphers(struct ieee80211_hw *hw, 1982 + struct ieee80211_vif *vif, 1983 + struct ieee80211_sta *sta, 1984 + struct ieee80211_key_conf *key, 1985 + void *data) 1986 + { 1987 + struct iwl_mvm_d3_mlo_old_keys *old_keys = data; 1988 + enum iwl_wowlan_mlo_gtk_type key_type; 1989 + 1990 + if (key->link_id < 0) 1991 + return; 1992 + 1993 + if (WARN_ON(key->link_id >= IEEE80211_MLD_MAX_NUM_LINKS || 1994 + key->keyidx >= 8)) 1995 + return; 1996 + 1997 + if (WARN_ON(old_keys->key[key->link_id][key->keyidx])) 1998 + return; 1999 + 2000 + switch (key->cipher) { 2001 + case WLAN_CIPHER_SUITE_CCMP: 2002 + case WLAN_CIPHER_SUITE_GCMP: 2003 + case WLAN_CIPHER_SUITE_GCMP_256: 2004 + key_type = WOWLAN_MLO_GTK_KEY_TYPE_GTK; 2005 + break; 2006 + case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2007 + case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2008 + case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2009 + case WLAN_CIPHER_SUITE_AES_CMAC: 2010 + if (key->keyidx == 4 || key->keyidx == 5) { 2011 + key_type = WOWLAN_MLO_GTK_KEY_TYPE_IGTK; 2012 + break; 2013 + } else if (key->keyidx == 6 || key->keyidx == 7) { 2014 + key_type = WOWLAN_MLO_GTK_KEY_TYPE_BIGTK; 2015 + break; 2016 + } 2017 + return; 2018 + default: 2019 + /* ignore WEP/TKIP or unknown ciphers */ 2020 + return; 2021 + } 2022 + 2023 + old_keys->cipher[key->link_id][key_type] = key->cipher; 2024 + old_keys->key[key->link_id][key->keyidx] = key; 2025 + } 2026 + 2027 + static bool iwl_mvm_mlo_gtk_rekey(struct iwl_wowlan_status_data *status, 2028 + struct ieee80211_vif *vif, 2029 + struct iwl_mvm *mvm) 2030 + { 2031 + int i; 2032 + struct iwl_mvm_d3_mlo_old_keys *old_keys; 2033 + bool ret = true; 2034 + 2035 + IWL_DEBUG_WOWLAN(mvm, "Num of MLO Keys: %d\n", status->num_mlo_keys); 2036 + if (!status->num_mlo_keys) 2037 + return true; 2038 + 2039 + old_keys = kzalloc(sizeof(*old_keys), GFP_KERNEL); 2040 + if (!old_keys) 2041 + return false; 2042 + 2043 + /* find the cipher for each mlo key */ 2044 + ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_mlo_key_ciphers, old_keys); 2045 + 2046 + for (i = 0; i < status->num_mlo_keys; i++) { 2047 + struct iwl_wowlan_mlo_gtk *mlo_key = &status->mlo_keys[i]; 2048 + struct ieee80211_key_conf *key, *old_key; 2049 + struct ieee80211_key_seq seq; 2050 + struct { 2051 + struct ieee80211_key_conf conf; 2052 + u8 key[32]; 2053 + } conf = {}; 2054 + u16 flags = le16_to_cpu(mlo_key->flags); 2055 + int j, link_id, key_id, key_type; 2056 + 2057 + link_id = u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK); 2058 + key_id = u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK); 2059 + key_type = u16_get_bits(flags, 2060 + WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK); 2061 + 2062 + if (!(vif->valid_links & BIT(link_id))) 2063 + continue; 2064 + 2065 + if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS || 2066 + key_id >= 8 || 2067 + key_type >= WOWLAN_MLO_GTK_KEY_NUM_TYPES)) 2068 + continue; 2069 + 2070 + conf.conf.cipher = old_keys->cipher[link_id][key_type]; 2071 + /* WARN_ON? */ 2072 + if (!conf.conf.cipher) 2073 + continue; 2074 + 2075 + conf.conf.keylen = 0; 2076 + switch (conf.conf.cipher) { 2077 + case WLAN_CIPHER_SUITE_CCMP: 2078 + case WLAN_CIPHER_SUITE_GCMP: 2079 + conf.conf.keylen = WLAN_KEY_LEN_CCMP; 2080 + break; 2081 + case WLAN_CIPHER_SUITE_GCMP_256: 2082 + conf.conf.keylen = WLAN_KEY_LEN_GCMP_256; 2083 + break; 2084 + case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2085 + conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_128; 2086 + break; 2087 + case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2088 + conf.conf.keylen = WLAN_KEY_LEN_BIP_GMAC_256; 2089 + break; 2090 + case WLAN_CIPHER_SUITE_AES_CMAC: 2091 + conf.conf.keylen = WLAN_KEY_LEN_AES_CMAC; 2092 + break; 2093 + case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2094 + conf.conf.keylen = WLAN_KEY_LEN_BIP_CMAC_256; 2095 + break; 2096 + } 2097 + 2098 + if (WARN_ON(!conf.conf.keylen || 2099 + conf.conf.keylen > sizeof(conf.key))) 2100 + continue; 2101 + 2102 + memcpy(conf.conf.key, mlo_key->key, conf.conf.keylen); 2103 + conf.conf.keyidx = key_id; 2104 + 2105 + old_key = old_keys->key[link_id][key_id]; 2106 + if (old_key) { 2107 + IWL_DEBUG_WOWLAN(mvm, 2108 + "Remove MLO key id %d, link id %d\n", 2109 + key_id, link_id); 2110 + ieee80211_remove_key(old_key); 2111 + } 2112 + 2113 + IWL_DEBUG_WOWLAN(mvm, "Add MLO key id %d, link id %d\n", 2114 + key_id, link_id); 2115 + key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); 2116 + if (WARN_ON(IS_ERR(key))) { 2117 + ret = false; 2118 + goto out; 2119 + } 2120 + 2121 + /* 2122 + * mac80211 expects the pn in big-endian 2123 + * also note that seq is a union of all cipher types 2124 + * (ccmp, gcmp, cmac, gmac), and they all have the same 2125 + * pn field (of length 6) so just copy it to ccmp.pn. 2126 + */ 2127 + for (j = 5; j >= 0; j--) 2128 + seq.ccmp.pn[5 - j] = mlo_key->pn[j]; 2129 + 2130 + /* group keys are non-QoS and use TID 0 */ 2131 + ieee80211_set_key_rx_seq(key, 0, &seq); 2132 + } 2133 + 2134 + out: 2135 + kfree(old_keys); 2136 + return ret; 1986 2137 } 1987 2138 1988 2139 static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status, ··· 2351 2176 return false; 2352 2177 } 2353 2178 2179 + if (!iwl_mvm_mlo_gtk_rekey(status, vif, mvm)) 2180 + return false; 2181 + 2354 2182 ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, 2355 2183 (void *)&replay_ctr, GFP_KERNEL); 2356 2184 } ··· 2481 2303 static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, 2482 2304 struct iwl_wowlan_info_notif *data, 2483 2305 struct iwl_wowlan_status_data *status, 2484 - u32 len) 2306 + u32 len, bool has_mlo_keys) 2485 2307 { 2486 2308 u32 i; 2309 + u32 expected_len = sizeof(*data); 2487 2310 2488 2311 if (!data) { 2489 2312 IWL_ERR(mvm, "iwl_wowlan_info_notif data is NULL\n"); ··· 2492 2313 return; 2493 2314 } 2494 2315 2495 - if (len < sizeof(*data)) { 2316 + if (has_mlo_keys) 2317 + expected_len += (data->num_mlo_link_keys * 2318 + sizeof(status->mlo_keys[0])); 2319 + 2320 + if (len < expected_len) { 2496 2321 IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); 2497 2322 status = NULL; 2498 2323 return; ··· 2516 2333 le32_to_cpu(data->num_of_gtk_rekeys); 2517 2334 status->received_beacons = le32_to_cpu(data->received_beacons); 2518 2335 status->tid_tear_down = data->tid_tear_down; 2336 + 2337 + if (has_mlo_keys && data->num_mlo_link_keys) { 2338 + status->num_mlo_keys = data->num_mlo_link_keys; 2339 + if (IWL_FW_CHECK(mvm, 2340 + status->num_mlo_keys > WOWLAN_MAX_MLO_KEYS, 2341 + "Too many mlo keys: %d, max %d\n", 2342 + status->num_mlo_keys, WOWLAN_MAX_MLO_KEYS)) 2343 + status->num_mlo_keys = WOWLAN_MAX_MLO_KEYS; 2344 + memcpy(status->mlo_keys, data->mlo_gtks, 2345 + status->num_mlo_keys * sizeof(status->mlo_keys[0])); 2346 + } 2519 2347 } 2520 2348 2521 2349 static void ··· 2747 2553 int i; 2748 2554 bool keep = false; 2749 2555 struct iwl_mvm_sta *mvm_ap_sta; 2556 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2557 + int link_id = vif->active_links ? __ffs(vif->active_links) : 0; 2558 + struct iwl_mvm_vif_link_info *mvm_link = mvmvif->link[link_id]; 2559 + 2560 + if (WARN_ON(!mvm_link)) 2561 + goto out_unlock; 2750 2562 2751 2563 if (!status) 2752 2564 goto out_unlock; ··· 2760 2560 IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n", 2761 2561 status->wakeup_reasons); 2762 2562 2763 - /* still at hard-coded place 0 for D3 image */ 2764 - mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0); 2563 + mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, mvm_link->ap_sta_id); 2765 2564 if (!mvm_ap_sta) 2766 2565 goto out_unlock; 2767 2566 ··· 3273 3074 (void *)pkt->data; 3274 3075 3275 3076 iwl_mvm_parse_wowlan_info_notif(mvm, notif, 3276 - d3_data->status, len); 3077 + d3_data->status, len, 3078 + wowlan_info_ver > 3); 3277 3079 } 3278 3080 3279 3081 d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO;
+59 -1
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
··· 407 407 }; 408 408 409 409 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 410 - if (mvmvif->bf_data.bf_enabled) 410 + if (mvmvif->bf_enabled) 411 411 cmd.bf_enable_beacon_filter = cpu_to_le32(1); 412 412 else 413 413 cmd.bf_enable_beacon_filter = 0; ··· 692 692 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 693 693 } 694 694 695 + static ssize_t iwl_dbgfs_int_mlo_scan_write(struct ieee80211_vif *vif, 696 + char *buf, size_t count, 697 + loff_t *ppos) 698 + { 699 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 700 + struct iwl_mvm *mvm = mvmvif->mvm; 701 + u32 action; 702 + int ret; 703 + 704 + if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif)) 705 + return -EINVAL; 706 + 707 + if (kstrtou32(buf, 0, &action)) 708 + return -EINVAL; 709 + 710 + mutex_lock(&mvm->mutex); 711 + 712 + if (!action) { 713 + ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_INT_MLO, false); 714 + } else if (action == 1) { 715 + struct ieee80211_channel *channels[IEEE80211_MLD_MAX_NUM_LINKS]; 716 + unsigned long usable_links = ieee80211_vif_usable_links(vif); 717 + size_t n_channels = 0; 718 + u8 link_id; 719 + 720 + rcu_read_lock(); 721 + 722 + for_each_set_bit(link_id, &usable_links, 723 + IEEE80211_MLD_MAX_NUM_LINKS) { 724 + struct ieee80211_bss_conf *link_conf = 725 + rcu_dereference(vif->link_conf[link_id]); 726 + 727 + if (WARN_ON_ONCE(!link_conf)) 728 + continue; 729 + 730 + channels[n_channels++] = link_conf->chanreq.oper.chan; 731 + } 732 + 733 + rcu_read_unlock(); 734 + 735 + if (n_channels) 736 + ret = iwl_mvm_int_mlo_scan_start(mvm, vif, channels, 737 + n_channels); 738 + else 739 + ret = -EINVAL; 740 + } else { 741 + ret = -EINVAL; 742 + } 743 + 744 + mutex_unlock(&mvm->mutex); 745 + 746 + return ret ?: count; 747 + } 748 + 695 749 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 696 750 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif) 697 751 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ ··· 765 711 MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10); 766 712 MVM_DEBUGFS_READ_WRITE_FILE_OPS(quota_min, 32); 767 713 MVM_DEBUGFS_READ_FILE_OPS(os_device_timediff); 714 + MVM_DEBUGFS_WRITE_FILE_OPS(int_mlo_scan, 32); 768 715 769 716 void iwl_mvm_vif_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 770 717 { ··· 793 738 MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir, 0600); 794 739 MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir, 0600); 795 740 MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff, mvmvif->dbgfs_dir, 0400); 741 + debugfs_create_bool("ftm_unprotected", 0200, mvmvif->dbgfs_dir, 742 + &mvmvif->ftm_unprotected); 743 + MVM_DEBUGFS_ADD_FILE_VIF(int_mlo_scan, mvmvif->dbgfs_dir, 0200); 796 744 797 745 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 798 746 mvmvif == mvm->bf_allowed_vif)
+16 -1
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 3 * Copyright (C) 2015-2017 Intel Deutschland GmbH 4 - * Copyright (C) 2018-2023 Intel Corporation 4 + * Copyright (C) 2018-2024 Intel Corporation 5 5 */ 6 6 #include <linux/etherdevice.h> 7 7 #include <linux/math64.h> ··· 551 551 break; 552 552 } 553 553 rcu_read_unlock(); 554 + 555 + #ifdef CONFIG_IWLWIFI_DEBUGFS 556 + if (mvmvif->ftm_unprotected) { 557 + target->sta_id = IWL_MVM_INVALID_STA; 558 + target->initiator_ap_flags &= 559 + ~cpu_to_le32(IWL_INITIATOR_AP_FLAGS_PMF); 560 + } 561 + 562 + #endif 554 563 } else { 555 564 target->sta_id = IWL_MVM_INVALID_STA; 556 565 } ··· 722 713 { 723 714 struct iwl_mvm_ftm_pasn_entry *entry; 724 715 u32 flags = le32_to_cpu(target->initiator_ap_flags); 716 + #ifdef CONFIG_IWLWIFI_DEBUGFS 717 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 718 + 719 + if (mvmvif->ftm_unprotected) 720 + return; 721 + #endif 725 722 726 723 if (!(flags & (IWL_INITIATOR_AP_FLAGS_NON_TB | 727 724 IWL_INITIATOR_AP_FLAGS_TB)))
+11 -2
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
··· 896 896 u32 n_subbands; 897 897 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 898 898 IWL_FW_CMD_VER_UNKNOWN); 899 - if (cmd_ver == 7) { 899 + if (cmd_ver >= 7) { 900 900 len = sizeof(cmd.v7); 901 901 n_subbands = IWL_NUM_SUB_BANDS_V2; 902 902 per_chain = cmd.v7.per_chain[0][0]; 903 903 cmd.v7.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags); 904 + if (cmd_ver == 8) 905 + len = sizeof(cmd.v8); 904 906 } else if (cmd_ver == 6) { 905 907 len = sizeof(cmd.v6); 906 908 n_subbands = IWL_NUM_SUB_BANDS_V2; ··· 1239 1237 cmd.oem_11ax_allow_bitmap = cpu_to_le32(value); 1240 1238 1241 1239 ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value); 1242 - if (!ret) 1240 + if (!ret) { 1241 + if (cmd_ver < 9) 1242 + value &= DSM_UNII4_ALLOW_BITMAP_CMD_V8; 1243 + else 1244 + value &= DSM_UNII4_ALLOW_BITMAP; 1245 + 1243 1246 cmd.oem_unii4_allow_bitmap = cpu_to_le32(value); 1247 + } 1244 1248 1245 1249 ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value); 1246 1250 if (!ret) { ··· 1279 1271 size_t cmd_size; 1280 1272 1281 1273 switch (cmd_ver) { 1274 + case 9: 1282 1275 case 8: 1283 1276 case 7: 1284 1277 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7);
+103 -14
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 359 359 /* Set this early since we need to have it for the check below */ 360 360 if (mvm->mld_api_is_used && mvm->nvm_data->sku_cap_11be_enable && 361 361 !iwlwifi_mod_params.disable_11ax && 362 - !iwlwifi_mod_params.disable_11be) 362 + !iwlwifi_mod_params.disable_11be) { 363 363 hw->wiphy->flags |= WIPHY_FLAG_DISABLE_WEXT; 364 + /* we handle this already earlier, but need it for MLO */ 365 + ieee80211_hw_set(hw, HANDLES_QUIET_CSA); 366 + } 364 367 365 368 /* With MLD FW API, it tracks timing by itself, 366 369 * no need for any timing from the host ··· 723 720 724 721 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 725 722 723 + ieee80211_hw_set(hw, DISALLOW_PUNCTURING_5GHZ); 724 + 726 725 #ifdef CONFIG_PM_SLEEP 727 726 if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) && 728 727 mvm->trans->ops->d3_suspend && ··· 907 902 while (likely(!test_bit(IWL_MVM_TXQ_STATE_STOP_FULL, 908 903 &mvmtxq->state) && 909 904 !test_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT, 905 + &mvmtxq->state) && 906 + !test_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, 910 907 &mvmtxq->state) && 911 908 !test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))) { 912 909 skb = ieee80211_tx_dequeue(hw, txq); ··· 1104 1097 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 1105 1098 spin_unlock_bh(&mvm->time_event_lock); 1106 1099 1107 - memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data)); 1100 + mvmvif->bf_enabled = false; 1101 + mvmvif->ba_enabled = false; 1108 1102 mvmvif->ap_sta = NULL; 1103 + 1104 + mvmvif->esr_active = false; 1105 + vif->driver_flags &= ~IEEE80211_VIF_EML_ACTIVE; 1109 1106 1110 1107 for_each_mvm_vif_valid_link(mvmvif, link_id) { 1111 1108 mvmvif->link[link_id]->ap_sta_id = IWL_MVM_INVALID_STA; ··· 1117 1106 mvmvif->link[link_id]->phy_ctxt = NULL; 1118 1107 mvmvif->link[link_id]->active = 0; 1119 1108 mvmvif->link[link_id]->igtk = NULL; 1109 + memset(&mvmvif->link[link_id]->bf_data, 0, 1110 + sizeof(mvmvif->link[link_id]->bf_data)); 1120 1111 } 1121 1112 1122 1113 probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data, ··· 1345 1332 { 1346 1333 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1347 1334 1335 + /* Stop internal MLO scan, if running */ 1336 + mutex_lock(&mvm->mutex); 1337 + iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_INT_MLO, false); 1338 + mutex_unlock(&mvm->mutex); 1339 + 1348 1340 flush_work(&mvm->async_handlers_wk); 1349 1341 flush_work(&mvm->add_stream_wk); 1350 1342 ··· 1417 1399 if (tx_power == IWL_DEFAULT_MAX_TX_POWER) 1418 1400 cmd.common.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); 1419 1401 1420 - if (cmd_ver == 7) 1402 + if (cmd_ver == 8) 1403 + len = sizeof(cmd.v8); 1404 + else if (cmd_ver == 7) 1421 1405 len = sizeof(cmd.v7); 1422 1406 else if (cmd_ver == 6) 1423 1407 len = sizeof(cmd.v6); ··· 1438 1418 return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd); 1439 1419 } 1440 1420 1421 + static void iwl_mvm_post_csa_tx(void *data, struct ieee80211_sta *sta) 1422 + { 1423 + struct ieee80211_hw *hw = data; 1424 + int i; 1425 + 1426 + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { 1427 + struct iwl_mvm_txq *mvmtxq = 1428 + iwl_mvm_txq_from_mac80211(sta->txq[i]); 1429 + 1430 + clear_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); 1431 + iwl_mvm_mac_itxq_xmit(hw, sta->txq[i]); 1432 + } 1433 + } 1434 + 1441 1435 int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, 1442 1436 struct ieee80211_vif *vif, 1443 1437 struct ieee80211_bss_conf *link_conf) ··· 1468 1434 u8 ap_sta_id = mvmvif->link[link_id]->ap_sta_id; 1469 1435 1470 1436 mvmvif->csa_bcn_pending = false; 1437 + mvmvif->csa_blocks_tx = false; 1471 1438 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, ap_sta_id); 1472 1439 1473 1440 if (WARN_ON(!mvmsta)) { ··· 1490 1455 1491 1456 iwl_mvm_stop_session_protection(mvm, vif); 1492 1457 } 1458 + } else if (vif->type == NL80211_IFTYPE_AP && mvmvif->csa_blocks_tx) { 1459 + struct iwl_mvm_txq *mvmtxq = 1460 + iwl_mvm_txq_from_mac80211(vif->txq); 1461 + 1462 + clear_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); 1463 + 1464 + local_bh_disable(); 1465 + iwl_mvm_mac_itxq_xmit(hw, vif->txq); 1466 + ieee80211_iterate_stations_atomic(hw, iwl_mvm_post_csa_tx, hw); 1467 + local_bh_enable(); 1468 + 1469 + mvmvif->csa_blocks_tx = false; 1493 1470 } 1494 1471 1495 1472 mvmvif->ps_disabled = false; ··· 1697 1650 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 1698 1651 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 1699 1652 } 1700 - 1701 - if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) 1702 - vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 1703 1653 1704 1654 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 1705 1655 mvm->p2p_device_vif = vif; ··· 2589 2545 { 2590 2546 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2591 2547 int ret; 2548 + int link_id; 2592 2549 2593 2550 /* The firmware tracks the MU-MIMO group on its own. 2594 2551 * However, on HW restart we should restore this data. ··· 2605 2560 iwl_mvm_recalc_multicast(mvm); 2606 2561 2607 2562 /* reset rssi values */ 2608 - mvmvif->bf_data.ave_beacon_signal = 0; 2563 + for_each_mvm_vif_valid_link(mvmvif, link_id) 2564 + mvmvif->link[link_id]->bf_data.ave_beacon_signal = 0; 2609 2565 2610 2566 iwl_mvm_bt_coex_vif_change(mvm); 2611 2567 iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_TT, ··· 2647 2601 } 2648 2602 2649 2603 if (changes & BSS_CHANGED_CQM) { 2650 - IWL_DEBUG_MAC80211(mvm, "cqm info_changed\n"); 2651 - /* reset cqm events tracking */ 2652 - mvmvif->bf_data.last_cqm_event = 0; 2653 - if (mvmvif->bf_data.bf_enabled) { 2604 + struct iwl_mvm_vif_link_info *link_info = 2605 + mvmvif->link[link_conf->link_id]; 2606 + 2607 + IWL_DEBUG_MAC80211(mvm, "CQM info_changed\n"); 2608 + if (link_info) 2609 + link_info->bf_data.last_cqm_event = 0; 2610 + 2611 + if (mvmvif->bf_enabled) { 2654 2612 /* FIXME: need to update per link when FW API will 2655 2613 * support it 2656 2614 */ ··· 5448 5398 if (chsw->block_tx) 5449 5399 iwl_mvm_csa_client_absent(mvm, vif); 5450 5400 5451 - if (mvmvif->bf_data.bf_enabled) { 5401 + if (mvmvif->bf_enabled) { 5452 5402 int ret = iwl_mvm_disable_beacon_filter(mvm, vif); 5453 5403 5454 5404 if (ret) ··· 5461 5411 return 0; 5462 5412 } 5463 5413 5414 + static void iwl_mvm_csa_block_txqs(void *data, struct ieee80211_sta *sta) 5415 + { 5416 + int i; 5417 + 5418 + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { 5419 + struct iwl_mvm_txq *mvmtxq = 5420 + iwl_mvm_txq_from_mac80211(sta->txq[i]); 5421 + 5422 + set_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); 5423 + } 5424 + } 5425 + 5464 5426 #define IWL_MAX_CSA_BLOCK_TX 1500 5465 5427 int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, 5466 5428 struct ieee80211_vif *vif, ··· 5481 5419 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 5482 5420 struct ieee80211_vif *csa_vif; 5483 5421 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 5422 + struct iwl_mvm_txq *mvmtxq; 5484 5423 int ret; 5485 5424 5486 5425 mutex_lock(&mvm->mutex); 5487 5426 5488 5427 mvmvif->csa_failed = false; 5428 + mvmvif->csa_blocks_tx = false; 5489 5429 5490 5430 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", 5491 5431 chsw->chandef.center_freq1); ··· 5524 5460 5525 5461 mvmvif->csa_target_freq = chsw->chandef.chan->center_freq; 5526 5462 5463 + if (!chsw->block_tx) 5464 + break; 5465 + /* don't need blocking in driver otherwise - mac80211 will do */ 5466 + if (!ieee80211_hw_check(mvm->hw, HANDLES_QUIET_CSA)) 5467 + break; 5468 + 5469 + mvmvif->csa_blocks_tx = true; 5470 + mvmtxq = iwl_mvm_txq_from_mac80211(vif->txq); 5471 + set_bit(IWL_MVM_TXQ_STATE_STOP_AP_CSA, &mvmtxq->state); 5472 + ieee80211_iterate_stations_atomic(mvm->hw, 5473 + iwl_mvm_csa_block_txqs, 5474 + NULL); 5527 5475 break; 5528 5476 case NL80211_IFTYPE_STATION: 5477 + mvmvif->csa_blocks_tx = chsw->block_tx; 5478 + 5529 5479 /* 5530 5480 * In the new flow FW is in charge of timing the switch so there 5531 5481 * is no need for all of this ··· 5704 5626 void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5705 5627 u32 queues, bool drop) 5706 5628 { 5629 + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 5707 5630 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 5708 - struct iwl_mvm_vif *mvmvif; 5709 5631 struct iwl_mvm_sta *mvmsta; 5710 5632 struct ieee80211_sta *sta; 5711 5633 bool ap_sta_done = false; ··· 5717 5639 return; 5718 5640 } 5719 5641 5642 + if (!drop && hweight16(vif->active_links) <= 1) { 5643 + int link_id = vif->active_links ? __ffs(vif->active_links) : 0; 5644 + struct ieee80211_bss_conf *link_conf; 5645 + 5646 + link_conf = wiphy_dereference(hw->wiphy, 5647 + vif->link_conf[link_id]); 5648 + if (WARN_ON(!link_conf)) 5649 + return; 5650 + if (link_conf->csa_active && mvmvif->csa_blocks_tx) 5651 + drop = true; 5652 + } 5653 + 5720 5654 /* Make sure we're done with the deferred traffic before flushing */ 5721 5655 flush_work(&mvm->add_stream_wk); 5722 5656 5723 5657 mutex_lock(&mvm->mutex); 5724 - mvmvif = iwl_mvm_vif_from_mac80211(vif); 5725 5658 5726 5659 /* flush the AP-station and all TDLS peers */ 5727 5660 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
+12 -18
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
··· 92 92 mvm->csme_vif = vif; 93 93 } 94 94 95 + if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) 96 + vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 97 + 95 98 goto out_unlock; 96 99 97 100 out_free_bf: ··· 192 189 mutex_unlock(&mvm->mutex); 193 190 } 194 191 195 - static unsigned int iwl_mvm_mld_count_active_links(struct ieee80211_vif *vif) 192 + static unsigned int iwl_mvm_mld_count_active_links(struct iwl_mvm_vif *mvmvif) 196 193 { 197 194 unsigned int n_active = 0; 198 195 int i; 199 196 200 197 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 201 - struct ieee80211_bss_conf *link_conf; 202 - 203 - link_conf = link_conf_dereference_protected(vif, i); 204 - if (link_conf && 205 - rcu_access_pointer(link_conf->chanctx_conf)) 198 + if (mvmvif->link[i] && mvmvif->link[i]->phy_ctxt) 206 199 n_active++; 207 200 } 208 201 ··· 244 245 { 245 246 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 246 247 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 247 - unsigned int n_active = iwl_mvm_mld_count_active_links(vif); 248 248 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 249 + unsigned int n_active = iwl_mvm_mld_count_active_links(mvmvif); 249 250 unsigned int link_id = link_conf->link_id; 250 251 int ret; 251 252 252 - /* if the assigned one was not counted yet, count it now */ 253 - if (!rcu_access_pointer(link_conf->chanctx_conf)) 254 - n_active++; 255 - 256 253 if (WARN_ON_ONCE(!mvmvif->link[link_id])) 257 254 return -EINVAL; 255 + 256 + /* if the assigned one was not counted yet, count it now */ 257 + if (!mvmvif->link[link_id]->phy_ctxt) 258 + n_active++; 258 259 259 260 /* mac parameters such as HE support can change at this stage 260 261 * For sta, need first to configure correct state from drv_sta_state ··· 295 296 * this needs the phy context assigned (and in FW?), and we cannot 296 297 * do it later because it needs to be initialized as soon as we're 297 298 * able to TX on the link, i.e. when active. 298 - * 299 - * Firmware restart isn't quite correct yet for MLO, but we don't 300 - * need to do it in that case anyway since it will happen from the 301 - * normal station state callback. 302 299 */ 303 - if (mvmvif->ap_sta && 304 - !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 300 + if (mvmvif->ap_sta) { 305 301 struct ieee80211_link_sta *link_sta; 306 302 307 303 rcu_read_lock(); ··· 410 416 411 417 { 412 418 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 413 - unsigned int n_active = iwl_mvm_mld_count_active_links(vif); 419 + unsigned int n_active = iwl_mvm_mld_count_active_links(mvmvif); 414 420 unsigned int link_id = link_conf->link_id; 415 421 416 422 /* shouldn't happen, but verify link_id is valid before accessing */
+27 -12
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
··· 9 9 u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 10 10 int filter_link_id) 11 11 { 12 + struct ieee80211_link_sta *link_sta; 12 13 struct iwl_mvm_sta *mvmsta; 14 + struct ieee80211_vif *vif; 13 15 unsigned int link_id; 14 16 u32 result = 0; 15 17 ··· 19 17 return 0; 20 18 21 19 mvmsta = iwl_mvm_sta_from_mac80211(sta); 20 + vif = mvmsta->vif; 22 21 23 22 /* it's easy when the STA is not an MLD */ 24 23 if (!sta->valid_links) 25 24 return BIT(mvmsta->deflink.sta_id); 26 25 27 26 /* but if it is an MLD, get the mask of all the FW STAs it has ... */ 28 - for (link_id = 0; link_id < ARRAY_SIZE(mvmsta->link); link_id++) { 29 - struct iwl_mvm_link_sta *link_sta; 27 + for_each_sta_active_link(vif, sta, link_sta, link_id) { 28 + struct iwl_mvm_link_sta *mvm_link_sta; 30 29 31 30 /* unless we have a specific link in mind */ 32 31 if (filter_link_id >= 0 && link_id != filter_link_id) 33 32 continue; 34 33 35 - link_sta = 34 + mvm_link_sta = 36 35 rcu_dereference_check(mvmsta->link[link_id], 37 36 lockdep_is_held(&mvm->mutex)); 38 - if (!link_sta) 37 + if (!mvm_link_sta) 39 38 continue; 40 39 41 - result |= BIT(link_sta->sta_id); 40 + result |= BIT(mvm_link_sta->sta_id); 42 41 } 43 42 44 43 return result; ··· 585 582 struct ieee80211_sta *sta) 586 583 { 587 584 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); 585 + struct ieee80211_link_sta *link_sta; 588 586 unsigned int link_id; 589 587 int ret; 590 588 591 589 lockdep_assert_held(&mvm->mutex); 592 590 593 - for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) { 594 - if (!rcu_access_pointer(sta->link[link_id]) || 595 - mvm_sta->link[link_id]) 591 + for_each_sta_active_link(vif, sta, link_sta, link_id) { 592 + if (WARN_ON(mvm_sta->link[link_id])) 596 593 continue; 597 594 598 595 ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta, link_id); ··· 619 616 } 620 617 } 621 618 622 - /* FIXME: consider waiting for mac80211 to add the STA instead of allocating 623 - * queues here 624 - */ 625 619 static int iwl_mvm_alloc_sta_after_restart(struct iwl_mvm *mvm, 626 620 struct ieee80211_vif *vif, 627 621 struct ieee80211_sta *sta) ··· 989 989 u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, RX_BAID_ALLOCATION_CONFIG_CMD); 990 990 int baid; 991 991 992 + /* mac80211 will remove sessions later, but we ignore all that */ 993 + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 994 + return 0; 995 + 992 996 BUILD_BUG_ON(sizeof(struct iwl_rx_baid_cfg_resp) != sizeof(baid)); 993 997 994 998 for (baid = 0; baid < ARRAY_SIZE(mvm->baid_map); baid++) { ··· 1126 1122 } 1127 1123 1128 1124 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 1129 - if (WARN_ON(!mvm_sta->link[link_id])) { 1125 + struct iwl_mvm_link_sta *mvm_link_sta = 1126 + rcu_dereference_protected(mvm_sta->link[link_id], 1127 + lockdep_is_held(&mvm->mutex)); 1128 + u32 sta_id; 1129 + 1130 + if (WARN_ON(!mvm_link_sta)) { 1130 1131 ret = -EINVAL; 1131 1132 goto err; 1132 1133 } 1134 + 1135 + sta_id = mvm_link_sta->sta_id; 1136 + 1137 + rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); 1138 + rcu_assign_pointer(mvm->fw_id_to_link_sta[sta_id], 1139 + link_sta); 1133 1140 } else { 1134 1141 if (WARN_ON(mvm_sta->link[link_id])) { 1135 1142 ret = -EINVAL;
+26 -12
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 255 255 }; 256 256 257 257 /** 258 - * struct iwl_mvm_vif_bf_data - beacon filtering related data 259 - * @bf_enabled: indicates if beacon filtering is enabled 260 - * @ba_enabled: indicated if beacon abort is enabled 258 + * struct iwl_mvm_link_bf_data - beacon filtering related data 261 259 * @ave_beacon_signal: average beacon signal 262 260 * @last_cqm_event: rssi of the last cqm event 263 261 * @bt_coex_min_thold: minimum threshold for BT coex 264 262 * @bt_coex_max_thold: maximum threshold for BT coex 265 263 * @last_bt_coex_event: rssi of the last BT coex event 266 264 */ 267 - struct iwl_mvm_vif_bf_data { 268 - bool bf_enabled; 269 - bool ba_enabled; 265 + struct iwl_mvm_link_bf_data { 270 266 int ave_beacon_signal; 271 267 int last_cqm_event; 272 268 int bt_coex_min_thold; ··· 305 309 * @listen_lmac: indicates this link is allocated to the listen LMAC 306 310 * @mcast_sta: multicast station 307 311 * @phy_ctxt: phy context allocated to this link, if any 312 + * @bf_data: beacon filtering data 308 313 */ 309 314 struct iwl_mvm_vif_link_info { 310 315 u8 bssid[ETH_ALEN]; ··· 341 344 struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; 342 345 343 346 u16 mgmt_queue; 347 + 348 + struct iwl_mvm_link_bf_data bf_data; 344 349 }; 345 350 346 351 /** ··· 370 371 * @csa_countdown: indicates that CSA countdown may be started 371 372 * @csa_failed: CSA failed to schedule time event, report an error later 372 373 * @csa_bcn_pending: indicates that we are waiting for a beacon on a new channel 374 + * @csa_blocks_tx: CSA is blocking TX 373 375 * @features: hw features active for this vif 374 376 * @ap_beacon_time: AP beacon time for synchronisation (on older FW) 377 + * @bf_enabled: indicates if beacon filtering is enabled 378 + * @ba_enabled: indicated if beacon abort is enabled 375 379 * @bcn_prot: beacon protection data (keys; FIXME: needs to be per link) 376 - * @bf_data: beacon filtering data 377 380 * @deflink: default link data for use in non-MLO 378 381 * @link: link data for each link in MLO 379 382 * @esr_active: indicates eSR mode is active ··· 402 401 bool ps_disabled; 403 402 404 403 u32 ap_beacon_time; 405 - struct iwl_mvm_vif_bf_data bf_data; 404 + bool bf_enabled; 405 + bool ba_enabled; 406 406 407 407 #ifdef CONFIG_PM 408 408 /* WoWLAN GTK rekey data */ ··· 437 435 struct iwl_dbgfs_bf dbgfs_bf; 438 436 struct iwl_mac_power_cmd mac_pwr_cmd; 439 437 int dbgfs_quota_min; 438 + bool ftm_unprotected; 440 439 #endif 441 440 442 441 /* FW identified misbehaving AP */ ··· 447 444 bool csa_countdown; 448 445 bool csa_failed; 449 446 bool csa_bcn_pending; 447 + bool csa_blocks_tx; 450 448 u16 csa_target_freq; 451 449 u16 csa_count; 452 450 u16 csa_misbehave; ··· 494 490 IWL_MVM_SCAN_REGULAR = BIT(0), 495 491 IWL_MVM_SCAN_SCHED = BIT(1), 496 492 IWL_MVM_SCAN_NETDETECT = BIT(2), 493 + IWL_MVM_SCAN_INT_MLO = BIT(3), 497 494 498 495 IWL_MVM_SCAN_STOPPING_REGULAR = BIT(8), 499 496 IWL_MVM_SCAN_STOPPING_SCHED = BIT(9), 500 497 IWL_MVM_SCAN_STOPPING_NETDETECT = BIT(10), 498 + IWL_MVM_SCAN_STOPPING_INT_MLO = BIT(11), 501 499 502 500 IWL_MVM_SCAN_REGULAR_MASK = IWL_MVM_SCAN_REGULAR | 503 501 IWL_MVM_SCAN_STOPPING_REGULAR, ··· 507 501 IWL_MVM_SCAN_STOPPING_SCHED, 508 502 IWL_MVM_SCAN_NETDETECT_MASK = IWL_MVM_SCAN_NETDETECT | 509 503 IWL_MVM_SCAN_STOPPING_NETDETECT, 504 + IWL_MVM_SCAN_INT_MLO_MASK = IWL_MVM_SCAN_INT_MLO | 505 + IWL_MVM_SCAN_STOPPING_INT_MLO, 510 506 511 507 IWL_MVM_SCAN_STOPPING_MASK = 0xff << IWL_MVM_SCAN_STOPPING_SHIFT, 512 508 IWL_MVM_SCAN_MASK = 0xff, ··· 762 754 struct list_head list; 763 755 u16 txq_id; 764 756 atomic_t tx_request; 765 - #define IWL_MVM_TXQ_STATE_STOP_FULL 0 766 - #define IWL_MVM_TXQ_STATE_STOP_REDIRECT 1 767 - #define IWL_MVM_TXQ_STATE_READY 2 757 + #define IWL_MVM_TXQ_STATE_READY 0 758 + #define IWL_MVM_TXQ_STATE_STOP_FULL 1 759 + #define IWL_MVM_TXQ_STATE_STOP_REDIRECT 2 760 + #define IWL_MVM_TXQ_STATE_STOP_AP_CSA 3 768 761 unsigned long state; 769 762 }; 770 763 ··· 2014 2005 struct ieee80211_scan_ies *ies); 2015 2006 size_t iwl_mvm_scan_size(struct iwl_mvm *mvm); 2016 2007 int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify); 2008 + int iwl_mvm_int_mlo_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2009 + struct ieee80211_channel **channels, 2010 + size_t n_channels); 2011 + 2017 2012 int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm); 2018 2013 void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm); 2019 2014 void iwl_mvm_scan_timeout_wk(struct work_struct *work); ··· 2126 2113 struct ieee80211_vif *vif, 2127 2114 bool disable_offloading, 2128 2115 bool offload_ns, 2129 - u32 cmd_flags); 2116 + u32 cmd_flags, 2117 + u8 sta_id); 2130 2118 2131 2119 /* BT Coex */ 2132 2120 int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm);
+6 -2
drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2021-2022 Intel Corporation 3 + * Copyright (C) 2012-2014, 2021-2022, 2024 Intel Corporation 4 4 * Copyright (C) 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2015 Intel Deutschland GmbH 6 6 */ ··· 30 30 struct ieee80211_vif *vif, 31 31 bool disable_offloading, 32 32 bool offload_ns, 33 - u32 cmd_flags) 33 + u32 cmd_flags, 34 + u8 sta_id) 34 35 { 35 36 union { 36 37 struct iwl_proto_offload_cmd_v1 v1; ··· 205 204 206 205 if (!disable_offloading) 207 206 common->enabled = cpu_to_le32(enabled); 207 + 208 + if (ver >= 4) 209 + cmd.v4.sta_id = cpu_to_le32(sta_id); 208 210 209 211 hcmd.len[0] = size; 210 212 return iwl_mvm_send_cmd(mvm, &hcmd);
+8 -8
drivers/net/wireless/intel/iwlwifi/mvm/power.c
··· 79 79 cmd->bf_roaming_state = 80 80 cpu_to_le32(-vif->bss_conf.cqm_rssi_thold); 81 81 } 82 - cmd->ba_enable_beacon_abort = cpu_to_le32(mvmvif->bf_data.ba_enabled); 82 + cmd->ba_enable_beacon_abort = cpu_to_le32(mvmvif->ba_enabled); 83 83 } 84 84 85 85 static void iwl_mvm_power_log(struct iwl_mvm *mvm, ··· 826 826 ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd); 827 827 828 828 if (!ret) 829 - mvmvif->bf_data.bf_enabled = true; 829 + mvmvif->bf_enabled = true; 830 830 831 831 return ret; 832 832 } ··· 855 855 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 856 856 857 857 if (!ret) 858 - mvmvif->bf_data.bf_enabled = false; 858 + mvmvif->bf_enabled = false; 859 859 860 860 return ret; 861 861 } ··· 903 903 .bf_enable_beacon_filter = cpu_to_le32(1), 904 904 }; 905 905 906 - if (!mvmvif->bf_data.bf_enabled) 906 + if (!mvmvif->bf_enabled) 907 907 return 0; 908 908 909 909 if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) 910 910 cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3); 911 911 912 - mvmvif->bf_data.ba_enabled = !(!mvmvif->pm_enabled || 913 - mvm->ps_disabled || 914 - !vif->cfg.ps || 915 - iwl_mvm_vif_low_latency(mvmvif)); 912 + mvmvif->ba_enabled = !(!mvmvif->pm_enabled || 913 + mvm->ps_disabled || 914 + !vif->cfg.ps || 915 + iwl_mvm_vif_low_latency(mvmvif)); 916 916 917 917 return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd); 918 918 }
+27 -21
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
··· 556 556 struct iwl_stats_ntfy_per_mac *per_mac; 557 557 }; 558 558 559 - static void iwl_mvm_update_vif_sig(struct ieee80211_vif *vif, int sig) 559 + static void iwl_mvm_update_vif_sig(struct ieee80211_vif *vif, int sig, 560 + struct iwl_mvm_vif_link_info *link_info) 560 561 { 561 - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 562 - struct iwl_mvm *mvm = mvmvif->mvm; 563 - int thold = vif->bss_conf.cqm_rssi_thold; 564 - int hyst = vif->bss_conf.cqm_rssi_hyst; 562 + struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(vif)->mvm; 563 + struct ieee80211_bss_conf *bss_conf = 564 + iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_info->fw_link_id, 565 + false); 566 + int thold = bss_conf->cqm_rssi_thold; 567 + int hyst = bss_conf->cqm_rssi_hyst; 565 568 int last_event; 566 569 567 570 if (sig == 0) { ··· 572 569 return; 573 570 } 574 571 575 - mvmvif->bf_data.ave_beacon_signal = sig; 572 + link_info->bf_data.ave_beacon_signal = sig; 576 573 577 574 /* BT Coex */ 578 - if (mvmvif->bf_data.bt_coex_min_thold != 579 - mvmvif->bf_data.bt_coex_max_thold) { 580 - last_event = mvmvif->bf_data.last_bt_coex_event; 581 - if (sig > mvmvif->bf_data.bt_coex_max_thold && 582 - (last_event <= mvmvif->bf_data.bt_coex_min_thold || 575 + if (link_info->bf_data.bt_coex_min_thold != 576 + link_info->bf_data.bt_coex_max_thold) { 577 + last_event = link_info->bf_data.last_bt_coex_event; 578 + if (sig > link_info->bf_data.bt_coex_max_thold && 579 + (last_event <= link_info->bf_data.bt_coex_min_thold || 583 580 last_event == 0)) { 584 - mvmvif->bf_data.last_bt_coex_event = sig; 581 + link_info->bf_data.last_bt_coex_event = sig; 585 582 IWL_DEBUG_RX(mvm, "cqm_iterator bt coex high %d\n", 586 583 sig); 587 584 iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_HIGH); 588 - } else if (sig < mvmvif->bf_data.bt_coex_min_thold && 589 - (last_event >= mvmvif->bf_data.bt_coex_max_thold || 585 + } else if (sig < link_info->bf_data.bt_coex_min_thold && 586 + (last_event >= link_info->bf_data.bt_coex_max_thold || 590 587 last_event == 0)) { 591 - mvmvif->bf_data.last_bt_coex_event = sig; 588 + link_info->bf_data.last_bt_coex_event = sig; 592 589 IWL_DEBUG_RX(mvm, "cqm_iterator bt coex low %d\n", 593 590 sig); 594 591 iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_LOW); ··· 599 596 return; 600 597 601 598 /* CQM Notification */ 602 - last_event = mvmvif->bf_data.last_cqm_event; 599 + last_event = link_info->bf_data.last_cqm_event; 603 600 if (thold && sig < thold && (last_event == 0 || 604 601 sig < last_event - hyst)) { 605 - mvmvif->bf_data.last_cqm_event = sig; 602 + link_info->bf_data.last_cqm_event = sig; 606 603 IWL_DEBUG_RX(mvm, "cqm_iterator cqm low %d\n", 607 604 sig); 608 605 ieee80211_cqm_rssi_notify( ··· 612 609 GFP_KERNEL); 613 610 } else if (sig > thold && 614 611 (last_event == 0 || sig > last_event + hyst)) { 615 - mvmvif->bf_data.last_cqm_event = sig; 612 + link_info->bf_data.last_cqm_event = sig; 616 613 IWL_DEBUG_RX(mvm, "cqm_iterator cqm high %d\n", 617 614 sig); 618 615 ieee80211_cqm_rssi_notify( ··· 654 651 mvmvif->deflink.beacon_stats.accu_num_beacons += 655 652 mvmvif->deflink.beacon_stats.num_beacons; 656 653 657 - iwl_mvm_update_vif_sig(vif, sig); 654 + /* This is used in pre-MLO API so use deflink */ 655 + iwl_mvm_update_vif_sig(vif, sig, &mvmvif->deflink); 658 656 } 659 657 660 658 static void iwl_mvm_stat_iterator_all_macs(void *_data, u8 *mac, ··· 688 684 mvmvif->deflink.beacon_stats.num_beacons; 689 685 690 686 sig = -le32_to_cpu(mac_stats->beacon_filter_average_energy); 691 - iwl_mvm_update_vif_sig(vif, sig); 687 + 688 + /* This is used in pre-MLO API so use deflink */ 689 + iwl_mvm_update_vif_sig(vif, sig, &mvmvif->deflink); 692 690 } 693 691 694 692 static inline void ··· 906 900 mvmvif->link[link_id]->beacon_stats.num_beacons; 907 901 908 902 sig = -le32_to_cpu(link_stats->beacon_filter_average_energy); 909 - iwl_mvm_update_vif_sig(bss_conf->vif, sig); 903 + iwl_mvm_update_vif_sig(bss_conf->vif, sig, link_info); 910 904 911 905 if (WARN_ONCE(mvmvif->id >= MAC_INDEX_AUX, 912 906 "invalid mvmvif id: %d", mvmvif->id))
+197 -95
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
··· 1377 1377 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2); 1378 1378 } 1379 1379 1380 - static u32 iwl_mvm_scan_umac_ooc_priority(struct iwl_mvm_scan_params *params) 1380 + static u32 iwl_mvm_scan_umac_ooc_priority(int type) 1381 1381 { 1382 - return iwl_mvm_is_regular_scan(params) ? 1383 - IWL_SCAN_PRIORITY_EXT_6 : 1384 - IWL_SCAN_PRIORITY_EXT_2; 1382 + if (type == IWL_MVM_SCAN_REGULAR) 1383 + return IWL_SCAN_PRIORITY_EXT_6; 1384 + if (type == IWL_MVM_SCAN_INT_MLO) 1385 + return IWL_SCAN_PRIORITY_EXT_4; 1386 + 1387 + return IWL_SCAN_PRIORITY_EXT_2; 1385 1388 } 1386 1389 1387 1390 static void ··· 1750 1747 &cp->channel_config[ch_cnt]; 1751 1748 1752 1749 u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0; 1753 - u8 j, k, s_max = 0, b_max = 0, n_used_bssid_entries; 1754 - bool force_passive, found = false, allow_passive = true, 1750 + u8 j, k, n_s_ssids = 0, n_bssids = 0; 1751 + u8 max_s_ssids, max_bssids; 1752 + bool force_passive = false, found = false, allow_passive = true, 1755 1753 unsolicited_probe_on_chan = false, psc_no_listen = false; 1756 1754 s8 psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED; 1757 1755 ··· 1775 1771 cfg->v5.iter_count = 1; 1776 1772 cfg->v5.iter_interval = 0; 1777 1773 1778 - /* 1779 - * The optimize the scan time, i.e., reduce the scan dwell time 1780 - * on each channel, the below logic tries to set 3 direct BSSID 1781 - * probe requests for each broadcast probe request with a short 1782 - * SSID. 1783 - * TODO: improve this logic 1784 - */ 1785 - n_used_bssid_entries = 3; 1786 1774 for (j = 0; j < params->n_6ghz_params; j++) { 1787 1775 s8 tmp_psd_20; 1788 1776 1789 1777 if (!(scan_6ghz_params[j].channel_idx == i)) 1790 1778 continue; 1779 + 1780 + unsolicited_probe_on_chan |= 1781 + scan_6ghz_params[j].unsolicited_probe; 1791 1782 1792 1783 /* Use the highest PSD value allowed as advertised by 1793 1784 * APs for this channel ··· 1795 1796 psd_20 < tmp_psd_20)) 1796 1797 psd_20 = tmp_psd_20; 1797 1798 1798 - found = false; 1799 - unsolicited_probe_on_chan |= 1800 - scan_6ghz_params[j].unsolicited_probe; 1801 1799 psc_no_listen |= scan_6ghz_params[j].psc_no_listen; 1802 - 1803 - for (k = 0; k < pp->short_ssid_num; k++) { 1804 - if (!scan_6ghz_params[j].unsolicited_probe && 1805 - le32_to_cpu(pp->short_ssid[k]) == 1806 - scan_6ghz_params[j].short_ssid) { 1807 - /* Relevant short SSID bit set */ 1808 - if (s_ssid_bitmap & BIT(k)) { 1809 - found = true; 1810 - break; 1811 - } 1812 - 1813 - /* 1814 - * Use short SSID only to create a new 1815 - * iteration during channel dwell or in 1816 - * case that the short SSID has a 1817 - * matching SSID, i.e., scan for hidden 1818 - * APs. 1819 - */ 1820 - if (n_used_bssid_entries >= 3) { 1821 - s_ssid_bitmap |= BIT(k); 1822 - s_max++; 1823 - n_used_bssid_entries -= 3; 1824 - found = true; 1825 - break; 1826 - } else if (pp->direct_scan[k].len) { 1827 - s_ssid_bitmap |= BIT(k); 1828 - s_max++; 1829 - found = true; 1830 - allow_passive = false; 1831 - break; 1832 - } 1833 - } 1834 - } 1835 - 1836 - if (found) 1837 - continue; 1838 - 1839 - for (k = 0; k < pp->bssid_num; k++) { 1840 - if (!memcmp(&pp->bssid_array[k], 1841 - scan_6ghz_params[j].bssid, 1842 - ETH_ALEN)) { 1843 - if (!(bssid_bitmap & BIT(k))) { 1844 - bssid_bitmap |= BIT(k); 1845 - b_max++; 1846 - n_used_bssid_entries++; 1847 - } 1848 - break; 1849 - } 1850 - } 1851 1800 } 1852 - 1853 - if (cfg80211_channel_is_psc(params->channels[i]) && 1854 - psc_no_listen) 1855 - flags |= IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN; 1856 - 1857 - if (unsolicited_probe_on_chan) 1858 - flags |= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES; 1859 1801 1860 1802 /* 1861 1803 * In the following cases apply passive scan: ··· 1818 1878 if (!iwl_mvm_is_scan_fragmented(params->type)) { 1819 1879 if (!cfg80211_channel_is_psc(params->channels[i]) || 1820 1880 flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) { 1821 - force_passive = (s_max > 3 || b_max > 9); 1822 - force_passive |= (unsolicited_probe_on_chan && 1823 - (s_max > 2 || b_max > 6)); 1881 + if (unsolicited_probe_on_chan) { 1882 + max_s_ssids = 2; 1883 + max_bssids = 6; 1884 + } else { 1885 + max_s_ssids = 3; 1886 + max_bssids = 9; 1887 + } 1824 1888 } else { 1825 - force_passive = (s_max > 2 || b_max > 6); 1889 + max_s_ssids = 2; 1890 + max_bssids = 6; 1826 1891 } 1827 1892 } else if (cfg80211_channel_is_psc(params->channels[i])) { 1828 - force_passive = (s_max > 1 || b_max > 3); 1893 + max_s_ssids = 1; 1894 + max_bssids = 3; 1829 1895 } else { 1830 - force_passive = (s_max > 2 || b_max > 6); 1831 - force_passive |= (unsolicited_probe_on_chan && 1832 - (s_max > 1 || b_max > 3)); 1896 + if (unsolicited_probe_on_chan) { 1897 + max_s_ssids = 1; 1898 + max_bssids = 3; 1899 + } else { 1900 + max_s_ssids = 2; 1901 + max_bssids = 6; 1902 + } 1833 1903 } 1904 + 1905 + /* 1906 + * The optimize the scan time, i.e., reduce the scan dwell time 1907 + * on each channel, the below logic tries to set 3 direct BSSID 1908 + * probe requests for each broadcast probe request with a short 1909 + * SSID. 1910 + * TODO: improve this logic 1911 + */ 1912 + for (j = 0; j < params->n_6ghz_params; j++) { 1913 + if (!(scan_6ghz_params[j].channel_idx == i)) 1914 + continue; 1915 + 1916 + found = false; 1917 + 1918 + for (k = 0; 1919 + k < pp->short_ssid_num && n_s_ssids < max_s_ssids; 1920 + k++) { 1921 + if (!scan_6ghz_params[j].unsolicited_probe && 1922 + le32_to_cpu(pp->short_ssid[k]) == 1923 + scan_6ghz_params[j].short_ssid) { 1924 + /* Relevant short SSID bit set */ 1925 + if (s_ssid_bitmap & BIT(k)) { 1926 + found = true; 1927 + break; 1928 + } 1929 + 1930 + /* 1931 + * Prefer creating BSSID entries unless 1932 + * the short SSID probe can be done in 1933 + * the same channel dwell iteration. 1934 + * 1935 + * We also need to create a short SSID 1936 + * entry for any hidden AP. 1937 + */ 1938 + if (3 * n_s_ssids > n_bssids && 1939 + !pp->direct_scan[k].len) 1940 + break; 1941 + 1942 + /* Hidden AP, cannot do passive scan */ 1943 + if (pp->direct_scan[k].len) 1944 + allow_passive = false; 1945 + 1946 + s_ssid_bitmap |= BIT(k); 1947 + n_s_ssids++; 1948 + found = true; 1949 + break; 1950 + } 1951 + } 1952 + 1953 + if (found) 1954 + continue; 1955 + 1956 + for (k = 0; k < pp->bssid_num; k++) { 1957 + if (!memcmp(&pp->bssid_array[k], 1958 + scan_6ghz_params[j].bssid, 1959 + ETH_ALEN)) { 1960 + if (!(bssid_bitmap & BIT(k))) { 1961 + if (n_bssids < max_bssids) { 1962 + bssid_bitmap |= BIT(k); 1963 + n_bssids++; 1964 + } else { 1965 + force_passive = TRUE; 1966 + } 1967 + } 1968 + break; 1969 + } 1970 + } 1971 + } 1972 + 1973 + if (cfg80211_channel_is_psc(params->channels[i]) && 1974 + psc_no_listen) 1975 + flags |= IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN; 1976 + 1977 + if (unsolicited_probe_on_chan) 1978 + flags |= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES; 1979 + 1834 1980 if ((allow_passive && force_passive) || 1835 1981 (!(bssid_bitmap | s_ssid_bitmap) && 1836 1982 !cfg80211_channel_is_psc(params->channels[i]))) ··· 2478 2452 2479 2453 mvm->scan_uid_status[uid] = type; 2480 2454 2481 - cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params)); 2455 + cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type)); 2482 2456 cmd->uid = cpu_to_le32(uid); 2483 2457 2484 2458 gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type); ··· 2515 2489 2516 2490 mvm->scan_uid_status[uid] = type; 2517 2491 2518 - cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params)); 2492 + cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(type)); 2519 2493 cmd->uid = cpu_to_le32(uid); 2520 2494 2521 2495 gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type); ··· 2940 2914 } 2941 2915 } 2942 2916 2943 - int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2944 - struct cfg80211_scan_request *req, 2945 - struct ieee80211_scan_ies *ies) 2917 + static int _iwl_mvm_single_scan_start(struct iwl_mvm *mvm, 2918 + struct ieee80211_vif *vif, 2919 + struct cfg80211_scan_request *req, 2920 + struct ieee80211_scan_ies *ies, 2921 + int type) 2946 2922 { 2947 2923 struct iwl_host_cmd hcmd = { 2948 2924 .len = { iwl_mvm_scan_size(mvm), }, ··· 2962 2934 return -EBUSY; 2963 2935 } 2964 2936 2965 - ret = iwl_mvm_check_running_scans(mvm, IWL_MVM_SCAN_REGULAR); 2937 + ret = iwl_mvm_check_running_scans(mvm, type); 2966 2938 if (ret) 2967 2939 return ret; 2968 2940 ··· 3011 2983 3012 2984 iwl_mvm_scan_6ghz_passive_scan(mvm, &params, vif); 3013 2985 3014 - uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params, 3015 - IWL_MVM_SCAN_REGULAR); 2986 + uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params, type); 3016 2987 3017 2988 if (uid < 0) 3018 2989 return uid; ··· 3031 3004 } 3032 3005 3033 3006 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n"); 3034 - mvm->scan_status |= IWL_MVM_SCAN_REGULAR; 3035 - mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif); 3007 + mvm->scan_status |= type; 3008 + 3009 + if (type == IWL_MVM_SCAN_REGULAR) { 3010 + mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif); 3011 + schedule_delayed_work(&mvm->scan_timeout_dwork, 3012 + msecs_to_jiffies(SCAN_TIMEOUT)); 3013 + } 3036 3014 3037 3015 if (params.enable_6ghz_passive) 3038 3016 mvm->last_6ghz_passive_scan_jiffies = jiffies; 3039 3017 3040 - schedule_delayed_work(&mvm->scan_timeout_dwork, 3041 - msecs_to_jiffies(SCAN_TIMEOUT)); 3042 - 3043 3018 return 0; 3019 + } 3020 + 3021 + int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 3022 + struct cfg80211_scan_request *req, 3023 + struct ieee80211_scan_ies *ies) 3024 + { 3025 + return _iwl_mvm_single_scan_start(mvm, vif, req, ies, 3026 + IWL_MVM_SCAN_REGULAR); 3044 3027 } 3045 3028 3046 3029 int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, ··· 3207 3170 struct iwl_mvm_vif_link_info *link_info = 3208 3171 scan_vif->link[mvm->scan_link_id]; 3209 3172 3210 - if (!WARN_ON(!link_info)) 3173 + /* It is possible that by the time the scan is complete the link 3174 + * was already removed and is not valid. 3175 + */ 3176 + if (link_info) 3211 3177 memcpy(info.tsf_bssid, link_info->bssid, ETH_ALEN); 3178 + else 3179 + IWL_DEBUG_SCAN(mvm, "Scan link is no longer valid\n"); 3212 3180 3213 3181 ieee80211_scan_completed(mvm->hw, &info); 3214 3182 mvm->scan_vif = NULL; ··· 3222 3180 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) { 3223 3181 ieee80211_sched_scan_stopped(mvm->hw); 3224 3182 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; 3183 + } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_INT_MLO) { 3184 + IWL_DEBUG_SCAN(mvm, "Internal MLO scan completed\n"); 3225 3185 } 3226 3186 3227 3187 mvm->scan_status &= ~mvm->scan_uid_status[uid]; ··· 3410 3366 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; 3411 3367 mvm->scan_uid_status[uid] = 0; 3412 3368 } 3369 + uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_INT_MLO); 3370 + if (uid >= 0) { 3371 + IWL_DEBUG_SCAN(mvm, "Internal MLO scan aborted\n"); 3372 + mvm->scan_uid_status[uid] = 0; 3373 + } 3374 + 3413 3375 uid = iwl_mvm_scan_uid_by_status(mvm, 3414 3376 IWL_MVM_SCAN_STOPPING_REGULAR); 3415 3377 if (uid >= 0) ··· 3423 3373 3424 3374 uid = iwl_mvm_scan_uid_by_status(mvm, 3425 3375 IWL_MVM_SCAN_STOPPING_SCHED); 3376 + if (uid >= 0) 3377 + mvm->scan_uid_status[uid] = 0; 3378 + 3379 + uid = iwl_mvm_scan_uid_by_status(mvm, 3380 + IWL_MVM_SCAN_STOPPING_INT_MLO); 3426 3381 if (uid >= 0) 3427 3382 mvm->scan_uid_status[uid] = 0; 3428 3383 ··· 3500 3445 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; 3501 3446 } 3502 3447 3448 + return ret; 3449 + } 3450 + 3451 + int iwl_mvm_int_mlo_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 3452 + struct ieee80211_channel **channels, 3453 + size_t n_channels) 3454 + { 3455 + struct cfg80211_scan_request *req = NULL; 3456 + struct ieee80211_scan_ies ies = {}; 3457 + size_t size, i; 3458 + int ret; 3459 + 3460 + lockdep_assert_held(&mvm->mutex); 3461 + 3462 + IWL_DEBUG_SCAN(mvm, "Starting Internal MLO scan: n_channels=%zu\n", 3463 + n_channels); 3464 + 3465 + if (!vif->cfg.assoc || !ieee80211_vif_is_mld(vif)) 3466 + return -EINVAL; 3467 + 3468 + size = struct_size(req, channels, n_channels); 3469 + req = kzalloc(size, GFP_KERNEL); 3470 + if (!req) 3471 + return -ENOMEM; 3472 + 3473 + /* set the requested channels */ 3474 + for (i = 0; i < n_channels; i++) 3475 + req->channels[i] = channels[i]; 3476 + 3477 + req->n_channels = n_channels; 3478 + 3479 + /* set the rates */ 3480 + for (i = 0; i < NUM_NL80211_BANDS; i++) 3481 + if (mvm->hw->wiphy->bands[i]) 3482 + req->rates[i] = 3483 + (1 << mvm->hw->wiphy->bands[i]->n_bitrates) - 1; 3484 + 3485 + req->wdev = ieee80211_vif_to_wdev(vif); 3486 + req->wiphy = mvm->hw->wiphy; 3487 + req->scan_start = jiffies; 3488 + req->tsf_report_link_id = -1; 3489 + 3490 + ret = _iwl_mvm_single_scan_start(mvm, vif, req, &ies, 3491 + IWL_MVM_SCAN_INT_MLO); 3492 + kfree(req); 3493 + 3494 + IWL_DEBUG_SCAN(mvm, "Internal MLO scan: ret=%d\n", ret); 3503 3495 return ret; 3504 3496 }
+20 -33
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
··· 33 33 .driver_data = _ASSIGN_CFG(cfg) 34 34 35 35 /* Hardware specific file defines the PCI IDs table for that hardware module */ 36 - static const struct pci_device_id iwl_hw_card_ids[] = { 36 + VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { 37 37 #if IS_ENABLED(CONFIG_IWLDVM) 38 38 {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ 39 39 {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ ··· 492 492 {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_trans_cfg)}, 493 493 {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, 494 494 {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, 495 - {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, 496 495 {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, 497 496 {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_trans_cfg)}, 498 497 ··· 516 517 {0} 517 518 }; 518 519 MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); 520 + EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_hw_card_ids); 519 521 520 522 #define _IWL_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ 521 523 _rf_id, _rf_step, _no_160, _cores, _cdb, _cfg, _name) \ ··· 946 946 iwl_cfg_ma, iwl_ax211_name), 947 947 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 948 948 IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, 949 - IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY, IWL_CFG_ANY, 950 - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, 951 - iwl_cfg_ma, iwl_ax221_name), 952 - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 953 - IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, 954 949 IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, 955 950 IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, 956 951 iwl_cfg_ma, iwl_ax231_name), ··· 997 1002 iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_name), 998 1003 999 1004 /* Bz */ 1005 + /* FIXME: need to change the naming according to the actual CRF */ 1000 1006 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1001 1007 IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, 1002 1008 IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, 1003 1009 IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, 1004 - iwl_cfg_bz, iwl_bz_name), 1010 + iwl_cfg_bz, iwl_fm_name), 1011 + 1012 + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1013 + IWL_CFG_MAC_TYPE_BZ_W, IWL_CFG_ANY, 1014 + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, 1015 + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, 1016 + iwl_cfg_bz, iwl_fm_name), 1005 1017 1006 1018 /* Ga (Gl) */ 1007 1019 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1008 1020 IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, 1009 1021 IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, 1010 1022 IWL_CFG_320, IWL_CFG_ANY, IWL_CFG_NO_CDB, 1011 - iwl_cfg_gl, iwl_bz_name), 1023 + iwl_cfg_gl, iwl_gl_name), 1012 1024 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1013 1025 IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, 1014 1026 IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, ··· 1102 1100 IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, 1103 1101 iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), 1104 1102 1105 - /* MsP */ 1106 - /* For now we use the same FW as MR, but this will change in the future. */ 1107 - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1108 - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, 1109 - IWL_CFG_RF_TYPE_MS, IWL_CFG_ANY, IWL_CFG_ANY, 1110 - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, 1111 - iwl_cfg_so_a0_ms_a0, iwl_ax204_name), 1112 - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1113 - IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, 1114 - IWL_CFG_RF_TYPE_MS, IWL_CFG_ANY, IWL_CFG_ANY, 1115 - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, 1116 - iwl_cfg_so_a0_ms_a0, iwl_ax204_name), 1117 - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1118 - IWL_CFG_MAC_TYPE_MA, IWL_CFG_ANY, 1119 - IWL_CFG_RF_TYPE_MS, IWL_CFG_ANY, IWL_CFG_ANY, 1120 - IWL_CFG_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, 1121 - iwl_cfg_ma, iwl_ax204_name), 1122 - 1123 1103 /* Sc */ 1124 1104 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1125 1105 IWL_CFG_MAC_TYPE_SC, IWL_CFG_ANY, ··· 1134 1150 { 1135 1151 u32 sd_reg_ver_addr; 1136 1152 u32 val = 0; 1153 + u8 step; 1137 1154 1138 1155 if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) 1139 1156 sd_reg_ver_addr = SD_REG_VER_GEN2; ··· 1153 1168 iwl_trans->hw_cnv_id = 1154 1169 iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP); 1155 1170 1171 + /* For BZ-W, take B step also when A step is indicated */ 1172 + if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) 1173 + step = SILICON_B_STEP; 1174 + 1156 1175 /* In BZ, the MAC step must be read from the CNVI aux register */ 1157 1176 if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ) { 1158 - u8 step = CNVI_AUX_MISC_CHIP_MAC_STEP(iwl_trans->hw_cnv_id); 1177 + step = CNVI_AUX_MISC_CHIP_MAC_STEP(iwl_trans->hw_cnv_id); 1159 1178 1160 1179 /* For BZ-U, take B step also when A step is indicated */ 1161 1180 if ((CNVI_AUX_MISC_CHIP_PROD_TYPE(iwl_trans->hw_cnv_id) == 1162 1181 CNVI_AUX_MISC_CHIP_PROD_TYPE_BZ_U) && 1163 1182 step == SILICON_A_STEP) 1164 1183 step = SILICON_B_STEP; 1184 + } 1165 1185 1186 + if (CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ || 1187 + CSR_HW_REV_TYPE(iwl_trans->hw_rev) == IWL_CFG_MAC_TYPE_BZ_W) { 1166 1188 iwl_trans->hw_rev_step = step; 1167 1189 iwl_trans->hw_rev |= step; 1168 1190 } ··· 1216 1224 case REG_CRF_ID_TYPE_GF: 1217 1225 iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_GF << 12); 1218 1226 break; 1219 - case REG_CRF_ID_TYPE_MR: 1220 - iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_MR << 12); 1221 - break; 1222 1227 case REG_CRF_ID_TYPE_FM: 1223 - case REG_CRF_ID_TYPE_FMI: 1224 - case REG_CRF_ID_TYPE_FMR: 1225 1228 iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12); 1226 1229 break; 1227 1230 case REG_CRF_ID_TYPE_WHP:
+25 -1
drivers/net/wireless/intel/iwlwifi/tests/devinfo.c
··· 2 2 /* 3 3 * KUnit tests for the iwlwifi device info table 4 4 * 5 - * Copyright (C) 2023 Intel Corporation 5 + * Copyright (C) 2023-2024 Intel Corporation 6 6 */ 7 7 #include <kunit/test.h> 8 + #include <linux/pci.h> 8 9 #include "iwl-drv.h" 9 10 #include "iwl-config.h" 10 11 ··· 42 41 } 43 42 } 44 43 44 + static void devinfo_pci_ids(struct kunit *test) 45 + { 46 + struct pci_dev *dev; 47 + 48 + dev = kunit_kmalloc(test, sizeof(*dev), GFP_KERNEL); 49 + KUNIT_ASSERT_NOT_NULL(test, dev); 50 + 51 + for (int i = 0; iwl_hw_card_ids[i].vendor; i++) { 52 + const struct pci_device_id *s, *t; 53 + 54 + s = &iwl_hw_card_ids[i]; 55 + dev->vendor = s->vendor; 56 + dev->device = s->device; 57 + dev->subsystem_vendor = s->subvendor; 58 + dev->subsystem_device = s->subdevice; 59 + dev->class = s->class; 60 + 61 + t = pci_match_id(iwl_hw_card_ids, dev); 62 + KUNIT_EXPECT_PTR_EQ(test, t, s); 63 + } 64 + } 65 + 45 66 static struct kunit_case devinfo_test_cases[] = { 46 67 KUNIT_CASE(devinfo_table_order), 68 + KUNIT_CASE(devinfo_pci_ids), 47 69 {} 48 70 }; 49 71
+1
drivers/net/wireless/marvell/mwifiex/sdio.c
··· 3192 3192 MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME); 3193 3193 MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); 3194 3194 MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); 3195 + MODULE_FIRMWARE(SD8801_DEFAULT_FW_NAME); 3195 3196 MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME); 3196 3197 MODULE_FIRMWARE(SD8887_DEFAULT_FW_NAME); 3197 3198 MODULE_FIRMWARE(SD8977_DEFAULT_FW_NAME);
+47 -45
drivers/net/wireless/marvell/mwl8k.c
··· 587 587 } 588 588 589 589 struct mwl8k_cmd_pkt { 590 - __le16 code; 591 - __le16 length; 592 - __u8 seq_num; 593 - __u8 macid; 594 - __le16 result; 595 - char payload[]; 590 + __struct_group(mwl8k_cmd_pkt_hdr, hdr, __packed, 591 + __le16 code; 592 + __le16 length; 593 + __u8 seq_num; 594 + __u8 macid; 595 + __le16 result; 596 + ); 597 + char payload[]; 596 598 } __packed; 597 599 598 600 /* ··· 2203 2201 /* Timeout firmware commands after 10s */ 2204 2202 #define MWL8K_CMD_TIMEOUT_MS 10000 2205 2203 2206 - static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) 2204 + static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt_hdr *cmd) 2207 2205 { 2208 2206 DECLARE_COMPLETION_ONSTACK(cmd_wait); 2209 2207 struct mwl8k_priv *priv = hw->priv; ··· 2300 2298 2301 2299 static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw, 2302 2300 struct ieee80211_vif *vif, 2303 - struct mwl8k_cmd_pkt *cmd) 2301 + struct mwl8k_cmd_pkt_hdr *cmd) 2304 2302 { 2305 2303 if (vif != NULL) 2306 2304 cmd->macid = MWL8K_VIF(vif)->macid; ··· 2352 2350 * CMD_GET_HW_SPEC (STA version). 2353 2351 */ 2354 2352 struct mwl8k_cmd_get_hw_spec_sta { 2355 - struct mwl8k_cmd_pkt header; 2353 + struct mwl8k_cmd_pkt_hdr header; 2356 2354 __u8 hw_rev; 2357 2355 __u8 host_interface; 2358 2356 __le16 num_mcaddrs; ··· 2501 2499 * CMD_GET_HW_SPEC (AP version). 2502 2500 */ 2503 2501 struct mwl8k_cmd_get_hw_spec_ap { 2504 - struct mwl8k_cmd_pkt header; 2502 + struct mwl8k_cmd_pkt_hdr header; 2505 2503 __u8 hw_rev; 2506 2504 __u8 host_interface; 2507 2505 __le16 num_wcb; ··· 2595 2593 * CMD_SET_HW_SPEC. 2596 2594 */ 2597 2595 struct mwl8k_cmd_set_hw_spec { 2598 - struct mwl8k_cmd_pkt header; 2596 + struct mwl8k_cmd_pkt_hdr header; 2599 2597 __u8 hw_rev; 2600 2598 __u8 host_interface; 2601 2599 __le16 num_mcaddrs; ··· 2672 2670 * CMD_MAC_MULTICAST_ADR. 2673 2671 */ 2674 2672 struct mwl8k_cmd_mac_multicast_adr { 2675 - struct mwl8k_cmd_pkt header; 2673 + struct mwl8k_cmd_pkt_hdr header; 2676 2674 __le16 action; 2677 2675 __le16 numaddr; 2678 2676 __u8 addr[][ETH_ALEN]; ··· 2683 2681 #define MWL8K_ENABLE_RX_ALL_MULTICAST 0x0004 2684 2682 #define MWL8K_ENABLE_RX_BROADCAST 0x0008 2685 2683 2686 - static struct mwl8k_cmd_pkt * 2684 + static struct mwl8k_cmd_pkt_hdr * 2687 2685 __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, 2688 2686 struct netdev_hw_addr_list *mc_list) 2689 2687 { ··· 2731 2729 * CMD_GET_STAT. 2732 2730 */ 2733 2731 struct mwl8k_cmd_get_stat { 2734 - struct mwl8k_cmd_pkt header; 2732 + struct mwl8k_cmd_pkt_hdr header; 2735 2733 __le32 stats[64]; 2736 2734 } __packed; 2737 2735 ··· 2773 2771 * CMD_RADIO_CONTROL. 2774 2772 */ 2775 2773 struct mwl8k_cmd_radio_control { 2776 - struct mwl8k_cmd_pkt header; 2774 + struct mwl8k_cmd_pkt_hdr header; 2777 2775 __le16 action; 2778 2776 __le16 control; 2779 2777 __le16 radio_on; ··· 2834 2832 #define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8 2835 2833 2836 2834 struct mwl8k_cmd_rf_tx_power { 2837 - struct mwl8k_cmd_pkt header; 2835 + struct mwl8k_cmd_pkt_hdr header; 2838 2836 __le16 action; 2839 2837 __le16 support_level; 2840 2838 __le16 current_level; ··· 2868 2866 #define MWL8K_TX_POWER_LEVEL_TOTAL 12 2869 2867 2870 2868 struct mwl8k_cmd_tx_power { 2871 - struct mwl8k_cmd_pkt header; 2869 + struct mwl8k_cmd_pkt_hdr header; 2872 2870 __le16 action; 2873 2871 __le16 band; 2874 2872 __le16 channel; ··· 2927 2925 * CMD_RF_ANTENNA. 2928 2926 */ 2929 2927 struct mwl8k_cmd_rf_antenna { 2930 - struct mwl8k_cmd_pkt header; 2928 + struct mwl8k_cmd_pkt_hdr header; 2931 2929 __le16 antenna; 2932 2930 __le16 mode; 2933 2931 } __packed; ··· 2960 2958 * CMD_SET_BEACON. 2961 2959 */ 2962 2960 struct mwl8k_cmd_set_beacon { 2963 - struct mwl8k_cmd_pkt header; 2961 + struct mwl8k_cmd_pkt_hdr header; 2964 2962 __le16 beacon_len; 2965 2963 __u8 beacon[]; 2966 2964 }; ··· 2990 2988 * CMD_SET_PRE_SCAN. 2991 2989 */ 2992 2990 struct mwl8k_cmd_set_pre_scan { 2993 - struct mwl8k_cmd_pkt header; 2991 + struct mwl8k_cmd_pkt_hdr header; 2994 2992 } __packed; 2995 2993 2996 2994 static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw) ··· 3015 3013 * CMD_BBP_REG_ACCESS. 3016 3014 */ 3017 3015 struct mwl8k_cmd_bbp_reg_access { 3018 - struct mwl8k_cmd_pkt header; 3016 + struct mwl8k_cmd_pkt_hdr header; 3019 3017 __le16 action; 3020 3018 __le16 offset; 3021 3019 u8 value; ··· 3056 3054 * CMD_SET_POST_SCAN. 3057 3055 */ 3058 3056 struct mwl8k_cmd_set_post_scan { 3059 - struct mwl8k_cmd_pkt header; 3057 + struct mwl8k_cmd_pkt_hdr header; 3060 3058 __le32 isibss; 3061 3059 __u8 bssid[ETH_ALEN]; 3062 3060 } __packed; ··· 3144 3142 * CMD_SET_RF_CHANNEL. 3145 3143 */ 3146 3144 struct mwl8k_cmd_set_rf_channel { 3147 - struct mwl8k_cmd_pkt header; 3145 + struct mwl8k_cmd_pkt_hdr header; 3148 3146 __le16 action; 3149 3147 __u8 current_channel; 3150 3148 __le32 channel_flags; ··· 3213 3211 #define MWL8K_FRAME_PROT_11N_HT_ALL 0x06 3214 3212 3215 3213 struct mwl8k_cmd_update_set_aid { 3216 - struct mwl8k_cmd_pkt header; 3214 + struct mwl8k_cmd_pkt_hdr header; 3217 3215 __le16 aid; 3218 3216 3219 3217 /* AP's MAC address (BSSID) */ ··· 3285 3283 * CMD_SET_RATE. 3286 3284 */ 3287 3285 struct mwl8k_cmd_set_rate { 3288 - struct mwl8k_cmd_pkt header; 3286 + struct mwl8k_cmd_pkt_hdr header; 3289 3287 __u8 legacy_rates[14]; 3290 3288 3291 3289 /* Bitmap for supported MCS codes. */ ··· 3321 3319 #define MWL8K_FJ_BEACON_MAXLEN 128 3322 3320 3323 3321 struct mwl8k_cmd_finalize_join { 3324 - struct mwl8k_cmd_pkt header; 3322 + struct mwl8k_cmd_pkt_hdr header; 3325 3323 __le32 sleep_interval; /* Number of beacon periods to sleep */ 3326 3324 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN]; 3327 3325 } __packed; ··· 3360 3358 * CMD_SET_RTS_THRESHOLD. 3361 3359 */ 3362 3360 struct mwl8k_cmd_set_rts_threshold { 3363 - struct mwl8k_cmd_pkt header; 3361 + struct mwl8k_cmd_pkt_hdr header; 3364 3362 __le16 action; 3365 3363 __le16 threshold; 3366 3364 } __packed; ··· 3390 3388 * CMD_SET_SLOT. 3391 3389 */ 3392 3390 struct mwl8k_cmd_set_slot { 3393 - struct mwl8k_cmd_pkt header; 3391 + struct mwl8k_cmd_pkt_hdr header; 3394 3392 __le16 action; 3395 3393 __u8 short_slot; 3396 3394 } __packed; ··· 3419 3417 * CMD_SET_EDCA_PARAMS. 3420 3418 */ 3421 3419 struct mwl8k_cmd_set_edca_params { 3422 - struct mwl8k_cmd_pkt header; 3420 + struct mwl8k_cmd_pkt_hdr header; 3423 3421 3424 3422 /* See MWL8K_SET_EDCA_XXX below */ 3425 3423 __le16 action; ··· 3504 3502 * CMD_SET_WMM_MODE. 3505 3503 */ 3506 3504 struct mwl8k_cmd_set_wmm_mode { 3507 - struct mwl8k_cmd_pkt header; 3505 + struct mwl8k_cmd_pkt_hdr header; 3508 3506 __le16 action; 3509 3507 } __packed; 3510 3508 ··· 3535 3533 * CMD_MIMO_CONFIG. 3536 3534 */ 3537 3535 struct mwl8k_cmd_mimo_config { 3538 - struct mwl8k_cmd_pkt header; 3536 + struct mwl8k_cmd_pkt_hdr header; 3539 3537 __le32 action; 3540 3538 __u8 rx_antenna_map; 3541 3539 __u8 tx_antenna_map; ··· 3566 3564 * CMD_USE_FIXED_RATE (STA version). 3567 3565 */ 3568 3566 struct mwl8k_cmd_use_fixed_rate_sta { 3569 - struct mwl8k_cmd_pkt header; 3567 + struct mwl8k_cmd_pkt_hdr header; 3570 3568 __le32 action; 3571 3569 __le32 allow_rate_drop; 3572 3570 __le32 num_rates; ··· 3608 3606 * CMD_USE_FIXED_RATE (AP version). 3609 3607 */ 3610 3608 struct mwl8k_cmd_use_fixed_rate_ap { 3611 - struct mwl8k_cmd_pkt header; 3609 + struct mwl8k_cmd_pkt_hdr header; 3612 3610 __le32 action; 3613 3611 __le32 allow_rate_drop; 3614 3612 __le32 num_rates; ··· 3649 3647 * CMD_ENABLE_SNIFFER. 3650 3648 */ 3651 3649 struct mwl8k_cmd_enable_sniffer { 3652 - struct mwl8k_cmd_pkt header; 3650 + struct mwl8k_cmd_pkt_hdr header; 3653 3651 __le32 action; 3654 3652 } __packed; 3655 3653 ··· 3673 3671 } 3674 3672 3675 3673 struct mwl8k_cmd_update_mac_addr { 3676 - struct mwl8k_cmd_pkt header; 3674 + struct mwl8k_cmd_pkt_hdr header; 3677 3675 union { 3678 3676 struct { 3679 3677 __le16 mac_type; ··· 3758 3756 * CMD_SET_RATEADAPT_MODE. 3759 3757 */ 3760 3758 struct mwl8k_cmd_set_rate_adapt_mode { 3761 - struct mwl8k_cmd_pkt header; 3759 + struct mwl8k_cmd_pkt_hdr header; 3762 3760 __le16 action; 3763 3761 __le16 mode; 3764 3762 } __packed; ··· 3787 3785 * CMD_GET_WATCHDOG_BITMAP. 3788 3786 */ 3789 3787 struct mwl8k_cmd_get_watchdog_bitmap { 3790 - struct mwl8k_cmd_pkt header; 3788 + struct mwl8k_cmd_pkt_hdr header; 3791 3789 u8 bitmap; 3792 3790 } __packed; 3793 3791 ··· 3867 3865 * CMD_BSS_START. 3868 3866 */ 3869 3867 struct mwl8k_cmd_bss_start { 3870 - struct mwl8k_cmd_pkt header; 3868 + struct mwl8k_cmd_pkt_hdr header; 3871 3869 __le32 enable; 3872 3870 } __packed; 3873 3871 ··· 3962 3960 } __packed; 3963 3961 3964 3962 struct mwl8k_cmd_bastream { 3965 - struct mwl8k_cmd_pkt header; 3963 + struct mwl8k_cmd_pkt_hdr header; 3966 3964 __le32 action; 3967 3965 union { 3968 3966 struct mwl8k_create_ba_stream create_params; ··· 4072 4070 * CMD_SET_NEW_STN. 4073 4071 */ 4074 4072 struct mwl8k_cmd_set_new_stn { 4075 - struct mwl8k_cmd_pkt header; 4073 + struct mwl8k_cmd_pkt_hdr header; 4076 4074 __le16 aid; 4077 4075 __u8 mac_addr[6]; 4078 4076 __le16 stn_id; ··· 4208 4206 #define MIC_KEY_LENGTH 8 4209 4207 4210 4208 struct mwl8k_cmd_update_encryption { 4211 - struct mwl8k_cmd_pkt header; 4209 + struct mwl8k_cmd_pkt_hdr header; 4212 4210 4213 4211 __le32 action; 4214 4212 __le32 reserved; ··· 4218 4216 } __packed; 4219 4217 4220 4218 struct mwl8k_cmd_set_key { 4221 - struct mwl8k_cmd_pkt header; 4219 + struct mwl8k_cmd_pkt_hdr header; 4222 4220 4223 4221 __le32 action; 4224 4222 __le32 reserved; ··· 4506 4504 } __packed; 4507 4505 4508 4506 struct mwl8k_cmd_update_stadb { 4509 - struct mwl8k_cmd_pkt header; 4507 + struct mwl8k_cmd_pkt_hdr header; 4510 4508 4511 4509 /* See STADB_ACTION_TYPE */ 4512 4510 __le32 action; ··· 5176 5174 static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 5177 5175 struct netdev_hw_addr_list *mc_list) 5178 5176 { 5179 - struct mwl8k_cmd_pkt *cmd; 5177 + struct mwl8k_cmd_pkt_hdr *cmd; 5180 5178 5181 5179 /* 5182 5180 * Synthesize and return a command packet that programs the ··· 5236 5234 u64 multicast) 5237 5235 { 5238 5236 struct mwl8k_priv *priv = hw->priv; 5239 - struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast; 5237 + struct mwl8k_cmd_pkt_hdr *cmd = (void *)(unsigned long)multicast; 5240 5238 5241 5239 /* 5242 5240 * AP firmware doesn't allow fine-grained control over
+5 -4
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
··· 523 523 524 524 /* WM CPU info record control */ 525 525 mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0)); 526 - mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | !dev->fw.debug_wm); 526 + mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | 527 + (dev->fw.debug_wm ? 0 : BIT(0))); 527 528 mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5)); 528 529 mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5)); 529 530 ··· 1050 1049 mt7915_rate_txpower_set(struct file *file, const char __user *user_buf, 1051 1050 size_t count, loff_t *ppos) 1052 1051 { 1052 + int i, ret, pwr, pwr160 = 0, pwr80 = 0, pwr40 = 0, pwr20 = 0; 1053 1053 struct mt7915_phy *phy = file->private_data; 1054 1054 struct mt7915_dev *dev = phy->dev; 1055 1055 struct mt76_phy *mphy = phy->mt76; ··· 1059 1057 .band_idx = phy->mt76->band_idx, 1060 1058 }; 1061 1059 char buf[100]; 1062 - int i, ret, pwr160 = 0, pwr80 = 0, pwr40 = 0, pwr20 = 0; 1063 1060 enum mac80211_rx_encoding mode; 1064 1061 u32 offs = 0, len = 0; 1065 1062 ··· 1131 1130 if (ret) 1132 1131 goto out; 1133 1132 1134 - mphy->txpower_cur = max(mphy->txpower_cur, 1135 - max(pwr160, max(pwr80, max(pwr40, pwr20)))); 1133 + pwr = max3(pwr80, pwr40, pwr20); 1134 + mphy->txpower_cur = max3(mphy->txpower_cur, pwr160, pwr); 1136 1135 out: 1137 1136 mutex_unlock(&dev->mt76.mutex); 1138 1137
+1 -1
drivers/net/wireless/quantenna/qtnfmac/bus.h
··· 59 59 struct qtnf_qlink_transport trans; 60 60 struct qtnf_hw_info hw_info; 61 61 struct napi_struct mux_napi; 62 - struct net_device mux_dev; 62 + struct net_device *mux_dev; 63 63 struct workqueue_struct *workqueue; 64 64 struct workqueue_struct *hprio_workqueue; 65 65 struct work_struct fw_work;
+11 -2
drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c
··· 372 372 goto error; 373 373 } 374 374 375 - init_dummy_netdev(&bus->mux_dev); 375 + bus->mux_dev = alloc_netdev(0, "dummy", NET_NAME_UNKNOWN, 376 + init_dummy_netdev); 377 + if (!bus->mux_dev) { 378 + ret = -ENOMEM; 379 + goto error; 380 + } 381 + 376 382 qtnf_pcie_init_irq(pcie_priv, use_msi); 377 383 pcie_priv->sysctl_bar = sysctl_bar; 378 384 pcie_priv->dmareg_bar = dmareg_bar; ··· 387 381 388 382 ret = pcie_priv->probe_cb(bus, tx_bd_size_param, rx_bd_size_param); 389 383 if (ret) 390 - goto error; 384 + goto error_free; 391 385 392 386 qtnf_pcie_bringup_fw_async(bus); 393 387 return 0; 394 388 389 + error_free: 390 + free_netdev(bus->mux_dev); 395 391 error: 396 392 destroy_workqueue(pcie_priv->workqueue); 397 393 pci_set_drvdata(pdev, NULL); ··· 425 417 netif_napi_del(&bus->mux_napi); 426 418 destroy_workqueue(priv->workqueue); 427 419 tasklet_kill(&priv->reclaim_tq); 420 + free_netdev(bus->mux_dev); 428 421 429 422 qtnf_pcie_free_shm_ipc(priv); 430 423 qtnf_debugfs_remove(bus);
+3 -3
drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
··· 761 761 napi_gro_receive(napi, skb); 762 762 } else { 763 763 pr_debug("drop untagged skb\n"); 764 - bus->mux_dev.stats.rx_dropped++; 764 + bus->mux_dev->stats.rx_dropped++; 765 765 dev_kfree_skb_any(skb); 766 766 } 767 767 } else { 768 768 if (skb) { 769 - bus->mux_dev.stats.rx_dropped++; 769 + bus->mux_dev->stats.rx_dropped++; 770 770 dev_kfree_skb_any(skb); 771 771 } 772 772 } ··· 1146 1146 } 1147 1147 1148 1148 tasklet_setup(&ps->base.reclaim_tq, qtnf_pearl_reclaim_tasklet_fn); 1149 - netif_napi_add_weight(&bus->mux_dev, &bus->mux_napi, 1149 + netif_napi_add_weight(bus->mux_dev, &bus->mux_napi, 1150 1150 qtnf_pcie_pearl_rx_poll, 10); 1151 1151 1152 1152 ipc_int.fn = qtnf_pcie_pearl_ipc_gen_ep_int;
+3 -3
drivers/net/wireless/quantenna/qtnfmac/pcie/topaz_pcie.c
··· 667 667 netif_receive_skb(skb); 668 668 } else { 669 669 pr_debug("drop untagged skb\n"); 670 - bus->mux_dev.stats.rx_dropped++; 670 + bus->mux_dev->stats.rx_dropped++; 671 671 dev_kfree_skb_any(skb); 672 672 } 673 673 } else { 674 674 if (skb) { 675 - bus->mux_dev.stats.rx_dropped++; 675 + bus->mux_dev->stats.rx_dropped++; 676 676 dev_kfree_skb_any(skb); 677 677 } 678 678 } ··· 1159 1159 } 1160 1160 1161 1161 tasklet_setup(&ts->base.reclaim_tq, qtnf_reclaim_tasklet_fn); 1162 - netif_napi_add_weight(&bus->mux_dev, &bus->mux_napi, 1162 + netif_napi_add_weight(bus->mux_dev, &bus->mux_napi, 1163 1163 qtnf_topaz_rx_poll, 10); 1164 1164 1165 1165 ipc_int.fn = qtnf_topaz_ipc_gen_ep_int;
+22
drivers/net/wireless/realtek/rtw88/Kconfig
··· 28 28 config RTW88_8822C 29 29 tristate 30 30 31 + config RTW88_8723X 32 + tristate 33 + 34 + config RTW88_8703B 35 + tristate 36 + select RTW88_8723X 37 + 31 38 config RTW88_8723D 32 39 tristate 40 + select RTW88_8723X 33 41 34 42 config RTW88_8821C 35 43 tristate ··· 129 121 Select this option will enable support for 8723DS chipset 130 122 131 123 802.11n SDIO wireless network adapter 124 + 125 + config RTW88_8723CS 126 + tristate "Realtek 8723CS SDIO wireless network adapter" 127 + depends on MMC 128 + select RTW88_CORE 129 + select RTW88_SDIO 130 + select RTW88_8703B 131 + help 132 + Select this option to enable support for 8723CS chipset (EXPERIMENTAL) 133 + 134 + This module adds support for the 8723CS 802.11n SDIO 135 + wireless network adapter. 136 + 137 + If you choose to build a module, it'll be called rtw88_8723cs. 132 138 133 139 config RTW88_8723DU 134 140 tristate "Realtek 8723DU USB wireless network adapter"
+9
drivers/net/wireless/realtek/rtw88/Makefile
··· 44 44 obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o 45 45 rtw88_8822cu-objs := rtw8822cu.o 46 46 47 + obj-$(CONFIG_RTW88_8723X) += rtw88_8723x.o 48 + rtw88_8723x-objs := rtw8723x.o 49 + 50 + obj-$(CONFIG_RTW88_8703B) += rtw88_8703b.o 51 + rtw88_8703b-objs := rtw8703b.o rtw8703b_tables.o 52 + 53 + obj-$(CONFIG_RTW88_8723CS) += rtw88_8723cs.o 54 + rtw88_8723cs-objs := rtw8723cs.o 55 + 47 56 obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o 48 57 rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o 49 58
+6
drivers/net/wireless/realtek/rtw88/mac.c
··· 943 943 { 944 944 int ret = 0; 945 945 946 + /* reset firmware if still present */ 947 + if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && 948 + rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) { 949 + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); 950 + } 951 + 946 952 en_download_firmware_legacy(rtwdev, true); 947 953 ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size); 948 954 en_download_firmware_legacy(rtwdev, false);
+3
drivers/net/wireless/realtek/rtw88/main.h
··· 187 187 RTW_CHIP_TYPE_8822C, 188 188 RTW_CHIP_TYPE_8723D, 189 189 RTW_CHIP_TYPE_8821C, 190 + RTW_CHIP_TYPE_8703B, 190 191 }; 191 192 192 193 enum rtw_tx_queue_type { ··· 1701 1700 s8 delta_power_index[RTW_RF_PATH_MAX]; 1702 1701 s8 delta_power_index_last[RTW_RF_PATH_MAX]; 1703 1702 u8 default_ofdm_index; 1703 + u8 default_cck_index; 1704 1704 bool pwr_trk_triggered; 1705 1705 bool pwr_trk_init_trigger; 1706 1706 struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; 1707 1707 s8 txagc_remnant_cck; 1708 1708 s8 txagc_remnant_ofdm; 1709 + u8 rx_cck_agc_report_type; 1709 1710 1710 1711 /* backup dack results for each path and I/Q */ 1711 1712 u32 dack_adck[RTW_RF_PATH_MAX];
+2109
drivers/net/wireless/realtek/rtw88/rtw8703b.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright Fiona Klute <fiona.klute@gmx.de> */ 3 + 4 + #include <linux/of_net.h> 5 + #include "main.h" 6 + #include "coex.h" 7 + #include "debug.h" 8 + #include "mac.h" 9 + #include "phy.h" 10 + #include "reg.h" 11 + #include "rx.h" 12 + #include "rtw8703b.h" 13 + #include "rtw8703b_tables.h" 14 + #include "rtw8723x.h" 15 + 16 + #define BIT_MASK_TXQ_INIT (BIT(7)) 17 + #define WLAN_RL_VAL 0x3030 18 + /* disable BAR */ 19 + #define WLAN_BAR_VAL 0x0201ffff 20 + #define WLAN_PIFS_VAL 0 21 + #define WLAN_RX_PKT_LIMIT 0x18 22 + #define WLAN_SLOT_TIME 0x09 23 + #define WLAN_SPEC_SIFS 0x100a 24 + #define WLAN_MAX_AGG_NR 0x1f 25 + #define WLAN_AMPDU_MAX_TIME 0x70 26 + 27 + /* unit is 32us */ 28 + #define TBTT_PROHIBIT_SETUP_TIME 0x04 29 + #define TBTT_PROHIBIT_HOLD_TIME 0x80 30 + #define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64 31 + 32 + /* raw pkt_stat->drv_info_sz is in unit of 8-bytes */ 33 + #define RX_DRV_INFO_SZ_UNIT_8703B 8 34 + 35 + #define TRANS_SEQ_END \ 36 + 0xFFFF, \ 37 + RTW_PWR_CUT_ALL_MSK, \ 38 + RTW_PWR_INTF_ALL_MSK, \ 39 + 0, \ 40 + RTW_PWR_CMD_END, 0, 0 41 + 42 + /* rssi in percentage % (dbm = % - 100) */ 43 + /* These are used to select simple signal quality levels, might need 44 + * tweaking. Same for rf_para tables below. 45 + */ 46 + static const u8 wl_rssi_step_8703b[] = {60, 50, 44, 30}; 47 + static const u8 bt_rssi_step_8703b[] = {30, 30, 30, 30}; 48 + static const struct coex_5g_afh_map afh_5g_8703b[] = { {0, 0, 0} }; 49 + 50 + /* Actually decreasing wifi TX power/RX gain isn't implemented in 51 + * rtw8703b, but hopefully adjusting the BT side helps. 52 + */ 53 + static const struct coex_rf_para rf_para_tx_8703b[] = { 54 + {0, 0, false, 7}, /* for normal */ 55 + {0, 10, false, 7}, /* for WL-CPT */ 56 + {1, 0, true, 4}, 57 + {1, 2, true, 4}, 58 + {1, 10, true, 4}, 59 + {1, 15, true, 4} 60 + }; 61 + 62 + static const struct coex_rf_para rf_para_rx_8703b[] = { 63 + {0, 0, false, 7}, /* for normal */ 64 + {0, 10, false, 7}, /* for WL-CPT */ 65 + {1, 0, true, 5}, 66 + {1, 2, true, 5}, 67 + {1, 10, true, 5}, 68 + {1, 15, true, 5} 69 + }; 70 + 71 + static const u32 rtw8703b_ofdm_swing_table[] = { 72 + 0x0b40002d, /* 0, -15.0dB */ 73 + 0x0c000030, /* 1, -14.5dB */ 74 + 0x0cc00033, /* 2, -14.0dB */ 75 + 0x0d800036, /* 3, -13.5dB */ 76 + 0x0e400039, /* 4, -13.0dB */ 77 + 0x0f00003c, /* 5, -12.5dB */ 78 + 0x10000040, /* 6, -12.0dB */ 79 + 0x11000044, /* 7, -11.5dB */ 80 + 0x12000048, /* 8, -11.0dB */ 81 + 0x1300004c, /* 9, -10.5dB */ 82 + 0x14400051, /* 10, -10.0dB */ 83 + 0x15800056, /* 11, -9.5dB */ 84 + 0x16c0005b, /* 12, -9.0dB */ 85 + 0x18000060, /* 13, -8.5dB */ 86 + 0x19800066, /* 14, -8.0dB */ 87 + 0x1b00006c, /* 15, -7.5dB */ 88 + 0x1c800072, /* 16, -7.0dB */ 89 + 0x1e400079, /* 17, -6.5dB */ 90 + 0x20000080, /* 18, -6.0dB */ 91 + 0x22000088, /* 19, -5.5dB */ 92 + 0x24000090, /* 20, -5.0dB */ 93 + 0x26000098, /* 21, -4.5dB */ 94 + 0x288000a2, /* 22, -4.0dB */ 95 + 0x2ac000ab, /* 23, -3.5dB */ 96 + 0x2d4000b5, /* 24, -3.0dB */ 97 + 0x300000c0, /* 25, -2.5dB */ 98 + 0x32c000cb, /* 26, -2.0dB */ 99 + 0x35c000d7, /* 27, -1.5dB */ 100 + 0x390000e4, /* 28, -1.0dB */ 101 + 0x3c8000f2, /* 29, -0.5dB */ 102 + 0x40000100, /* 30, +0dB */ 103 + 0x43c0010f, /* 31, +0.5dB */ 104 + 0x47c0011f, /* 32, +1.0dB */ 105 + 0x4c000130, /* 33, +1.5dB */ 106 + 0x50800142, /* 34, +2.0dB */ 107 + 0x55400155, /* 35, +2.5dB */ 108 + 0x5a400169, /* 36, +3.0dB */ 109 + 0x5fc0017f, /* 37, +3.5dB */ 110 + 0x65400195, /* 38, +4.0dB */ 111 + 0x6b8001ae, /* 39, +4.5dB */ 112 + 0x71c001c7, /* 40, +5.0dB */ 113 + 0x788001e2, /* 41, +5.5dB */ 114 + 0x7f8001fe /* 42, +6.0dB */ 115 + }; 116 + 117 + static const u32 rtw8703b_cck_pwr_regs[] = { 118 + 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29, 119 + 0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3, 120 + }; 121 + 122 + static const u8 rtw8703b_cck_swing_table[][16] = { 123 + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 124 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ 125 + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 126 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ 127 + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 128 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ 129 + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 130 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ 131 + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 132 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ 133 + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 134 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ 135 + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 136 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ 137 + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 138 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ 139 + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 140 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ 141 + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 142 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ 143 + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 144 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ 145 + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 146 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ 147 + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 148 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ 149 + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 150 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ 151 + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 152 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ 153 + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 154 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ 155 + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 156 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ 157 + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 158 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ 159 + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 160 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ 161 + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 162 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ 163 + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 164 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ 165 + }; 166 + 167 + #define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_ofdm_swing_table) 168 + #define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_cck_swing_table) 169 + 170 + static const struct rtw_pwr_seq_cmd trans_pre_enable_8703b[] = { 171 + /* set up external crystal (XTAL) */ 172 + {REG_PAD_CTRL1 + 2, 173 + RTW_PWR_CUT_ALL_MSK, 174 + RTW_PWR_INTF_ALL_MSK, 175 + RTW_PWR_ADDR_MAC, 176 + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, 177 + /* set CLK_REQ to high active */ 178 + {0x0069, 179 + RTW_PWR_CUT_ALL_MSK, 180 + RTW_PWR_INTF_ALL_MSK, 181 + RTW_PWR_ADDR_MAC, 182 + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 183 + /* unlock ISO/CLK/power control register */ 184 + {REG_RSV_CTRL, 185 + RTW_PWR_CUT_ALL_MSK, 186 + RTW_PWR_INTF_ALL_MSK, 187 + RTW_PWR_ADDR_MAC, 188 + RTW_PWR_CMD_WRITE, 0xff, 0}, 189 + {TRANS_SEQ_END}, 190 + }; 191 + 192 + static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8703b[] = { 193 + {0x0005, 194 + RTW_PWR_CUT_ALL_MSK, 195 + RTW_PWR_INTF_ALL_MSK, 196 + RTW_PWR_ADDR_MAC, 197 + RTW_PWR_CMD_WRITE, BIT(7), 0}, 198 + {TRANS_SEQ_END}, 199 + }; 200 + 201 + static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8703b[] = { 202 + {0x0023, 203 + RTW_PWR_CUT_ALL_MSK, 204 + RTW_PWR_INTF_SDIO_MSK, 205 + RTW_PWR_ADDR_MAC, 206 + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, 207 + {0x0007, 208 + RTW_PWR_CUT_ALL_MSK, 209 + RTW_PWR_INTF_SDIO_MSK | RTW_PWR_INTF_USB_MSK, 210 + RTW_PWR_ADDR_MAC, 211 + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, 212 + {0x0006, 213 + RTW_PWR_CUT_ALL_MSK, 214 + RTW_PWR_INTF_ALL_MSK, 215 + RTW_PWR_ADDR_MAC, 216 + RTW_PWR_CMD_WRITE, BIT(0), 0}, 217 + {0x0005, 218 + RTW_PWR_CUT_ALL_MSK, 219 + RTW_PWR_INTF_ALL_MSK, 220 + RTW_PWR_ADDR_MAC, 221 + RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, 222 + {TRANS_SEQ_END}, 223 + }; 224 + 225 + static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8703b[] = { 226 + {0x0020, 227 + RTW_PWR_CUT_ALL_MSK, 228 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 229 + RTW_PWR_ADDR_MAC, 230 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 231 + {0x0067, 232 + RTW_PWR_CUT_ALL_MSK, 233 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 234 + RTW_PWR_ADDR_MAC, 235 + RTW_PWR_CMD_WRITE, BIT(4), 0}, 236 + {0x0001, 237 + RTW_PWR_CUT_ALL_MSK, 238 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 239 + RTW_PWR_ADDR_MAC, 240 + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, 241 + {0x0000, 242 + RTW_PWR_CUT_ALL_MSK, 243 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 244 + RTW_PWR_ADDR_MAC, 245 + RTW_PWR_CMD_WRITE, BIT(5), 0}, 246 + {0x0005, 247 + RTW_PWR_CUT_ALL_MSK, 248 + RTW_PWR_INTF_ALL_MSK, 249 + RTW_PWR_ADDR_MAC, 250 + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, 251 + {0x0075, 252 + RTW_PWR_CUT_ALL_MSK, 253 + RTW_PWR_INTF_PCI_MSK, 254 + RTW_PWR_ADDR_MAC, 255 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 256 + {0x0004, 257 + RTW_PWR_CUT_ALL_MSK, 258 + RTW_PWR_INTF_PCI_MSK, 259 + RTW_PWR_ADDR_MAC, 260 + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, 261 + {0x0004, 262 + RTW_PWR_CUT_ALL_MSK, 263 + RTW_PWR_INTF_PCI_MSK, 264 + RTW_PWR_ADDR_MAC, 265 + RTW_PWR_CMD_WRITE, BIT(3), 0}, 266 + /* wait for power ready */ 267 + {0x0006, 268 + RTW_PWR_CUT_ALL_MSK, 269 + RTW_PWR_INTF_ALL_MSK, 270 + RTW_PWR_ADDR_MAC, 271 + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 272 + {0x0075, 273 + RTW_PWR_CUT_ALL_MSK, 274 + RTW_PWR_INTF_PCI_MSK, 275 + RTW_PWR_ADDR_MAC, 276 + RTW_PWR_CMD_WRITE, BIT(0), 0}, 277 + {0x0006, 278 + RTW_PWR_CUT_ALL_MSK, 279 + RTW_PWR_INTF_ALL_MSK, 280 + RTW_PWR_ADDR_MAC, 281 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 282 + {0x0005, 283 + RTW_PWR_CUT_ALL_MSK, 284 + RTW_PWR_INTF_ALL_MSK, 285 + RTW_PWR_ADDR_MAC, 286 + RTW_PWR_CMD_WRITE, BIT(7), 0}, 287 + {0x0005, 288 + RTW_PWR_CUT_ALL_MSK, 289 + RTW_PWR_INTF_ALL_MSK, 290 + RTW_PWR_ADDR_MAC, 291 + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, 292 + {0x0005, 293 + RTW_PWR_CUT_ALL_MSK, 294 + RTW_PWR_INTF_ALL_MSK, 295 + RTW_PWR_ADDR_MAC, 296 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 297 + {0x0005, 298 + RTW_PWR_CUT_ALL_MSK, 299 + RTW_PWR_INTF_ALL_MSK, 300 + RTW_PWR_ADDR_MAC, 301 + RTW_PWR_CMD_POLLING, BIT(0), 0}, 302 + {0x0010, 303 + RTW_PWR_CUT_ALL_MSK, 304 + RTW_PWR_INTF_ALL_MSK, 305 + RTW_PWR_ADDR_MAC, 306 + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, 307 + {0x0049, 308 + RTW_PWR_CUT_ALL_MSK, 309 + RTW_PWR_INTF_ALL_MSK, 310 + RTW_PWR_ADDR_MAC, 311 + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 312 + {0x0063, 313 + RTW_PWR_CUT_ALL_MSK, 314 + RTW_PWR_INTF_ALL_MSK, 315 + RTW_PWR_ADDR_MAC, 316 + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 317 + {0x0062, 318 + RTW_PWR_CUT_ALL_MSK, 319 + RTW_PWR_INTF_ALL_MSK, 320 + RTW_PWR_ADDR_MAC, 321 + RTW_PWR_CMD_WRITE, BIT(1), 0}, 322 + {0x0058, 323 + RTW_PWR_CUT_ALL_MSK, 324 + RTW_PWR_INTF_ALL_MSK, 325 + RTW_PWR_ADDR_MAC, 326 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 327 + {0x005A, 328 + RTW_PWR_CUT_ALL_MSK, 329 + RTW_PWR_INTF_ALL_MSK, 330 + RTW_PWR_ADDR_MAC, 331 + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 332 + {0x0068, 333 + RTW_PWR_CUT_TEST_MSK, 334 + RTW_PWR_INTF_ALL_MSK, 335 + RTW_PWR_ADDR_MAC, 336 + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, 337 + {0x0069, 338 + RTW_PWR_CUT_ALL_MSK, 339 + RTW_PWR_INTF_ALL_MSK, 340 + RTW_PWR_ADDR_MAC, 341 + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, 342 + {TRANS_SEQ_END}, 343 + }; 344 + 345 + static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8703b[] = { 346 + {0x001f, 347 + RTW_PWR_CUT_ALL_MSK, 348 + RTW_PWR_INTF_ALL_MSK, 349 + RTW_PWR_ADDR_MAC, 350 + RTW_PWR_CMD_WRITE, 0xff, 0}, 351 + {0x0049, 352 + RTW_PWR_CUT_ALL_MSK, 353 + RTW_PWR_INTF_ALL_MSK, 354 + RTW_PWR_ADDR_MAC, 355 + RTW_PWR_CMD_WRITE, BIT(1), 0}, 356 + {0x0006, 357 + RTW_PWR_CUT_ALL_MSK, 358 + RTW_PWR_INTF_ALL_MSK, 359 + RTW_PWR_ADDR_MAC, 360 + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 361 + {0x0005, 362 + RTW_PWR_CUT_ALL_MSK, 363 + RTW_PWR_INTF_ALL_MSK, 364 + RTW_PWR_ADDR_MAC, 365 + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 366 + {0x0005, 367 + RTW_PWR_CUT_ALL_MSK, 368 + RTW_PWR_INTF_ALL_MSK, 369 + RTW_PWR_ADDR_MAC, 370 + RTW_PWR_CMD_POLLING, BIT(1), 0}, 371 + {0x0010, 372 + RTW_PWR_CUT_ALL_MSK, 373 + RTW_PWR_INTF_ALL_MSK, 374 + RTW_PWR_ADDR_MAC, 375 + RTW_PWR_CMD_WRITE, BIT(6), 0}, 376 + {0x0000, 377 + RTW_PWR_CUT_ALL_MSK, 378 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 379 + RTW_PWR_ADDR_MAC, 380 + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 381 + {0x0020, 382 + RTW_PWR_CUT_ALL_MSK, 383 + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 384 + RTW_PWR_ADDR_MAC, 385 + RTW_PWR_CMD_WRITE, BIT(0), 0}, 386 + {TRANS_SEQ_END}, 387 + }; 388 + 389 + static const struct rtw_pwr_seq_cmd trans_act_to_reset_mcu_8703b[] = { 390 + {REG_SYS_FUNC_EN + 1, 391 + RTW_PWR_CUT_ALL_MSK, 392 + RTW_PWR_INTF_SDIO_MSK, 393 + RTW_PWR_ADDR_MAC, 394 + RTW_PWR_CMD_WRITE, BIT_FEN_CPUEN, 0}, 395 + /* reset MCU ready */ 396 + {REG_MCUFW_CTRL, 397 + RTW_PWR_CUT_ALL_MSK, 398 + RTW_PWR_INTF_SDIO_MSK, 399 + RTW_PWR_ADDR_MAC, 400 + RTW_PWR_CMD_WRITE, 0xff, 0}, 401 + /* reset MCU IO wrapper */ 402 + {REG_RSV_CTRL + 1, 403 + RTW_PWR_CUT_ALL_MSK, 404 + RTW_PWR_INTF_SDIO_MSK, 405 + RTW_PWR_ADDR_MAC, 406 + RTW_PWR_CMD_WRITE, BIT(0), 0}, 407 + {REG_RSV_CTRL + 1, 408 + RTW_PWR_CUT_ALL_MSK, 409 + RTW_PWR_INTF_SDIO_MSK, 410 + RTW_PWR_ADDR_MAC, 411 + RTW_PWR_CMD_WRITE, BIT(0), 1}, 412 + {TRANS_SEQ_END}, 413 + }; 414 + 415 + static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = { 416 + {0x0301, 417 + RTW_PWR_CUT_ALL_MSK, 418 + RTW_PWR_INTF_ALL_MSK, 419 + RTW_PWR_ADDR_MAC, 420 + RTW_PWR_CMD_WRITE, 0xff, 0xff}, 421 + {0x0522, 422 + RTW_PWR_CUT_ALL_MSK, 423 + RTW_PWR_INTF_ALL_MSK, 424 + RTW_PWR_ADDR_MAC, 425 + RTW_PWR_CMD_WRITE, 0xff, 0xff}, 426 + {0x05f8, 427 + RTW_PWR_CUT_ALL_MSK, 428 + RTW_PWR_INTF_ALL_MSK, 429 + RTW_PWR_ADDR_MAC, 430 + RTW_PWR_CMD_POLLING, 0xff, 0}, 431 + {0x05f9, 432 + RTW_PWR_CUT_ALL_MSK, 433 + RTW_PWR_INTF_ALL_MSK, 434 + RTW_PWR_ADDR_MAC, 435 + RTW_PWR_CMD_POLLING, 0xff, 0}, 436 + {0x05fa, 437 + RTW_PWR_CUT_ALL_MSK, 438 + RTW_PWR_INTF_ALL_MSK, 439 + RTW_PWR_ADDR_MAC, 440 + RTW_PWR_CMD_POLLING, 0xff, 0}, 441 + {0x05fb, 442 + RTW_PWR_CUT_ALL_MSK, 443 + RTW_PWR_INTF_ALL_MSK, 444 + RTW_PWR_ADDR_MAC, 445 + RTW_PWR_CMD_POLLING, 0xff, 0}, 446 + {0x0002, 447 + RTW_PWR_CUT_ALL_MSK, 448 + RTW_PWR_INTF_ALL_MSK, 449 + RTW_PWR_ADDR_MAC, 450 + RTW_PWR_CMD_WRITE, BIT(0), 0}, 451 + {0x0002, 452 + RTW_PWR_CUT_ALL_MSK, 453 + RTW_PWR_INTF_ALL_MSK, 454 + RTW_PWR_ADDR_MAC, 455 + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, 456 + {0x0002, 457 + RTW_PWR_CUT_ALL_MSK, 458 + RTW_PWR_INTF_ALL_MSK, 459 + RTW_PWR_ADDR_MAC, 460 + RTW_PWR_CMD_WRITE, BIT(1), 0}, 461 + {0x0100, 462 + RTW_PWR_CUT_ALL_MSK, 463 + RTW_PWR_INTF_ALL_MSK, 464 + RTW_PWR_ADDR_MAC, 465 + RTW_PWR_CMD_WRITE, 0xff, 0x03}, 466 + {0x0101, 467 + RTW_PWR_CUT_ALL_MSK, 468 + RTW_PWR_INTF_ALL_MSK, 469 + RTW_PWR_ADDR_MAC, 470 + RTW_PWR_CMD_WRITE, BIT(1), 0}, 471 + {0x0093, 472 + RTW_PWR_CUT_ALL_MSK, 473 + RTW_PWR_INTF_SDIO_MSK, 474 + RTW_PWR_ADDR_MAC, 475 + RTW_PWR_CMD_WRITE, 0xff, 0}, 476 + {0x0553, 477 + RTW_PWR_CUT_ALL_MSK, 478 + RTW_PWR_INTF_ALL_MSK, 479 + RTW_PWR_ADDR_MAC, 480 + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 481 + {TRANS_SEQ_END}, 482 + }; 483 + 484 + static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = { 485 + trans_pre_enable_8703b, 486 + trans_carddis_to_cardemu_8703b, 487 + trans_cardemu_to_act_8703b, 488 + NULL 489 + }; 490 + 491 + static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = { 492 + trans_act_to_lps_8703b, 493 + trans_act_to_reset_mcu_8703b, 494 + trans_act_to_cardemu_8703b, 495 + trans_cardemu_to_carddis_8703b, 496 + NULL 497 + }; 498 + 499 + static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { 500 + [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, 501 + .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,}, 502 + }; 503 + 504 + static const struct rtw_page_table page_table_8703b[] = { 505 + {12, 2, 2, 0, 1}, 506 + {12, 2, 2, 0, 1}, 507 + {12, 2, 2, 0, 1}, 508 + {12, 2, 2, 0, 1}, 509 + {12, 2, 2, 0, 1}, 510 + }; 511 + 512 + static const struct rtw_rqpn rqpn_table_8703b[] = { 513 + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 514 + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 515 + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 516 + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 517 + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 518 + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 519 + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 520 + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, 521 + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 522 + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 523 + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 524 + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 525 + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 526 + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 527 + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 528 + }; 529 + 530 + /* Default power index table for RTL8703B, used if EFUSE does not 531 + * contain valid data. Replaces EFUSE data from offset 0x10 (start of 532 + * txpwr_idx_table). 533 + */ 534 + static const u8 rtw8703b_txpwr_idx_table[] = { 535 + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 536 + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02 537 + }; 538 + 539 + static void try_mac_from_devicetree(struct rtw_dev *rtwdev) 540 + { 541 + struct device_node *node = rtwdev->dev->of_node; 542 + struct rtw_efuse *efuse = &rtwdev->efuse; 543 + int ret; 544 + 545 + if (node) { 546 + ret = of_get_mac_address(node, efuse->addr); 547 + if (ret == 0) { 548 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 549 + "got wifi mac address from DT: %pM\n", 550 + efuse->addr); 551 + } 552 + } 553 + } 554 + 555 + #define DBG_EFUSE_FIX(rtwdev, name) \ 556 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \ 557 + # name "=0x%x\n", rtwdev->efuse.name) 558 + 559 + static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 560 + { 561 + struct rtw_efuse *efuse = &rtwdev->efuse; 562 + u8 *pwr = (u8 *)efuse->txpwr_idx_table; 563 + bool valid = false; 564 + int ret; 565 + 566 + ret = rtw8723x_read_efuse(rtwdev, log_map); 567 + if (ret != 0) 568 + return ret; 569 + 570 + if (!is_valid_ether_addr(efuse->addr)) 571 + try_mac_from_devicetree(rtwdev); 572 + 573 + /* If TX power index table in EFUSE is invalid, fall back to 574 + * built-in table. 575 + */ 576 + for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++) 577 + if (pwr[i] != 0xff) { 578 + valid = true; 579 + break; 580 + } 581 + if (!valid) { 582 + for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++) 583 + pwr[i] = rtw8703b_txpwr_idx_table[i]; 584 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 585 + "Replaced invalid EFUSE TX power index table."); 586 + rtw8723x_debug_txpwr_limit(rtwdev, 587 + efuse->txpwr_idx_table, 2); 588 + } 589 + 590 + /* Override invalid antenna settings. */ 591 + if (efuse->bt_setting == 0xff) { 592 + /* shared antenna */ 593 + efuse->bt_setting |= BIT(0); 594 + /* RF path A */ 595 + efuse->bt_setting &= ~BIT(6); 596 + DBG_EFUSE_FIX(rtwdev, bt_setting); 597 + } 598 + 599 + /* Override invalid board options: The coex code incorrectly 600 + * assumes that if bits 6 & 7 are set the board doesn't 601 + * support coex. Regd is also derived from rf_board_option and 602 + * should be 0 if there's no valid data. 603 + */ 604 + if (efuse->rf_board_option == 0xff) { 605 + efuse->regd = 0; 606 + efuse->rf_board_option &= GENMASK(5, 0); 607 + DBG_EFUSE_FIX(rtwdev, rf_board_option); 608 + } 609 + 610 + /* Override invalid crystal cap setting, default comes from 611 + * vendor driver. Chip specific. 612 + */ 613 + if (efuse->crystal_cap == 0xff) { 614 + efuse->crystal_cap = 0x20; 615 + DBG_EFUSE_FIX(rtwdev, crystal_cap); 616 + } 617 + 618 + return 0; 619 + } 620 + 621 + static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev) 622 + { 623 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 624 + u8 path; 625 + 626 + /* TODO: The vendor driver selects these using tables in 627 + * halrf_powertracking_ce.c, functions are called 628 + * get_swing_index and get_cck_swing_index. There the current 629 + * fixed values are only the defaults in case no match is 630 + * found. 631 + */ 632 + dm_info->default_ofdm_index = 30; 633 + dm_info->default_cck_index = 20; 634 + 635 + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { 636 + ewma_thermal_init(&dm_info->avg_thermal[path]); 637 + dm_info->delta_power_index[path] = 0; 638 + } 639 + dm_info->pwr_trk_triggered = false; 640 + dm_info->pwr_trk_init_trigger = true; 641 + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 642 + dm_info->txagc_remnant_cck = 0; 643 + dm_info->txagc_remnant_ofdm = 0; 644 + } 645 + 646 + static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) 647 + { 648 + u8 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; 649 + 650 + /* power on BB/RF domain */ 651 + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, 652 + BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); 653 + rtw_write8_set(rtwdev, REG_RF_CTRL, 654 + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 655 + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780); 656 + rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); 657 + 658 + rtw_phy_load_tables(rtwdev); 659 + 660 + rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); 661 + /* 0xff is from vendor driver, rtw8723d uses 662 + * BIT_HIQ_NO_LMT_EN_ROOT. Comment in vendor driver: "Packet 663 + * in Hi Queue Tx immediately". I wonder if setting all bits 664 + * is really necessary. 665 + */ 666 + rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); 667 + rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); 668 + 669 + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, 670 + xtal_cap | (xtal_cap << 6)); 671 + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); 672 + 673 + /* Init EDCA */ 674 + rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SPEC_SIFS); 675 + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); 676 + rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); /* CCK */ 677 + rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); /* OFDM */ 678 + /* TXOP */ 679 + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); 680 + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); 681 + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); 682 + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); 683 + 684 + /* Init retry */ 685 + rtw_write8(rtwdev, REG_ACKTO, 0x40); 686 + 687 + /* Set up RX aggregation. sdio.c also sets DMA mode, but not 688 + * the burst parameters. 689 + */ 690 + rtw_write8(rtwdev, REG_RXDMA_MODE, 691 + BIT_DMA_MODE | 692 + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) | 693 + FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE)); 694 + 695 + /* Init beacon parameters */ 696 + rtw_write8(rtwdev, REG_BCN_CTRL, 697 + BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); 698 + rtw_write8(rtwdev, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME); 699 + rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1, 700 + TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF); 701 + rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2, 702 + (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xF0) 703 + | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8)); 704 + 705 + /* configure packet burst */ 706 + rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); 707 + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); 708 + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); 709 + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); 710 + rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT_MASK_TXQ_INIT); 711 + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); 712 + 713 + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); 714 + rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); 715 + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); 716 + rtw_write16(rtwdev, REG_ATIMWND, 0x2); 717 + 718 + rtw_phy_init(rtwdev); 719 + 720 + if (rtw_read32_mask(rtwdev, REG_BB_AMP, BIT_MASK_RX_LNA) != 0) { 721 + rtwdev->dm_info.rx_cck_agc_report_type = 1; 722 + } else { 723 + rtwdev->dm_info.rx_cck_agc_report_type = 0; 724 + rtw_warn(rtwdev, "unexpected cck agc report type"); 725 + } 726 + 727 + rtw8723x_lck(rtwdev); 728 + 729 + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 730 + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); 731 + 732 + rtw8703b_pwrtrack_init(rtwdev); 733 + } 734 + 735 + static bool rtw8703b_check_spur_ov_thres(struct rtw_dev *rtwdev, 736 + u32 freq, u32 thres) 737 + { 738 + bool ret = false; 739 + 740 + rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); 741 + rtw_write32(rtwdev, REG_PSDFN, freq); 742 + rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); 743 + 744 + msleep(30); 745 + if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) 746 + ret = true; 747 + 748 + rtw_write32(rtwdev, REG_PSDFN, freq); 749 + rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); 750 + 751 + return ret; 752 + } 753 + 754 + static void rtw8703b_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) 755 + { 756 + if (!notch) { 757 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); 758 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); 759 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 760 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 761 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 762 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); 763 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); 764 + return; 765 + } 766 + 767 + switch (channel) { 768 + case 5: 769 + fallthrough; 770 + case 13: 771 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb); 772 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 773 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x06000000); 774 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 775 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 776 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); 777 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 778 + break; 779 + case 6: 780 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x4); 781 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 782 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000600); 783 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 784 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 785 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); 786 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 787 + break; 788 + case 7: 789 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x3); 790 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 791 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 792 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 793 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 794 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x06000000); 795 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 796 + break; 797 + case 8: 798 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xa); 799 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 800 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 801 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 802 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 803 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000380); 804 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 805 + break; 806 + case 14: 807 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); 808 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 809 + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 810 + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 811 + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 812 + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00180000); 813 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 814 + break; 815 + default: 816 + rtw_warn(rtwdev, 817 + "Bug: Notch filter enable called for channel %u!", 818 + channel); 819 + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); 820 + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); 821 + break; 822 + } 823 + } 824 + 825 + static void rtw8703b_spur_cal(struct rtw_dev *rtwdev, u8 channel) 826 + { 827 + bool notch; 828 + u32 freq; 829 + 830 + if (channel == 5) { 831 + freq = FREQ_CH5; 832 + } else if (channel == 6) { 833 + freq = FREQ_CH6; 834 + } else if (channel == 7) { 835 + freq = FREQ_CH7; 836 + } else if (channel == 8) { 837 + freq = FREQ_CH8; 838 + } else if (channel == 13) { 839 + freq = FREQ_CH13; 840 + } else if (channel == 14) { 841 + freq = FREQ_CH14; 842 + } else { 843 + rtw8703b_cfg_notch(rtwdev, channel, false); 844 + return; 845 + } 846 + 847 + notch = rtw8703b_check_spur_ov_thres(rtwdev, freq, SPUR_THRES); 848 + rtw8703b_cfg_notch(rtwdev, channel, notch); 849 + } 850 + 851 + static void rtw8703b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 852 + { 853 + u32 rf_cfgch_a; 854 + u32 rf_cfgch_b; 855 + /* default value for 20M */ 856 + u32 rf_rck = 0x00000C08; 857 + 858 + rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 859 + rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); 860 + 861 + rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; 862 + rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; 863 + rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); 864 + rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); 865 + 866 + rf_cfgch_a &= ~RFCFGCH_BW_MASK; 867 + switch (bw) { 868 + case RTW_CHANNEL_WIDTH_20: 869 + rf_cfgch_a |= RFCFGCH_BW_20M; 870 + break; 871 + case RTW_CHANNEL_WIDTH_40: 872 + rf_cfgch_a |= RFCFGCH_BW_40M; 873 + rf_rck = 0x00000C4C; 874 + break; 875 + default: 876 + break; 877 + } 878 + 879 + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a); 880 + rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b); 881 + 882 + rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK, rf_rck); 883 + rtw8703b_spur_cal(rtwdev, channel); 884 + } 885 + 886 + #define CCK_DFIR_NR_8703B 2 887 + static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR_8703B] = { 888 + [0] = { 889 + { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x5A7DA0BD }, 890 + { .len = 4, .reg = REG_CCK_DBG, .val = 0x0000223B }, 891 + }, 892 + [1] = { 893 + { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x00000000 }, 894 + { .len = 4, .reg = REG_CCK_DBG, .val = 0x00000000 }, 895 + }, 896 + }; 897 + 898 + static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, 899 + u8 primary_ch_idx) 900 + { 901 + const struct rtw_backup_info *cck_dfir; 902 + int i; 903 + 904 + cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; 905 + 906 + for (i = 0; i < CCK_DFIR_NR_8703B; i++, cck_dfir++) 907 + rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); 908 + 909 + switch (bw) { 910 + case RTW_CHANNEL_WIDTH_20: 911 + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); 912 + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); 913 + rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE, 914 + GENMASK(31, 20), 0x0); 915 + rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000); 916 + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000); 917 + break; 918 + case RTW_CHANNEL_WIDTH_40: 919 + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); 920 + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); 921 + rtw_write32(rtwdev, REG_BBRX_DFIR, 0x40100000); 922 + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x51F60000); 923 + rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, 924 + primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0); 925 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, 0xC00, 926 + primary_ch_idx == RTW_SC_20_UPPER ? 2 : 1); 927 + 928 + rtw_write32_mask(rtwdev, REG_BB_PWR_SAV5_11N, GENMASK(27, 26), 929 + primary_ch_idx == RTW_SC_20_UPPER ? 1 : 2); 930 + break; 931 + default: 932 + break; 933 + } 934 + } 935 + 936 + static void rtw8703b_set_channel(struct rtw_dev *rtwdev, u8 channel, 937 + u8 bw, u8 primary_chan_idx) 938 + { 939 + rtw8703b_set_channel_rf(rtwdev, channel, bw); 940 + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); 941 + rtw8703b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 942 + } 943 + 944 + /* Not all indices are valid, based on available data. None of the 945 + * known valid values are positive, so use 0x7f as "invalid". 946 + */ 947 + #define LNA_IDX_INVALID 0x7f 948 + static const s8 lna_gain_table[16] = { 949 + -2, LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, 950 + -6, LNA_IDX_INVALID, LNA_IDX_INVALID, -19, 951 + -32, LNA_IDX_INVALID, -36, -42, 952 + LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, -48, 953 + }; 954 + 955 + static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) 956 + { 957 + s8 lna_gain = 0; 958 + 959 + if (lna_idx < ARRAY_SIZE(lna_gain_table)) 960 + lna_gain = lna_gain_table[lna_idx]; 961 + 962 + if (lna_gain >= 0) { 963 + rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); 964 + return -120; 965 + } 966 + 967 + return lna_gain - 2 * vga_idx; 968 + } 969 + 970 + static void query_phy_status_cck(struct rtw_dev *rtwdev, u8 *phy_raw, 971 + struct rtw_rx_pkt_stat *pkt_stat) 972 + { 973 + struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; 974 + u8 vga_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & VGA_BITS; 975 + u8 lna_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & LNA_L_BITS; 976 + s8 rx_power; 977 + 978 + if (rtwdev->dm_info.rx_cck_agc_report_type == 1) 979 + lna_idx = FIELD_PREP(BIT_LNA_H_MASK, 980 + phy_status->cck_rpt_b_ofdm_cfosho_b & LNA_H_BIT) 981 + | FIELD_PREP(BIT_LNA_L_MASK, lna_idx); 982 + else 983 + lna_idx = FIELD_PREP(BIT_LNA_L_MASK, lna_idx); 984 + rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx); 985 + 986 + pkt_stat->rx_power[RF_PATH_A] = rx_power; 987 + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 988 + rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi; 989 + pkt_stat->signal_power = rx_power; 990 + } 991 + 992 + static void query_phy_status_ofdm(struct rtw_dev *rtwdev, u8 *phy_raw, 993 + struct rtw_rx_pkt_stat *pkt_stat) 994 + { 995 + struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; 996 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 997 + s8 val_s8; 998 + 999 + val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F; 1000 + pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110; 1001 + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 1002 + pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2); 1003 + 1004 + /* signal power reported by HW */ 1005 + val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1; 1006 + pkt_stat->signal_power = (val_s8 & 0x7f) - 110; 1007 + 1008 + pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A]; 1009 + pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A]; 1010 + 1011 + dm_info->curr_rx_rate = pkt_stat->rate; 1012 + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 1013 + dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; 1014 + /* convert to KHz (used only for debugfs) */ 1015 + dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; 1016 + 1017 + /* (EVM value as s8 / 2) is dbm, should usually be in -33 to 0 1018 + * range. rx_evm_dbm needs the absolute (positive) value. 1019 + */ 1020 + val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A]; 1021 + val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64); 1022 + val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ 1023 + dm_info->rx_evm_dbm[RF_PATH_A] = val_s8; 1024 + } 1025 + 1026 + static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 1027 + struct rtw_rx_pkt_stat *pkt_stat) 1028 + { 1029 + if (pkt_stat->rate <= DESC_RATE11M) 1030 + query_phy_status_cck(rtwdev, phy_status, pkt_stat); 1031 + else 1032 + query_phy_status_ofdm(rtwdev, phy_status, pkt_stat); 1033 + } 1034 + 1035 + static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, 1036 + struct rtw_rx_pkt_stat *pkt_stat, 1037 + struct ieee80211_rx_status *rx_status) 1038 + { 1039 + struct ieee80211_hdr *hdr; 1040 + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; 1041 + u8 *phy_status = NULL; 1042 + 1043 + memset(pkt_stat, 0, sizeof(*pkt_stat)); 1044 + 1045 + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); 1046 + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); 1047 + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); 1048 + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && 1049 + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; 1050 + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); 1051 + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); 1052 + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); 1053 + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); 1054 + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); 1055 + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); 1056 + pkt_stat->ppdu_cnt = 0; 1057 + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); 1058 + 1059 + pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B; 1060 + 1061 + if (pkt_stat->is_c2h) 1062 + return; 1063 + 1064 + hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + 1065 + pkt_stat->drv_info_sz); 1066 + 1067 + pkt_stat->bw = GET_RX_DESC_BW(rx_desc); 1068 + 1069 + if (pkt_stat->phy_status) { 1070 + phy_status = rx_desc + desc_sz + pkt_stat->shift; 1071 + query_phy_status(rtwdev, phy_status, pkt_stat); 1072 + } 1073 + 1074 + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); 1075 + 1076 + /* Rtl8723cs driver checks for size < 14 or size > 8192 and 1077 + * simply drops the packet. Maybe this should go into 1078 + * rtw_rx_fill_rx_status()? 1079 + */ 1080 + if (pkt_stat->pkt_len == 0) { 1081 + rx_status->flag |= RX_FLAG_NO_PSDU; 1082 + rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); 1083 + } 1084 + } 1085 + 1086 + #define ADDA_ON_VAL_8703B 0x03c00014 1087 + 1088 + static 1089 + void rtw8703b_iqk_config_mac(struct rtw_dev *rtwdev, 1090 + const struct rtw8723x_iqk_backup_regs *backup) 1091 + { 1092 + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[0], 0x3F); 1093 + for (int i = 1; i < RTW8723X_IQK_MAC8_REG_NUM; i++) 1094 + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], 1095 + backup->mac8[i] & (~BIT(3))); 1096 + } 1097 + 1098 + #define IQK_LTE_WRITE_VAL_8703B 0x00007700 1099 + #define IQK_DELAY_TIME_8703B 4 1100 + 1101 + static void rtw8703b_iqk_one_shot(struct rtw_dev *rtwdev, bool tx) 1102 + { 1103 + u32 regval; 1104 + ktime_t t; 1105 + s64 dur; 1106 + int ret; 1107 + 1108 + /* enter IQK mode */ 1109 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 1110 + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); 1111 + 1112 + /* One shot, LOK & IQK */ 1113 + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); 1114 + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); 1115 + 1116 + t = ktime_get(); 1117 + msleep(IQK_DELAY_TIME_8703B); 1118 + ret = read_poll_timeout(rtw_read32, regval, regval != 0, 1000, 1119 + 100000, false, rtwdev, 1120 + REG_IQK_RDY); 1121 + dur = ktime_us_delta(ktime_get(), t); 1122 + 1123 + if (ret) 1124 + rtw_warn(rtwdev, "[IQK] %s timed out after %lldus!\n", 1125 + tx ? "TX" : "RX", dur); 1126 + else 1127 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1128 + "[IQK] %s done after %lldus\n", 1129 + tx ? "TX" : "RX", dur); 1130 + } 1131 + 1132 + static void rtw8703b_iqk_txrx_path_post(struct rtw_dev *rtwdev, 1133 + const struct rtw8723x_iqk_backup_regs *backup) 1134 + { 1135 + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); 1136 + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); 1137 + 1138 + /* leave IQK mode */ 1139 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 1140 + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x0); 1141 + } 1142 + 1143 + static u8 rtw8703b_iqk_check_tx_failed(struct rtw_dev *rtwdev) 1144 + { 1145 + s32 tx_x, tx_y; 1146 + u32 tx_fail; 1147 + 1148 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", 1149 + rtw_read32(rtwdev, REG_IQK_RES_RY)); 1150 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", 1151 + rtw_read32(rtwdev, REG_IQK_RES_TX), 1152 + rtw_read32(rtwdev, REG_IQK_RES_TY)); 1153 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1154 + "[IQK] 0xe90(before IQK) = 0x%x, 0xe98(after IQK) = 0x%x\n", 1155 + rtw_read32(rtwdev, REG_IQK_RDY), 1156 + rtw_read32(rtwdev, 0xe98)); 1157 + 1158 + tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); 1159 + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 1160 + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 1161 + 1162 + if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) 1163 + return IQK_TX_OK; 1164 + 1165 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A TX IQK failed\n"); 1166 + 1167 + return 0; 1168 + } 1169 + 1170 + static u8 rtw8703b_iqk_check_rx_failed(struct rtw_dev *rtwdev) 1171 + { 1172 + s32 rx_x, rx_y; 1173 + u32 rx_fail; 1174 + 1175 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", 1176 + rtw_read32(rtwdev, REG_IQK_RES_RX), 1177 + rtw_read32(rtwdev, REG_IQK_RES_RY)); 1178 + 1179 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1180 + "[IQK] 0xea0(before IQK) = 0x%x, 0xea8(after IQK) = 0x%x\n", 1181 + rtw_read32(rtwdev, 0xea0), 1182 + rtw_read32(rtwdev, 0xea8)); 1183 + 1184 + rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); 1185 + rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); 1186 + rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); 1187 + rx_y = abs(iqkxy_to_s32(rx_y)); 1188 + 1189 + if (!rx_fail && rx_x != IQK_RX_X_ERR && rx_y != IQK_RX_Y_ERR && 1190 + rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && 1191 + rx_y < IQK_RX_Y_LMT) 1192 + return IQK_RX_OK; 1193 + 1194 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A RX IQK failed\n"); 1195 + 1196 + return 0; 1197 + } 1198 + 1199 + static u8 rtw8703b_iqk_tx_path(struct rtw_dev *rtwdev, 1200 + const struct rtw8723x_iqk_backup_regs *backup) 1201 + { 1202 + u8 status; 1203 + 1204 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n"); 1205 + 1206 + /* IQK setting */ 1207 + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); 1208 + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 1209 + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); 1210 + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); 1211 + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); 1212 + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); 1213 + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f); 1214 + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); 1215 + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); 1216 + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); 1217 + 1218 + /* LO calibration setting */ 1219 + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); 1220 + 1221 + /* leave IQK mode */ 1222 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); 1223 + 1224 + /* PA, PAD setting */ 1225 + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); 1226 + rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x7); 1227 + rtw_write_rf(rtwdev, RF_PATH_A, 0x7f, RFREG_MASK, 0xd400); 1228 + 1229 + rtw8703b_iqk_one_shot(rtwdev, true); 1230 + status = rtw8703b_iqk_check_tx_failed(rtwdev); 1231 + 1232 + rtw8703b_iqk_txrx_path_post(rtwdev, backup); 1233 + 1234 + return status; 1235 + } 1236 + 1237 + static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev, 1238 + const struct rtw8723x_iqk_backup_regs *backup) 1239 + { 1240 + u8 status; 1241 + u32 tx_x, tx_y; 1242 + 1243 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 1!\n"); 1244 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK1 = 0x%x\n", 1245 + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 1246 + rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x99000000); 1247 + 1248 + /* disable IQC mode */ 1249 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 1250 + 1251 + /* IQK setting */ 1252 + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); 1253 + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 1254 + 1255 + /* path IQK setting */ 1256 + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); 1257 + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); 1258 + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); 1259 + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); 1260 + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f); 1261 + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); 1262 + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000); 1263 + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); 1264 + 1265 + /* LOK setting */ 1266 + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); 1267 + 1268 + /* RX IQK mode */ 1269 + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); 1270 + rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); 1271 + rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); 1272 + rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0x57db7); 1273 + 1274 + rtw8703b_iqk_one_shot(rtwdev, true); 1275 + /* leave IQK mode */ 1276 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); 1277 + status = rtw8703b_iqk_check_tx_failed(rtwdev); 1278 + 1279 + if (!status) 1280 + goto restore; 1281 + 1282 + /* second round */ 1283 + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 1284 + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 1285 + 1286 + rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); 1287 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", 1288 + rtw_read32(rtwdev, REG_TXIQK_11N), 1289 + BIT_SET_TXIQK_11N(tx_x, tx_y)); 1290 + 1291 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 2!\n"); 1292 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK 2 = 0x%x\n", 1293 + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 1294 + 1295 + /* IQK setting */ 1296 + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 1297 + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); 1298 + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); 1299 + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); 1300 + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); 1301 + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82110000); 1302 + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160c1f); 1303 + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); 1304 + rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); 1305 + 1306 + /* LO calibration setting */ 1307 + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); 1308 + 1309 + /* leave IQK mode */ 1310 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); 1311 + /* modify RX IQK mode table */ 1312 + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); 1313 + /* RF_RCK_OS, RF_TXPA_G1, RF_TXPA_G2 */ 1314 + rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); 1315 + rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); 1316 + rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0xf7d77); 1317 + 1318 + /* PA, PAD setting */ 1319 + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); 1320 + rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x5); 1321 + 1322 + rtw8703b_iqk_one_shot(rtwdev, false); 1323 + status |= rtw8703b_iqk_check_rx_failed(rtwdev); 1324 + 1325 + restore: 1326 + rtw8703b_iqk_txrx_path_post(rtwdev, backup); 1327 + 1328 + return status; 1329 + } 1330 + 1331 + static 1332 + void rtw8703b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, 1333 + const struct rtw8723x_iqk_backup_regs *backup) 1334 + { 1335 + u32 i; 1336 + u8 a_ok; 1337 + 1338 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1339 + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); 1340 + 1341 + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8703B); 1342 + rtw8703b_iqk_config_mac(rtwdev, backup); 1343 + rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); 1344 + rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05600); 1345 + rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); 1346 + rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204000); 1347 + 1348 + for (i = 0; i < PATH_IQK_RETRY; i++) { 1349 + a_ok = rtw8703b_iqk_tx_path(rtwdev, backup); 1350 + if (a_ok == IQK_TX_OK) { 1351 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1352 + "[IQK] path A TX IQK success!\n"); 1353 + result[t][IQK_S1_TX_X] = 1354 + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, 1355 + BIT_MASK_RES_TX); 1356 + result[t][IQK_S1_TX_Y] = 1357 + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, 1358 + BIT_MASK_RES_TY); 1359 + break; 1360 + } 1361 + 1362 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n"); 1363 + result[t][IQK_S1_TX_X] = 0x100; 1364 + result[t][IQK_S1_TX_Y] = 0x0; 1365 + } 1366 + 1367 + for (i = 0; i < PATH_IQK_RETRY; i++) { 1368 + a_ok = rtw8703b_iqk_rx_path(rtwdev, backup); 1369 + if (a_ok == (IQK_TX_OK | IQK_RX_OK)) { 1370 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1371 + "[IQK] path A RX IQK success!\n"); 1372 + result[t][IQK_S1_RX_X] = 1373 + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, 1374 + BIT_MASK_RES_RX); 1375 + result[t][IQK_S1_RX_Y] = 1376 + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, 1377 + BIT_MASK_RES_RY); 1378 + break; 1379 + } 1380 + 1381 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n"); 1382 + result[t][IQK_S1_RX_X] = 0x100; 1383 + result[t][IQK_S1_RX_Y] = 0x0; 1384 + } 1385 + 1386 + if (a_ok == 0x0) 1387 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n"); 1388 + 1389 + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 1390 + mdelay(1); 1391 + } 1392 + 1393 + static 1394 + void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[]) 1395 + { 1396 + u32 tmp_rx_iqi = 0x40000100 & GENMASK(31, 16); 1397 + s32 tx1_a, tx1_a_ext; 1398 + s32 tx1_c, tx1_c_ext; 1399 + s32 oldval_1; 1400 + s32 x, y; 1401 + 1402 + if (result[IQK_S1_TX_X] == 0) 1403 + return; 1404 + 1405 + oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 1406 + BIT_MASK_TXIQ_ELM_D); 1407 + 1408 + x = iqkxy_to_s32(result[IQK_S1_TX_X]); 1409 + tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); 1410 + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 1411 + BIT_MASK_TXIQ_ELM_A, tx1_a); 1412 + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, 1413 + BIT_MASK_OFDM0_EXT_A, tx1_a_ext); 1414 + 1415 + y = iqkxy_to_s32(result[IQK_S1_TX_Y]); 1416 + tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); 1417 + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 1418 + BIT_SET_TXIQ_ELM_C1(tx1_c)); 1419 + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 1420 + BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); 1421 + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, 1422 + BIT_MASK_OFDM0_EXT_C, tx1_c_ext); 1423 + 1424 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1425 + "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", 1426 + x, tx1_a, oldval_1); 1427 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1428 + "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); 1429 + 1430 + if (result[IQK_S1_RX_X] == 0) 1431 + return; 1432 + 1433 + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]); 1434 + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]); 1435 + rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi); 1436 + rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, 1437 + BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); 1438 + } 1439 + 1440 + static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev) 1441 + { 1442 + /* For some reason path A is called S1 and B S0 in shared 1443 + * rtw88 calibration data. 1444 + */ 1445 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1446 + struct rtw8723x_iqk_backup_regs backup; 1447 + u8 final_candidate = IQK_ROUND_INVALID; 1448 + s32 result[IQK_ROUND_SIZE][IQK_NR]; 1449 + bool good; 1450 + u8 i, j; 1451 + 1452 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n"); 1453 + 1454 + memset(result, 0, sizeof(result)); 1455 + 1456 + rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); 1457 + rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); 1458 + rtw8723x_iqk_backup_regs(rtwdev, &backup); 1459 + 1460 + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { 1461 + rtw8723x_iqk_config_path_ctrl(rtwdev); 1462 + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); 1463 + 1464 + rtw8703b_iqk_one_round(rtwdev, result, i, &backup); 1465 + 1466 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1467 + "[IQK] back to BB mode, load original values!\n"); 1468 + if (i > IQK_ROUND_0) 1469 + rtw8723x_iqk_restore_regs(rtwdev, &backup); 1470 + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); 1471 + rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); 1472 + 1473 + for (j = IQK_ROUND_0; j < i; j++) { 1474 + good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); 1475 + 1476 + if (good) { 1477 + final_candidate = j; 1478 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1479 + "[IQK] cmp %d:%d final_candidate is %x\n", 1480 + j, i, final_candidate); 1481 + goto iqk_done; 1482 + } 1483 + } 1484 + } 1485 + 1486 + if (final_candidate == IQK_ROUND_INVALID) { 1487 + s32 reg_tmp = 0; 1488 + 1489 + for (i = 0; i < IQK_NR; i++) 1490 + reg_tmp += result[IQK_ROUND_HYBRID][i]; 1491 + 1492 + if (reg_tmp != 0) { 1493 + final_candidate = IQK_ROUND_HYBRID; 1494 + } else { 1495 + WARN(1, "IQK failed\n"); 1496 + goto out; 1497 + } 1498 + } 1499 + 1500 + iqk_done: 1501 + /* only path A is calibrated in rtl8703b */ 1502 + rtw8703b_iqk_fill_a_matrix(rtwdev, result[final_candidate]); 1503 + 1504 + dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; 1505 + dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; 1506 + dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; 1507 + dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; 1508 + dm_info->iqk.done = true; 1509 + 1510 + out: 1511 + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); 1512 + 1513 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", 1514 + final_candidate); 1515 + 1516 + for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) 1517 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1518 + "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", 1519 + i, 1520 + result[i][0], result[i][1], result[i][2], result[i][3], 1521 + result[i][4], result[i][5], result[i][6], result[i][7], 1522 + final_candidate == i ? "(final candidate)" : ""); 1523 + 1524 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1525 + "[IQK] 0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", 1526 + rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), 1527 + rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), 1528 + rtw_read32(rtwdev, REG_A_RXIQI), 1529 + rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); 1530 + rtw_dbg(rtwdev, RTW_DBG_RFK, 1531 + "[IQK] 0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", 1532 + rtw_read32(rtwdev, REG_TXIQ_AB_S0), 1533 + rtw_read32(rtwdev, REG_TXIQ_CD_S0), 1534 + rtw_read32(rtwdev, REG_RXIQ_AB_S0)); 1535 + 1536 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Finished.\n"); 1537 + } 1538 + 1539 + static void rtw8703b_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, 1540 + u32 ofdm_swing, u8 rf_path) 1541 + { 1542 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1543 + s32 ele_A, ele_D, ele_C; 1544 + s32 ele_A_ext, ele_C_ext, ele_D_ext; 1545 + s32 iqk_result_x; 1546 + s32 iqk_result_y; 1547 + s32 value32; 1548 + 1549 + switch (rf_path) { 1550 + default: 1551 + case RF_PATH_A: 1552 + iqk_result_x = dm_info->iqk.result.s1_x; 1553 + iqk_result_y = dm_info->iqk.result.s1_y; 1554 + break; 1555 + case RF_PATH_B: 1556 + iqk_result_x = dm_info->iqk.result.s0_x; 1557 + iqk_result_y = dm_info->iqk.result.s0_y; 1558 + break; 1559 + } 1560 + 1561 + /* new element D */ 1562 + ele_D = OFDM_SWING_D(ofdm_swing); 1563 + iqk_mult(iqk_result_x, ele_D, &ele_D_ext); 1564 + /* new element A */ 1565 + iqk_result_x = iqkxy_to_s32(iqk_result_x); 1566 + ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); 1567 + /* new element C */ 1568 + iqk_result_y = iqkxy_to_s32(iqk_result_y); 1569 + ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); 1570 + 1571 + switch (rf_path) { 1572 + case RF_PATH_A: 1573 + default: 1574 + /* write new elements A, C, D, and element B is always 0 */ 1575 + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); 1576 + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); 1577 + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); 1578 + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 1579 + value32); 1580 + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1581 + value32 &= ~BIT_MASK_OFDM0_EXTS; 1582 + value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); 1583 + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1584 + break; 1585 + 1586 + case RF_PATH_B: 1587 + /* write new elements A, C, D, and element B is always 0 */ 1588 + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); 1589 + rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, value32); 1590 + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); 1591 + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, 1592 + value32); 1593 + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1594 + value32 &= ~BIT_MASK_OFDM0_EXTS_B; 1595 + value32 |= BIT_SET_OFDM0_EXTS_B(ele_A_ext, ele_C_ext, ele_D_ext); 1596 + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1597 + break; 1598 + } 1599 + } 1600 + 1601 + static void rtw8703b_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, 1602 + u8 rf_path) 1603 + { 1604 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1605 + s32 value32; 1606 + u32 ofdm_swing; 1607 + 1608 + ofdm_index = clamp_t(s8, ofdm_index, 0, RTW_OFDM_SWING_TABLE_SIZE - 1); 1609 + 1610 + ofdm_swing = rtw8703b_ofdm_swing_table[ofdm_index]; 1611 + 1612 + if (dm_info->iqk.done) { 1613 + rtw8703b_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); 1614 + return; 1615 + } 1616 + 1617 + switch (rf_path) { 1618 + case RF_PATH_A: 1619 + default: 1620 + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); 1621 + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 1622 + 0x00); 1623 + 1624 + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1625 + value32 &= ~BIT_MASK_OFDM0_EXTS; 1626 + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1627 + break; 1628 + 1629 + case RF_PATH_B: 1630 + rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, ofdm_swing); 1631 + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, 1632 + 0x00); 1633 + 1634 + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1635 + value32 &= ~BIT_MASK_OFDM0_EXTS_B; 1636 + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1637 + break; 1638 + } 1639 + } 1640 + 1641 + static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, 1642 + s8 txagc_idx) 1643 + { 1644 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1645 + 1646 + dm_info->txagc_remnant_ofdm = txagc_idx; 1647 + 1648 + /* Only path A is calibrated for rtl8703b */ 1649 + rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); 1650 + } 1651 + 1652 + static void rtw8703b_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, 1653 + s8 txagc_idx) 1654 + { 1655 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1656 + 1657 + dm_info->txagc_remnant_cck = txagc_idx; 1658 + 1659 + swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1); 1660 + 1661 + BUILD_BUG_ON(ARRAY_SIZE(rtw8703b_cck_pwr_regs) 1662 + != ARRAY_SIZE(rtw8703b_cck_swing_table[0])); 1663 + 1664 + for (int i = 0; i < ARRAY_SIZE(rtw8703b_cck_pwr_regs); i++) 1665 + rtw_write8(rtwdev, rtw8703b_cck_pwr_regs[i], 1666 + rtw8703b_cck_swing_table[swing_idx][i]); 1667 + } 1668 + 1669 + static void rtw8703b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) 1670 + { 1671 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1672 + struct rtw_hal *hal = &rtwdev->hal; 1673 + u8 limit_ofdm; 1674 + u8 limit_cck = 21; 1675 + s8 final_ofdm_swing_index; 1676 + s8 final_cck_swing_index; 1677 + 1678 + limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); 1679 + 1680 + final_ofdm_swing_index = dm_info->default_ofdm_index + 1681 + dm_info->delta_power_index[path]; 1682 + final_cck_swing_index = dm_info->default_cck_index + 1683 + dm_info->delta_power_index[path]; 1684 + 1685 + if (final_ofdm_swing_index > limit_ofdm) 1686 + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, 1687 + final_ofdm_swing_index - limit_ofdm); 1688 + else if (final_ofdm_swing_index < 0) 1689 + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, 0, 1690 + final_ofdm_swing_index); 1691 + else 1692 + rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); 1693 + 1694 + if (final_cck_swing_index > limit_cck) 1695 + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, limit_cck, 1696 + final_cck_swing_index - limit_cck); 1697 + else if (final_cck_swing_index < 0) 1698 + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, 0, 1699 + final_cck_swing_index); 1700 + else 1701 + rtw8703b_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); 1702 + 1703 + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); 1704 + } 1705 + 1706 + static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev) 1707 + { 1708 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1709 + struct rtw_swing_table swing_table; 1710 + u8 thermal_value, delta, path; 1711 + bool do_iqk = false; 1712 + 1713 + rtw_phy_config_swing_table(rtwdev, &swing_table); 1714 + 1715 + if (rtwdev->efuse.thermal_meter[0] == 0xff) 1716 + return; 1717 + 1718 + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); 1719 + 1720 + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); 1721 + 1722 + do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); 1723 + 1724 + if (do_iqk) 1725 + rtw8723x_lck(rtwdev); 1726 + 1727 + if (dm_info->pwr_trk_init_trigger) 1728 + dm_info->pwr_trk_init_trigger = false; 1729 + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, 1730 + RF_PATH_A)) 1731 + goto iqk; 1732 + 1733 + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); 1734 + 1735 + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); 1736 + 1737 + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 1738 + s8 delta_cur, delta_last; 1739 + 1740 + delta_last = dm_info->delta_power_index[path]; 1741 + delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, 1742 + path, RF_PATH_A, delta); 1743 + if (delta_last == delta_cur) 1744 + continue; 1745 + 1746 + dm_info->delta_power_index[path] = delta_cur; 1747 + rtw8703b_pwrtrack_set(rtwdev, path); 1748 + } 1749 + 1750 + rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); 1751 + 1752 + iqk: 1753 + if (do_iqk) 1754 + rtw8703b_phy_calibration(rtwdev); 1755 + } 1756 + 1757 + static void rtw8703b_pwr_track(struct rtw_dev *rtwdev) 1758 + { 1759 + struct rtw_efuse *efuse = &rtwdev->efuse; 1760 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1761 + 1762 + if (efuse->power_track_type != 0) { 1763 + rtw_warn(rtwdev, "unsupported power track type"); 1764 + return; 1765 + } 1766 + 1767 + if (!dm_info->pwr_trk_triggered) { 1768 + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 1769 + GENMASK(17, 16), 0x03); 1770 + dm_info->pwr_trk_triggered = true; 1771 + return; 1772 + } 1773 + 1774 + rtw8703b_phy_pwrtrack(rtwdev); 1775 + dm_info->pwr_trk_triggered = false; 1776 + } 1777 + 1778 + static void rtw8703b_coex_set_gnt_fix(struct rtw_dev *rtwdev) 1779 + { 1780 + } 1781 + 1782 + static void rtw8703b_coex_set_gnt_debug(struct rtw_dev *rtwdev) 1783 + { 1784 + } 1785 + 1786 + static void rtw8703b_coex_set_rfe_type(struct rtw_dev *rtwdev) 1787 + { 1788 + struct rtw_coex *coex = &rtwdev->coex; 1789 + struct rtw_coex_rfe *coex_rfe = &coex->rfe; 1790 + 1791 + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; 1792 + coex_rfe->ant_switch_polarity = 0; 1793 + coex_rfe->ant_switch_exist = false; 1794 + coex_rfe->ant_switch_with_bt = false; 1795 + coex_rfe->ant_switch_diversity = false; 1796 + coex_rfe->wlg_at_btg = true; 1797 + 1798 + /* disable LTE coex on wifi side */ 1799 + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); 1800 + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); 1801 + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); 1802 + } 1803 + 1804 + static void rtw8703b_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 1805 + { 1806 + } 1807 + 1808 + static void rtw8703b_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 1809 + { 1810 + } 1811 + 1812 + static const u8 rtw8703b_pwrtrk_2gb_n[] = { 1813 + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 1814 + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 1815 + }; 1816 + 1817 + static const u8 rtw8703b_pwrtrk_2gb_p[] = { 1818 + 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, 1819 + 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 1820 + }; 1821 + 1822 + static const u8 rtw8703b_pwrtrk_2ga_n[] = { 1823 + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 1824 + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 1825 + }; 1826 + 1827 + static const u8 rtw8703b_pwrtrk_2ga_p[] = { 1828 + 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, 1829 + 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 1830 + }; 1831 + 1832 + static const u8 rtw8703b_pwrtrk_2g_cck_b_n[] = { 1833 + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 1834 + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 1835 + }; 1836 + 1837 + static const u8 rtw8703b_pwrtrk_2g_cck_b_p[] = { 1838 + 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 1839 + 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 1840 + }; 1841 + 1842 + static const u8 rtw8703b_pwrtrk_2g_cck_a_n[] = { 1843 + 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 1844 + 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 1845 + }; 1846 + 1847 + static const u8 rtw8703b_pwrtrk_2g_cck_a_p[] = { 1848 + 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 1849 + 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 1850 + }; 1851 + 1852 + static const s8 rtw8703b_pwrtrk_xtal_n[] = { 1853 + 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -3, -3, -3, -3, -3, 1854 + -4, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 1855 + }; 1856 + 1857 + static const s8 rtw8703b_pwrtrk_xtal_p[] = { 1858 + 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, -1, -1, -1, 1859 + -2, -3, -7, -9, -10, -11, -14, -16, -18, -20, -22, -24, -26, -28, -30 1860 + }; 1861 + 1862 + static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = { 1863 + .pwrtrk_2gb_n = rtw8703b_pwrtrk_2gb_n, 1864 + .pwrtrk_2gb_p = rtw8703b_pwrtrk_2gb_p, 1865 + .pwrtrk_2ga_n = rtw8703b_pwrtrk_2ga_n, 1866 + .pwrtrk_2ga_p = rtw8703b_pwrtrk_2ga_p, 1867 + .pwrtrk_2g_cckb_n = rtw8703b_pwrtrk_2g_cck_b_n, 1868 + .pwrtrk_2g_cckb_p = rtw8703b_pwrtrk_2g_cck_b_p, 1869 + .pwrtrk_2g_ccka_n = rtw8703b_pwrtrk_2g_cck_a_n, 1870 + .pwrtrk_2g_ccka_p = rtw8703b_pwrtrk_2g_cck_a_p, 1871 + .pwrtrk_xtal_n = rtw8703b_pwrtrk_xtal_n, 1872 + .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, 1873 + }; 1874 + 1875 + /* Shared-Antenna Coex Table */ 1876 + static const struct coex_table_para table_sant_8703b[] = { 1877 + {0xffffffff, 0xffffffff}, /* case-0 */ 1878 + {0x55555555, 0x55555555}, 1879 + {0x66555555, 0x66555555}, 1880 + {0xaaaaaaaa, 0xaaaaaaaa}, 1881 + {0x5a5a5a5a, 0x5a5a5a5a}, 1882 + {0xfafafafa, 0xfafafafa}, /* case-5 */ 1883 + {0x6a5a5555, 0xaaaaaaaa}, 1884 + {0x6a5a56aa, 0x6a5a56aa}, 1885 + {0x6a5a5a5a, 0x6a5a5a5a}, 1886 + {0x66555555, 0x5a5a5a5a}, 1887 + {0x66555555, 0x6a5a5a5a}, /* case-10 */ 1888 + {0x66555555, 0x6a5a5aaa}, 1889 + {0x66555555, 0x5a5a5aaa}, 1890 + {0x66555555, 0x6aaa5aaa}, 1891 + {0x66555555, 0xaaaa5aaa}, 1892 + {0x66555555, 0xaaaaaaaa}, /* case-15 */ 1893 + {0xffff55ff, 0xfafafafa}, 1894 + {0xffff55ff, 0x6afa5afa}, 1895 + {0xaaffffaa, 0xfafafafa}, 1896 + {0xaa5555aa, 0x5a5a5a5a}, 1897 + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 1898 + {0xaa5555aa, 0xaaaaaaaa}, 1899 + {0xffffffff, 0x5a5a5a5a}, 1900 + {0xffffffff, 0x5a5a5a5a}, 1901 + {0xffffffff, 0x55555555}, 1902 + {0xffffffff, 0x5a5a5aaa}, /* case-25 */ 1903 + {0x55555555, 0x5a5a5a5a}, 1904 + {0x55555555, 0xaaaaaaaa}, 1905 + {0x55555555, 0x6a5a6a5a}, 1906 + {0x66556655, 0x66556655}, 1907 + {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ 1908 + {0xffffffff, 0x5aaa5aaa}, 1909 + {0x56555555, 0x5a5a5aaa}, 1910 + }; 1911 + 1912 + /* Shared-Antenna TDMA */ 1913 + static const struct coex_tdma_para tdma_sant_8703b[] = { 1914 + { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 1915 + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 1916 + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 1917 + { {0x61, 0x30, 0x03, 0x11, 0x11} }, 1918 + { {0x61, 0x20, 0x03, 0x11, 0x11} }, 1919 + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ 1920 + { {0x61, 0x45, 0x03, 0x11, 0x10} }, 1921 + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, 1922 + { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1923 + { {0x61, 0x20, 0x03, 0x11, 0x10} }, 1924 + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 1925 + { {0x61, 0x08, 0x03, 0x11, 0x14} }, 1926 + { {0x61, 0x08, 0x03, 0x10, 0x14} }, 1927 + { {0x51, 0x08, 0x03, 0x10, 0x54} }, 1928 + { {0x51, 0x08, 0x03, 0x10, 0x55} }, 1929 + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ 1930 + { {0x51, 0x45, 0x03, 0x10, 0x50} }, 1931 + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 1932 + { {0x51, 0x30, 0x03, 0x10, 0x50} }, 1933 + { {0x51, 0x20, 0x03, 0x10, 0x50} }, 1934 + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ 1935 + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 1936 + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, 1937 + { {0x55, 0x08, 0x03, 0x10, 0x54} }, 1938 + { {0x65, 0x10, 0x03, 0x11, 0x10} }, 1939 + { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ 1940 + { {0x51, 0x08, 0x03, 0x10, 0x50} }, 1941 + { {0x61, 0x08, 0x03, 0x11, 0x11} }, 1942 + }; 1943 + 1944 + static struct rtw_chip_ops rtw8703b_ops = { 1945 + .mac_init = rtw8723x_mac_init, 1946 + .dump_fw_crash = NULL, 1947 + .shutdown = NULL, 1948 + .read_efuse = rtw8703b_read_efuse, 1949 + .phy_set_param = rtw8703b_phy_set_param, 1950 + .set_channel = rtw8703b_set_channel, 1951 + .query_rx_desc = rtw8703b_query_rx_desc, 1952 + .read_rf = rtw_phy_read_rf_sipi, 1953 + .write_rf = rtw_phy_write_rf_reg_sipi, 1954 + .set_tx_power_index = rtw8723x_set_tx_power_index, 1955 + .set_antenna = NULL, 1956 + .cfg_ldo25 = rtw8723x_cfg_ldo25, 1957 + .efuse_grant = rtw8723x_efuse_grant, 1958 + .false_alarm_statistics = rtw8723x_false_alarm_statistics, 1959 + .phy_calibration = rtw8703b_phy_calibration, 1960 + .dpk_track = NULL, 1961 + /* 8723d uses REG_CSRATIO to set dm_info.cck_pd_default, which 1962 + * is used in its cck_pd_set function. According to comments 1963 + * in the vendor driver code it doesn't exist in this chip 1964 + * generation, only 0xa0a ("ODM_CCK_PD_THRESH", which is only 1965 + * *written* to). 1966 + */ 1967 + .cck_pd_set = NULL, 1968 + .pwr_track = rtw8703b_pwr_track, 1969 + .config_bfee = NULL, 1970 + .set_gid_table = NULL, 1971 + .cfg_csi_rate = NULL, 1972 + .adaptivity_init = NULL, 1973 + .adaptivity = NULL, 1974 + .cfo_init = NULL, 1975 + .cfo_track = NULL, 1976 + .config_tx_path = NULL, 1977 + .config_txrx_mode = NULL, 1978 + .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, 1979 + 1980 + /* for coex */ 1981 + .coex_set_init = rtw8723x_coex_cfg_init, 1982 + .coex_set_ant_switch = NULL, 1983 + .coex_set_gnt_fix = rtw8703b_coex_set_gnt_fix, 1984 + .coex_set_gnt_debug = rtw8703b_coex_set_gnt_debug, 1985 + .coex_set_rfe_type = rtw8703b_coex_set_rfe_type, 1986 + .coex_set_wl_tx_power = rtw8703b_coex_set_wl_tx_power, 1987 + .coex_set_wl_rx_gain = rtw8703b_coex_set_wl_rx_gain, 1988 + }; 1989 + 1990 + const struct rtw_chip_info rtw8703b_hw_spec = { 1991 + .ops = &rtw8703b_ops, 1992 + .id = RTW_CHIP_TYPE_8703B, 1993 + 1994 + .fw_name = "rtw88/rtw8703b_fw.bin", 1995 + .wlan_cpu = RTW_WCPU_11N, 1996 + .tx_pkt_desc_sz = 40, 1997 + .tx_buf_desc_sz = 16, 1998 + .rx_pkt_desc_sz = 24, 1999 + .rx_buf_desc_sz = 8, 2000 + .phy_efuse_size = 256, 2001 + .log_efuse_size = 512, 2002 + .ptct_efuse_size = 15, 2003 + .txff_size = 32768, 2004 + .rxff_size = 16384, 2005 + .rsvd_drv_pg_num = 8, 2006 + .band = RTW_BAND_2G, 2007 + .page_size = TX_PAGE_SIZE, 2008 + .csi_buf_pg_num = 0, 2009 + .dig_min = 0x20, 2010 + .txgi_factor = 1, 2011 + .is_pwr_by_rate_dec = true, 2012 + .rx_ldpc = false, 2013 + .tx_stbc = false, 2014 + .max_power_index = 0x3f, 2015 + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 2016 + 2017 + .path_div_supported = false, 2018 + .ht_supported = true, 2019 + .vht_supported = false, 2020 + .lps_deep_mode_supported = 0, 2021 + 2022 + .sys_func_en = 0xFD, 2023 + .pwr_on_seq = card_enable_flow_8703b, 2024 + .pwr_off_seq = card_disable_flow_8703b, 2025 + .rqpn_table = rqpn_table_8703b, 2026 + .prioq_addrs = &rtw8723x_common.prioq_addrs, 2027 + .page_table = page_table_8703b, 2028 + /* used only in pci.c, not needed for SDIO devices */ 2029 + .intf_table = NULL, 2030 + 2031 + .dig = rtw8723x_common.dig, 2032 + .dig_cck = rtw8723x_common.dig_cck, 2033 + 2034 + .rf_sipi_addr = {0x840, 0x844}, 2035 + .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, 2036 + .fix_rf_phy_num = 2, 2037 + .ltecoex_addr = &rtw8723x_common.ltecoex_addr, 2038 + 2039 + .mac_tbl = &rtw8703b_mac_tbl, 2040 + .agc_tbl = &rtw8703b_agc_tbl, 2041 + .bb_tbl = &rtw8703b_bb_tbl, 2042 + .rf_tbl = {&rtw8703b_rf_a_tbl}, 2043 + 2044 + .rfe_defs = rtw8703b_rfe_defs, 2045 + .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), 2046 + 2047 + .iqk_threshold = 8, 2048 + .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, 2049 + 2050 + /* WOWLAN firmware exists, but not implemented yet */ 2051 + .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", 2052 + .wowlan_stub = NULL, 2053 + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, 2054 + 2055 + /* Vendor driver has a time-based format, converted from 2056 + * 20180330 2057 + */ 2058 + .coex_para_ver = 0x0133ed6a, 2059 + .bt_desired_ver = 0x1c, 2060 + .scbd_support = true, 2061 + .new_scbd10_def = true, 2062 + .ble_hid_profile_support = false, 2063 + .wl_mimo_ps_support = false, 2064 + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 2065 + .bt_rssi_type = COEX_BTRSSI_RATIO, 2066 + .ant_isolation = 15, 2067 + .rssi_tolerance = 2, 2068 + .bt_rssi_step = bt_rssi_step_8703b, 2069 + .wl_rssi_step = wl_rssi_step_8703b, 2070 + /* sant -> shared antenna, nsant -> non-shared antenna 2071 + * Not sure if 8703b versions with non-shard antenna even exist. 2072 + */ 2073 + .table_sant_num = ARRAY_SIZE(table_sant_8703b), 2074 + .table_sant = table_sant_8703b, 2075 + .table_nsant_num = 0, 2076 + .table_nsant = NULL, 2077 + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8703b), 2078 + .tdma_sant = tdma_sant_8703b, 2079 + .tdma_nsant_num = 0, 2080 + .tdma_nsant = NULL, 2081 + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8703b), 2082 + .wl_rf_para_tx = rf_para_tx_8703b, 2083 + .wl_rf_para_rx = rf_para_rx_8703b, 2084 + .bt_afh_span_bw20 = 0x20, 2085 + .bt_afh_span_bw40 = 0x30, 2086 + .afh_5g_num = ARRAY_SIZE(afh_5g_8703b), 2087 + .afh_5g = afh_5g_8703b, 2088 + /* REG_BTG_SEL doesn't seem to have a counterpart in the 2089 + * vendor driver. Mathematically it's REG_PAD_CTRL1 + 3. 2090 + * 2091 + * It is used in the cardemu_to_act power sequence by though 2092 + * (by address, 0x0067), comment: "0x67[0] = 0 to disable 2093 + * BT_GPS_SEL pins" That seems to fit. 2094 + */ 2095 + .btg_reg = NULL, 2096 + /* These registers are used to read (and print) from if 2097 + * CONFIG_RTW88_DEBUGFS is enabled. 2098 + */ 2099 + .coex_info_hw_regs_num = 0, 2100 + .coex_info_hw_regs = NULL, 2101 + }; 2102 + EXPORT_SYMBOL(rtw8703b_hw_spec); 2103 + 2104 + MODULE_FIRMWARE("rtw88/rtw8703b_fw.bin"); 2105 + MODULE_FIRMWARE("rtw88/rtw8703b_wow_fw.bin"); 2106 + 2107 + MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>"); 2108 + MODULE_DESCRIPTION("Realtek 802.11n wireless 8703b driver"); 2109 + MODULE_LICENSE("Dual BSD/GPL");
+102
drivers/net/wireless/realtek/rtw88/rtw8703b.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 + /* Copyright Fiona Klute <fiona.klute@gmx.de> */ 3 + 4 + #ifndef __RTW8703B_H__ 5 + #define __RTW8703B_H__ 6 + 7 + #include "rtw8723x.h" 8 + 9 + extern const struct rtw_chip_info rtw8703b_hw_spec; 10 + 11 + /* phy status parsing */ 12 + #define VGA_BITS GENMASK(4, 0) 13 + #define LNA_L_BITS GENMASK(7, 5) 14 + #define LNA_H_BIT BIT(7) 15 + /* masks for assembling LNA index from high and low bits */ 16 + #define BIT_LNA_H_MASK BIT(3) 17 + #define BIT_LNA_L_MASK GENMASK(2, 0) 18 + 19 + struct phy_rx_agc_info { 20 + #ifdef __LITTLE_ENDIAN 21 + u8 gain: 7; 22 + u8 trsw: 1; 23 + #else 24 + u8 trsw: 1; 25 + u8 gain: 7; 26 + #endif 27 + } __packed; 28 + 29 + /* This struct is called phy_status_rpt_8192cd in the vendor driver, 30 + * there might be potential to share it with drivers for other chips 31 + * of the same generation. 32 + */ 33 + struct phy_status_8703b { 34 + struct phy_rx_agc_info path_agc[2]; 35 + u8 ch_corr[2]; 36 + u8 cck_sig_qual_ofdm_pwdb_all; 37 + /* for CCK: bits 0:4: VGA index, bits 5:7: LNA index (low) */ 38 + u8 cck_agc_rpt_ofdm_cfosho_a; 39 + /* for CCK: bit 7 is high bit of LNA index if long report type */ 40 + u8 cck_rpt_b_ofdm_cfosho_b; 41 + u8 reserved_1; 42 + u8 noise_power_db_msb; 43 + s8 path_cfotail[2]; 44 + u8 pcts_mask[2]; 45 + s8 stream_rxevm[2]; 46 + u8 path_rxsnr[2]; 47 + u8 noise_power_db_lsb; 48 + u8 reserved_2[3]; 49 + u8 stream_csi[2]; 50 + u8 stream_target_csi[2]; 51 + s8 sig_evm; 52 + u8 reserved_3; 53 + 54 + #ifdef __LITTLE_ENDIAN 55 + u8 antsel_rx_keep_2: 1; 56 + u8 sgi_en: 1; 57 + u8 rxsc: 2; 58 + u8 idle_long: 1; 59 + u8 r_ant_train_en: 1; 60 + u8 ant_sel_b: 1; 61 + u8 ant_sel: 1; 62 + #else /* __BIG_ENDIAN */ 63 + u8 ant_sel: 1; 64 + u8 ant_sel_b: 1; 65 + u8 r_ant_train_en: 1; 66 + u8 idle_long: 1; 67 + u8 rxsc: 2; 68 + u8 sgi_en: 1; 69 + u8 antsel_rx_keep_2: 1; 70 + #endif 71 + } __packed; 72 + 73 + /* Baseband registers */ 74 + #define REG_BB_PWR_SAV5_11N 0x0818 75 + /* BIT(11) should be 1 for 8703B *and* 8723D, which means LNA uses 4 76 + * bit for CCK rates in report, not 3. Vendor driver logs a warning if 77 + * it's 0, but handles the case. 78 + * 79 + * Purpose of other parts of this register is unknown, 8723cs driver 80 + * code indicates some other chips use certain bits for antenna 81 + * diversity. 82 + */ 83 + #define REG_BB_AMP 0x0950 84 + #define BIT_MASK_RX_LNA (BIT(11)) 85 + 86 + /* 0xaXX: 40MHz channel settings */ 87 + #define REG_CCK_TXSF2 0x0a24 /* CCK TX filter 2 */ 88 + #define REG_CCK_DBG 0x0a28 /* debug port */ 89 + #define REG_OFDM0_A_TX_AFE 0x0c84 90 + #define REG_TXIQK_MATRIXB_LSB2_11N 0x0c9c 91 + #define REG_OFDM0_TX_PSD_NOISE 0x0ce4 /* TX pseudo noise weighting */ 92 + #define REG_IQK_RDY 0x0e90 /* is != 0 when IQK is done */ 93 + 94 + /* RF registers */ 95 + #define RF_RCK1 0x1E 96 + 97 + #define AGG_BURST_NUM 3 98 + #define AGG_BURST_SIZE 0 /* 1K */ 99 + #define BIT_MASK_AGG_BURST_NUM (GENMASK(3, 2)) 100 + #define BIT_MASK_AGG_BURST_SIZE (GENMASK(5, 4)) 101 + 102 + #endif /* __RTW8703B_H__ */
+902
drivers/net/wireless/realtek/rtw88/rtw8703b_tables.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright Fiona Klute <fiona.klute@gmx.de> */ 3 + 4 + #include "main.h" 5 + #include "phy.h" 6 + #include "rtw8703b_tables.h" 7 + 8 + static const struct rtw_phy_pg_cfg_pair rtw8703b_bb_pg[] = { 9 + { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, }, 10 + { 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, }, 11 + { 0, 0, 0, 0x00000e00, 0xffffffff, 0x34363636, }, 12 + { 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303234, }, 13 + { 0, 0, 0, 0x00000e10, 0xffffffff, 0x30343434, }, 14 + { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26262830, }, 15 + }; 16 + 17 + RTW_DECL_TABLE_BB_PG(rtw8703b_bb_pg); 18 + 19 + /* Regd: FCC -> 0, ETSI -> 2, MKK -> 1 20 + * Band: 2.4G -> 0, 5G -> 1 21 + * Bandwidth (bw): 20M -> 0, 40M -> 1, 80M -> 2, 160M -> 3 22 + * Rate Section (rs): CCK -> 0, OFDM -> 1, HT -> 2, VHT -> 3 23 + */ 24 + static const struct rtw_txpwr_lmt_cfg_pair rtw8703b_txpwr_lmt[] = { 25 + {0, 0, 0, 0, 1, 30}, 26 + {2, 0, 0, 0, 1, 26}, 27 + {1, 0, 0, 0, 1, 32}, 28 + {0, 0, 0, 0, 2, 30}, 29 + {2, 0, 0, 0, 2, 26}, 30 + {1, 0, 0, 0, 2, 32}, 31 + {0, 0, 0, 0, 3, 30}, 32 + {2, 0, 0, 0, 3, 26}, 33 + {1, 0, 0, 0, 3, 32}, 34 + {0, 0, 0, 0, 4, 30}, 35 + {2, 0, 0, 0, 4, 26}, 36 + {1, 0, 0, 0, 4, 32}, 37 + {0, 0, 0, 0, 5, 30}, 38 + {2, 0, 0, 0, 5, 26}, 39 + {1, 0, 0, 0, 5, 32}, 40 + {0, 0, 0, 0, 6, 30}, 41 + {2, 0, 0, 0, 6, 26}, 42 + {1, 0, 0, 0, 6, 32}, 43 + {0, 0, 0, 0, 7, 30}, 44 + {2, 0, 0, 0, 7, 26}, 45 + {1, 0, 0, 0, 7, 32}, 46 + {0, 0, 0, 0, 8, 30}, 47 + {2, 0, 0, 0, 8, 26}, 48 + {1, 0, 0, 0, 8, 32}, 49 + {0, 0, 0, 0, 9, 30}, 50 + {2, 0, 0, 0, 9, 26}, 51 + {1, 0, 0, 0, 9, 32}, 52 + {0, 0, 0, 0, 10, 30}, 53 + {2, 0, 0, 0, 10, 26}, 54 + {1, 0, 0, 0, 10, 32}, 55 + {0, 0, 0, 0, 11, 30}, 56 + {2, 0, 0, 0, 11, 26}, 57 + {1, 0, 0, 0, 11, 32}, 58 + {0, 0, 0, 0, 12, 63}, 59 + {2, 0, 0, 0, 12, 26}, 60 + {1, 0, 0, 0, 12, 32}, 61 + {0, 0, 0, 0, 13, 63}, 62 + {2, 0, 0, 0, 13, 26}, 63 + {1, 0, 0, 0, 13, 32}, 64 + {0, 0, 0, 0, 14, 63}, 65 + {2, 0, 0, 0, 14, 63}, 66 + {1, 0, 0, 0, 14, 32}, 67 + {0, 0, 0, 1, 1, 28}, 68 + {2, 0, 0, 1, 1, 28}, 69 + {1, 0, 0, 1, 1, 28}, 70 + {0, 0, 0, 1, 2, 28}, 71 + {2, 0, 0, 1, 2, 32}, 72 + {1, 0, 0, 1, 2, 32}, 73 + {0, 0, 0, 1, 3, 32}, 74 + {2, 0, 0, 1, 3, 32}, 75 + {1, 0, 0, 1, 3, 32}, 76 + {0, 0, 0, 1, 4, 32}, 77 + {2, 0, 0, 1, 4, 32}, 78 + {1, 0, 0, 1, 4, 32}, 79 + {0, 0, 0, 1, 5, 32}, 80 + {2, 0, 0, 1, 5, 32}, 81 + {1, 0, 0, 1, 5, 32}, 82 + {0, 0, 0, 1, 6, 32}, 83 + {2, 0, 0, 1, 6, 32}, 84 + {1, 0, 0, 1, 6, 32}, 85 + {0, 0, 0, 1, 7, 32}, 86 + {2, 0, 0, 1, 7, 32}, 87 + {1, 0, 0, 1, 7, 32}, 88 + {0, 0, 0, 1, 8, 32}, 89 + {2, 0, 0, 1, 8, 32}, 90 + {1, 0, 0, 1, 8, 32}, 91 + {0, 0, 0, 1, 9, 32}, 92 + {2, 0, 0, 1, 9, 32}, 93 + {1, 0, 0, 1, 9, 32}, 94 + {0, 0, 0, 1, 10, 28}, 95 + {2, 0, 0, 1, 10, 32}, 96 + {1, 0, 0, 1, 10, 32}, 97 + {0, 0, 0, 1, 11, 28}, 98 + {2, 0, 0, 1, 11, 32}, 99 + {1, 0, 0, 1, 11, 32}, 100 + {0, 0, 0, 1, 12, 63}, 101 + {2, 0, 0, 1, 12, 32}, 102 + {1, 0, 0, 1, 12, 32}, 103 + {0, 0, 0, 1, 13, 63}, 104 + {2, 0, 0, 1, 13, 28}, 105 + {1, 0, 0, 1, 13, 28}, 106 + {0, 0, 0, 1, 14, 63}, 107 + {2, 0, 0, 1, 14, 63}, 108 + {1, 0, 0, 1, 14, 63}, 109 + {0, 0, 0, 2, 1, 26}, 110 + {2, 0, 0, 2, 1, 26}, 111 + {1, 0, 0, 2, 1, 28}, 112 + {0, 0, 0, 2, 2, 26}, 113 + {2, 0, 0, 2, 2, 32}, 114 + {1, 0, 0, 2, 2, 32}, 115 + {0, 0, 0, 2, 3, 32}, 116 + {2, 0, 0, 2, 3, 32}, 117 + {1, 0, 0, 2, 3, 32}, 118 + {0, 0, 0, 2, 4, 32}, 119 + {2, 0, 0, 2, 4, 32}, 120 + {1, 0, 0, 2, 4, 32}, 121 + {0, 0, 0, 2, 5, 32}, 122 + {2, 0, 0, 2, 5, 32}, 123 + {1, 0, 0, 2, 5, 32}, 124 + {0, 0, 0, 2, 6, 32}, 125 + {2, 0, 0, 2, 6, 32}, 126 + {1, 0, 0, 2, 6, 32}, 127 + {0, 0, 0, 2, 7, 32}, 128 + {2, 0, 0, 2, 7, 32}, 129 + {1, 0, 0, 2, 7, 32}, 130 + {0, 0, 0, 2, 8, 32}, 131 + {2, 0, 0, 2, 8, 32}, 132 + {1, 0, 0, 2, 8, 32}, 133 + {0, 0, 0, 2, 9, 32}, 134 + {2, 0, 0, 2, 9, 32}, 135 + {1, 0, 0, 2, 9, 32}, 136 + {0, 0, 0, 2, 10, 26}, 137 + {2, 0, 0, 2, 10, 32}, 138 + {1, 0, 0, 2, 10, 32}, 139 + {0, 0, 0, 2, 11, 26}, 140 + {2, 0, 0, 2, 11, 32}, 141 + {1, 0, 0, 2, 11, 32}, 142 + {0, 0, 0, 2, 12, 63}, 143 + {2, 0, 0, 2, 12, 32}, 144 + {1, 0, 0, 2, 12, 32}, 145 + {0, 0, 0, 2, 13, 63}, 146 + {2, 0, 0, 2, 13, 26}, 147 + {1, 0, 0, 2, 13, 28}, 148 + {0, 0, 0, 2, 14, 63}, 149 + {2, 0, 0, 2, 14, 63}, 150 + {1, 0, 0, 2, 14, 63}, 151 + {0, 0, 1, 2, 1, 63}, 152 + {2, 0, 1, 2, 1, 63}, 153 + {1, 0, 1, 2, 1, 63}, 154 + {0, 0, 1, 2, 2, 63}, 155 + {2, 0, 1, 2, 2, 63}, 156 + {1, 0, 1, 2, 2, 63}, 157 + {0, 0, 1, 2, 3, 26}, 158 + {2, 0, 1, 2, 3, 26}, 159 + {1, 0, 1, 2, 3, 26}, 160 + {0, 0, 1, 2, 4, 26}, 161 + {2, 0, 1, 2, 4, 28}, 162 + {1, 0, 1, 2, 4, 26}, 163 + {0, 0, 1, 2, 5, 28}, 164 + {2, 0, 1, 2, 5, 28}, 165 + {1, 0, 1, 2, 5, 26}, 166 + {0, 0, 1, 2, 6, 28}, 167 + {2, 0, 1, 2, 6, 28}, 168 + {1, 0, 1, 2, 6, 26}, 169 + {0, 0, 1, 2, 7, 28}, 170 + {2, 0, 1, 2, 7, 28}, 171 + {1, 0, 1, 2, 7, 26}, 172 + {0, 0, 1, 2, 8, 26}, 173 + {2, 0, 1, 2, 8, 28}, 174 + {1, 0, 1, 2, 8, 26}, 175 + {0, 0, 1, 2, 9, 26}, 176 + {2, 0, 1, 2, 9, 28}, 177 + {1, 0, 1, 2, 9, 26}, 178 + {0, 0, 1, 2, 10, 26}, 179 + {2, 0, 1, 2, 10, 28}, 180 + {1, 0, 1, 2, 10, 26}, 181 + {0, 0, 1, 2, 11, 26}, 182 + {2, 0, 1, 2, 11, 26}, 183 + {1, 0, 1, 2, 11, 26}, 184 + {0, 0, 1, 2, 12, 63}, 185 + {2, 0, 1, 2, 12, 26}, 186 + {1, 0, 1, 2, 12, 26}, 187 + {0, 0, 1, 2, 13, 63}, 188 + {2, 0, 1, 2, 13, 26}, 189 + {1, 0, 1, 2, 13, 26}, 190 + {0, 0, 1, 2, 14, 63}, 191 + {2, 0, 1, 2, 14, 63}, 192 + {1, 0, 1, 2, 14, 63}, 193 + }; 194 + 195 + RTW_DECL_TABLE_TXPWR_LMT(rtw8703b_txpwr_lmt); 196 + 197 + static const u32 rtw8703b_mac[] = { 198 + 0x02F, 0x00000030, 199 + 0x035, 0x00000000, 200 + 0x067, 0x00000002, 201 + 0x092, 0x00000080, 202 + 0x421, 0x0000000F, 203 + 0x428, 0x0000000A, 204 + 0x429, 0x00000010, 205 + 0x430, 0x00000000, 206 + 0x431, 0x00000000, 207 + 0x432, 0x00000000, 208 + 0x433, 0x00000001, 209 + 0x434, 0x00000002, 210 + 0x435, 0x00000003, 211 + 0x436, 0x00000005, 212 + 0x437, 0x00000007, 213 + 0x438, 0x00000000, 214 + 0x439, 0x00000000, 215 + 0x43A, 0x00000000, 216 + 0x43B, 0x00000001, 217 + 0x43C, 0x00000002, 218 + 0x43D, 0x00000003, 219 + 0x43E, 0x00000005, 220 + 0x43F, 0x00000007, 221 + 0x440, 0x0000005D, 222 + 0x441, 0x00000001, 223 + 0x442, 0x00000000, 224 + 0x444, 0x00000010, 225 + 0x445, 0x00000000, 226 + 0x446, 0x00000000, 227 + 0x447, 0x00000000, 228 + 0x448, 0x00000000, 229 + 0x449, 0x000000F0, 230 + 0x44A, 0x0000000F, 231 + 0x44B, 0x0000003E, 232 + 0x44C, 0x00000010, 233 + 0x44D, 0x00000000, 234 + 0x44E, 0x00000000, 235 + 0x44F, 0x00000000, 236 + 0x450, 0x00000000, 237 + 0x451, 0x000000F0, 238 + 0x452, 0x0000000F, 239 + 0x453, 0x00000000, 240 + 0x456, 0x0000005E, 241 + 0x460, 0x00000066, 242 + 0x461, 0x00000066, 243 + 0x4C8, 0x000000FF, 244 + 0x4C9, 0x00000008, 245 + 0x4CC, 0x000000FF, 246 + 0x4CD, 0x000000FF, 247 + 0x4CE, 0x00000001, 248 + 0x500, 0x00000026, 249 + 0x501, 0x000000A2, 250 + 0x502, 0x0000002F, 251 + 0x503, 0x00000000, 252 + 0x504, 0x00000028, 253 + 0x505, 0x000000A3, 254 + 0x506, 0x0000005E, 255 + 0x507, 0x00000000, 256 + 0x508, 0x0000002B, 257 + 0x509, 0x000000A4, 258 + 0x50A, 0x0000005E, 259 + 0x50B, 0x00000000, 260 + 0x50C, 0x0000004F, 261 + 0x50D, 0x000000A4, 262 + 0x50E, 0x00000000, 263 + 0x50F, 0x00000000, 264 + 0x512, 0x0000001C, 265 + 0x514, 0x0000000A, 266 + 0x516, 0x0000000A, 267 + 0x525, 0x0000004F, 268 + 0x550, 0x00000010, 269 + 0x551, 0x00000010, 270 + 0x559, 0x00000002, 271 + 0x55C, 0x00000028, 272 + 0x55D, 0x000000FF, 273 + 0x605, 0x00000030, 274 + 0x608, 0x0000000E, 275 + 0x609, 0x0000002A, 276 + 0x620, 0x000000FF, 277 + 0x621, 0x000000FF, 278 + 0x622, 0x000000FF, 279 + 0x623, 0x000000FF, 280 + 0x624, 0x000000FF, 281 + 0x625, 0x000000FF, 282 + 0x626, 0x000000FF, 283 + 0x627, 0x000000FF, 284 + 0x638, 0x00000028, 285 + 0x63C, 0x0000000A, 286 + 0x63D, 0x0000000A, 287 + 0x63E, 0x0000000C, 288 + 0x63F, 0x0000000C, 289 + 0x640, 0x00000040, 290 + 0x642, 0x00000040, 291 + 0x643, 0x00000000, 292 + 0x652, 0x000000C8, 293 + 0x66A, 0x000000B0, 294 + 0x66E, 0x00000005, 295 + 0x700, 0x00000021, 296 + 0x701, 0x00000043, 297 + 0x702, 0x00000065, 298 + 0x703, 0x00000087, 299 + 0x708, 0x00000021, 300 + 0x709, 0x00000043, 301 + 0x70A, 0x00000065, 302 + 0x70B, 0x00000087, 303 + 0x765, 0x00000018, 304 + 0x76E, 0x00000004, 305 + }; 306 + 307 + RTW_DECL_TABLE_PHY_COND(rtw8703b_mac, rtw_phy_cfg_mac); 308 + 309 + static const u32 rtw8703b_agc[] = { 310 + 0xC78, 0xFC000101, 311 + 0xC78, 0xFB010101, 312 + 0xC78, 0xFA020101, 313 + 0xC78, 0xF9030101, 314 + 0xC78, 0xF8040101, 315 + 0xC78, 0xF7050101, 316 + 0xC78, 0xF6060101, 317 + 0xC78, 0xF5070101, 318 + 0xC78, 0xF4080101, 319 + 0xC78, 0xF3090101, 320 + 0xC78, 0xF20A0101, 321 + 0xC78, 0xF10B0101, 322 + 0xC78, 0xF00C0101, 323 + 0xC78, 0xEF0D0101, 324 + 0xC78, 0xEE0E0101, 325 + 0xC78, 0xED0F0101, 326 + 0xC78, 0xEC100101, 327 + 0xC78, 0xEB110101, 328 + 0xC78, 0xEA120101, 329 + 0xC78, 0xE9130101, 330 + 0xC78, 0xE8140101, 331 + 0xC78, 0xE7150101, 332 + 0xC78, 0xE6160101, 333 + 0xC78, 0xE5170101, 334 + 0xC78, 0xE4180101, 335 + 0xC78, 0xE3190101, 336 + 0xC78, 0x661A0101, 337 + 0xC78, 0x651B0101, 338 + 0xC78, 0x641C0101, 339 + 0xC78, 0x631D0101, 340 + 0xC78, 0x071E0101, 341 + 0xC78, 0x061F0101, 342 + 0xC78, 0x05200101, 343 + 0xC78, 0x04210101, 344 + 0xC78, 0x03220101, 345 + 0xC78, 0xE8230001, 346 + 0xC78, 0xE7240001, 347 + 0xC78, 0xE6250001, 348 + 0xC78, 0xE5260001, 349 + 0xC78, 0xE4270001, 350 + 0xC78, 0x89280001, 351 + 0xC78, 0x88290001, 352 + 0xC78, 0x872A0001, 353 + 0xC78, 0x862B0001, 354 + 0xC78, 0x852C0001, 355 + 0xC78, 0x482D0001, 356 + 0xC78, 0x472E0001, 357 + 0xC78, 0x462F0001, 358 + 0xC78, 0x45300001, 359 + 0xC78, 0x44310001, 360 + 0xC78, 0x07320001, 361 + 0xC78, 0x06330001, 362 + 0xC78, 0x05340001, 363 + 0xC78, 0x04350001, 364 + 0xC78, 0x03360001, 365 + 0xC78, 0x02370001, 366 + 0xC78, 0x01380001, 367 + 0xC78, 0x00390001, 368 + 0xC78, 0x003A0001, 369 + 0xC78, 0x003B0001, 370 + 0xC78, 0x003C0001, 371 + 0xC78, 0x003D0001, 372 + 0xC78, 0x003E0001, 373 + 0xC78, 0x003F0001, 374 + 0xC78, 0x7F002001, 375 + 0xC78, 0x7F012001, 376 + 0xC78, 0x7F022001, 377 + 0xC78, 0x7F032001, 378 + 0xC78, 0x7F042001, 379 + 0xC78, 0x7F052001, 380 + 0xC78, 0x7F062001, 381 + 0xC78, 0x7F072001, 382 + 0xC78, 0x7F082001, 383 + 0xC78, 0x7F092001, 384 + 0xC78, 0x7F0A2001, 385 + 0xC78, 0x7F0B2001, 386 + 0xC78, 0x7F0C2001, 387 + 0xC78, 0x7F0D2001, 388 + 0xC78, 0x7F0E2001, 389 + 0xC78, 0x7F0F2001, 390 + 0xC78, 0x7F102001, 391 + 0xC78, 0x7F112001, 392 + 0xC78, 0x7E122001, 393 + 0xC78, 0x7D132001, 394 + 0xC78, 0x7C142001, 395 + 0xC78, 0x7B152001, 396 + 0xC78, 0x7A162001, 397 + 0xC78, 0x79172001, 398 + 0xC78, 0x78182001, 399 + 0xC78, 0x77192001, 400 + 0xC78, 0x761A2001, 401 + 0xC78, 0x751B2001, 402 + 0xC78, 0x741C2001, 403 + 0xC78, 0x731D2001, 404 + 0xC78, 0x721E2001, 405 + 0xC78, 0x711F2001, 406 + 0xC78, 0x70202001, 407 + 0xC78, 0x6F212001, 408 + 0xC78, 0x6E222001, 409 + 0xC78, 0x6D232001, 410 + 0xC78, 0x6C242001, 411 + 0xC78, 0x6B252001, 412 + 0xC78, 0x6A262001, 413 + 0xC78, 0x69272001, 414 + 0xC78, 0x68282001, 415 + 0xC78, 0x67292001, 416 + 0xC78, 0x662A2001, 417 + 0xC78, 0x652B2001, 418 + 0xC78, 0x642C2001, 419 + 0xC78, 0x632D2001, 420 + 0xC78, 0x622E2001, 421 + 0xC78, 0x612F2001, 422 + 0xC78, 0x60302001, 423 + 0xC78, 0x42312001, 424 + 0xC78, 0x41322001, 425 + 0xC78, 0x40332001, 426 + 0xC78, 0x23342001, 427 + 0xC78, 0x22352001, 428 + 0xC78, 0x21362001, 429 + 0xC78, 0x20372001, 430 + 0xC78, 0x00382001, 431 + 0xC78, 0x02392001, 432 + 0xC78, 0x013A2001, 433 + 0xC78, 0x003B2001, 434 + 0xC78, 0x003C2001, 435 + 0xC78, 0x003D2001, 436 + 0xC78, 0x003E2001, 437 + 0xC78, 0x003F2001, 438 + 0xC78, 0x7F003101, 439 + 0xC78, 0x7F013101, 440 + 0xC78, 0x7F023101, 441 + 0xC78, 0x7F033101, 442 + 0xC78, 0x7F043101, 443 + 0xC78, 0x7F053101, 444 + 0xC78, 0x7F063101, 445 + 0xC78, 0x7E073101, 446 + 0xC78, 0x7D083101, 447 + 0xC78, 0x7C093101, 448 + 0xC78, 0x7B0A3101, 449 + 0xC78, 0x7A0B3101, 450 + 0xC78, 0x790C3101, 451 + 0xC78, 0x780D3101, 452 + 0xC78, 0x770E3101, 453 + 0xC78, 0x760F3101, 454 + 0xC78, 0x75103101, 455 + 0xC78, 0x74113101, 456 + 0xC78, 0x73123101, 457 + 0xC78, 0x72133101, 458 + 0xC78, 0x71143101, 459 + 0xC78, 0x70153101, 460 + 0xC78, 0x6F163101, 461 + 0xC78, 0x69173101, 462 + 0xC78, 0x68183101, 463 + 0xC78, 0x67193101, 464 + 0xC78, 0x661A3101, 465 + 0xC78, 0x651B3101, 466 + 0xC78, 0x641C3101, 467 + 0xC78, 0x631D3101, 468 + 0xC78, 0x621E3101, 469 + 0xC78, 0x611F3101, 470 + 0xC78, 0x60203101, 471 + 0xC78, 0x42213101, 472 + 0xC78, 0x41223101, 473 + 0xC78, 0x40233101, 474 + 0xC78, 0x22243101, 475 + 0xC78, 0x21253101, 476 + 0xC78, 0x20263101, 477 + 0xC78, 0x00273101, 478 + 0xC78, 0x00283101, 479 + 0xC78, 0x00293101, 480 + 0xC78, 0x002A3101, 481 + 0xC78, 0x002B3101, 482 + 0xC78, 0x002C3101, 483 + 0xC78, 0x002D3101, 484 + 0xC78, 0x002E3101, 485 + 0xC78, 0x002F3101, 486 + 0xC78, 0x00303101, 487 + 0xC78, 0x00313101, 488 + 0xC78, 0x00323101, 489 + 0xC78, 0x00333101, 490 + 0xC78, 0x00343101, 491 + 0xC78, 0x00353101, 492 + 0xC78, 0x00363101, 493 + 0xC78, 0x00373101, 494 + 0xC78, 0x00383101, 495 + 0xC78, 0x00393101, 496 + 0xC78, 0x003A3101, 497 + 0xC78, 0x003B3101, 498 + 0xC78, 0x003C3101, 499 + 0xC78, 0x003D3101, 500 + 0xC78, 0x003E3101, 501 + 0xC78, 0x003F3101, 502 + 0xC78, 0xFA403101, 503 + 0xC78, 0xF9413101, 504 + 0xC78, 0xF8423101, 505 + 0xC78, 0xF7433101, 506 + 0xC78, 0xF6443101, 507 + 0xC78, 0xF5453101, 508 + 0xC78, 0xF4463101, 509 + 0xC78, 0xF3473101, 510 + 0xC78, 0xF2483101, 511 + 0xC78, 0xE1493101, 512 + 0xC78, 0xE04A3101, 513 + 0xC78, 0xEF4B3101, 514 + 0xC78, 0xEE4C3101, 515 + 0xC78, 0xED4D3101, 516 + 0xC78, 0xEC4E3101, 517 + 0xC78, 0xEB4F3101, 518 + 0xC78, 0xEA503101, 519 + 0xC78, 0xE9513101, 520 + 0xC78, 0xE8523101, 521 + 0xC78, 0xE7533101, 522 + 0xC78, 0xE6543101, 523 + 0xC78, 0xE5553101, 524 + 0xC78, 0xE4563101, 525 + 0xC78, 0xE3573101, 526 + 0xC78, 0xE2583101, 527 + 0xC78, 0xE1593101, 528 + 0xC78, 0xE05A3101, 529 + 0xC78, 0xC25B3101, 530 + 0xC78, 0xC15C3101, 531 + 0xC78, 0xC05D3101, 532 + 0xC78, 0x825E3101, 533 + 0xC78, 0x815F3101, 534 + 0xC78, 0x80603101, 535 + 0xC78, 0x80613101, 536 + 0xC78, 0x80623101, 537 + 0xC78, 0x80633101, 538 + 0xC78, 0x80643101, 539 + 0xC78, 0x80653101, 540 + 0xC78, 0x80663101, 541 + 0xC78, 0x80673101, 542 + 0xC78, 0x80683101, 543 + 0xC78, 0x80693101, 544 + 0xC78, 0x806A3101, 545 + 0xC78, 0x806B3101, 546 + 0xC78, 0x806C3101, 547 + 0xC78, 0x806D3101, 548 + 0xC78, 0x806E3101, 549 + 0xC78, 0x806F3101, 550 + 0xC78, 0x80703101, 551 + 0xC78, 0x80713101, 552 + 0xC78, 0x80723101, 553 + 0xC78, 0x80733101, 554 + 0xC78, 0x80743101, 555 + 0xC78, 0x80753101, 556 + 0xC78, 0x80763101, 557 + 0xC78, 0x80773101, 558 + 0xC78, 0x80783101, 559 + 0xC78, 0x80793101, 560 + 0xC78, 0x807A3101, 561 + 0xC78, 0x807B3101, 562 + 0xC78, 0x807C3101, 563 + 0xC78, 0x807D3101, 564 + 0xC78, 0x807E3101, 565 + 0xC78, 0x807F3101, 566 + 0xC78, 0xFF402001, 567 + 0xC78, 0xFF412001, 568 + 0xC78, 0xFF422001, 569 + 0xC78, 0xFF432001, 570 + 0xC78, 0xFF442001, 571 + 0xC78, 0xFF452001, 572 + 0xC78, 0xFF462001, 573 + 0xC78, 0xFF472001, 574 + 0xC78, 0xFF482001, 575 + 0xC78, 0xFF492001, 576 + 0xC78, 0xFF4A2001, 577 + 0xC78, 0xFF4B2001, 578 + 0xC78, 0xFF4C2001, 579 + 0xC78, 0xFE4D2001, 580 + 0xC78, 0xFD4E2001, 581 + 0xC78, 0xFC4F2001, 582 + 0xC78, 0xFB502001, 583 + 0xC78, 0xFA512001, 584 + 0xC78, 0xF9522001, 585 + 0xC78, 0xF8532001, 586 + 0xC78, 0xF7542001, 587 + 0xC78, 0xF6552001, 588 + 0xC78, 0xF5562001, 589 + 0xC78, 0xF4572001, 590 + 0xC78, 0xF3582001, 591 + 0xC78, 0xF2592001, 592 + 0xC78, 0xF15A2001, 593 + 0xC78, 0xF05B2001, 594 + 0xC78, 0xEF5C2001, 595 + 0xC78, 0xEE5D2001, 596 + 0xC78, 0xED5E2001, 597 + 0xC78, 0xEC5F2001, 598 + 0xC78, 0xEB602001, 599 + 0xC78, 0xEA612001, 600 + 0xC78, 0xE9622001, 601 + 0xC78, 0xE8632001, 602 + 0xC78, 0xE7642001, 603 + 0xC78, 0xE6652001, 604 + 0xC78, 0xE5662001, 605 + 0xC78, 0xE4672001, 606 + 0xC78, 0xE3682001, 607 + 0xC78, 0xC5692001, 608 + 0xC78, 0xC46A2001, 609 + 0xC78, 0xC36B2001, 610 + 0xC78, 0xA46C2001, 611 + 0xC78, 0x846D2001, 612 + 0xC78, 0x836E2001, 613 + 0xC78, 0x826F2001, 614 + 0xC78, 0x81702001, 615 + 0xC78, 0x80712001, 616 + 0xC78, 0x80722001, 617 + 0xC78, 0x80732001, 618 + 0xC78, 0x80742001, 619 + 0xC78, 0x80752001, 620 + 0xC78, 0x80762001, 621 + 0xC78, 0x80772001, 622 + 0xC78, 0x80782001, 623 + 0xC78, 0x80792001, 624 + 0xC78, 0x807A2001, 625 + 0xC78, 0x807B2001, 626 + 0xC78, 0x807C2001, 627 + 0xC78, 0x807D2001, 628 + 0xC78, 0x807E2001, 629 + 0xC78, 0x807F2001, 630 + 0xC50, 0x69553422, 631 + 0xC50, 0x69553420, 632 + }; 633 + 634 + RTW_DECL_TABLE_PHY_COND(rtw8703b_agc, rtw_phy_cfg_agc); 635 + 636 + /* init values for BB registers */ 637 + static const u32 rtw8703b_bb[] = { 638 + 0x800, 0x83045700, 639 + 0x804, 0x00000003, 640 + 0x808, 0x0000FC00, 641 + 0x80C, 0x0000000A, 642 + 0x810, 0x10001331, 643 + 0x814, 0x020C3D10, 644 + 0x818, 0x02200385, 645 + 0x81C, 0x00000000, 646 + 0x820, 0x01000100, 647 + 0x824, 0x00390204, 648 + 0x828, 0x00000000, 649 + 0x82C, 0x00000000, 650 + 0x830, 0x00000000, 651 + 0x834, 0x00000000, 652 + 0x838, 0x00000000, 653 + 0x83C, 0x00000000, 654 + 0x840, 0x00010000, 655 + 0x844, 0x00000000, 656 + 0x848, 0x00000000, 657 + 0x84C, 0x00000000, 658 + 0x850, 0x00000000, 659 + 0x854, 0x00000000, 660 + 0x858, 0x569A11A9, 661 + 0x85C, 0x01000014, 662 + 0x860, 0x66F60110, 663 + 0x864, 0x061F0649, 664 + 0x868, 0x00000000, 665 + 0x86C, 0x27272700, 666 + 0x870, 0x07000760, 667 + 0x874, 0x25004000, 668 + 0x878, 0x00000808, 669 + 0x87C, 0x004F0201, 670 + 0x880, 0xB0000B1E, 671 + 0x884, 0x00000001, 672 + 0x888, 0x00000000, 673 + 0x88C, 0xCCC000C0, 674 + 0x890, 0x00000800, 675 + 0x894, 0xFFFFFFFE, 676 + 0x898, 0x40302010, 677 + 0x89C, 0x00706050, 678 + 0x900, 0x00000000, 679 + 0x904, 0x00000023, 680 + 0x908, 0x00000000, 681 + 0x90C, 0x81121111, 682 + 0x910, 0x00000002, 683 + 0x914, 0x00000201, 684 + 0x948, 0x99000000, 685 + 0x94C, 0x00000010, 686 + 0x950, 0x20003800, 687 + 0x954, 0x4A880000, 688 + 0x958, 0x4BC5D87A, 689 + 0x95C, 0x04EB9B79, 690 + 0xA00, 0x00D047C8, 691 + 0xA04, 0x80FF800C, 692 + 0xA08, 0x8C838300, 693 + 0xA0C, 0x2E7F120F, 694 + 0xA10, 0x9500BB78, 695 + 0xA14, 0x1114D028, 696 + 0xA18, 0x00881117, 697 + 0xA1C, 0x89140F00, 698 + 0xA20, 0xD1D80000, 699 + 0xA24, 0x5A7DA0BD, 700 + 0xA28, 0x0000223B, 701 + 0xA2C, 0x00D30000, 702 + 0xA70, 0x101FBF00, 703 + 0xA74, 0x00000007, 704 + 0xA78, 0x00008900, 705 + 0xA7C, 0x225B0606, 706 + 0xA80, 0x2180FA74, 707 + 0xA84, 0x00120000, 708 + 0xA88, 0x040C0000, 709 + 0xA8C, 0x12345678, 710 + 0xA90, 0xABCDEF00, 711 + 0xA94, 0x001B1B89, 712 + 0xA98, 0x05100000, 713 + 0xA9C, 0x3F000000, 714 + 0xAA0, 0x00000000, 715 + 0xB2C, 0x00000000, 716 + 0xC00, 0x48071D40, 717 + 0xC04, 0x03A05611, 718 + 0xC08, 0x000000E4, 719 + 0xC0C, 0x6C6C6C6C, 720 + 0xC10, 0x18800000, 721 + 0xC14, 0x40000100, 722 + 0xC18, 0x08800000, 723 + 0xC1C, 0x40000100, 724 + 0xC20, 0x00000000, 725 + 0xC24, 0x00000000, 726 + 0xC28, 0x00000000, 727 + 0xC2C, 0x00000000, 728 + 0xC30, 0x69E9AC4B, 729 + 0xC34, 0x31000040, 730 + 0xC38, 0x21688080, 731 + 0xC3C, 0x000016CC, 732 + 0xC40, 0x1F78403F, 733 + 0xC44, 0x00010036, 734 + 0xC48, 0xEC020107, 735 + 0xC4C, 0x007F037F, 736 + 0xC50, 0x69553420, 737 + 0xC54, 0x43BC0094, 738 + 0xC58, 0x00015967, 739 + 0xC5C, 0x18250492, 740 + 0xC60, 0x00000000, 741 + 0xC64, 0x7112848B, 742 + 0xC68, 0x47C07BFF, 743 + 0xC6C, 0x00000036, 744 + 0xC70, 0x2C7F000D, 745 + 0xC74, 0x020600DB, 746 + 0xC78, 0x0000001F, 747 + 0xC7C, 0x00B91612, 748 + 0xC80, 0x390000E4, 749 + 0xC84, 0x19F60000, 750 + 0xC88, 0x40000100, 751 + 0xC8C, 0x20200000, 752 + 0xC90, 0x00091521, 753 + 0xC94, 0x00000000, 754 + 0xC98, 0x00121820, 755 + 0xC9C, 0x00007F7F, 756 + 0xCA0, 0x00000000, 757 + 0xCA4, 0x000300A0, 758 + 0xCA8, 0x00000000, 759 + 0xCAC, 0x00000000, 760 + 0xCB0, 0x00000000, 761 + 0xCB4, 0x00000000, 762 + 0xCB8, 0x00000000, 763 + 0xCBC, 0x28000000, 764 + 0xCC0, 0x00000000, 765 + 0xCC4, 0x00000000, 766 + 0xCC8, 0x00000000, 767 + 0xCCC, 0x00000000, 768 + 0xCD0, 0x00000000, 769 + 0xCD4, 0x00000000, 770 + 0xCD8, 0x64B22427, 771 + 0xCDC, 0x00766932, 772 + 0xCE0, 0x00222222, 773 + 0xCE4, 0x10000000, 774 + 0xCE8, 0x37644302, 775 + 0xCEC, 0x2F97D40C, 776 + 0xD00, 0x00030740, 777 + 0xD04, 0x40020401, 778 + 0xD08, 0x0000907F, 779 + 0xD0C, 0x20010201, 780 + 0xD10, 0xA0633333, 781 + 0xD14, 0x3333BC53, 782 + 0xD18, 0x7A8F5B6F, 783 + 0xD2C, 0xCB979975, 784 + 0xD30, 0x00000000, 785 + 0xD34, 0x80608000, 786 + 0xD38, 0x98000000, 787 + 0xD3C, 0x40127353, 788 + 0xD40, 0x00000000, 789 + 0xD44, 0x00000000, 790 + 0xD48, 0x00000000, 791 + 0xD4C, 0x00000000, 792 + 0xD50, 0x6437140A, 793 + 0xD54, 0x00000000, 794 + 0xD58, 0x00000282, 795 + 0xD5C, 0x30032064, 796 + 0xD60, 0x4653DE68, 797 + 0xD64, 0x04518A3C, 798 + 0xD68, 0x00002101, 799 + 0xE00, 0x2D2D2D2D, 800 + 0xE04, 0x2D2D2D2D, 801 + 0xE08, 0x0390272D, 802 + 0xE10, 0x2D2D2D2D, 803 + 0xE14, 0x2D2D2D2D, 804 + 0xE18, 0x2D2D2D2D, 805 + 0xE1C, 0x2D2D2D2D, 806 + 0xE28, 0x00000000, 807 + 0xE30, 0x1000DC1F, 808 + 0xE34, 0x10008C1F, 809 + 0xE38, 0x02140102, 810 + 0xE3C, 0x681604C2, 811 + 0xE40, 0x01007C00, 812 + 0xE44, 0x01004800, 813 + 0xE48, 0xFB000000, 814 + 0xE4C, 0x000028D1, 815 + 0xE50, 0x1000DC1F, 816 + 0xE54, 0x10008C1F, 817 + 0xE58, 0x02140102, 818 + 0xE5C, 0x28160D05, 819 + 0xE60, 0x00000048, 820 + 0xE68, 0x001B25A4, 821 + 0xE6C, 0x01C00014, 822 + 0xE70, 0x01C00014, 823 + 0xE74, 0x02000014, 824 + 0xE78, 0x02000014, 825 + 0xE7C, 0x02000014, 826 + 0xE80, 0x02000014, 827 + 0xE84, 0x01C00014, 828 + 0xE88, 0x02000014, 829 + 0xE8C, 0x01C00014, 830 + 0xED0, 0x01C00014, 831 + 0xED4, 0x01C00014, 832 + 0xED8, 0x01C00014, 833 + 0xEDC, 0x00000014, 834 + 0xEE0, 0x00000014, 835 + 0xEE8, 0x21555448, 836 + 0xEEC, 0x03C00014, 837 + 0xF14, 0x00000003, 838 + 0xF4C, 0x00000000, 839 + 0xF00, 0x00000300, 840 + }; 841 + 842 + RTW_DECL_TABLE_PHY_COND(rtw8703b_bb, rtw_phy_cfg_bb); 843 + 844 + static const u32 rtw8703b_rf_a[] = { 845 + 0x018, 0x00008C01, 846 + 0x0B5, 0x0008C050, 847 + 0x0B1, 0x00054258, 848 + 0x0B2, 0x00054C00, 849 + 0x030, 0x00018000, 850 + 0x031, 0x00000027, 851 + 0x032, 0x000A7F07, 852 + 0x030, 0x00020000, 853 + 0x031, 0x00000027, 854 + 0x032, 0x000E7D87, 855 + 0x01C, 0x000F8635, 856 + 0x0EF, 0x00080000, 857 + 0x030, 0x00008000, 858 + 0x031, 0x00000004, 859 + 0x032, 0x00006105, 860 + 0x0EF, 0x00000000, 861 + 0x0EF, 0x00000400, 862 + 0x041, 0x0000BD54, 863 + 0x041, 0x00003DD4, 864 + 0x041, 0x0000FDD4, 865 + 0x0EF, 0x00000000, 866 + 0x0DF, 0x00000600, 867 + 0x050, 0x0000C6DB, 868 + 0x051, 0x00004505, 869 + 0x052, 0x0000E31D, 870 + 0x053, 0x00040579, 871 + 0x054, 0x00000000, 872 + 0x055, 0x0008206E, 873 + 0x056, 0x00040000, 874 + 0x0EF, 0x00000100, 875 + 0x034, 0x0000ADD7, 876 + 0x034, 0x00009DD4, 877 + 0x034, 0x00008DD1, 878 + 0x034, 0x00007DCE, 879 + 0x034, 0x00006DCB, 880 + 0x034, 0x00005CCE, 881 + 0x034, 0x000048CD, 882 + 0x034, 0x000034CC, 883 + 0x034, 0x0000244F, 884 + 0x034, 0x0000144C, 885 + 0x034, 0x0000004E, 886 + 0x0EF, 0x00000000, 887 + 0x0EF, 0x00002000, 888 + 0x03B, 0x0003801F, 889 + 0x03B, 0x00030002, 890 + 0x03B, 0x00028001, 891 + 0x03B, 0x00020000, 892 + 0x03B, 0x00018003, 893 + 0x03B, 0x00010002, 894 + 0x03B, 0x00008001, 895 + 0x03B, 0x00000000, 896 + 0x0EF, 0x00000000, 897 + 0x082, 0x000C0000, 898 + 0x083, 0x000AF025, 899 + 0x01E, 0x00000C08, 900 + }; 901 + 902 + RTW_DECL_TABLE_RF_RADIO(rtw8703b_rf_a, A);
+14
drivers/net/wireless/realtek/rtw88/rtw8703b_tables.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 + /* Copyright Fiona Klute <fiona.klute@gmx.de> */ 3 + 4 + #ifndef __RTW8703B_TABLES_H__ 5 + #define __RTW8703B_TABLES_H__ 6 + 7 + extern const struct rtw_table rtw8703b_bb_pg_tbl; 8 + extern const struct rtw_table rtw8703b_txpwr_lmt_tbl; 9 + extern const struct rtw_table rtw8703b_mac_tbl; 10 + extern const struct rtw_table rtw8703b_agc_tbl; 11 + extern const struct rtw_table rtw8703b_bb_tbl; 12 + extern const struct rtw_table rtw8703b_rf_a_tbl; 13 + 14 + #endif
+34
drivers/net/wireless/realtek/rtw88/rtw8723cs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright Fiona Klute <fiona.klute@gmx.de> */ 3 + 4 + #include <linux/mmc/sdio_func.h> 5 + #include <linux/mmc/sdio_ids.h> 6 + #include <linux/module.h> 7 + #include "main.h" 8 + #include "rtw8703b.h" 9 + #include "sdio.h" 10 + 11 + static const struct sdio_device_id rtw_8723cs_id_table[] = { 12 + { 13 + SDIO_DEVICE(SDIO_VENDOR_ID_REALTEK, 14 + SDIO_DEVICE_ID_REALTEK_RTW8723CS), 15 + .driver_data = (kernel_ulong_t)&rtw8703b_hw_spec, 16 + }, 17 + {} 18 + }; 19 + MODULE_DEVICE_TABLE(sdio, rtw_8723cs_id_table); 20 + 21 + static struct sdio_driver rtw_8723cs_driver = { 22 + .name = "rtw8723cs", 23 + .id_table = rtw_8723cs_id_table, 24 + .probe = rtw_sdio_probe, 25 + .remove = rtw_sdio_remove, 26 + .drv = { 27 + .pm = &rtw_sdio_pm_ops, 28 + .shutdown = rtw_sdio_shutdown 29 + }}; 30 + module_sdio_driver(rtw_8723cs_driver); 31 + 32 + MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>"); 33 + MODULE_DESCRIPTION("Realtek 802.11n wireless 8723cs driver"); 34 + MODULE_LICENSE("Dual BSD/GPL");
+41 -632
drivers/net/wireless/realtek/rtw88/rtw8723d.c
··· 9 9 #include "tx.h" 10 10 #include "rx.h" 11 11 #include "phy.h" 12 + #include "rtw8723x.h" 12 13 #include "rtw8723d.h" 13 14 #include "rtw8723d_table.h" 14 15 #include "mac.h" 15 16 #include "reg.h" 16 17 #include "debug.h" 17 18 18 - static const struct rtw_hw_reg rtw8723d_txagc[] = { 19 - [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, 20 - [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, 21 - [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, 22 - [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, 23 - [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, 24 - [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, 25 - [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, 26 - [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, 27 - [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, 28 - [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, 29 - [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, 30 - [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, 31 - [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, 32 - [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, 33 - [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, 34 - [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, 35 - [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, 36 - [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, 37 - [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, 38 - [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, 39 - }; 40 - 41 - #define WLAN_TXQ_RPT_EN 0x1F 42 19 #define WLAN_SLOT_TIME 0x09 43 20 #define WLAN_RL_VAL 0x3030 44 21 #define WLAN_BAR_VAL 0x0201ffff ··· 41 64 #define WLAN_LTR_ACT_LAT 0x883c883c 42 65 #define WLAN_LTR_CTRL1 0xCB004010 43 66 #define WLAN_LTR_CTRL2 0x01233425 44 - 45 - static void rtw8723d_lck(struct rtw_dev *rtwdev) 46 - { 47 - u32 lc_cal; 48 - u8 val_ctx, rf_val; 49 - int ret; 50 - 51 - val_ctx = rtw_read8(rtwdev, REG_CTX); 52 - if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 53 - rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); 54 - else 55 - rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); 56 - lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 57 - 58 - rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); 59 - 60 - ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, 61 - 10000, 1000000, false, 62 - rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); 63 - if (ret) 64 - rtw_warn(rtwdev, "failed to poll LCK status bit\n"); 65 - 66 - rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); 67 - if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 68 - rtw_write8(rtwdev, REG_CTX, val_ctx); 69 - else 70 - rtw_write8(rtwdev, REG_TXPAUSE, 0x00); 71 - } 72 67 73 68 static const u32 rtw8723d_ofdm_swing_table[] = { 74 69 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, ··· 145 196 146 197 rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); 147 198 148 - rtw8723d_lck(rtwdev); 199 + rtw8723x_lck(rtwdev); 149 200 150 201 rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 151 202 rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); 152 203 153 204 rtw8723d_pwrtrack_init(rtwdev); 154 - } 155 - 156 - static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, 157 - struct rtw8723d_efuse *map) 158 - { 159 - ether_addr_copy(efuse->addr, map->e.mac_addr); 160 - } 161 - 162 - static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, 163 - struct rtw8723d_efuse *map) 164 - { 165 - ether_addr_copy(efuse->addr, map->u.mac_addr); 166 - } 167 - 168 - static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, 169 - struct rtw8723d_efuse *map) 170 - { 171 - ether_addr_copy(efuse->addr, map->s.mac_addr); 172 - } 173 - 174 - static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 175 - { 176 - struct rtw_efuse *efuse = &rtwdev->efuse; 177 - struct rtw8723d_efuse *map; 178 - int i; 179 - 180 - map = (struct rtw8723d_efuse *)log_map; 181 - 182 - efuse->rfe_option = 0; 183 - efuse->rf_board_option = map->rf_board_option; 184 - efuse->crystal_cap = map->xtal_k; 185 - efuse->pa_type_2g = map->pa_type; 186 - efuse->lna_type_2g = map->lna_type_2g[0]; 187 - efuse->channel_plan = map->channel_plan; 188 - efuse->country_code[0] = map->country_code[0]; 189 - efuse->country_code[1] = map->country_code[1]; 190 - efuse->bt_setting = map->rf_bt_setting; 191 - efuse->regd = map->rf_board_option & 0x7; 192 - efuse->thermal_meter[0] = map->thermal_meter; 193 - efuse->thermal_meter_k = map->thermal_meter; 194 - efuse->afe = map->afe; 195 - 196 - for (i = 0; i < 4; i++) 197 - efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 198 - 199 - switch (rtw_hci_type(rtwdev)) { 200 - case RTW_HCI_TYPE_PCIE: 201 - rtw8723de_efuse_parsing(efuse, map); 202 - break; 203 - case RTW_HCI_TYPE_USB: 204 - rtw8723du_efuse_parsing(efuse, map); 205 - break; 206 - case RTW_HCI_TYPE_SDIO: 207 - rtw8723ds_efuse_parsing(efuse, map); 208 - break; 209 - default: 210 - /* unsupported now */ 211 - return -ENOTSUPP; 212 - } 213 - 214 - return 0; 215 205 } 216 206 217 207 static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, ··· 428 540 rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 429 541 } 430 542 431 - #define BIT_CFENDFORM BIT(9) 432 - #define BIT_WMAC_TCR_ERR0 BIT(12) 433 - #define BIT_WMAC_TCR_ERR1 BIT(13) 434 - #define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ 435 - BIT_WMAC_TCR_ERR1) 436 - #define WLAN_RX_FILTER0 0xFFFF 437 - #define WLAN_RX_FILTER1 0x400 438 - #define WLAN_RX_FILTER2 0xFFFF 439 - #define WLAN_RCR_CFG 0x700060CE 440 - 441 - static int rtw8723d_mac_init(struct rtw_dev *rtwdev) 442 - { 443 - rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 444 - rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); 445 - 446 - rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 447 - rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); 448 - rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 449 - rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 450 - 451 - rtw_write32(rtwdev, REG_INT_MIG, 0); 452 - rtw_write32(rtwdev, REG_MCUTST_1, 0x0); 453 - 454 - rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); 455 - rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); 456 - 457 - return 0; 458 - } 459 - 460 543 static void rtw8723d_shutdown(struct rtw_dev *rtwdev) 461 544 { 462 545 rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); 463 - } 464 - 465 - static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 466 - { 467 - u8 ldo_pwr; 468 - 469 - ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); 470 - if (enable) { 471 - ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; 472 - ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; 473 - } else { 474 - ldo_pwr &= ~BIT_LDO25_EN; 475 - } 476 - rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); 477 - } 478 - 479 - static void 480 - rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) 481 - { 482 - struct rtw_hal *hal = &rtwdev->hal; 483 - const struct rtw_hw_reg *txagc; 484 - u8 rate, pwr_index; 485 - int j; 486 - 487 - for (j = 0; j < rtw_rate_size[rs]; j++) { 488 - rate = rtw_rate_section[rs][j]; 489 - pwr_index = hal->tx_pwr_tbl[path][rate]; 490 - 491 - if (rate >= ARRAY_SIZE(rtw8723d_txagc)) { 492 - rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); 493 - continue; 494 - } 495 - txagc = &rtw8723d_txagc[rate]; 496 - if (!txagc->addr) { 497 - rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); 498 - continue; 499 - } 500 - 501 - rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); 502 - } 503 - } 504 - 505 - static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev) 506 - { 507 - struct rtw_hal *hal = &rtwdev->hal; 508 - int rs, path; 509 - 510 - for (path = 0; path < hal->rf_path_num; path++) { 511 - for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) 512 - rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs); 513 - } 514 - } 515 - 516 - static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on) 517 - { 518 - if (on) { 519 - rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); 520 - 521 - rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); 522 - rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); 523 - } else { 524 - rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); 525 - } 526 - } 527 - 528 - static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev) 529 - { 530 - struct rtw_dm_info *dm_info = &rtwdev->dm_info; 531 - u32 cck_fa_cnt; 532 - u32 ofdm_fa_cnt; 533 - u32 crc32_cnt; 534 - u32 val32; 535 - 536 - /* hold counter */ 537 - rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); 538 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); 539 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); 540 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); 541 - 542 - cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); 543 - cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; 544 - 545 - val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); 546 - ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); 547 - ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); 548 - val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); 549 - dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); 550 - ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); 551 - val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); 552 - ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); 553 - ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); 554 - val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); 555 - ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); 556 - 557 - dm_info->cck_fa_cnt = cck_fa_cnt; 558 - dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 559 - dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; 560 - 561 - dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); 562 - dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); 563 - crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); 564 - dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); 565 - dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); 566 - crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); 567 - dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); 568 - dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); 569 - dm_info->vht_err_cnt = 0; 570 - dm_info->vht_ok_cnt = 0; 571 - 572 - val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); 573 - dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | 574 - u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); 575 - dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; 576 - 577 - /* reset counter */ 578 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); 579 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); 580 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); 581 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); 582 - rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); 583 - rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); 584 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); 585 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); 586 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); 587 - rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); 588 - rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); 589 - rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); 590 - } 591 - 592 - static const u32 iqk_adda_regs[] = { 593 - 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 594 - 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec 595 - }; 596 - 597 - static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551}; 598 - static const u32 iqk_mac32_regs[] = {0x40}; 599 - 600 - static const u32 iqk_bb_regs[] = { 601 - 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 602 - }; 603 - 604 - #define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs) 605 - #define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs) 606 - #define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs) 607 - #define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs) 608 - 609 - struct iqk_backup_regs { 610 - u32 adda[IQK_ADDA_REG_NUM]; 611 - u8 mac8[IQK_MAC8_REG_NUM]; 612 - u32 mac32[IQK_MAC32_REG_NUM]; 613 - u32 bb[IQK_BB_REG_NUM]; 614 - 615 - u32 lte_path; 616 - u32 lte_gnt; 617 - 618 - u32 bb_sel_btg; 619 - u8 btg_sel; 620 - 621 - u8 igia; 622 - u8 igib; 623 - }; 624 - 625 - static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev, 626 - struct iqk_backup_regs *backup) 627 - { 628 - int i; 629 - 630 - for (i = 0; i < IQK_ADDA_REG_NUM; i++) 631 - backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]); 632 - 633 - for (i = 0; i < IQK_MAC8_REG_NUM; i++) 634 - backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]); 635 - for (i = 0; i < IQK_MAC32_REG_NUM; i++) 636 - backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]); 637 - 638 - for (i = 0; i < IQK_BB_REG_NUM; i++) 639 - backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]); 640 - 641 - backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); 642 - backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); 643 - 644 - backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); 645 - } 646 - 647 - static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev, 648 - const struct iqk_backup_regs *backup) 649 - { 650 - int i; 651 - 652 - for (i = 0; i < IQK_ADDA_REG_NUM; i++) 653 - rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]); 654 - 655 - for (i = 0; i < IQK_MAC8_REG_NUM; i++) 656 - rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]); 657 - for (i = 0; i < IQK_MAC32_REG_NUM; i++) 658 - rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]); 659 - 660 - for (i = 0; i < IQK_BB_REG_NUM; i++) 661 - rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]); 662 - 663 - rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 664 - rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); 665 - 666 - rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); 667 - rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); 668 - 669 - rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); 670 - rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); 671 - } 672 - 673 - static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, 674 - struct iqk_backup_regs *backup) 675 - { 676 - backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); 677 - rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", 678 - backup->btg_sel); 679 - } 680 - 681 - static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev) 682 - { 683 - rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); 684 - rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", 685 - rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 686 - } 687 - 688 - static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, 689 - const struct iqk_backup_regs *backup) 690 - { 691 - rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); 692 - rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", 693 - rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 694 - } 695 - 696 - static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, 697 - struct iqk_backup_regs *backup) 698 - { 699 - backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); 700 - rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); 701 - mdelay(1); 702 - backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); 703 - rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", 704 - backup->lte_gnt); 705 - } 706 - 707 - static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev) 708 - { 709 - rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00); 710 - rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); 711 - rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1); 712 - } 713 - 714 - static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, 715 - const struct iqk_backup_regs *bak) 716 - { 717 - rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); 718 - rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); 719 - rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); 720 546 } 721 547 722 548 struct rtw_8723d_iqk_cfg { ··· 532 930 return 0; 533 931 } 534 932 933 + #define IQK_LTE_WRITE_VAL_8723D 0x0000ff00 934 + 535 935 static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, 536 936 const struct rtw_8723d_iqk_cfg *iqk_cfg) 537 937 { ··· 541 937 542 938 /* enter IQK mode */ 543 939 rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 544 - rtw8723d_iqk_config_lte_path_gnt(rtwdev); 940 + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); 545 941 546 942 rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054); 547 943 mdelay(1); ··· 563 959 564 960 static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, 565 961 const struct rtw_8723d_iqk_cfg *iqk_cfg, 566 - const struct iqk_backup_regs *backup) 962 + const struct rtw8723x_iqk_backup_regs *backup) 567 963 { 568 - rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup); 964 + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); 569 965 rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); 570 966 571 967 /* leave IQK mode */ ··· 578 974 579 975 static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, 580 976 const struct rtw_8723d_iqk_cfg *iqk_cfg, 581 - const struct iqk_backup_regs *backup) 977 + const struct rtw8723x_iqk_backup_regs *backup) 582 978 { 583 979 u8 status; 584 980 ··· 637 1033 638 1034 static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, 639 1035 const struct rtw_8723d_iqk_cfg *iqk_cfg, 640 - const struct iqk_backup_regs *backup) 1036 + const struct rtw8723x_iqk_backup_regs *backup) 641 1037 { 642 1038 u32 tx_x, tx_y; 643 1039 u8 status; ··· 824 1220 result[IQK_S0_RX_Y]); 825 1221 } 826 1222 827 - static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev) 828 - { 829 - int i; 830 - 831 - for (i = 0; i < IQK_ADDA_REG_NUM; i++) 832 - rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016); 833 - } 834 - 835 1223 static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) 836 1224 { 837 1225 rtw_write8(rtwdev, REG_TXPAUSE, 0xff); ··· 841 1245 rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 842 1246 } 843 1247 844 - static 845 - bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], 846 - u8 c1, u8 c2) 847 - { 848 - u32 i, j, diff; 849 - u32 bitmap = 0; 850 - u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; 851 - bool ret = true; 852 - 853 - s32 tmp1, tmp2; 854 - 855 - for (i = 0; i < IQK_NR; i++) { 856 - tmp1 = iqkxy_to_s32(result[c1][i]); 857 - tmp2 = iqkxy_to_s32(result[c2][i]); 858 - 859 - diff = abs(tmp1 - tmp2); 860 - 861 - if (diff <= MAX_TOLERANCE) 862 - continue; 863 - 864 - if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { 865 - if (result[c1][i] + result[c1][i + 1] == 0) 866 - candidate[i / IQK_SX_NR] = c2; 867 - else if (result[c2][i] + result[c2][i + 1] == 0) 868 - candidate[i / IQK_SX_NR] = c1; 869 - else 870 - bitmap |= BIT(i); 871 - } else { 872 - bitmap |= BIT(i); 873 - } 874 - } 875 - 876 - if (bitmap != 0) 877 - goto check_sim; 878 - 879 - for (i = 0; i < PATH_NR; i++) { 880 - if (candidate[i] == IQK_ROUND_INVALID) 881 - continue; 882 - 883 - for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) 884 - result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; 885 - ret = false; 886 - } 887 - 888 - return ret; 889 - 890 - check_sim: 891 - for (i = 0; i < IQK_NR; i++) { 892 - j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ 893 - if (bitmap & GENMASK(j + 1, j)) 894 - continue; 895 - 896 - result[IQK_ROUND_HYBRID][i] = result[c1][i]; 897 - } 898 - 899 - return false; 900 - } 1248 + #define ADDA_ON_VAL_8723D 0x03c00016 901 1249 902 1250 static 903 - void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) 1251 + void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723x_path path) 904 1252 { 905 1253 if (path == PATH_S0) { 906 1254 rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A); 907 - rtw8723d_iqk_path_adda_on(rtwdev); 1255 + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); 908 1256 } 909 1257 910 1258 rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); ··· 857 1317 858 1318 if (path == PATH_S1) { 859 1319 rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B); 860 - rtw8723d_iqk_path_adda_on(rtwdev); 1320 + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); 861 1321 } 862 1322 } 863 1323 864 1324 static 865 1325 void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, 866 - const struct iqk_backup_regs *backup) 1326 + const struct rtw8723x_iqk_backup_regs *backup) 867 1327 { 868 1328 u32 i; 869 1329 u8 s1_ok, s0_ok; ··· 871 1331 rtw_dbg(rtwdev, RTW_DBG_RFK, 872 1332 "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); 873 1333 874 - rtw8723d_iqk_path_adda_on(rtwdev); 1334 + rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); 875 1335 rtw8723d_iqk_config_mac(rtwdev); 876 1336 rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); 877 1337 rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611); ··· 967 1427 { 968 1428 struct rtw_dm_info *dm_info = &rtwdev->dm_info; 969 1429 s32 result[IQK_ROUND_SIZE][IQK_NR]; 970 - struct iqk_backup_regs backup; 1430 + struct rtw8723x_iqk_backup_regs backup; 971 1431 u8 i, j; 972 1432 u8 final_candidate = IQK_ROUND_INVALID; 973 1433 bool good; ··· 976 1436 977 1437 memset(result, 0, sizeof(result)); 978 1438 979 - rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup); 980 - rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup); 981 - rtw8723d_iqk_backup_regs(rtwdev, &backup); 1439 + rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); 1440 + rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); 1441 + rtw8723x_iqk_backup_regs(rtwdev, &backup); 982 1442 983 1443 for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { 984 - rtw8723d_iqk_config_path_ctrl(rtwdev); 985 - rtw8723d_iqk_config_lte_path_gnt(rtwdev); 1444 + rtw8723x_iqk_config_path_ctrl(rtwdev); 1445 + rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); 986 1446 987 1447 rtw8723d_iqk_one_round(rtwdev, result, i, &backup); 988 1448 989 1449 if (i > IQK_ROUND_0) 990 - rtw8723d_iqk_restore_regs(rtwdev, &backup); 991 - rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup); 992 - rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup); 1450 + rtw8723x_iqk_restore_regs(rtwdev, &backup); 1451 + rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); 1452 + rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); 993 1453 994 1454 for (j = IQK_ROUND_0; j < i; j++) { 995 - good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i); 1455 + good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); 996 1456 997 1457 if (good) { 998 1458 final_candidate = j; ··· 1086 1546 } 1087 1547 1088 1548 /* for coex */ 1089 - static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev) 1090 - { 1091 - /* enable TBTT nterrupt */ 1092 - rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 1093 - 1094 - /* BT report packet sample rate */ 1095 - /* 0x790[5:0]=0x5 */ 1096 - rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 1097 - 1098 - /* enable BT counter statistics */ 1099 - rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); 1100 - 1101 - /* enable PTA (3-wire function form BT side) */ 1102 - rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 1103 - rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); 1104 - 1105 - /* enable PTA (tx/rx signal form WiFi side) */ 1106 - rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 1107 - } 1108 - 1109 1549 static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 1110 1550 { 1111 1551 } ··· 1189 1669 for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) 1190 1670 rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_off[i]); 1191 1671 } 1192 - } 1193 - 1194 - static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) 1195 - { 1196 - struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1197 - u8 tx_rate = dm_info->tx_rate; 1198 - u8 limit_ofdm = 30; 1199 - 1200 - switch (tx_rate) { 1201 - case DESC_RATE1M...DESC_RATE5_5M: 1202 - case DESC_RATE11M: 1203 - break; 1204 - case DESC_RATE6M...DESC_RATE48M: 1205 - limit_ofdm = 36; 1206 - break; 1207 - case DESC_RATE54M: 1208 - limit_ofdm = 34; 1209 - break; 1210 - case DESC_RATEMCS0...DESC_RATEMCS2: 1211 - limit_ofdm = 38; 1212 - break; 1213 - case DESC_RATEMCS3...DESC_RATEMCS4: 1214 - limit_ofdm = 36; 1215 - break; 1216 - case DESC_RATEMCS5...DESC_RATEMCS7: 1217 - limit_ofdm = 34; 1218 - break; 1219 - default: 1220 - rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); 1221 - break; 1222 - } 1223 - 1224 - return limit_ofdm; 1225 1672 } 1226 1673 1227 1674 static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, ··· 1332 1845 s8 final_ofdm_swing_index; 1333 1846 s8 final_cck_swing_index; 1334 1847 1335 - limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev); 1848 + limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); 1336 1849 1337 1850 final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + 1338 1851 dm_info->delta_power_index[path]; ··· 1360 1873 rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); 1361 1874 } 1362 1875 1363 - static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, 1364 - u8 delta) 1365 - { 1366 - struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1367 - const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; 1368 - const s8 *pwrtrk_xtal; 1369 - s8 xtal_cap; 1370 - 1371 - if (dm_info->thermal_avg[therm_path] > 1372 - rtwdev->efuse.thermal_meter[therm_path]) 1373 - pwrtrk_xtal = tbl->pwrtrk_xtal_p; 1374 - else 1375 - pwrtrk_xtal = tbl->pwrtrk_xtal_n; 1376 - 1377 - xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; 1378 - xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); 1379 - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, 1380 - xtal_cap | (xtal_cap << 6)); 1381 - } 1382 - 1383 1876 static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) 1384 1877 { 1385 1878 struct rtw_dm_info *dm_info = &rtwdev->dm_info; ··· 1379 1912 do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); 1380 1913 1381 1914 if (do_iqk) 1382 - rtw8723d_lck(rtwdev); 1915 + rtw8723x_lck(rtwdev); 1383 1916 1384 1917 if (dm_info->pwr_trk_init_trigger) 1385 1918 dm_info->pwr_trk_init_trigger = false; ··· 1404 1937 rtw8723d_pwrtrack_set(rtwdev, path); 1405 1938 } 1406 1939 1407 - rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); 1940 + rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); 1408 1941 1409 1942 iqk: 1410 1943 if (do_iqk) ··· 1430 1963 dm_info->pwr_trk_triggered = false; 1431 1964 } 1432 1965 1433 - static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev, 1434 - struct rtw_tx_pkt_info *pkt_info, 1435 - u8 *txdesc) 1436 - { 1437 - size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ 1438 - __le16 chksum = 0; 1439 - __le16 *data = (__le16 *)(txdesc); 1440 - struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; 1441 - 1442 - le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); 1443 - 1444 - while (words--) 1445 - chksum ^= *data++; 1446 - 1447 - chksum = ~chksum; 1448 - 1449 - le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), 1450 - RTW_TX_DESC_W7_TXDESC_CHECKSUM); 1451 - } 1452 - 1453 1966 static struct rtw_chip_ops rtw8723d_ops = { 1454 1967 .phy_set_param = rtw8723d_phy_set_param, 1455 - .read_efuse = rtw8723d_read_efuse, 1968 + .read_efuse = rtw8723x_read_efuse, 1456 1969 .query_rx_desc = rtw8723d_query_rx_desc, 1457 1970 .set_channel = rtw8723d_set_channel, 1458 - .mac_init = rtw8723d_mac_init, 1971 + .mac_init = rtw8723x_mac_init, 1459 1972 .shutdown = rtw8723d_shutdown, 1460 1973 .read_rf = rtw_phy_read_rf_sipi, 1461 1974 .write_rf = rtw_phy_write_rf_reg_sipi, 1462 - .set_tx_power_index = rtw8723d_set_tx_power_index, 1975 + .set_tx_power_index = rtw8723x_set_tx_power_index, 1463 1976 .set_antenna = NULL, 1464 - .cfg_ldo25 = rtw8723d_cfg_ldo25, 1465 - .efuse_grant = rtw8723d_efuse_grant, 1466 - .false_alarm_statistics = rtw8723d_false_alarm_statistics, 1977 + .cfg_ldo25 = rtw8723x_cfg_ldo25, 1978 + .efuse_grant = rtw8723x_efuse_grant, 1979 + .false_alarm_statistics = rtw8723x_false_alarm_statistics, 1467 1980 .phy_calibration = rtw8723d_phy_calibration, 1468 1981 .cck_pd_set = rtw8723d_phy_cck_pd_set, 1469 1982 .pwr_track = rtw8723d_pwr_track, 1470 1983 .config_bfee = NULL, 1471 1984 .set_gid_table = NULL, 1472 1985 .cfg_csi_rate = NULL, 1473 - .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum, 1986 + .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, 1474 1987 1475 - .coex_set_init = rtw8723d_coex_cfg_init, 1988 + .coex_set_init = rtw8723x_coex_cfg_init, 1476 1989 .coex_set_ant_switch = NULL, 1477 1990 .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, 1478 1991 .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, ··· 2039 2592 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 2040 2593 }; 2041 2594 2042 - static const struct rtw_prioq_addrs prioq_addrs_8723d = { 2043 - .prio[RTW_DMA_MAPPING_EXTRA] = { 2044 - .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, 2045 - }, 2046 - .prio[RTW_DMA_MAPPING_LOW] = { 2047 - .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, 2048 - }, 2049 - .prio[RTW_DMA_MAPPING_NORMAL] = { 2050 - .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, 2051 - }, 2052 - .prio[RTW_DMA_MAPPING_HIGH] = { 2053 - .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, 2054 - }, 2055 - .wsize = false, 2056 - }; 2057 - 2058 2595 static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = { 2059 2596 {0x0008, 0x4a22, 2060 2597 RTW_IP_SEL_PHY, ··· 2057 2626 static const struct rtw_intf_phy_para_table phy_para_table_8723d = { 2058 2627 .gen1_para = pcie_gen1_param_8723d, 2059 2628 .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), 2060 - }; 2061 - 2062 - static const struct rtw_hw_reg rtw8723d_dig[] = { 2063 - [0] = { .addr = 0xc50, .mask = 0x7f }, 2064 - [1] = { .addr = 0xc50, .mask = 0x7f }, 2065 - }; 2066 - 2067 - static const struct rtw_hw_reg rtw8723d_dig_cck[] = { 2068 - [0] = { .addr = 0xa0c, .mask = 0x3f00 }, 2069 - }; 2070 - 2071 - static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = { 2072 - [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, 2073 - .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, 2074 - [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, 2075 - .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, 2076 - }; 2077 - 2078 - static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = { 2079 - .ctrl = REG_LTECOEX_CTRL, 2080 - .wdata = REG_LTECOEX_WRITE_DATA, 2081 - .rdata = REG_LTECOEX_READ_DATA, 2082 2629 }; 2083 2630 2084 2631 static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { ··· 2179 2770 .pwr_off_seq = card_disable_flow_8723d, 2180 2771 .page_table = page_table_8723d, 2181 2772 .rqpn_table = rqpn_table_8723d, 2182 - .prioq_addrs = &prioq_addrs_8723d, 2773 + .prioq_addrs = &rtw8723x_common.prioq_addrs, 2183 2774 .intf_table = &phy_para_table_8723d, 2184 - .dig = rtw8723d_dig, 2185 - .dig_cck = rtw8723d_dig_cck, 2775 + .dig = rtw8723x_common.dig, 2776 + .dig_cck = rtw8723x_common.dig_cck, 2186 2777 .rf_sipi_addr = {0x840, 0x844}, 2187 - .rf_sipi_read_addr = rtw8723d_rf_sipi_addr, 2778 + .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, 2188 2779 .fix_rf_phy_num = 2, 2189 - .ltecoex_addr = &rtw8723d_ltecoex_addr, 2780 + .ltecoex_addr = &rtw8723x_common.ltecoex_addr, 2190 2781 .mac_tbl = &rtw8723d_mac_tbl, 2191 2782 .agc_tbl = &rtw8723d_agc_tbl, 2192 2783 .bb_tbl = &rtw8723d_bb_tbl,
+1 -268
drivers/net/wireless/realtek/rtw88/rtw8723d.h
··· 5 5 #ifndef __RTW8723D_H__ 6 6 #define __RTW8723D_H__ 7 7 8 - enum rtw8723d_path { 9 - PATH_S1, 10 - PATH_S0, 11 - PATH_NR, 12 - }; 13 - 14 - enum rtw8723d_iqk_round { 15 - IQK_ROUND_0, 16 - IQK_ROUND_1, 17 - IQK_ROUND_2, 18 - IQK_ROUND_HYBRID, 19 - IQK_ROUND_SIZE, 20 - IQK_ROUND_INVALID = 0xff, 21 - }; 22 - 23 - enum rtw8723d_iqk_result { 24 - IQK_S1_TX_X, 25 - IQK_S1_TX_Y, 26 - IQK_S1_RX_X, 27 - IQK_S1_RX_Y, 28 - IQK_S0_TX_X, 29 - IQK_S0_TX_Y, 30 - IQK_S0_RX_X, 31 - IQK_S0_RX_Y, 32 - IQK_NR, 33 - IQK_SX_NR = IQK_NR / PATH_NR, 34 - }; 35 - 36 - struct rtw8723de_efuse { 37 - u8 mac_addr[ETH_ALEN]; /* 0xd0 */ 38 - u8 vender_id[2]; 39 - u8 device_id[2]; 40 - u8 sub_vender_id[2]; 41 - u8 sub_device_id[2]; 42 - }; 43 - 44 - struct rtw8723du_efuse { 45 - u8 res4[48]; /* 0xd0 */ 46 - u8 vender_id[2]; /* 0x100 */ 47 - u8 product_id[2]; /* 0x102 */ 48 - u8 usb_option; /* 0x104 */ 49 - u8 res5[2]; /* 0x105 */ 50 - u8 mac_addr[ETH_ALEN]; /* 0x107 */ 51 - }; 52 - 53 - struct rtw8723ds_efuse { 54 - u8 res4[0x4a]; /* 0xd0 */ 55 - u8 mac_addr[ETH_ALEN]; /* 0x11a */ 56 - }; 57 - 58 - struct rtw8723d_efuse { 59 - __le16 rtl_id; 60 - u8 rsvd[2]; 61 - u8 afe; 62 - u8 rsvd1[11]; 63 - 64 - /* power index for four RF paths */ 65 - struct rtw_txpwr_idx txpwr_idx_table[4]; 66 - 67 - u8 channel_plan; /* 0xb8 */ 68 - u8 xtal_k; 69 - u8 thermal_meter; 70 - u8 iqk_lck; 71 - u8 pa_type; /* 0xbc */ 72 - u8 lna_type_2g[2]; /* 0xbd */ 73 - u8 lna_type_5g[2]; 74 - u8 rf_board_option; 75 - u8 rf_feature_option; 76 - u8 rf_bt_setting; 77 - u8 eeprom_version; 78 - u8 eeprom_customer_id; 79 - u8 tx_bb_swing_setting_2g; 80 - u8 res_c7; 81 - u8 tx_pwr_calibrate_rate; 82 - u8 rf_antenna_option; /* 0xc9 */ 83 - u8 rfe_option; 84 - u8 country_code[2]; 85 - u8 res[3]; 86 - union { 87 - struct rtw8723de_efuse e; 88 - struct rtw8723du_efuse u; 89 - struct rtw8723ds_efuse s; 90 - }; 91 - }; 8 + #include "rtw8723x.h" 92 9 93 10 extern const struct rtw_chip_info rtw8723d_hw_spec; 94 11 ··· 31 114 #define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ 32 115 le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) 33 116 34 - static inline s32 iqkxy_to_s32(s32 val) 35 - { 36 - /* val is Q10.8 */ 37 - return sign_extend32(val, 9); 38 - } 39 - 40 - static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) 41 - { 42 - /* x, y and return value are Q10.8 */ 43 - s32 t; 44 - 45 - t = x * y; 46 - if (ext) 47 - *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ 48 - 49 - return (t >> 8); /* Q.16 --> Q.8 */ 50 - } 51 - 52 - #define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing) 53 - #define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing) 54 - #define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing) 55 - #define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing) 56 117 #define RTW_DEF_OFDM_SWING_INDEX 28 57 118 #define RTW_DEF_CCK_SWING_INDEX 28 58 119 59 - #define MAX_TOLERANCE 5 60 - #define IQK_TX_X_ERR 0x142 61 - #define IQK_TX_Y_ERR 0x42 62 - #define IQK_RX_X_UPPER 0x11a 63 - #define IQK_RX_X_LOWER 0xe6 64 - #define IQK_RX_Y_LMT 0x1a 65 - #define IQK_TX_OK BIT(0) 66 - #define IQK_RX_OK BIT(1) 67 - #define PATH_IQK_RETRY 2 68 - 69 - #define SPUR_THRES 0x16 70 120 #define CCK_DFIR_NR 3 71 - #define DIS_3WIRE 0xccf000c0 72 - #define EN_3WIRE 0xccc000c0 73 - #define START_PSD 0x400000 74 - #define FREQ_CH13 0xfccd 75 - #define FREQ_CH14 0xff9a 76 - #define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) 77 - #define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) 78 - #define RFCFGCH_BW_20M (BIT(11) | BIT(10)) 79 - #define RFCFGCH_BW_40M BIT(10) 80 - #define BIT_MASK_RFMOD BIT(0) 81 - #define BIT_LCK BIT(15) 82 - 83 - #define REG_GPIO_INTM 0x0048 84 - #define REG_BTG_SEL 0x0067 85 - #define BIT_MASK_BTG_WL BIT(7) 86 - #define REG_LTECOEX_PATH_CONTROL 0x0070 87 - #define REG_LTECOEX_CTRL 0x07c0 88 - #define REG_LTECOEX_WRITE_DATA 0x07c4 89 - #define REG_LTECOEX_READ_DATA 0x07c8 90 - #define REG_PSDFN 0x0808 91 - #define REG_BB_PWR_SAV1_11N 0x0874 92 - #define REG_ANA_PARAM1 0x0880 93 - #define REG_ANALOG_P4 0x088c 94 - #define REG_PSDRPT 0x08b4 95 - #define REG_FPGA1_RFMOD 0x0900 96 - #define REG_BB_SEL_BTG 0x0948 97 - #define REG_BBRX_DFIR 0x0954 98 - #define BIT_MASK_RXBB_DFIR GENMASK(27, 24) 99 - #define BIT_RXBB_DFIR_EN BIT(19) 100 - #define REG_CCK0_SYS 0x0a00 101 - #define BIT_CCK_SIDE_BAND BIT(4) 102 - #define REG_CCK_ANT_SEL_11N 0x0a04 103 - #define REG_PWRTH 0x0a08 104 - #define REG_CCK_FA_RST_11N 0x0a2c 105 - #define BIT_MASK_CCK_CNT_KEEP BIT(12) 106 - #define BIT_MASK_CCK_CNT_EN BIT(13) 107 - #define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) 108 - #define BIT_MASK_CCK_FA_KEEP BIT(14) 109 - #define BIT_MASK_CCK_FA_EN BIT(15) 110 - #define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) 111 - #define REG_CCK_FA_LSB_11N 0x0a5c 112 - #define REG_CCK_FA_MSB_11N 0x0a58 113 - #define REG_CCK_CCA_CNT_11N 0x0a60 114 - #define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) 115 - #define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) 116 - #define REG_PWRTH2 0x0aa8 117 - #define REG_CSRATIO 0x0aaa 118 - #define REG_OFDM_FA_HOLDC_11N 0x0c00 119 - #define BIT_MASK_OFDM_FA_KEEP BIT(31) 120 - #define REG_BB_RX_PATH_11N 0x0c04 121 - #define REG_TRMUX_11N 0x0c08 122 - #define REG_OFDM_FA_RSTC_11N 0x0c0c 123 - #define BIT_MASK_OFDM_FA_RST BIT(31) 124 - #define REG_A_RXIQI 0x0c14 125 - #define BIT_MASK_RXIQ_S1_X 0x000003FF 126 - #define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 127 - #define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) 128 - #define REG_OFDM0_RXDSP 0x0c40 129 - #define BIT_MASK_RXDSP GENMASK(28, 24) 130 - #define BIT_EN_RXDSP BIT(9) 131 - #define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c 132 - #define BIT_MASK_OFDM0_EXT_A BIT(31) 133 - #define BIT_MASK_OFDM0_EXT_C BIT(29) 134 - #define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) 135 - #define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) 136 - #define REG_OFDM0_XAAGC1 0x0c50 137 - #define REG_OFDM0_XBAGC1 0x0c58 138 - #define REG_AGCRSSI 0x0c78 139 - #define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 140 - #define BIT_MASK_TXIQ_ELM_A 0x03ff 141 - #define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ 142 - ((a) & 0x03ff)) 143 - #define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) 144 - #define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) 145 - #define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) 146 - #define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 147 - #define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) 148 - #define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 149 - #define BIT_MASK_RXIQ_S1_Y2 0xF0000000 150 - #define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) 151 - #define REG_TXIQ_AB_S0 0x0cd0 152 - #define BIT_MASK_TXIQ_A_S0 0x000007FE 153 - #define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) 154 - #define BIT_MASK_TXIQ_B_S0 0x0007E000 155 - #define REG_TXIQ_CD_S0 0x0cd4 156 - #define BIT_MASK_TXIQ_C_S0 0x000007FE 157 - #define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) 158 - #define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) 159 - #define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) 160 - #define REG_RXIQ_AB_S0 0x0cd8 161 - #define BIT_MASK_RXIQ_X_S0 0x000003FF 162 - #define BIT_MASK_RXIQ_Y_S0 0x003FF000 163 - #define REG_OFDM_FA_TYPE1_11N 0x0cf0 164 - #define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) 165 - #define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) 166 - #define REG_OFDM_FA_RSTD_11N 0x0d00 167 - #define BIT_MASK_OFDM_FA_RST1 BIT(27) 168 - #define BIT_MASK_OFDM_FA_KEEP1 BIT(31) 169 - #define REG_CTX 0x0d03 170 - #define BIT_MASK_CTX_TYPE GENMASK(6, 4) 171 - #define REG_OFDM1_CFOTRK 0x0d2c 172 - #define BIT_EN_CFOTRK BIT(28) 173 - #define REG_OFDM1_CSI1 0x0d40 174 - #define REG_OFDM1_CSI2 0x0d44 175 - #define REG_OFDM1_CSI3 0x0d48 176 - #define REG_OFDM1_CSI4 0x0d4c 177 - #define REG_OFDM_FA_TYPE2_11N 0x0da0 178 - #define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) 179 - #define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) 180 - #define REG_OFDM_FA_TYPE3_11N 0x0da4 181 - #define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) 182 - #define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) 183 - #define REG_OFDM_FA_TYPE4_11N 0x0da8 184 - #define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) 185 - #define REG_FPGA0_IQK_11N 0x0e28 186 - #define BIT_MASK_IQK_MOD 0xffffff00 187 - #define EN_IQK 0x808000 188 - #define RST_IQK 0x000000 189 - #define REG_TXIQK_TONE_A_11N 0x0e30 190 - #define REG_RXIQK_TONE_A_11N 0x0e34 191 - #define REG_TXIQK_PI_A_11N 0x0e38 192 - #define REG_RXIQK_PI_A_11N 0x0e3c 193 - #define REG_TXIQK_11N 0x0e40 194 - #define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) 195 - #define REG_RXIQK_11N 0x0e44 196 - #define REG_IQK_AGC_PTS_11N 0x0e48 197 - #define REG_IQK_AGC_RSP_11N 0x0e4c 198 - #define REG_TX_IQK_TONE_B 0x0e50 199 - #define REG_RX_IQK_TONE_B 0x0e54 200 - #define REG_IQK_RES_TX 0x0e94 201 - #define BIT_MASK_RES_TX GENMASK(25, 16) 202 - #define REG_IQK_RES_TY 0x0e9c 203 - #define BIT_MASK_RES_TY GENMASK(25, 16) 204 - #define REG_IQK_RES_RX 0x0ea4 205 - #define BIT_MASK_RES_RX GENMASK(25, 16) 206 - #define REG_IQK_RES_RY 0x0eac 207 - #define BIT_IQK_TX_FAIL BIT(28) 208 - #define BIT_IQK_RX_FAIL BIT(27) 209 - #define BIT_IQK_DONE BIT(26) 210 - #define BIT_MASK_RES_RY GENMASK(25, 16) 211 - #define REG_PAGE_F_RST_11N 0x0f14 212 - #define BIT_MASK_F_RST_ALL BIT(16) 213 - #define REG_IGI_C_11N 0x0f84 214 - #define REG_IGI_D_11N 0x0f88 215 - #define REG_HT_CRC32_CNT_11N 0x0f90 216 - #define BIT_MASK_HT_CRC_OK GENMASK(15, 0) 217 - #define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) 218 - #define REG_OFDM_CRC32_CNT_11N 0x0f94 219 - #define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) 220 - #define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) 221 - #define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 222 121 223 122 #endif
+721
drivers/net/wireless/realtek/rtw88/rtw8723x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright 2024 Fiona Klute 3 + * 4 + * Based on code originally in rtw8723d.[ch], 5 + * Copyright(c) 2018-2019 Realtek Corporation 6 + */ 7 + 8 + #include "main.h" 9 + #include "debug.h" 10 + #include "phy.h" 11 + #include "reg.h" 12 + #include "tx.h" 13 + #include "rtw8723x.h" 14 + 15 + static const struct rtw_hw_reg rtw8723x_txagc[] = { 16 + [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, 17 + [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, 18 + [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, 19 + [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, 20 + [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, 21 + [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, 22 + [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, 23 + [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, 24 + [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, 25 + [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, 26 + [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, 27 + [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, 28 + [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, 29 + [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, 30 + [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, 31 + [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, 32 + [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, 33 + [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, 34 + [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, 35 + [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, 36 + }; 37 + 38 + static void __rtw8723x_lck(struct rtw_dev *rtwdev) 39 + { 40 + u32 lc_cal; 41 + u8 val_ctx, rf_val; 42 + int ret; 43 + 44 + val_ctx = rtw_read8(rtwdev, REG_CTX); 45 + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 46 + rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); 47 + else 48 + rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); 49 + lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 50 + 51 + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); 52 + 53 + ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, 54 + 10000, 1000000, false, 55 + rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); 56 + if (ret) 57 + rtw_warn(rtwdev, "failed to poll LCK status bit\n"); 58 + 59 + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); 60 + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 61 + rtw_write8(rtwdev, REG_CTX, val_ctx); 62 + else 63 + rtw_write8(rtwdev, REG_TXPAUSE, 0x00); 64 + } 65 + 66 + #define DBG_EFUSE_VAL(rtwdev, map, name) \ 67 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \ 68 + (map)->name) 69 + #define DBG_EFUSE_2BYTE(rtwdev, map, name) \ 70 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \ 71 + (map)->name[0], (map)->name[1]) 72 + 73 + static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev, 74 + struct rtw8723x_efuse *map) 75 + { 76 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr); 77 + DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id); 78 + DBG_EFUSE_2BYTE(rtwdev, map, e.device_id); 79 + DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id); 80 + DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id); 81 + } 82 + 83 + static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev, 84 + struct rtw8723x_efuse *map) 85 + { 86 + DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id); 87 + DBG_EFUSE_2BYTE(rtwdev, map, u.product_id); 88 + DBG_EFUSE_VAL(rtwdev, map, u.usb_option); 89 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr); 90 + } 91 + 92 + static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev, 93 + struct rtw8723x_efuse *map) 94 + { 95 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr); 96 + } 97 + 98 + static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, 99 + struct rtw_txpwr_idx *table, 100 + int tx_path_count) 101 + { 102 + if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) 103 + return; 104 + 105 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 106 + "Power index table (2.4G):\n"); 107 + /* CCK base */ 108 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n"); 109 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n"); 110 + for (int i = 0; i < tx_path_count; i++) 111 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 112 + "[%c]: %3u %3u %3u %3u %3u %3u\n", 113 + 'A' + i, 114 + table[i].pwr_idx_2g.cck_base[0], 115 + table[i].pwr_idx_2g.cck_base[1], 116 + table[i].pwr_idx_2g.cck_base[2], 117 + table[i].pwr_idx_2g.cck_base[3], 118 + table[i].pwr_idx_2g.cck_base[4], 119 + table[i].pwr_idx_2g.cck_base[5]); 120 + /* CCK diff */ 121 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n"); 122 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); 123 + for (int i = 0; i < tx_path_count; i++) 124 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 125 + "[%c]: %2d %2d %2d %2d\n", 126 + 'A' + i, 0 /* no diff for 1S */, 127 + table[i].pwr_idx_2g.ht_2s_diff.cck, 128 + table[i].pwr_idx_2g.ht_3s_diff.cck, 129 + table[i].pwr_idx_2g.ht_4s_diff.cck); 130 + /* BW40-1S base */ 131 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n"); 132 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n"); 133 + for (int i = 0; i < tx_path_count; i++) 134 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 135 + "[%c]: %3u %3u %3u %3u %3u\n", 136 + 'A' + i, 137 + table[i].pwr_idx_2g.bw40_base[0], 138 + table[i].pwr_idx_2g.bw40_base[1], 139 + table[i].pwr_idx_2g.bw40_base[2], 140 + table[i].pwr_idx_2g.bw40_base[3], 141 + table[i].pwr_idx_2g.bw40_base[4]); 142 + /* OFDM diff */ 143 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n"); 144 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); 145 + for (int i = 0; i < tx_path_count; i++) 146 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 147 + "[%c]: %2d %2d %2d %2d\n", 148 + 'A' + i, 149 + table[i].pwr_idx_2g.ht_1s_diff.ofdm, 150 + table[i].pwr_idx_2g.ht_2s_diff.ofdm, 151 + table[i].pwr_idx_2g.ht_3s_diff.ofdm, 152 + table[i].pwr_idx_2g.ht_4s_diff.ofdm); 153 + /* BW20 diff */ 154 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n"); 155 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); 156 + for (int i = 0; i < tx_path_count; i++) 157 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 158 + "[%c]: %2d %2d %2d %2d\n", 159 + 'A' + i, 160 + table[i].pwr_idx_2g.ht_1s_diff.bw20, 161 + table[i].pwr_idx_2g.ht_2s_diff.bw20, 162 + table[i].pwr_idx_2g.ht_3s_diff.bw20, 163 + table[i].pwr_idx_2g.ht_4s_diff.bw20); 164 + /* BW40 diff */ 165 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n"); 166 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); 167 + for (int i = 0; i < tx_path_count; i++) 168 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, 169 + "[%c]: %2d %2d %2d %2d\n", 170 + 'A' + i, 0 /* no diff for 1S */, 171 + table[i].pwr_idx_2g.ht_2s_diff.bw40, 172 + table[i].pwr_idx_2g.ht_3s_diff.bw40, 173 + table[i].pwr_idx_2g.ht_4s_diff.bw40); 174 + } 175 + 176 + static void efuse_debug_dump(struct rtw_dev *rtwdev, 177 + struct rtw8723x_efuse *map) 178 + { 179 + if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) 180 + return; 181 + 182 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n"); 183 + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, 184 + (u8 *)map, sizeof(struct rtw8723x_efuse), false); 185 + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n"); 186 + DBG_EFUSE_VAL(rtwdev, map, rtl_id); 187 + DBG_EFUSE_VAL(rtwdev, map, afe); 188 + rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4); 189 + DBG_EFUSE_VAL(rtwdev, map, channel_plan); 190 + DBG_EFUSE_VAL(rtwdev, map, xtal_k); 191 + DBG_EFUSE_VAL(rtwdev, map, thermal_meter); 192 + DBG_EFUSE_VAL(rtwdev, map, iqk_lck); 193 + DBG_EFUSE_VAL(rtwdev, map, pa_type); 194 + DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g); 195 + DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g); 196 + DBG_EFUSE_VAL(rtwdev, map, rf_board_option); 197 + DBG_EFUSE_VAL(rtwdev, map, rf_feature_option); 198 + DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting); 199 + DBG_EFUSE_VAL(rtwdev, map, eeprom_version); 200 + DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id); 201 + DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g); 202 + DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate); 203 + DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option); 204 + DBG_EFUSE_VAL(rtwdev, map, rfe_option); 205 + DBG_EFUSE_2BYTE(rtwdev, map, country_code); 206 + 207 + switch (rtw_hci_type(rtwdev)) { 208 + case RTW_HCI_TYPE_PCIE: 209 + rtw8723xe_efuse_debug(rtwdev, map); 210 + break; 211 + case RTW_HCI_TYPE_USB: 212 + rtw8723xu_efuse_debug(rtwdev, map); 213 + break; 214 + case RTW_HCI_TYPE_SDIO: 215 + rtw8723xs_efuse_debug(rtwdev, map); 216 + break; 217 + default: 218 + /* unsupported now */ 219 + break; 220 + } 221 + } 222 + 223 + static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse, 224 + struct rtw8723x_efuse *map) 225 + { 226 + ether_addr_copy(efuse->addr, map->e.mac_addr); 227 + } 228 + 229 + static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse, 230 + struct rtw8723x_efuse *map) 231 + { 232 + ether_addr_copy(efuse->addr, map->u.mac_addr); 233 + } 234 + 235 + static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse, 236 + struct rtw8723x_efuse *map) 237 + { 238 + ether_addr_copy(efuse->addr, map->s.mac_addr); 239 + } 240 + 241 + static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 242 + { 243 + struct rtw_efuse *efuse = &rtwdev->efuse; 244 + struct rtw8723x_efuse *map; 245 + int i; 246 + 247 + map = (struct rtw8723x_efuse *)log_map; 248 + efuse_debug_dump(rtwdev, map); 249 + 250 + efuse->rfe_option = 0; 251 + efuse->rf_board_option = map->rf_board_option; 252 + efuse->crystal_cap = map->xtal_k; 253 + efuse->pa_type_2g = map->pa_type; 254 + efuse->lna_type_2g = map->lna_type_2g[0]; 255 + efuse->channel_plan = map->channel_plan; 256 + efuse->country_code[0] = map->country_code[0]; 257 + efuse->country_code[1] = map->country_code[1]; 258 + efuse->bt_setting = map->rf_bt_setting; 259 + efuse->regd = map->rf_board_option & 0x7; 260 + efuse->thermal_meter[0] = map->thermal_meter; 261 + efuse->thermal_meter_k = map->thermal_meter; 262 + efuse->afe = map->afe; 263 + 264 + for (i = 0; i < 4; i++) 265 + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 266 + 267 + switch (rtw_hci_type(rtwdev)) { 268 + case RTW_HCI_TYPE_PCIE: 269 + rtw8723xe_efuse_parsing(efuse, map); 270 + break; 271 + case RTW_HCI_TYPE_USB: 272 + rtw8723xu_efuse_parsing(efuse, map); 273 + break; 274 + case RTW_HCI_TYPE_SDIO: 275 + rtw8723xs_efuse_parsing(efuse, map); 276 + break; 277 + default: 278 + /* unsupported now */ 279 + return -EOPNOTSUPP; 280 + } 281 + 282 + return 0; 283 + } 284 + 285 + #define BIT_CFENDFORM BIT(9) 286 + #define BIT_WMAC_TCR_ERR0 BIT(12) 287 + #define BIT_WMAC_TCR_ERR1 BIT(13) 288 + #define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ 289 + BIT_WMAC_TCR_ERR1) 290 + #define WLAN_RX_FILTER0 0xFFFF 291 + #define WLAN_RX_FILTER1 0x400 292 + #define WLAN_RX_FILTER2 0xFFFF 293 + #define WLAN_RCR_CFG 0x700060CE 294 + 295 + static int __rtw8723x_mac_init(struct rtw_dev *rtwdev) 296 + { 297 + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 298 + rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); 299 + 300 + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 301 + rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); 302 + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 303 + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 304 + 305 + rtw_write32(rtwdev, REG_INT_MIG, 0); 306 + rtw_write32(rtwdev, REG_MCUTST_1, 0x0); 307 + 308 + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); 309 + rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); 310 + 311 + return 0; 312 + } 313 + 314 + static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 315 + { 316 + u8 ldo_pwr; 317 + 318 + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); 319 + if (enable) { 320 + ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; 321 + ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; 322 + } else { 323 + ldo_pwr &= ~BIT_LDO25_EN; 324 + } 325 + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); 326 + } 327 + 328 + static void 329 + rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) 330 + { 331 + struct rtw_hal *hal = &rtwdev->hal; 332 + const struct rtw_hw_reg *txagc; 333 + u8 rate, pwr_index; 334 + int j; 335 + 336 + for (j = 0; j < rtw_rate_size[rs]; j++) { 337 + rate = rtw_rate_section[rs][j]; 338 + pwr_index = hal->tx_pwr_tbl[path][rate]; 339 + 340 + if (rate >= ARRAY_SIZE(rtw8723x_txagc)) { 341 + rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); 342 + continue; 343 + } 344 + txagc = &rtw8723x_txagc[rate]; 345 + if (!txagc->addr) { 346 + rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); 347 + continue; 348 + } 349 + 350 + rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); 351 + } 352 + } 353 + 354 + static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) 355 + { 356 + struct rtw_hal *hal = &rtwdev->hal; 357 + int rs, path; 358 + 359 + for (path = 0; path < hal->rf_path_num; path++) { 360 + for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) 361 + rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs); 362 + } 363 + } 364 + 365 + static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) 366 + { 367 + if (on) { 368 + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); 369 + 370 + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); 371 + rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); 372 + } else { 373 + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); 374 + } 375 + } 376 + 377 + static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) 378 + { 379 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 380 + u32 cck_fa_cnt; 381 + u32 ofdm_fa_cnt; 382 + u32 crc32_cnt; 383 + u32 val32; 384 + 385 + /* hold counter */ 386 + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); 387 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); 388 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); 389 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); 390 + 391 + cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); 392 + cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; 393 + 394 + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); 395 + ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); 396 + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); 397 + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); 398 + dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); 399 + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); 400 + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); 401 + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); 402 + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); 403 + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); 404 + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); 405 + 406 + dm_info->cck_fa_cnt = cck_fa_cnt; 407 + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 408 + dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; 409 + 410 + dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); 411 + dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); 412 + crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); 413 + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); 414 + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); 415 + crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); 416 + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); 417 + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); 418 + dm_info->vht_err_cnt = 0; 419 + dm_info->vht_ok_cnt = 0; 420 + 421 + val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); 422 + dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | 423 + u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); 424 + dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; 425 + 426 + /* reset counter */ 427 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); 428 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); 429 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); 430 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); 431 + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); 432 + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); 433 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); 434 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); 435 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); 436 + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); 437 + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); 438 + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); 439 + } 440 + 441 + /* IQK (IQ calibration) */ 442 + 443 + static 444 + void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, 445 + struct rtw8723x_iqk_backup_regs *backup) 446 + { 447 + int i; 448 + 449 + for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) 450 + backup->adda[i] = rtw_read32(rtwdev, 451 + rtw8723x_common.iqk_adda_regs[i]); 452 + 453 + for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) 454 + backup->mac8[i] = rtw_read8(rtwdev, 455 + rtw8723x_common.iqk_mac8_regs[i]); 456 + for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) 457 + backup->mac32[i] = rtw_read32(rtwdev, 458 + rtw8723x_common.iqk_mac32_regs[i]); 459 + 460 + for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) 461 + backup->bb[i] = rtw_read32(rtwdev, 462 + rtw8723x_common.iqk_bb_regs[i]); 463 + 464 + backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); 465 + backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); 466 + 467 + backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); 468 + } 469 + 470 + static 471 + void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, 472 + const struct rtw8723x_iqk_backup_regs *backup) 473 + { 474 + int i; 475 + 476 + for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) 477 + rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], 478 + backup->adda[i]); 479 + 480 + for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) 481 + rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], 482 + backup->mac8[i]); 483 + for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) 484 + rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i], 485 + backup->mac32[i]); 486 + 487 + for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) 488 + rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i], 489 + backup->bb[i]); 490 + 491 + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 492 + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); 493 + 494 + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); 495 + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); 496 + 497 + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); 498 + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); 499 + } 500 + 501 + static 502 + bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, 503 + s32 result[][IQK_NR], 504 + u8 c1, u8 c2) 505 + { 506 + u32 i, j, diff; 507 + u32 bitmap = 0; 508 + u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; 509 + bool ret = true; 510 + 511 + s32 tmp1, tmp2; 512 + 513 + for (i = 0; i < IQK_NR; i++) { 514 + tmp1 = iqkxy_to_s32(result[c1][i]); 515 + tmp2 = iqkxy_to_s32(result[c2][i]); 516 + 517 + diff = abs(tmp1 - tmp2); 518 + 519 + if (diff <= MAX_TOLERANCE) 520 + continue; 521 + 522 + if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { 523 + if (result[c1][i] + result[c1][i + 1] == 0) 524 + candidate[i / IQK_SX_NR] = c2; 525 + else if (result[c2][i] + result[c2][i + 1] == 0) 526 + candidate[i / IQK_SX_NR] = c1; 527 + else 528 + bitmap |= BIT(i); 529 + } else { 530 + bitmap |= BIT(i); 531 + } 532 + } 533 + 534 + if (bitmap != 0) 535 + goto check_sim; 536 + 537 + for (i = 0; i < PATH_NR; i++) { 538 + if (candidate[i] == IQK_ROUND_INVALID) 539 + continue; 540 + 541 + for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) 542 + result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; 543 + ret = false; 544 + } 545 + 546 + return ret; 547 + 548 + check_sim: 549 + for (i = 0; i < IQK_NR; i++) { 550 + j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ 551 + if (bitmap & GENMASK(j + 1, j)) 552 + continue; 553 + 554 + result[IQK_ROUND_HYBRID][i] = result[c1][i]; 555 + } 556 + 557 + return false; 558 + } 559 + 560 + static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) 561 + { 562 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 563 + u8 tx_rate = dm_info->tx_rate; 564 + u8 limit_ofdm = 30; 565 + 566 + switch (tx_rate) { 567 + case DESC_RATE1M...DESC_RATE5_5M: 568 + case DESC_RATE11M: 569 + break; 570 + case DESC_RATE6M...DESC_RATE48M: 571 + limit_ofdm = 36; 572 + break; 573 + case DESC_RATE54M: 574 + limit_ofdm = 34; 575 + break; 576 + case DESC_RATEMCS0...DESC_RATEMCS2: 577 + limit_ofdm = 38; 578 + break; 579 + case DESC_RATEMCS3...DESC_RATEMCS4: 580 + limit_ofdm = 36; 581 + break; 582 + case DESC_RATEMCS5...DESC_RATEMCS7: 583 + limit_ofdm = 34; 584 + break; 585 + default: 586 + rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); 587 + break; 588 + } 589 + 590 + return limit_ofdm; 591 + } 592 + 593 + static 594 + void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, 595 + u8 delta) 596 + { 597 + struct rtw_dm_info *dm_info = &rtwdev->dm_info; 598 + const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; 599 + const s8 *pwrtrk_xtal; 600 + s8 xtal_cap; 601 + 602 + if (dm_info->thermal_avg[therm_path] > 603 + rtwdev->efuse.thermal_meter[therm_path]) 604 + pwrtrk_xtal = tbl->pwrtrk_xtal_p; 605 + else 606 + pwrtrk_xtal = tbl->pwrtrk_xtal_n; 607 + 608 + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; 609 + xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); 610 + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, 611 + xtal_cap | (xtal_cap << 6)); 612 + } 613 + 614 + static 615 + void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev, 616 + struct rtw_tx_pkt_info *pkt_info, 617 + u8 *txdesc) 618 + { 619 + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ 620 + __le16 chksum = 0; 621 + __le16 *data = (__le16 *)(txdesc); 622 + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; 623 + 624 + le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); 625 + 626 + while (words--) 627 + chksum ^= *data++; 628 + 629 + chksum = ~chksum; 630 + 631 + le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), 632 + RTW_TX_DESC_W7_TXDESC_CHECKSUM); 633 + } 634 + 635 + static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) 636 + { 637 + /* enable TBTT nterrupt */ 638 + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 639 + 640 + /* BT report packet sample rate */ 641 + /* 0x790[5:0]=0x5 */ 642 + rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 643 + 644 + /* enable BT counter statistics */ 645 + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); 646 + 647 + /* enable PTA (3-wire function form BT side) */ 648 + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 649 + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); 650 + 651 + /* enable PTA (tx/rx signal form WiFi side) */ 652 + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 653 + } 654 + 655 + const struct rtw8723x_common rtw8723x_common = { 656 + .iqk_adda_regs = { 657 + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 658 + 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec 659 + }, 660 + .iqk_mac8_regs = {0x522, 0x550, 0x551}, 661 + .iqk_mac32_regs = {0x40}, 662 + .iqk_bb_regs = { 663 + 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 664 + }, 665 + 666 + .ltecoex_addr = { 667 + .ctrl = REG_LTECOEX_CTRL, 668 + .wdata = REG_LTECOEX_WRITE_DATA, 669 + .rdata = REG_LTECOEX_READ_DATA, 670 + }, 671 + .rf_sipi_addr = { 672 + [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, 673 + .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, 674 + [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, 675 + .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, 676 + }, 677 + .dig = { 678 + [0] = { .addr = 0xc50, .mask = 0x7f }, 679 + [1] = { .addr = 0xc50, .mask = 0x7f }, 680 + }, 681 + .dig_cck = { 682 + [0] = { .addr = 0xa0c, .mask = 0x3f00 }, 683 + }, 684 + .prioq_addrs = { 685 + .prio[RTW_DMA_MAPPING_EXTRA] = { 686 + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, 687 + }, 688 + .prio[RTW_DMA_MAPPING_LOW] = { 689 + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, 690 + }, 691 + .prio[RTW_DMA_MAPPING_NORMAL] = { 692 + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, 693 + }, 694 + .prio[RTW_DMA_MAPPING_HIGH] = { 695 + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, 696 + }, 697 + .wsize = false, 698 + }, 699 + 700 + .lck = __rtw8723x_lck, 701 + .read_efuse = __rtw8723x_read_efuse, 702 + .mac_init = __rtw8723x_mac_init, 703 + .cfg_ldo25 = __rtw8723x_cfg_ldo25, 704 + .set_tx_power_index = __rtw8723x_set_tx_power_index, 705 + .efuse_grant = __rtw8723x_efuse_grant, 706 + .false_alarm_statistics = __rtw8723x_false_alarm_statistics, 707 + .iqk_backup_regs = __rtw8723x_iqk_backup_regs, 708 + .iqk_restore_regs = __rtw8723x_iqk_restore_regs, 709 + .iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp, 710 + .pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm, 711 + .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal, 712 + .coex_cfg_init = __rtw8723x_coex_cfg_init, 713 + .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum, 714 + .debug_txpwr_limit = __rtw8723x_debug_txpwr_limit, 715 + }; 716 + EXPORT_SYMBOL(rtw8723x_common); 717 + 718 + MODULE_AUTHOR("Realtek Corporation"); 719 + MODULE_AUTHOR("Fiona Klute <fiona.klute@gmx.de>"); 720 + MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers"); 721 + MODULE_LICENSE("Dual BSD/GPL");
+518
drivers/net/wireless/realtek/rtw88/rtw8723x.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 + /* Copyright 2024 Fiona Klute 3 + * 4 + * Based on code originally in rtw8723d.[ch], 5 + * Copyright(c) 2018-2019 Realtek Corporation 6 + */ 7 + 8 + #ifndef __RTW8723X_H__ 9 + #define __RTW8723X_H__ 10 + 11 + #include "main.h" 12 + #include "debug.h" 13 + #include "phy.h" 14 + #include "reg.h" 15 + 16 + enum rtw8723x_path { 17 + PATH_S1, 18 + PATH_S0, 19 + PATH_NR, 20 + }; 21 + 22 + enum rtw8723x_iqk_round { 23 + IQK_ROUND_0, 24 + IQK_ROUND_1, 25 + IQK_ROUND_2, 26 + IQK_ROUND_HYBRID, 27 + IQK_ROUND_SIZE, 28 + IQK_ROUND_INVALID = 0xff, 29 + }; 30 + 31 + enum rtw8723x_iqk_result { 32 + IQK_S1_TX_X, 33 + IQK_S1_TX_Y, 34 + IQK_S1_RX_X, 35 + IQK_S1_RX_Y, 36 + IQK_S0_TX_X, 37 + IQK_S0_TX_Y, 38 + IQK_S0_RX_X, 39 + IQK_S0_RX_Y, 40 + IQK_NR, 41 + IQK_SX_NR = IQK_NR / PATH_NR, 42 + }; 43 + 44 + struct rtw8723xe_efuse { 45 + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ 46 + u8 vendor_id[2]; 47 + u8 device_id[2]; 48 + u8 sub_vendor_id[2]; 49 + u8 sub_device_id[2]; 50 + }; 51 + 52 + struct rtw8723xu_efuse { 53 + u8 res4[48]; /* 0xd0 */ 54 + u8 vendor_id[2]; /* 0x100 */ 55 + u8 product_id[2]; /* 0x102 */ 56 + u8 usb_option; /* 0x104 */ 57 + u8 res5[2]; /* 0x105 */ 58 + u8 mac_addr[ETH_ALEN]; /* 0x107 */ 59 + }; 60 + 61 + struct rtw8723xs_efuse { 62 + u8 res4[0x4a]; /* 0xd0 */ 63 + u8 mac_addr[ETH_ALEN]; /* 0x11a */ 64 + }; 65 + 66 + struct rtw8723x_efuse { 67 + __le16 rtl_id; 68 + u8 rsvd[2]; 69 + u8 afe; 70 + u8 rsvd1[11]; 71 + 72 + /* power index for four RF paths */ 73 + struct rtw_txpwr_idx txpwr_idx_table[4]; 74 + 75 + u8 channel_plan; /* 0xb8 */ 76 + u8 xtal_k; 77 + u8 thermal_meter; 78 + u8 iqk_lck; 79 + u8 pa_type; /* 0xbc */ 80 + u8 lna_type_2g[2]; /* 0xbd */ 81 + u8 lna_type_5g[2]; 82 + u8 rf_board_option; 83 + u8 rf_feature_option; 84 + u8 rf_bt_setting; 85 + u8 eeprom_version; 86 + u8 eeprom_customer_id; 87 + u8 tx_bb_swing_setting_2g; 88 + u8 res_c7; 89 + u8 tx_pwr_calibrate_rate; 90 + u8 rf_antenna_option; /* 0xc9 */ 91 + u8 rfe_option; 92 + u8 country_code[2]; 93 + u8 res[3]; 94 + union { 95 + struct rtw8723xe_efuse e; 96 + struct rtw8723xu_efuse u; 97 + struct rtw8723xs_efuse s; 98 + }; 99 + }; 100 + 101 + #define RTW8723X_IQK_ADDA_REG_NUM 16 102 + #define RTW8723X_IQK_MAC8_REG_NUM 3 103 + #define RTW8723X_IQK_MAC32_REG_NUM 1 104 + #define RTW8723X_IQK_BB_REG_NUM 9 105 + 106 + struct rtw8723x_iqk_backup_regs { 107 + u32 adda[RTW8723X_IQK_ADDA_REG_NUM]; 108 + u8 mac8[RTW8723X_IQK_MAC8_REG_NUM]; 109 + u32 mac32[RTW8723X_IQK_MAC32_REG_NUM]; 110 + u32 bb[RTW8723X_IQK_BB_REG_NUM]; 111 + 112 + u32 lte_path; 113 + u32 lte_gnt; 114 + 115 + u32 bb_sel_btg; 116 + u8 btg_sel; 117 + 118 + u8 igia; 119 + u8 igib; 120 + }; 121 + 122 + struct rtw8723x_common { 123 + /* registers that must be backed up before IQK and restored after */ 124 + u32 iqk_adda_regs[RTW8723X_IQK_ADDA_REG_NUM]; 125 + u32 iqk_mac8_regs[RTW8723X_IQK_MAC8_REG_NUM]; 126 + u32 iqk_mac32_regs[RTW8723X_IQK_MAC32_REG_NUM]; 127 + u32 iqk_bb_regs[RTW8723X_IQK_BB_REG_NUM]; 128 + 129 + /* chip register definitions */ 130 + struct rtw_ltecoex_addr ltecoex_addr; 131 + struct rtw_rf_sipi_addr rf_sipi_addr[2]; 132 + struct rtw_hw_reg dig[2]; 133 + struct rtw_hw_reg dig_cck[1]; 134 + struct rtw_prioq_addrs prioq_addrs; 135 + 136 + /* common functions */ 137 + void (*lck)(struct rtw_dev *rtwdev); 138 + int (*read_efuse)(struct rtw_dev *rtwdev, u8 *log_map); 139 + int (*mac_init)(struct rtw_dev *rtwdev); 140 + void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); 141 + void (*set_tx_power_index)(struct rtw_dev *rtwdev); 142 + void (*efuse_grant)(struct rtw_dev *rtwdev, bool on); 143 + void (*false_alarm_statistics)(struct rtw_dev *rtwdev); 144 + void (*iqk_backup_regs)(struct rtw_dev *rtwdev, 145 + struct rtw8723x_iqk_backup_regs *backup); 146 + void (*iqk_restore_regs)(struct rtw_dev *rtwdev, 147 + const struct rtw8723x_iqk_backup_regs *backup); 148 + bool (*iqk_similarity_cmp)(struct rtw_dev *rtwdev, s32 result[][IQK_NR], 149 + u8 c1, u8 c2); 150 + u8 (*pwrtrack_get_limit_ofdm)(struct rtw_dev *rtwdev); 151 + void (*pwrtrack_set_xtal)(struct rtw_dev *rtwdev, u8 therm_path, 152 + u8 delta); 153 + void (*coex_cfg_init)(struct rtw_dev *rtwdev); 154 + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, 155 + struct rtw_tx_pkt_info *pkt_info, 156 + u8 *txdesc); 157 + void (*debug_txpwr_limit)(struct rtw_dev *rtwdev, 158 + struct rtw_txpwr_idx *table, 159 + int tx_path_count); 160 + }; 161 + 162 + extern const struct rtw8723x_common rtw8723x_common; 163 + 164 + #define PATH_IQK_RETRY 2 165 + #define MAX_TOLERANCE 5 166 + #define IQK_TX_X_ERR 0x142 167 + #define IQK_TX_Y_ERR 0x42 168 + #define IQK_RX_X_ERR 0x132 169 + #define IQK_RX_Y_ERR 0x36 170 + #define IQK_RX_X_UPPER 0x11a 171 + #define IQK_RX_X_LOWER 0xe6 172 + #define IQK_RX_Y_LMT 0x1a 173 + #define IQK_TX_OK BIT(0) 174 + #define IQK_RX_OK BIT(1) 175 + 176 + #define WLAN_TXQ_RPT_EN 0x1F 177 + 178 + #define SPUR_THRES 0x16 179 + #define DIS_3WIRE 0xccf000c0 180 + #define EN_3WIRE 0xccc000c0 181 + #define START_PSD 0x400000 182 + #define FREQ_CH5 0xfccd 183 + #define FREQ_CH6 0xfc4d 184 + #define FREQ_CH7 0xffcd 185 + #define FREQ_CH8 0xff4d 186 + #define FREQ_CH13 0xfccd 187 + #define FREQ_CH14 0xff9a 188 + #define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) 189 + #define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) 190 + #define RFCFGCH_BW_20M (BIT(11) | BIT(10)) 191 + #define RFCFGCH_BW_40M BIT(10) 192 + #define BIT_MASK_RFMOD BIT(0) 193 + #define BIT_LCK BIT(15) 194 + 195 + #define REG_GPIO_INTM 0x0048 196 + #define REG_BTG_SEL 0x0067 197 + #define BIT_MASK_BTG_WL BIT(7) 198 + #define REG_LTECOEX_PATH_CONTROL 0x0070 199 + #define REG_LTECOEX_CTRL 0x07c0 200 + #define REG_LTECOEX_WRITE_DATA 0x07c4 201 + #define REG_LTECOEX_READ_DATA 0x07c8 202 + #define REG_PSDFN 0x0808 203 + #define REG_BB_PWR_SAV1_11N 0x0874 204 + #define REG_ANA_PARAM1 0x0880 205 + #define REG_ANALOG_P4 0x088c 206 + #define REG_PSDRPT 0x08b4 207 + #define REG_FPGA1_RFMOD 0x0900 208 + #define REG_BB_SEL_BTG 0x0948 209 + #define REG_BBRX_DFIR 0x0954 210 + #define BIT_MASK_RXBB_DFIR GENMASK(27, 24) 211 + #define BIT_RXBB_DFIR_EN BIT(19) 212 + #define REG_CCK0_SYS 0x0a00 213 + #define BIT_CCK_SIDE_BAND BIT(4) 214 + #define REG_CCK_ANT_SEL_11N 0x0a04 215 + #define REG_PWRTH 0x0a08 216 + #define REG_CCK_FA_RST_11N 0x0a2c 217 + #define BIT_MASK_CCK_CNT_KEEP BIT(12) 218 + #define BIT_MASK_CCK_CNT_EN BIT(13) 219 + #define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) 220 + #define BIT_MASK_CCK_FA_KEEP BIT(14) 221 + #define BIT_MASK_CCK_FA_EN BIT(15) 222 + #define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) 223 + #define REG_CCK_FA_LSB_11N 0x0a5c 224 + #define REG_CCK_FA_MSB_11N 0x0a58 225 + #define REG_CCK_CCA_CNT_11N 0x0a60 226 + #define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) 227 + #define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) 228 + #define REG_PWRTH2 0x0aa8 229 + #define REG_CSRATIO 0x0aaa 230 + #define REG_OFDM_FA_HOLDC_11N 0x0c00 231 + #define BIT_MASK_OFDM_FA_KEEP BIT(31) 232 + #define REG_BB_RX_PATH_11N 0x0c04 233 + #define REG_TRMUX_11N 0x0c08 234 + #define REG_OFDM_FA_RSTC_11N 0x0c0c 235 + #define BIT_MASK_OFDM_FA_RST BIT(31) 236 + #define REG_A_RXIQI 0x0c14 237 + #define BIT_MASK_RXIQ_S1_X 0x000003FF 238 + #define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 239 + #define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) 240 + #define REG_OFDM0_RXDSP 0x0c40 241 + #define BIT_MASK_RXDSP GENMASK(28, 24) 242 + #define BIT_EN_RXDSP BIT(9) 243 + #define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c 244 + #define BIT_MASK_OFDM0_EXT_A BIT(31) 245 + #define BIT_MASK_OFDM0_EXT_C BIT(29) 246 + #define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) 247 + #define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) 248 + #define BIT_MASK_OFDM0_EXTS_B (BIT(27) | BIT(25) | BIT(24)) 249 + #define BIT_SET_OFDM0_EXTS_B(a, c, d) (((a) << 27) | ((c) << 25) | ((d) << 24)) 250 + #define REG_OFDM0_XAAGC1 0x0c50 251 + #define REG_OFDM0_XBAGC1 0x0c58 252 + #define REG_AGCRSSI 0x0c78 253 + #define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 254 + #define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88 255 + #define BIT_MASK_TXIQ_ELM_A 0x03ff 256 + #define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ 257 + ((a) & 0x03ff)) 258 + #define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) 259 + #define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) 260 + #define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) 261 + #define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 262 + #define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) 263 + #define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 264 + #define BIT_MASK_RXIQ_S1_Y2 0xF0000000 265 + #define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) 266 + #define REG_TXIQ_AB_S0 0x0cd0 267 + #define BIT_MASK_TXIQ_A_S0 0x000007FE 268 + #define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) 269 + #define BIT_MASK_TXIQ_B_S0 0x0007E000 270 + #define REG_TXIQ_CD_S0 0x0cd4 271 + #define BIT_MASK_TXIQ_C_S0 0x000007FE 272 + #define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) 273 + #define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) 274 + #define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) 275 + #define REG_RXIQ_AB_S0 0x0cd8 276 + #define BIT_MASK_RXIQ_X_S0 0x000003FF 277 + #define BIT_MASK_RXIQ_Y_S0 0x003FF000 278 + #define REG_OFDM_FA_TYPE1_11N 0x0cf0 279 + #define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) 280 + #define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) 281 + #define REG_OFDM_FA_RSTD_11N 0x0d00 282 + #define BIT_MASK_OFDM_FA_RST1 BIT(27) 283 + #define BIT_MASK_OFDM_FA_KEEP1 BIT(31) 284 + #define REG_CTX 0x0d03 285 + #define BIT_MASK_CTX_TYPE GENMASK(6, 4) 286 + #define REG_OFDM1_CFOTRK 0x0d2c 287 + #define BIT_EN_CFOTRK BIT(28) 288 + #define REG_OFDM1_CSI1 0x0d40 289 + #define REG_OFDM1_CSI2 0x0d44 290 + #define REG_OFDM1_CSI3 0x0d48 291 + #define REG_OFDM1_CSI4 0x0d4c 292 + #define REG_OFDM_FA_TYPE2_11N 0x0da0 293 + #define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) 294 + #define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) 295 + #define REG_OFDM_FA_TYPE3_11N 0x0da4 296 + #define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) 297 + #define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) 298 + #define REG_OFDM_FA_TYPE4_11N 0x0da8 299 + #define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) 300 + #define REG_FPGA0_IQK_11N 0x0e28 301 + #define BIT_MASK_IQK_MOD 0xffffff00 302 + #define EN_IQK 0x808000 303 + #define RST_IQK 0x000000 304 + #define REG_TXIQK_TONE_A_11N 0x0e30 305 + #define REG_RXIQK_TONE_A_11N 0x0e34 306 + #define REG_TXIQK_PI_A_11N 0x0e38 307 + #define REG_RXIQK_PI_A_11N 0x0e3c 308 + #define REG_TXIQK_11N 0x0e40 309 + #define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) 310 + #define REG_RXIQK_11N 0x0e44 311 + #define REG_IQK_AGC_PTS_11N 0x0e48 312 + #define REG_IQK_AGC_RSP_11N 0x0e4c 313 + #define REG_TX_IQK_TONE_B 0x0e50 314 + #define REG_RX_IQK_TONE_B 0x0e54 315 + #define REG_TXIQK_PI_B 0x0e58 316 + #define REG_RXIQK_PI_B 0x0e5c 317 + #define REG_IQK_RES_TX 0x0e94 318 + #define BIT_MASK_RES_TX GENMASK(25, 16) 319 + #define REG_IQK_RES_TY 0x0e9c 320 + #define BIT_MASK_RES_TY GENMASK(25, 16) 321 + #define REG_IQK_RES_RX 0x0ea4 322 + #define BIT_MASK_RES_RX GENMASK(25, 16) 323 + #define REG_IQK_RES_RY 0x0eac 324 + #define BIT_IQK_TX_FAIL BIT(28) 325 + #define BIT_IQK_RX_FAIL BIT(27) 326 + #define BIT_IQK_DONE BIT(26) 327 + #define BIT_MASK_RES_RY GENMASK(25, 16) 328 + #define REG_PAGE_F_RST_11N 0x0f14 329 + #define BIT_MASK_F_RST_ALL BIT(16) 330 + #define REG_IGI_C_11N 0x0f84 331 + #define REG_IGI_D_11N 0x0f88 332 + #define REG_HT_CRC32_CNT_11N 0x0f90 333 + #define BIT_MASK_HT_CRC_OK GENMASK(15, 0) 334 + #define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) 335 + #define REG_OFDM_CRC32_CNT_11N 0x0f94 336 + #define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) 337 + #define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) 338 + #define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 339 + 340 + #define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing) 341 + #define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing) 342 + #define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing) 343 + #define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing) 344 + 345 + static inline s32 iqkxy_to_s32(s32 val) 346 + { 347 + /* val is Q10.8 */ 348 + return sign_extend32(val, 9); 349 + } 350 + 351 + static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) 352 + { 353 + /* x, y and return value are Q10.8 */ 354 + s32 t; 355 + 356 + t = x * y; 357 + if (ext) 358 + *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ 359 + 360 + return (t >> 8); /* Q.16 --> Q.8 */ 361 + } 362 + 363 + static inline 364 + void rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, 365 + struct rtw_txpwr_idx *table, 366 + int tx_path_count) 367 + { 368 + rtw8723x_common.debug_txpwr_limit(rtwdev, table, tx_path_count); 369 + } 370 + 371 + static inline void rtw8723x_lck(struct rtw_dev *rtwdev) 372 + { 373 + rtw8723x_common.lck(rtwdev); 374 + } 375 + 376 + static inline int rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 377 + { 378 + return rtw8723x_common.read_efuse(rtwdev, log_map); 379 + } 380 + 381 + static inline int rtw8723x_mac_init(struct rtw_dev *rtwdev) 382 + { 383 + return rtw8723x_common.mac_init(rtwdev); 384 + } 385 + 386 + static inline void rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 387 + { 388 + rtw8723x_common.cfg_ldo25(rtwdev, enable); 389 + } 390 + 391 + static inline void rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) 392 + { 393 + rtw8723x_common.set_tx_power_index(rtwdev); 394 + } 395 + 396 + static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) 397 + { 398 + rtw8723x_common.efuse_grant(rtwdev, on); 399 + } 400 + 401 + static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) 402 + { 403 + rtw8723x_common.false_alarm_statistics(rtwdev); 404 + } 405 + 406 + static inline 407 + void rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, 408 + struct rtw8723x_iqk_backup_regs *backup) 409 + { 410 + rtw8723x_common.iqk_backup_regs(rtwdev, backup); 411 + } 412 + 413 + static inline 414 + void rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, 415 + const struct rtw8723x_iqk_backup_regs *backup) 416 + { 417 + rtw8723x_common.iqk_restore_regs(rtwdev, backup); 418 + } 419 + 420 + static inline 421 + bool rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], 422 + u8 c1, u8 c2) 423 + { 424 + return rtw8723x_common.iqk_similarity_cmp(rtwdev, result, c1, c2); 425 + } 426 + 427 + static inline u8 rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) 428 + { 429 + return rtw8723x_common.pwrtrack_get_limit_ofdm(rtwdev); 430 + } 431 + 432 + static inline 433 + void rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, 434 + u8 delta) 435 + { 436 + rtw8723x_common.pwrtrack_set_xtal(rtwdev, therm_path, delta); 437 + } 438 + 439 + static inline void rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) 440 + { 441 + rtw8723x_common.coex_cfg_init(rtwdev); 442 + } 443 + 444 + static inline 445 + void rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev, 446 + struct rtw_tx_pkt_info *pkt_info, 447 + u8 *txdesc) 448 + { 449 + rtw8723x_common.fill_txdesc_checksum(rtwdev, pkt_info, txdesc); 450 + } 451 + 452 + /* IQK helper functions, defined as inline so they can be shared 453 + * without needing an EXPORT_SYMBOL each. 454 + */ 455 + static inline void 456 + rtw8723x_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, 457 + struct rtw8723x_iqk_backup_regs *backup) 458 + { 459 + backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); 460 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", 461 + backup->btg_sel); 462 + } 463 + 464 + static inline void rtw8723x_iqk_config_path_ctrl(struct rtw_dev *rtwdev) 465 + { 466 + rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); 467 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", 468 + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 469 + } 470 + 471 + static inline void 472 + rtw8723x_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, 473 + const struct rtw8723x_iqk_backup_regs *backup) 474 + { 475 + rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); 476 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", 477 + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 478 + } 479 + 480 + static inline void 481 + rtw8723x_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, 482 + struct rtw8723x_iqk_backup_regs *backup) 483 + { 484 + backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); 485 + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); 486 + mdelay(1); 487 + backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); 488 + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", 489 + backup->lte_gnt); 490 + } 491 + 492 + static inline void 493 + rtw8723x_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev, 494 + u32 write_data) 495 + { 496 + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, write_data); 497 + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); 498 + rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, 499 + BIT_LTE_MUX_CTRL_PATH, 0x1); 500 + } 501 + 502 + static inline void 503 + rtw8723x_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, 504 + const struct rtw8723x_iqk_backup_regs *bak) 505 + { 506 + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); 507 + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); 508 + rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); 509 + } 510 + 511 + /* set all ADDA registers to the given value */ 512 + static inline void rtw8723x_iqk_path_adda_on(struct rtw_dev *rtwdev, u32 value) 513 + { 514 + for (int i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) 515 + rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], value); 516 + } 517 + 518 + #endif /* __RTW8723X_H__ */
+2
drivers/net/wireless/realtek/rtw88/rx.h
··· 40 40 le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29)) 41 41 #define GET_RX_DESC_TSFL(rxdesc) \ 42 42 le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0)) 43 + #define GET_RX_DESC_BW(rxdesc) \ 44 + (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(31, 24))) 43 45 44 46 void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, 45 47 struct sk_buff *skb);
+15
drivers/net/wireless/realtek/rtw89/Kconfig
··· 28 28 config RTW89_8852C 29 29 tristate 30 30 31 + config RTW89_8922A 32 + tristate 33 + 31 34 config RTW89_8851BE 32 35 tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter" 33 36 depends on PCI ··· 74 71 Select this option will enable support for 8852CE chipset 75 72 76 73 802.11ax PCIe wireless network (Wi-Fi 6E) adapter 74 + 75 + config RTW89_8922AE 76 + tristate "Realtek 8922AE PCI wireless network (Wi-Fi 7) adapter" 77 + depends on PCI 78 + select RTW89_CORE 79 + select RTW89_PCI 80 + select RTW89_8922A 81 + help 82 + Select this option will enable support for 8922AE chipset 83 + 84 + 802.11be PCIe wireless network (Wi-Fi 7) adapter 85 + supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels. 77 86 78 87 config RTW89_DEBUG 79 88 bool
+11 -1
drivers/net/wireless/realtek/rtw89/Makefile
··· 4 4 rtw89_core-y += core.o \ 5 5 mac80211.o \ 6 6 mac.o \ 7 + mac_be.o \ 7 8 phy.o \ 9 + phy_be.o \ 8 10 fw.o \ 9 11 cam.o \ 10 12 efuse.o \ 13 + efuse_be.o \ 11 14 regd.o \ 12 15 sar.o \ 13 16 coex.o \ ··· 57 54 obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o 58 55 rtw89_8852ce-objs := rtw8852ce.o 59 56 57 + obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o 58 + rtw89_8922a-objs := rtw8922a.o \ 59 + rtw8922a_rfk.o 60 + 61 + obj-$(CONFIG_RTW89_8922AE) += rtw89_8922ae.o 62 + rtw89_8922ae-objs := rtw8922ae.o 63 + 60 64 rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o 61 65 62 66 obj-$(CONFIG_RTW89_PCI) += rtw89_pci.o 63 - rtw89_pci-y := pci.o 67 + rtw89_pci-y := pci.o pci_be.o 64 68
+858 -106
drivers/net/wireless/realtek/rtw89/coex.c
··· 12 12 13 13 #define RTW89_COEX_VERSION 0x07000113 14 14 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ 15 + #define BTC_E2G_LIMIT_DEF 80 15 16 16 17 enum btc_fbtc_tdma_template { 17 18 CXTD_OFF = 0x0, ··· 55 54 MLME_LINKED, 56 55 }; 57 56 58 - #define FCXONESLOT_VER 1 59 57 struct btc_fbtc_1slot { 60 58 u8 fver; 61 59 u8 sid; /* slot id */ ··· 133 133 .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, 134 134 .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, 135 135 .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, 136 - .fwlrole = 2, .frptmap = 7, .fcxctrl = 7, .fcxinit = 7, 136 + .fwlrole = 8, .frptmap = 7, .fcxctrl = 7, .fcxinit = 7, 137 137 .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6, 138 138 }, 139 139 {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0), ··· 218 218 u8 val[]; 219 219 } __packed; 220 220 221 + struct rtw89_btc_btf_tlv_v7 { 222 + u8 type; 223 + u8 ver; 224 + u8 len; 225 + u8 val[]; 226 + } __packed; 227 + 221 228 enum btc_btf_set_report_en { 222 229 RPT_EN_TDMA, 223 230 RPT_EN_CYCLE, ··· 254 247 u8 fver; 255 248 u8 tbl_num; 256 249 struct rtw89_btc_fbtc_slot tbls[] __counted_by(tbl_num); 250 + } __packed; 251 + 252 + struct rtw89_btc_btf_set_slot_table_v7 { 253 + u8 type; 254 + u8 ver; 255 + u8 len; 256 + struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; 257 257 } __packed; 258 258 259 259 struct rtw89_btc_btf_set_mon_reg { ··· 324 310 BTC_ANT_W25G, 325 311 BTC_ANT_FREERUN, 326 312 BTC_ANT_WRFK, 313 + BTC_ANT_WRFK2, 327 314 BTC_ANT_BRFK, 328 315 BTC_ANT_MAX 329 316 }; ··· 629 614 BTC_CTRL_BY_WL 630 615 }; 631 616 617 + enum btc_wlact_state { 618 + BTC_WLACT_HW = 0, 619 + BTC_WLACT_SW_LO, 620 + BTC_WLACT_SW_HI, 621 + BTC_WLACT_MAX, 622 + }; 623 + 632 624 enum btc_wl_max_tx_time { 633 625 BTC_MAX_TX_TIME_L1 = 500, 634 626 BTC_MAX_TX_TIME_L2 = 1000, ··· 761 739 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 762 740 struct rtw89_btc_bt_info *bt = &btc->cx.bt; 763 741 struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 764 - struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info; 742 + struct rtw89_btc_wl_link_info *wl_linfo; 765 743 u8 i; 766 744 767 745 rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__); ··· 783 761 if (type & BTC_RESET_DM) { 784 762 memset(&btc->dm, 0, sizeof(btc->dm)); 785 763 memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state)); 786 - 787 - for (i = 0; i < RTW89_PORT_NUM; i++) 788 - memset(wl_linfo[i].rssi_state, 0, 789 - sizeof(wl_linfo[i].rssi_state)); 764 + for (i = 0; i < RTW89_PORT_NUM; i++) { 765 + if (btc->ver->fwlrole == 8) 766 + wl_linfo = &wl->rlink_info[i][0]; 767 + else 768 + wl_linfo = &wl->link_info[i]; 769 + memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state)); 770 + } 790 771 791 772 /* set the slot_now table to original */ 792 773 btc->dm.tdma_now = t_def[CXTD_OFF]; ··· 1223 1198 if (ver->fcxtdma == 1) { 1224 1199 pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; 1225 1200 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); 1226 - } else if (ver->fcxtdma == 3) { 1201 + } else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) { 1227 1202 pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; 1228 1203 pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); 1229 1204 } else { ··· 1233 1208 break; 1234 1209 case BTC_RPT_TYPE_SLOT: 1235 1210 pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; 1236 - pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; 1237 - pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); 1211 + if (ver->fcxslots == 1) { 1212 + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v1; 1213 + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v1); 1214 + } else if (ver->fcxslots == 7) { 1215 + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo.v7; 1216 + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo.v7); 1217 + } else { 1218 + goto err; 1219 + } 1238 1220 pcinfo->req_fver = ver->fcxslots; 1239 1221 break; 1240 1222 case BTC_RPT_TYPE_CYSTA: ··· 1506 1474 memcmp(&dm->tdma_now, 1507 1475 &pfwinfo->rpt_fbtc_tdma.finfo.v1, 1508 1476 sizeof(dm->tdma_now))); 1509 - else if (ver->fcxtdma == 3) 1477 + else if (ver->fcxtdma == 3 || ver->fcxtdma == 7) 1510 1478 _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, 1511 1479 memcmp(&dm->tdma_now, 1512 1480 &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma, ··· 1515 1483 goto err; 1516 1484 break; 1517 1485 case BTC_RPT_TYPE_SLOT: 1518 - rtw89_debug(rtwdev, RTW89_DBG_BTC, 1519 - "[BTC], %s(): check %d %zu\n", 1520 - __func__, BTC_DCNT_SLOT_NONSYNC, 1521 - sizeof(dm->slot_now)); 1522 - _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, 1523 - memcmp(dm->slot_now, 1524 - pfwinfo->rpt_fbtc_slots.finfo.slot, 1525 - sizeof(dm->slot_now))); 1486 + if (ver->fcxslots == 7) { 1487 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1488 + "[BTC], %s(): check %d %zu\n", 1489 + __func__, BTC_DCNT_SLOT_NONSYNC, 1490 + sizeof(dm->slot_now.v7)); 1491 + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, 1492 + memcmp(dm->slot_now.v7, 1493 + pfwinfo->rpt_fbtc_slots.finfo.v7.slot, 1494 + sizeof(dm->slot_now.v7))); 1495 + } else if (ver->fcxslots == 1) { 1496 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1497 + "[BTC], %s(): check %d %zu\n", 1498 + __func__, BTC_DCNT_SLOT_NONSYNC, 1499 + sizeof(dm->slot_now.v1)); 1500 + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, 1501 + memcmp(dm->slot_now.v1, 1502 + pfwinfo->rpt_fbtc_slots.finfo.v1.slot, 1503 + sizeof(dm->slot_now.v1))); 1504 + } 1526 1505 break; 1527 1506 case BTC_RPT_TYPE_CYSTA: 1528 1507 if (ver->fcxcysta == 2) { ··· 1549 1506 1550 1507 /* Check diff time between WL slot and W1/E2G slot */ 1551 1508 if (dm->tdma_now.type == CXTDMA_OFF && 1552 - dm->tdma_now.ext_ctrl == CXECTL_EXT) 1553 - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); 1554 - else 1555 - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); 1509 + dm->tdma_now.ext_ctrl == CXECTL_EXT) { 1510 + if (ver->fcxslots == 1) 1511 + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_E2G].dur); 1512 + else if (ver->fcxslots == 7) 1513 + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_E2G].dur); 1514 + } else { 1515 + if (ver->fcxslots == 1) 1516 + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1517 + else if (ver->fcxslots == 7) 1518 + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1519 + } 1556 1520 1557 1521 if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) { 1558 1522 diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set; ··· 1589 1539 1590 1540 /* Check diff time between real WL slot and W1 slot */ 1591 1541 if (dm->tdma_now.type == CXTDMA_OFF) { 1592 - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); 1542 + if (ver->fcxslots == 1) 1543 + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1544 + else if (ver->fcxslots == 7) 1545 + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1593 1546 wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]); 1594 1547 if (wl_slot_real > wl_slot_set) { 1595 1548 diff_t = wl_slot_real - wl_slot_set; ··· 1633 1580 1634 1581 /* Check diff time between real WL slot and W1 slot */ 1635 1582 if (dm->tdma_now.type == CXTDMA_OFF) { 1636 - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); 1583 + if (ver->fcxslots == 1) 1584 + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1585 + else if (ver->fcxslots == 7) 1586 + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1637 1587 wl_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_WL]); 1638 1588 if (wl_slot_real > wl_slot_set) { 1639 1589 diff_t = wl_slot_real - wl_slot_set; ··· 1678 1622 1679 1623 /* Check diff time between real WL slot and W1 slot */ 1680 1624 if (dm->tdma_now.type == CXTDMA_OFF) { 1681 - wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); 1625 + if (ver->fcxslots == 1) 1626 + wl_slot_set = le16_to_cpu(dm->slot_now.v1[CXST_W1].dur); 1627 + else if (ver->fcxslots == 7) 1628 + wl_slot_set = le16_to_cpu(dm->slot_now.v7[CXST_W1].dur); 1682 1629 wl_slot_real = le16_to_cpu(pcysta->v5.cycle_time.tavg[CXT_WL]); 1683 1630 1684 1631 if (wl_slot_real > wl_slot_set) ··· 1774 1715 } 1775 1716 1776 1717 #define BTC_TLV_HDR_LEN 2 1718 + #define BTC_TLV_HDR_LEN_V7 3 1777 1719 1778 1720 static void _append_tdma(struct rtw89_dev *rtwdev) 1779 1721 { ··· 1782 1722 const struct rtw89_btc_ver *ver = btc->ver; 1783 1723 struct rtw89_btc_dm *dm = &btc->dm; 1784 1724 struct rtw89_btc_btf_tlv *tlv; 1725 + struct rtw89_btc_btf_tlv_v7 *tlv_v7; 1785 1726 struct rtw89_btc_fbtc_tdma *v; 1786 1727 struct rtw89_btc_fbtc_tdma_v3 *v3; 1787 1728 u16 len = btc->policy_len; ··· 1802 1741 tlv->len = sizeof(*v); 1803 1742 *v = dm->tdma; 1804 1743 btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); 1744 + } else if (ver->fcxtdma == 7) { 1745 + tlv_v7 = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; 1746 + tlv_v7->len = sizeof(dm->tdma); 1747 + tlv_v7->ver = ver->fcxtdma; 1748 + tlv_v7->type = CXPOLICY_TDMA; 1749 + memcpy(tlv_v7->val, &dm->tdma, tlv_v7->len); 1750 + btc->policy_len += BTC_TLV_HDR_LEN_V7 + tlv_v7->len; 1805 1751 } else { 1806 1752 tlv->len = sizeof(*v3); 1807 1753 v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0]; ··· 1824 1756 dm->tdma.ext_ctrl); 1825 1757 } 1826 1758 1827 - static void _append_slot(struct rtw89_dev *rtwdev) 1759 + static void _append_slot_v1(struct rtw89_dev *rtwdev) 1828 1760 { 1829 1761 struct rtw89_btc *btc = &rtwdev->btc; 1830 1762 struct rtw89_btc_dm *dm = &btc->dm; ··· 1839 1771 1840 1772 for (i = 0; i < CXST_MAX; i++) { 1841 1773 if (!btc->update_policy_force && 1842 - !memcmp(&dm->slot[i], &dm->slot_now[i], 1843 - sizeof(dm->slot[i]))) 1774 + !memcmp(&dm->slot.v1[i], &dm->slot_now.v1[i], 1775 + sizeof(dm->slot.v1[i]))) 1844 1776 continue; 1845 1777 1846 1778 len = btc->policy_len; ··· 1850 1782 tlv->type = CXPOLICY_SLOT; 1851 1783 tlv->len = sizeof(*v); 1852 1784 1853 - v->fver = FCXONESLOT_VER; 1785 + v->fver = btc->ver->fcxslots; 1854 1786 v->sid = i; 1855 - v->slot = dm->slot[i]; 1787 + v->slot = dm->slot.v1[i]; 1856 1788 1857 1789 rtw89_debug(rtwdev, RTW89_DBG_BTC, 1858 1790 "[BTC], %s(): slot-%d: dur=%d, table=0x%08x, type=%d\n", 1859 - __func__, i, dm->slot[i].dur, dm->slot[i].cxtbl, 1860 - dm->slot[i].cxtype); 1791 + __func__, i, dm->slot.v1[i].dur, dm->slot.v1[i].cxtbl, 1792 + dm->slot.v1[i].cxtype); 1861 1793 cnt++; 1862 1794 1863 1795 btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); ··· 1867 1799 rtw89_debug(rtwdev, RTW89_DBG_BTC, 1868 1800 "[BTC], %s(): slot update (cnt=%d)!!\n", 1869 1801 __func__, cnt); 1802 + } 1803 + 1804 + static void _append_slot_v7(struct rtw89_dev *rtwdev) 1805 + { 1806 + struct rtw89_btc_btf_tlv_v7 *tlv = NULL; 1807 + struct rtw89_btc *btc = &rtwdev->btc; 1808 + struct rtw89_btc_dm *dm = &btc->dm; 1809 + u8 i, cnt = 0; 1810 + u16 len; 1811 + 1812 + for (i = 0; i < CXST_MAX; i++) { 1813 + if (!btc->update_policy_force && 1814 + !memcmp(&dm->slot.v7[i], &dm->slot_now.v7[i], 1815 + sizeof(dm->slot.v7[i]))) 1816 + continue; 1817 + 1818 + len = btc->policy_len; 1819 + 1820 + if (!tlv) { 1821 + if ((len + BTC_TLV_HDR_LEN_V7) > RTW89_BTC_POLICY_MAXLEN) { 1822 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1823 + "[BTC], %s(): buff overflow!\n", __func__); 1824 + break; 1825 + } 1826 + 1827 + tlv = (struct rtw89_btc_btf_tlv_v7 *)&btc->policy[len]; 1828 + tlv->type = CXPOLICY_SLOT; 1829 + tlv->ver = btc->ver->fcxslots; 1830 + tlv->len = sizeof(dm->slot.v7[0]) + BTC_TLV_SLOT_ID_LEN_V7; 1831 + len += BTC_TLV_HDR_LEN_V7; 1832 + } 1833 + 1834 + if ((len + (u16)tlv->len) > RTW89_BTC_POLICY_MAXLEN) { 1835 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1836 + "[BTC], %s(): buff overflow!\n", __func__); 1837 + break; 1838 + } 1839 + 1840 + btc->policy[len] = i; /* slot-id */ 1841 + memcpy(&btc->policy[len + 1], &dm->slot.v7[i], 1842 + sizeof(dm->slot.v7[0])); 1843 + len += tlv->len; 1844 + 1845 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1846 + "[BTC], %s: policy_len=%d, slot-%d: dur=%d, type=%d, table=0x%08x\n", 1847 + __func__, btc->policy_len, i, dm->slot.v7[i].dur, 1848 + dm->slot.v7[i].cxtype, dm->slot.v7[i].cxtbl); 1849 + cnt++; 1850 + btc->policy_len = len; /* update total length */ 1851 + } 1852 + 1853 + if (cnt > 0) 1854 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 1855 + "[BTC], %s: slot update (cnt=%d, len=%d)!!\n", 1856 + __func__, cnt, btc->policy_len); 1857 + } 1858 + 1859 + static void _append_slot(struct rtw89_dev *rtwdev) 1860 + { 1861 + struct rtw89_btc *btc = &rtwdev->btc; 1862 + 1863 + if (btc->ver->fcxslots == 7) 1864 + _append_slot_v7(rtwdev); 1865 + else 1866 + _append_slot_v1(rtwdev); 1870 1867 } 1871 1868 1872 1869 static u32 rtw89_btc_fw_rpt_ver(struct rtw89_dev *rtwdev, u32 rpt_map) ··· 2079 1946 return bit_map; 2080 1947 } 2081 1948 1949 + static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev) 1950 + { 1951 + struct rtw89_btc *btc = &rtwdev->btc; 1952 + const struct rtw89_btc_ver *ver = btc->ver; 1953 + struct rtw89_btc_btf_tlv_v7 *tlv_v7 = NULL; 1954 + struct rtw89_btc_btf_set_slot_table *tbl; 1955 + struct rtw89_btc_dm *dm = &btc->dm; 1956 + u16 n, len; 1957 + 1958 + if (ver->fcxslots == 7) { 1959 + len = sizeof(*tlv_v7) + sizeof(dm->slot.v7); 1960 + tlv_v7 = kmalloc(len, GFP_KERNEL); 1961 + if (!tlv_v7) 1962 + return; 1963 + 1964 + tlv_v7->type = SET_SLOT_TABLE; 1965 + tlv_v7->ver = ver->fcxslots; 1966 + tlv_v7->len = sizeof(dm->slot.v7); 1967 + memcpy(tlv_v7->val, dm->slot.v7, sizeof(dm->slot.v7)); 1968 + 1969 + _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, (u8 *)tlv_v7, len); 1970 + 1971 + kfree(tlv_v7); 1972 + } else { 1973 + n = struct_size(tbl, tbls, CXST_MAX); 1974 + tbl = kmalloc(n, GFP_KERNEL); 1975 + if (!tbl) 1976 + return; 1977 + 1978 + tbl->fver = BTF_SET_SLOT_TABLE_VER; 1979 + tbl->tbl_num = CXST_MAX; 1980 + memcpy(tbl->tbls, dm->slot.v1, flex_array_size(tbl, tbls, CXST_MAX)); 1981 + 1982 + _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n); 1983 + 1984 + kfree(tbl); 1985 + } 1986 + } 1987 + 2082 1988 static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, 2083 1989 u32 rpt_map, bool rpt_state) 2084 1990 { ··· 2152 1980 ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r, sizeof(r)); 2153 1981 if (!ret) 2154 1982 fwinfo->rpt_en_map = val; 2155 - } 2156 - 2157 - static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev, u8 num, 2158 - struct rtw89_btc_fbtc_slot *s) 2159 - { 2160 - struct rtw89_btc_btf_set_slot_table *tbl; 2161 - u16 n; 2162 - 2163 - n = struct_size(tbl, tbls, num); 2164 - tbl = kmalloc(n, GFP_KERNEL); 2165 - if (!tbl) 2166 - return; 2167 - 2168 - tbl->fver = BTF_SET_SLOT_TABLE_VER; 2169 - tbl->tbl_num = num; 2170 - memcpy(tbl->tbls, s, flex_array_size(tbl, tbls, num)); 2171 - 2172 - _send_fw_cmd(rtwdev, BTFC_SET, SET_SLOT_TABLE, tbl, n); 2173 - 2174 - kfree(tbl); 2175 1983 } 2176 1984 2177 1985 static void btc_fw_set_monreg(struct rtw89_dev *rtwdev) ··· 2252 2100 btc->policy, btc->policy_len); 2253 2101 if (!ret) { 2254 2102 memcpy(&dm->tdma_now, &dm->tdma, sizeof(dm->tdma_now)); 2255 - memcpy(&dm->slot_now, &dm->slot, sizeof(dm->slot_now)); 2103 + if (btc->ver->fcxslots == 7) 2104 + memcpy(&dm->slot_now.v7, &dm->slot.v7, sizeof(dm->slot_now.v7)); 2105 + else 2106 + memcpy(&dm->slot_now.v1, &dm->slot.v1, sizeof(dm->slot_now.v1)); 2256 2107 } 2257 2108 2258 2109 if (btc->update_policy_force) ··· 2396 2241 } 2397 2242 2398 2243 rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt); 2244 + } 2245 + 2246 + static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map, 2247 + u8 wl_state, u8 bt_state, u8 wlact_state) 2248 + { 2249 + struct rtw89_btc *btc = &rtwdev->btc; 2250 + struct rtw89_btc_dm *dm = &btc->dm; 2251 + struct rtw89_mac_ax_gnt *g = dm->gnt.band; 2252 + u8 i, bt_idx = dm->bt_select + 1; 2253 + 2254 + if (phy_map > BTC_PHY_ALL) 2255 + return; 2256 + 2257 + for (i = 0; i < RTW89_PHY_MAX; i++) { 2258 + if (!(phy_map & BIT(i))) 2259 + continue; 2260 + 2261 + switch (wl_state) { 2262 + case BTC_GNT_HW: 2263 + g[i].gnt_wl_sw_en = 0; 2264 + g[i].gnt_wl = 0; 2265 + break; 2266 + case BTC_GNT_SW_LO: 2267 + g[i].gnt_wl_sw_en = 1; 2268 + g[i].gnt_wl = 0; 2269 + break; 2270 + case BTC_GNT_SW_HI: 2271 + g[i].gnt_wl_sw_en = 1; 2272 + g[i].gnt_wl = 1; 2273 + break; 2274 + } 2275 + 2276 + switch (bt_state) { 2277 + case BTC_GNT_HW: 2278 + g[i].gnt_bt_sw_en = 0; 2279 + g[i].gnt_bt = 0; 2280 + break; 2281 + case BTC_GNT_SW_LO: 2282 + g[i].gnt_bt_sw_en = 1; 2283 + g[i].gnt_bt = 0; 2284 + break; 2285 + case BTC_GNT_SW_HI: 2286 + g[i].gnt_bt_sw_en = 1; 2287 + g[i].gnt_bt = 1; 2288 + break; 2289 + } 2290 + } 2291 + 2292 + if (rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX) { 2293 + for (i = 0; i < 2; i++) { 2294 + if (!(bt_idx & BIT(i))) 2295 + continue; 2296 + 2297 + switch (wlact_state) { 2298 + case BTC_WLACT_HW: 2299 + dm->gnt.bt[i].wlan_act_en = 0; 2300 + dm->gnt.bt[i].wlan_act = 0; 2301 + break; 2302 + case BTC_WLACT_SW_LO: 2303 + dm->gnt.bt[i].wlan_act_en = 1; 2304 + dm->gnt.bt[i].wlan_act = 0; 2305 + break; 2306 + case BTC_WLACT_SW_HI: 2307 + dm->gnt.bt[i].wlan_act_en = 1; 2308 + dm->gnt.bt[i].wlan_act = 1; 2309 + break; 2310 + } 2311 + } 2312 + } 2313 + rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt); 2399 2314 } 2400 2315 2401 2316 #define BTC_TDMA_WLROLE_MAX 2 ··· 2847 2622 struct rtw89_btc_bt_info *bt = &btc->cx.bt; 2848 2623 struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 2849 2624 struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 2625 + struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 2626 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 2850 2627 struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; 2851 2628 struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc; 2852 2629 union rtw89_btc_module_info *md = &btc->mdinfo; 2853 2630 const struct rtw89_btc_ver *ver = btc->ver; 2854 - u8 isolation; 2631 + u8 isolation, connect_cnt = 0; 2855 2632 2856 2633 if (ver->fcxinit == 7) 2857 2634 isolation = md->md_v7.ant.isolation; 2858 2635 else 2859 2636 isolation = md->md.ant.isolation; 2637 + 2638 + if (ver->fwlrole == 0) 2639 + connect_cnt = wl_rinfo->connect_cnt; 2640 + else if (ver->fwlrole == 1) 2641 + connect_cnt = wl_rinfo_v1->connect_cnt; 2642 + else if (ver->fwlrole == 2) 2643 + connect_cnt = wl_rinfo_v2->connect_cnt; 2644 + else if (ver->fwlrole == 8) 2645 + connect_cnt = wl_rinfo_v8->connect_cnt; 2860 2646 2861 2647 if (btc->ant_type == BTC_ANT_SHARED) { 2862 2648 btc->dm.trx_para_level = 0; ··· 2875 2639 } 2876 2640 2877 2641 /* The below is dedicated antenna case */ 2878 - if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX || 2879 - wl_rinfo_v1->connect_cnt > BTC_TDMA_WLROLE_MAX) { 2642 + if (connect_cnt > BTC_TDMA_WLROLE_MAX) { 2880 2643 btc->dm.trx_para_level = 5; 2881 2644 return true; 2882 2645 } ··· 2927 2692 #define _tdma_set_flctrl_role(btc, role) ({(btc)->dm.tdma.rxflctrl_role = role; }) 2928 2693 #define _tdma_set_tog(btc, wtg) ({(btc)->dm.tdma.wtgle_n = wtg; }) 2929 2694 #define _tdma_set_lek(btc, lek) ({(btc)->dm.tdma.leak_n = lek; }) 2930 - 2931 - #define _slot_set(btc, sid, dura, tbl, type) \ 2932 - do { \ 2933 - typeof(sid) _sid = (sid); \ 2934 - typeof(btc) _btc = (btc); \ 2935 - _btc->dm.slot[_sid].dur = cpu_to_le16(dura);\ 2936 - _btc->dm.slot[_sid].cxtbl = cpu_to_le32(tbl); \ 2937 - _btc->dm.slot[_sid].cxtype = cpu_to_le16(type); \ 2938 - } while (0) 2939 - 2940 - #define _slot_set_dur(btc, sid, dura) (btc)->dm.slot[sid].dur = cpu_to_le16(dura) 2941 - #define _slot_set_tbl(btc, sid, tbl) (btc)->dm.slot[sid].cxtbl = cpu_to_le32(tbl) 2942 - #define _slot_set_type(btc, sid, type) (btc)->dm.slot[sid].cxtype = cpu_to_le16(type) 2943 2695 2944 2696 struct btc_btinfo_lb2 { 2945 2697 u8 connect: 1; ··· 3002 2780 struct rtw89_btc *btc = &rtwdev->btc; 3003 2781 struct rtw89_btc_dm *dm = &btc->dm; 3004 2782 struct rtw89_btc_fbtc_tdma *t = &dm->tdma; 3005 - struct rtw89_btc_fbtc_slot *s = dm->slot; 2783 + struct rtw89_btc_fbtc_slot *s = dm->slot.v1; 3006 2784 u8 type; 3007 2785 u32 tbl_w1, tbl_b1, tbl_b4; 3008 2786 ··· 3313 3091 struct rtw89_btc *btc = &rtwdev->btc; 3314 3092 struct rtw89_btc_dm *dm = &btc->dm; 3315 3093 struct rtw89_btc_fbtc_tdma *t = &dm->tdma; 3316 - struct rtw89_btc_fbtc_slot *s = dm->slot; 3317 3094 struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &btc->cx.wl.role_info_v1; 3318 3095 struct rtw89_btc_bt_hid_desc *hid = &btc->cx.bt.link_info.hid_desc; 3319 3096 struct rtw89_btc_bt_hfp_desc *hfp = &btc->cx.bt.link_info.hfp_desc; ··· 3360 3139 case BTC_CXP_USERDEF0: 3361 3140 btc->update_policy_force = true; 3362 3141 *t = t_def[CXTD_OFF]; 3363 - s[CXST_OFF] = s_def[CXST_OFF]; 3142 + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3143 + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 3364 3144 _slot_set_tbl(btc, CXST_OFF, cxtbl[2]); 3365 3145 break; 3366 3146 case BTC_CXP_OFF: /* TDMA off */ 3367 3147 _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 3368 3148 *t = t_def[CXTD_OFF]; 3369 - s[CXST_OFF] = s_def[CXST_OFF]; 3149 + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3150 + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 3370 3151 3371 3152 switch (policy_type) { 3372 3153 case BTC_CXP_OFF_BT: ··· 3409 3186 case BTC_CXP_OFFB: /* TDMA off + beacon protect */ 3410 3187 _write_scbd(rtwdev, BTC_WSCB_TDMA, false); 3411 3188 *t = t_def[CXTD_OFF_B2]; 3412 - s[CXST_OFF] = s_def[CXST_OFF]; 3189 + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3190 + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 3413 3191 3414 3192 switch (policy_type) { 3415 3193 case BTC_CXP_OFFB_BWB0: ··· 3431 3207 3432 3208 switch (policy_type) { 3433 3209 case BTC_CXP_OFFE_DEF: 3434 - s[CXST_E2G] = s_def[CXST_E2G]; 3435 - s[CXST_E5G] = s_def[CXST_E5G]; 3436 - s[CXST_EBT] = s_def[CXST_EBT]; 3437 - s[CXST_ENULL] = s_def[CXST_ENULL]; 3210 + _slot_set_le(btc, CXST_E2G, s_def[CXST_E2G].dur, 3211 + s_def[CXST_E2G].cxtbl, s_def[CXST_E2G].cxtype); 3212 + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, 3213 + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); 3214 + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3215 + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3216 + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, 3217 + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); 3438 3218 break; 3439 3219 case BTC_CXP_OFFE_DEF2: 3440 3220 _slot_set(btc, CXST_E2G, 20, cxtbl[1], SLOT_ISO); 3441 - s[CXST_E5G] = s_def[CXST_E5G]; 3442 - s[CXST_EBT] = s_def[CXST_EBT]; 3443 - s[CXST_ENULL] = s_def[CXST_ENULL]; 3221 + _slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur, 3222 + s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype); 3223 + _slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur, 3224 + s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype); 3225 + _slot_set_le(btc, CXST_ENULL, s_def[CXST_ENULL].dur, 3226 + s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype); 3444 3227 break; 3445 3228 default: 3446 3229 break; 3447 3230 } 3448 - s[CXST_OFF] = s_def[CXST_OFF]; 3231 + _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur, 3232 + s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype); 3449 3233 break; 3450 3234 case BTC_CXP_FIX: /* TDMA Fix-Slot */ 3451 3235 _write_scbd(rtwdev, BTC_WSCB_TDMA, true); ··· 3730 3498 rtw89_mac_cfg_plt(rtwdev, &plt); 3731 3499 } 3732 3500 3733 - static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, 3734 - u8 phy_map, u8 type) 3501 + static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec, 3502 + u8 phy_map, u8 type) 3735 3503 { 3736 3504 struct rtw89_btc *btc = &rtwdev->btc; 3737 3505 struct rtw89_btc_dm *dm = &btc->dm; ··· 3740 3508 struct rtw89_btc_bt_info *bt = &cx->bt; 3741 3509 struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 3742 3510 u8 gnt_wl_ctrl, gnt_bt_ctrl, plt_ctrl, i, b2g = 0; 3511 + bool dbcc_chg = false; 3743 3512 u32 ant_path_type; 3744 3513 3745 3514 ant_path_type = ((phy_map << 8) + type); 3746 3515 3516 + if (btc->ver->fwlrole == 1) 3517 + dbcc_chg = wl->role_info_v1.dbcc_chg; 3518 + else if (btc->ver->fwlrole == 2) 3519 + dbcc_chg = wl->role_info_v2.dbcc_chg; 3520 + else if (btc->ver->fwlrole == 8) 3521 + dbcc_chg = wl->role_info_v8.dbcc_chg; 3522 + 3747 3523 if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF || 3748 3524 btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE || 3749 - btc->dm.run_reason == BTC_RSN_CMD_SET_COEX) 3525 + btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || dbcc_chg) 3750 3526 force_exec = FC_EXEC; 3751 3527 3752 3528 if (!force_exec && ant_path_type == dm->set_ant_path) { ··· 3857 3617 } 3858 3618 } 3859 3619 3620 + static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec, 3621 + u8 phy_map, u8 type) 3622 + { 3623 + struct rtw89_btc *btc = &rtwdev->btc; 3624 + struct rtw89_btc_wl_info *wl = &btc->cx.wl; 3625 + struct rtw89_btc_bt_info *bt = &btc->cx.bt; 3626 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 3627 + u32 ant_path_type = rtw89_get_antpath_type(phy_map, type); 3628 + struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 3629 + struct rtw89_btc_dm *dm = &btc->dm; 3630 + u8 gwl = BTC_GNT_HW; 3631 + 3632 + if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF || 3633 + btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE || 3634 + btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || wl_rinfo->dbcc_chg) 3635 + force_exec = FC_EXEC; 3636 + 3637 + if (wl_rinfo->link_mode != BTC_WLINK_25G_MCC && 3638 + btc->dm.wl_btg_rx == 2) 3639 + force_exec = FC_EXEC; 3640 + 3641 + if (!force_exec && ant_path_type == dm->set_ant_path) { 3642 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 3643 + "[BTC], %s(): return by no change!!\n", 3644 + __func__); 3645 + return; 3646 + } else if (bt->rfk_info.map.run) { 3647 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 3648 + "[BTC], %s(): return by bt rfk!!\n", __func__); 3649 + return; 3650 + } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK && 3651 + wl->rfk_info.state != BTC_WRFK_STOP) { 3652 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 3653 + "[BTC], %s(): return by wl rfk!!\n", __func__); 3654 + return; 3655 + } 3656 + 3657 + dm->set_ant_path = ant_path_type; 3658 + 3659 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 3660 + "[BTC], %s(): path=0x%x, set_type=0x%x\n", 3661 + __func__, phy_map, dm->set_ant_path & 0xff); 3662 + 3663 + switch (type) { 3664 + case BTC_ANT_WINIT: 3665 + /* To avoid BT MP driver case (bt_enable but no mailbox) */ 3666 + if (bt->enable.now && bt->run_patch_code) 3667 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI, 3668 + BTC_WLACT_SW_LO); 3669 + else 3670 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 3671 + BTC_WLACT_SW_HI); 3672 + break; 3673 + case BTC_ANT_WONLY: 3674 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 3675 + BTC_WLACT_SW_HI); 3676 + break; 3677 + case BTC_ANT_WOFF: 3678 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI, 3679 + BTC_WLACT_SW_LO); 3680 + break; 3681 + case BTC_ANT_W2G: 3682 + case BTC_ANT_W25G: 3683 + if (wl_rinfo->dbcc_en) { 3684 + if (wl_dinfo->real_band[RTW89_PHY_0] == RTW89_BAND_2G) 3685 + gwl = BTC_GNT_HW; 3686 + else 3687 + gwl = BTC_GNT_SW_HI; 3688 + _set_gnt_v1(rtwdev, BTC_PHY_0, gwl, BTC_GNT_HW, BTC_WLACT_HW); 3689 + 3690 + if (wl_dinfo->real_band[RTW89_PHY_1] == RTW89_BAND_2G) 3691 + gwl = BTC_GNT_HW; 3692 + else 3693 + gwl = BTC_GNT_SW_HI; 3694 + _set_gnt_v1(rtwdev, BTC_PHY_1, gwl, BTC_GNT_HW, BTC_WLACT_HW); 3695 + } else { 3696 + gwl = BTC_GNT_HW; 3697 + _set_gnt_v1(rtwdev, phy_map, gwl, BTC_GNT_HW, BTC_WLACT_HW); 3698 + } 3699 + break; 3700 + case BTC_ANT_W5G: 3701 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW, BTC_WLACT_HW); 3702 + break; 3703 + case BTC_ANT_FREERUN: 3704 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI, 3705 + BTC_WLACT_SW_LO); 3706 + break; 3707 + case BTC_ANT_WRFK: 3708 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 3709 + BTC_WLACT_HW); 3710 + break; 3711 + case BTC_ANT_WRFK2: 3712 + _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO, 3713 + BTC_WLACT_SW_HI); /* no BT-Tx */ 3714 + break; 3715 + default: 3716 + return; 3717 + } 3718 + 3719 + _set_bt_plut(rtwdev, phy_map, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL); 3720 + } 3721 + 3722 + static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec, 3723 + u8 phy_map, u8 type) 3724 + { 3725 + if (rtwdev->chip->chip_id == RTL8922A) 3726 + _set_ant_v1(rtwdev, force_exec, phy_map, type); 3727 + else 3728 + _set_ant_v0(rtwdev, force_exec, phy_map, type); 3729 + } 3730 + 3860 3731 static void _action_wl_only(struct rtw89_dev *rtwdev) 3861 3732 { 3862 3733 _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY); ··· 3992 3641 if (wl->status.map.rf_off || btc->dm.bt_only) { 3993 3642 _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF); 3994 3643 } else if (wl->status.map.lps == BTC_LPS_RF_ON) { 3995 - if (wl->role_info.link_mode == BTC_WLINK_5G) 3644 + if (mode == BTC_WLINK_5G) 3996 3645 _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W5G); 3997 3646 else 3998 3647 _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); ··· 4574 4223 u16 enable = iter_data->enable; 4575 4224 bool reenable = iter_data->reenable; 4576 4225 4577 - plink = &wl->link_info[port]; 4226 + if (btc->ver->fwlrole == 8) 4227 + plink = &wl->rlink_info[port][0]; 4228 + else 4229 + plink = &wl->link_info[port]; 4578 4230 4579 4231 rtw89_debug(rtwdev, RTW89_DBG_BTC, 4580 4232 "[BTC], %s(): port = %d\n", __func__, port); ··· 4630 4276 struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 4631 4277 struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 4632 4278 struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 4279 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 4633 4280 struct rtw89_txtime_data data = {.rtwdev = rtwdev}; 4634 4281 u8 mode, igno_bt, tx_retry; 4635 4282 u32 tx_time; ··· 4646 4291 mode = wl_rinfo_v1->link_mode; 4647 4292 else if (ver->fwlrole == 2) 4648 4293 mode = wl_rinfo_v2->link_mode; 4294 + else if (ver->fwlrole == 8) 4295 + mode = wl_rinfo_v8->link_mode; 4649 4296 else 4650 4297 return; 4651 4298 ··· 4705 4348 struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 4706 4349 struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 4707 4350 struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 4351 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 4708 4352 struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4709 4353 bool bt_hi_lna_rx = false; 4710 4354 u8 mode; ··· 4716 4358 mode = wl_rinfo_v1->link_mode; 4717 4359 else if (ver->fwlrole == 2) 4718 4360 mode = wl_rinfo_v2->link_mode; 4361 + else if (ver->fwlrole == 8) 4362 + mode = wl_rinfo_v8->link_mode; 4719 4363 else 4720 4364 return; 4721 4365 ··· 5050 4690 break; 5051 4691 } 5052 4692 } 4693 + 4694 + _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 4695 + _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); 4696 + } 4697 + 4698 + static void _action_wl_2g_scc_v8(struct rtw89_dev *rtwdev) 4699 + { 4700 + struct rtw89_btc *btc = &rtwdev->btc; 4701 + struct rtw89_btc_wl_info *wl = &btc->cx.wl; 4702 + struct rtw89_btc_bt_info *bt = &btc->cx.bt; 4703 + struct rtw89_btc_dm *dm = &btc->dm; 4704 + u16 policy_type = BTC_CXP_OFF_BT; 4705 + 4706 + if (btc->ant_type == BTC_ANT_SHARED) { 4707 + if (wl->status.map._4way) 4708 + policy_type = BTC_CXP_OFFE_WL; 4709 + else if (bt->link_info.status.map.connect == 0) 4710 + policy_type = BTC_CXP_OFFE_2GISOB; 4711 + else 4712 + policy_type = BTC_CXP_OFFE_2GBWISOB; 4713 + } else { 4714 + policy_type = BTC_CXP_OFF_EQ0; 4715 + } 4716 + 4717 + dm->e2g_slot_limit = BTC_E2G_LIMIT_DEF; 5053 4718 5054 4719 _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G); 5055 4720 _set_policy(rtwdev, policy_type, BTC_ACT_WL_2G_SCC); ··· 5672 5287 #define BTC_CHK_HANG_MAX 3 5673 5288 #define BTC_SCB_INV_VALUE GENMASK(31, 0) 5674 5289 5290 + static u8 _get_role_link_mode(u8 role) 5291 + { 5292 + switch (role) { 5293 + case RTW89_WIFI_ROLE_STATION: 5294 + return BTC_WLINK_2G_STA; 5295 + case RTW89_WIFI_ROLE_P2P_GO: 5296 + return BTC_WLINK_2G_GO; 5297 + case RTW89_WIFI_ROLE_P2P_CLIENT: 5298 + return BTC_WLINK_2G_GC; 5299 + case RTW89_WIFI_ROLE_AP: 5300 + return BTC_WLINK_2G_AP; 5301 + default: 5302 + return BTC_WLINK_OTHER; 5303 + } 5304 + } 5305 + 5306 + static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1, 5307 + const struct rtw89_btc_chdef *r2) 5308 + { 5309 + if (r1->chan != r2->chan) { /* primary ch is different */ 5310 + return false; 5311 + } else if (r1->bw == RTW89_CHANNEL_WIDTH_40 && 5312 + r2->bw == RTW89_CHANNEL_WIDTH_40) { 5313 + if (r1->offset != r2->offset) 5314 + return false; 5315 + } 5316 + return true; 5317 + } 5318 + 5319 + static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch, 5320 + u8 *phy, u8 *role, u8 *dbcc_2g_phy) 5321 + { 5322 + struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl; 5323 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 5324 + bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false; 5325 + u8 j, k, dbcc_2g_cid, dbcc_2g_cid2; 5326 + 5327 + /* find out the 2G-PHY by connect-id ->ch */ 5328 + for (j = 0; j < wl_rinfo->connect_cnt; j++) { 5329 + if (ch[j].center_ch <= 14) { 5330 + is_2g_ch_exist = true; 5331 + break; 5332 + } 5333 + } 5334 + 5335 + /* If no any 2G-port exist, it's impossible because 5G-exclude */ 5336 + if (!is_2g_ch_exist) 5337 + return BTC_WLINK_OTHER; 5338 + 5339 + dbcc_2g_cid = j; 5340 + *dbcc_2g_phy = phy[dbcc_2g_cid]; 5341 + 5342 + /* connect_cnt <= 2 */ 5343 + if (wl_rinfo->connect_cnt < BTC_TDMA_WLROLE_MAX) 5344 + return (_get_role_link_mode((role[dbcc_2g_cid]))); 5345 + 5346 + /* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */ 5347 + for (k = 0; k < wl_rinfo->connect_cnt; k++) { 5348 + if (k == dbcc_2g_cid) 5349 + continue; 5350 + 5351 + if (phy[k] == *dbcc_2g_phy) { 5352 + is_multi_role_in_2g_phy = true; 5353 + dbcc_2g_cid2 = k; 5354 + break; 5355 + } 5356 + } 5357 + 5358 + /* Single-role in 2G-PHY */ 5359 + if (!is_multi_role_in_2g_phy) 5360 + return (_get_role_link_mode(role[dbcc_2g_cid])); 5361 + 5362 + /* 2-role in 2G-PHY */ 5363 + if (ch[dbcc_2g_cid2].center_ch > 14) 5364 + return BTC_WLINK_25G_MCC; 5365 + else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2])) 5366 + return BTC_WLINK_2G_SCC; 5367 + else 5368 + return BTC_WLINK_2G_MCC; 5369 + } 5370 + 5371 + static void _update_role_link_mode(struct rtw89_dev *rtwdev, 5372 + bool client_joined, u32 noa) 5373 + { 5374 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &rtwdev->btc.cx.wl.role_info_v8; 5375 + u32 type = BTC_WLMROLE_NONE, dur = 0; 5376 + u32 wl_role = wl_rinfo->role_map; 5377 + 5378 + /* if no client_joined, don't care P2P-GO/AP role */ 5379 + if (((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 5380 + (wl_role & BIT(RTW89_WIFI_ROLE_AP))) && !client_joined) { 5381 + if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC) { 5382 + wl_rinfo->link_mode = BTC_WLINK_2G_STA; 5383 + wl_rinfo->connect_cnt--; 5384 + } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO || 5385 + wl_rinfo->link_mode == BTC_WLINK_2G_AP) { 5386 + wl_rinfo->link_mode = BTC_WLINK_NOLINK; 5387 + wl_rinfo->connect_cnt--; 5388 + } 5389 + } 5390 + 5391 + /* Identify 2-Role type */ 5392 + if (wl_rinfo->connect_cnt >= 2 && 5393 + (wl_rinfo->link_mode == BTC_WLINK_2G_SCC || 5394 + wl_rinfo->link_mode == BTC_WLINK_2G_MCC || 5395 + wl_rinfo->link_mode == BTC_WLINK_25G_MCC || 5396 + wl_rinfo->link_mode == BTC_WLINK_5G)) { 5397 + if ((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) || 5398 + (wl_role & BIT(RTW89_WIFI_ROLE_AP))) 5399 + type = noa ? BTC_WLMROLE_STA_GO_NOA : BTC_WLMROLE_STA_GO; 5400 + else if (wl_role & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)) 5401 + type = noa ? BTC_WLMROLE_STA_GC_NOA : BTC_WLMROLE_STA_GC; 5402 + else 5403 + type = BTC_WLMROLE_STA_STA; 5404 + 5405 + dur = noa; 5406 + } 5407 + 5408 + wl_rinfo->mrole_type = type; 5409 + wl_rinfo->mrole_noa_duration = dur; 5410 + } 5411 + 5412 + static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id, 5413 + enum btc_role_state state) 5414 + { 5415 + struct rtw89_btc *btc = &rtwdev->btc; 5416 + struct rtw89_btc_wl_info *wl = &btc->cx.wl; 5417 + struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER]; 5418 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8; 5419 + struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info; 5420 + bool client_joined = false, b2g = false, b5g = false; 5421 + u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 5422 + u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {}; 5423 + u8 dbcc_en = 0, pta_req_band = RTW89_MAC_0; 5424 + u8 i, j, cnt = 0, cnt_2g = 0, cnt_5g = 0; 5425 + struct rtw89_btc_wl_link_info *wl_linfo; 5426 + struct rtw89_btc_wl_rlink *rlink = NULL; 5427 + u8 dbcc_2g_phy = RTW89_PHY_0; 5428 + u8 mode = BTC_WLINK_NOLINK; 5429 + u32 noa_dur = 0; 5430 + 5431 + if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id > RTW89_MAC_1) 5432 + return; 5433 + 5434 + /* Extract wl->link_info[role_id][rlink_id] to wl->role_info 5435 + * role_id: role index 5436 + * rlink_id: rlink index (= HW-band index) 5437 + * pid: port_index 5438 + */ 5439 + 5440 + wl_linfo = &wl->rlink_info[role_id][rlink_id]; 5441 + if (wl_linfo->connected == MLME_LINKING) 5442 + return; 5443 + 5444 + rlink = &wl_rinfo->rlink[role_id][rlink_id]; 5445 + rlink->role = wl_linfo->role; 5446 + rlink->active = wl_linfo->active; /* Doze or not */ 5447 + rlink->pid = wl_linfo->pid; 5448 + rlink->phy = wl_linfo->phy; 5449 + rlink->rf_band = wl_linfo->band; 5450 + rlink->ch = wl_linfo->ch; 5451 + rlink->bw = wl_linfo->bw; 5452 + rlink->noa = wl_linfo->noa; 5453 + rlink->noa_dur = wl_linfo->noa_duration / 1000; 5454 + rlink->client_cnt = wl_linfo->client_cnt; 5455 + rlink->mode = wl_linfo->mode; 5456 + 5457 + switch (wl_linfo->connected) { 5458 + case MLME_NO_LINK: 5459 + rlink->connected = 0; 5460 + if (rlink->role == RTW89_WIFI_ROLE_STATION) 5461 + btc->dm.leak_ap = 0; 5462 + break; 5463 + case MLME_LINKED: 5464 + rlink->connected = 1; 5465 + break; 5466 + default: 5467 + return; 5468 + } 5469 + 5470 + wl->is_5g_hi_channel = false; 5471 + wl->bg_mode = false; 5472 + wl_rinfo->role_map = 0; 5473 + wl_rinfo->p2p_2g = 0; 5474 + memset(cid_ch, 0, sizeof(cid_ch)); 5475 + 5476 + for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { 5477 + for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) { 5478 + rlink = &wl_rinfo->rlink[i][j]; 5479 + 5480 + if (!rlink->active || !rlink->connected) 5481 + continue; 5482 + 5483 + cnt++; 5484 + wl_rinfo->role_map |= BIT(rlink->role); 5485 + 5486 + /* only if client connect for p2p-Go/AP */ 5487 + if ((rlink->role == RTW89_WIFI_ROLE_P2P_GO || 5488 + rlink->role == RTW89_WIFI_ROLE_AP) && 5489 + rlink->client_cnt > 1) 5490 + client_joined = true; 5491 + 5492 + /* Identufy if P2P-Go (GO/GC/AP) exist at 2G band*/ 5493 + if (rlink->rf_band == RTW89_BAND_2G && 5494 + (client_joined || rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) 5495 + wl_rinfo->p2p_2g = 1; 5496 + 5497 + /* only one noa-role exist */ 5498 + if (rlink->noa && rlink->noa_dur > 0) 5499 + noa_dur = rlink->noa_dur; 5500 + 5501 + /* for WL 5G-Rx interfered with BT issue */ 5502 + if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100) 5503 + wl->is_5g_hi_channel = 1; 5504 + 5505 + if ((rlink->mode & BIT(BTC_WL_MODE_11B)) || 5506 + (rlink->mode & BIT(BTC_WL_MODE_11G))) 5507 + wl->bg_mode = 1; 5508 + 5509 + if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) 5510 + continue; 5511 + 5512 + cid_ch[cnt - 1] = wl_linfo->chdef; 5513 + cid_phy[cnt - 1] = rlink->phy; 5514 + cid_role[cnt - 1] = rlink->role; 5515 + 5516 + if (rlink->rf_band != RTW89_BAND_2G) { 5517 + cnt_5g++; 5518 + b5g = true; 5519 + } else { 5520 + cnt_2g++; 5521 + b2g = true; 5522 + } 5523 + } 5524 + } 5525 + 5526 + if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) { 5527 + rtw89_debug(rtwdev, RTW89_DBG_BTC, 5528 + "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g); 5529 + rtw89_warn(rtwdev, "not support MLO feature yet"); 5530 + } else { 5531 + dbcc_en = rtwdev->dbcc_en; 5532 + 5533 + /* Be careful to change the following sequence!! */ 5534 + if (cnt == 0) { 5535 + mode = BTC_WLINK_NOLINK; 5536 + } else if (!b2g && b5g) { 5537 + mode = BTC_WLINK_5G; 5538 + } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) { 5539 + mode = BTC_WLINK_2G_NAN; 5540 + } else if (cnt > BTC_TDMA_WLROLE_MAX) { 5541 + mode = BTC_WLINK_OTHER; 5542 + } else if (dbcc_en) { 5543 + mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, 5544 + &dbcc_2g_phy); 5545 + } else if (b2g && b5g && cnt == 2) { 5546 + mode = BTC_WLINK_25G_MCC; 5547 + } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */ 5548 + if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1])) 5549 + mode = BTC_WLINK_2G_SCC; 5550 + else 5551 + mode = BTC_WLINK_2G_MCC; 5552 + } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */ 5553 + mode = _get_role_link_mode(cid_role[0]); 5554 + } 5555 + } 5556 + 5557 + wl_rinfo->link_mode = mode; 5558 + wl_rinfo->connect_cnt = cnt; 5559 + if (wl_rinfo->connect_cnt == 0) 5560 + wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE); 5561 + _update_role_link_mode(rtwdev, client_joined, noa_dur); 5562 + 5563 + wl_rinfo->dbcc_2g_phy = dbcc_2g_phy; 5564 + if (wl_rinfo->dbcc_en != dbcc_en) { 5565 + wl_rinfo->dbcc_en = dbcc_en; 5566 + wl_rinfo->dbcc_chg = 1; 5567 + btc->cx.cnt_wl[BTC_WCNT_DBCC_CHG]++; 5568 + } else { 5569 + wl_rinfo->dbcc_chg = 0; 5570 + } 5571 + 5572 + if (wl_rinfo->dbcc_en) { 5573 + memset(wl_dinfo, 0, sizeof(struct rtw89_btc_wl_dbcc_info)); 5574 + 5575 + if (mode == BTC_WLINK_5G) { 5576 + pta_req_band = RTW89_PHY_0; 5577 + wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 5578 + wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 5579 + } else if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_1) { 5580 + pta_req_band = RTW89_PHY_1; 5581 + wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_5G; 5582 + wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_2G; 5583 + } else { 5584 + pta_req_band = RTW89_PHY_0; 5585 + wl_dinfo->op_band[RTW89_PHY_0] = RTW89_BAND_2G; 5586 + wl_dinfo->op_band[RTW89_PHY_1] = RTW89_BAND_5G; 5587 + } 5588 + _update_dbcc_band(rtwdev, RTW89_PHY_0); 5589 + _update_dbcc_band(rtwdev, RTW89_PHY_1); 5590 + } 5591 + 5592 + wl_rinfo->pta_req_band = pta_req_band; 5593 + _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE); 5594 + } 5595 + 5675 5596 void rtw89_coex_act1_work(struct work_struct *work) 5676 5597 { 5677 5598 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, ··· 6136 5445 struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 6137 5446 struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 6138 5447 struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 5448 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 6139 5449 u8 mode, igno_bt, always_freerun; 6140 5450 6141 5451 lockdep_assert_held(&rtwdev->mutex); ··· 6151 5459 mode = wl_rinfo_v1->link_mode; 6152 5460 else if (ver->fwlrole == 2) 6153 5461 mode = wl_rinfo_v2->link_mode; 5462 + else if (ver->fwlrole == 8) 5463 + mode = wl_rinfo_v8->link_mode; 6154 5464 else 6155 5465 return; 6156 5466 ··· 6299 5605 _action_wl_2g_scc_v1(rtwdev); 6300 5606 else if (ver->fwlrole == 2) 6301 5607 _action_wl_2g_scc_v2(rtwdev); 5608 + else if (ver->fwlrole == 8) 5609 + _action_wl_2g_scc_v8(rtwdev); 6302 5610 break; 6303 5611 case BTC_WLINK_2G_MCC: 6304 5612 bt->scan_rx_low_pri = true; ··· 6432 5736 6433 5737 _set_init_info(rtwdev); 6434 5738 _set_wl_tx_power(rtwdev, RTW89_BTC_WL_DEF_TX_PWR); 6435 - rtw89_btc_fw_set_slots(rtwdev, CXST_MAX, dm->slot); 6436 5739 btc_fw_set_monreg(rtwdev); 5740 + rtw89_btc_fw_set_slots(rtwdev); 6437 5741 _fw_set_drv_info(rtwdev, CXDRVINFO_INIT); 6438 5742 _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL); 6439 5743 ··· 6652 5956 return rssi_level; 6653 5957 } 6654 5958 5959 + static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev) 5960 + { 5961 + u8 mode = rtwdev->btc.cx.wl.role_info.link_mode; 5962 + u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a; 5963 + 5964 + if (mode == BTC_WLINK_5G || rtwdev->btc.dm.freerun) { 5965 + zb_tbl0 = 0xffffffff; 5966 + zb_tbl1 = 0xffffffff; 5967 + } else if (mode == BTC_WLINK_25G_MCC) { 5968 + zb_tbl0 = 0xffffffff; /* for E5G slot */ 5969 + zb_tbl1 = 0xda5a5a5a; /* for E2G slot */ 5970 + } 5971 + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0); 5972 + rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1); 5973 + } 5974 + 6655 5975 #define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4) 6656 5976 6657 5977 static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) ··· 6805 6093 _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); 6806 6094 } 6807 6095 6808 - enum btc_wl_mode { 6809 - BTC_WL_MODE_HT = 0, 6810 - BTC_WL_MODE_VHT = 1, 6811 - BTC_WL_MODE_HE = 2, 6812 - BTC_WL_MODE_NUM, 6813 - }; 6814 - 6815 6096 void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, 6816 6097 struct rtw89_sta *rtwsta, enum btc_role_state state) 6817 6098 { ··· 6817 6112 struct rtw89_btc_wl_info *wl = &btc->cx.wl; 6818 6113 struct rtw89_btc_wl_link_info r = {0}; 6819 6114 struct rtw89_btc_wl_link_info *wlinfo = NULL; 6820 - u8 mode = 0; 6115 + u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type; 6821 6116 6822 6117 rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state); 6823 6118 rtw89_debug(rtwdev, RTW89_DBG_BTC, ··· 6867 6162 r.band = chan->band_type; 6868 6163 r.ch = chan->channel; 6869 6164 r.bw = chan->band_width; 6165 + r.chdef.band = chan->band_type; 6166 + r.chdef.center_ch = chan->channel; 6167 + r.chdef.bw = chan->band_width; 6168 + r.chdef.chan = chan->primary_channel; 6870 6169 ether_addr_copy(r.mac_addr, rtwvif->mac_addr); 6871 6170 6872 6171 if (rtwsta && vif->type == NL80211_IFTYPE_STATION) ··· 6880 6171 6881 6172 wlinfo = &wl->link_info[r.pid]; 6882 6173 6883 - memcpy(wlinfo, &r, sizeof(*wlinfo)); 6884 - if (ver->fwlrole == 0) 6174 + rlink_id = 0; /* to do */ 6175 + if (ver->fwlrole == 0) { 6176 + *wlinfo = r; 6885 6177 _update_wl_info(rtwdev); 6886 - else if (ver->fwlrole == 1) 6178 + } else if (ver->fwlrole == 1) { 6179 + *wlinfo = r; 6887 6180 _update_wl_info_v1(rtwdev); 6888 - else if (ver->fwlrole == 2) 6181 + } else if (ver->fwlrole == 2) { 6182 + *wlinfo = r; 6889 6183 _update_wl_info_v2(rtwdev); 6184 + } else if (ver->fwlrole == 8) { 6185 + wlinfo = &wl->rlink_info[r.pid][rlink_id]; 6186 + *wlinfo = r; 6187 + link_mode_ori = wl->role_info_v8.link_mode; 6188 + pta_req_mac_ori = wl->pta_req_mac; 6189 + _update_wl_info_v8(rtwdev, r.pid, rlink_id, state); 6190 + 6191 + if (wl->role_info_v8.link_mode != link_mode_ori) { 6192 + wl->role_info_v8.link_mode_chg = 1; 6193 + if (ver->fcxinit == 7) 6194 + wa_type = btc->mdinfo.md_v7.wa_type; 6195 + else 6196 + wa_type = btc->mdinfo.md.wa_type; 6197 + 6198 + if (wa_type & BTC_WA_HFP_ZB) 6199 + _update_zb_coex_tbl(rtwdev); 6200 + } 6201 + 6202 + if (wl->pta_req_mac != pta_req_mac_ori) 6203 + wl->pta_reg_mac_chg = 1; 6204 + } 6890 6205 6891 6206 if (wlinfo->role == RTW89_WIFI_ROLE_STATION && 6892 6207 wlinfo->connected == MLME_NO_LINK) ··· 7448 6715 } 7449 6716 7450 6717 for (i = 0; i < RTW89_PORT_NUM; i++) { 7451 - plink = &btc->cx.wl.link_info[i]; 6718 + if (btc->ver->fwlrole == 8) 6719 + plink = &btc->cx.wl.rlink_info[i][0]; 6720 + else 6721 + plink = &btc->cx.wl.link_info[i]; 7452 6722 7453 6723 if (!plink->active) 7454 6724 continue; ··· 7496 6760 struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; 7497 6761 struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; 7498 6762 struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2; 6763 + struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8; 7499 6764 u8 mode; 7500 6765 7501 6766 if (!(btc->dm.coex_info_map & BTC_COEX_INFO_WL)) ··· 7510 6773 mode = wl_rinfo_v1->link_mode; 7511 6774 else if (ver->fwlrole == 2) 7512 6775 mode = wl_rinfo_v2->link_mode; 6776 + else if (ver->fwlrole == 8) 6777 + mode = wl_rinfo_v8->link_mode; 7513 6778 else 7514 6779 return; 7515 6780 ··· 8169 7430 { 8170 7431 struct rtw89_btc *btc = &rtwdev->btc; 8171 7432 struct rtw89_btc_dm *dm = &btc->dm; 8172 - struct rtw89_btc_fbtc_slot *s; 7433 + u16 dur, cxtype; 7434 + u32 tbl; 8173 7435 u8 i = 0; 8174 7436 8175 7437 for (i = 0; i < CXST_MAX; i++) { 8176 - s = &dm->slot_now[i]; 7438 + if (btc->ver->fcxslots == 1) { 7439 + dur = le16_to_cpu(dm->slot_now.v1[i].dur); 7440 + tbl = le32_to_cpu(dm->slot_now.v1[i].cxtbl); 7441 + cxtype = le16_to_cpu(dm->slot_now.v1[i].cxtype); 7442 + } else if (btc->ver->fcxslots == 7) { 7443 + dur = le16_to_cpu(dm->slot_now.v7[i].dur); 7444 + tbl = le32_to_cpu(dm->slot_now.v7[i].cxtbl); 7445 + cxtype = le16_to_cpu(dm->slot_now.v7[i].cxtype); 7446 + } else { 7447 + return; 7448 + } 7449 + 8177 7450 if (i % 5 == 0) 8178 7451 seq_printf(m, 8179 7452 " %-15s : %5s[%03d/0x%x/%d]", 8180 7453 "[slot_list]", 8181 7454 id_to_slot((u32)i), 8182 - s->dur, s->cxtbl, s->cxtype); 7455 + dur, tbl, cxtype); 8183 7456 else 8184 7457 seq_printf(m, 8185 7458 ", %5s[%03d/0x%x/%d]", 8186 7459 id_to_slot((u32)i), 8187 - s->dur, s->cxtbl, s->cxtype); 7460 + dur, tbl, cxtype); 7461 + 8188 7462 if (i % 5 == 4) 8189 7463 seq_puts(m, "\n"); 8190 7464 }
+72
drivers/net/wireless/realtek/rtw89/coex.h
··· 8 8 #include "core.h" 9 9 10 10 #define BTC_H2C_MAXLEN 2020 11 + #define BTC_TLV_SLOT_ID_LEN_V7 1 11 12 12 13 enum btc_mode { 13 14 BTC_MODE_NORMAL, ··· 202 201 BTC_3CX_MAX, 203 202 }; 204 203 204 + enum btc_chip_feature { 205 + BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */ 206 + BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */ 207 + BTC_FEAT_WLAN_ACT_MUX = BIT(2), /* separate wlan_act/gnt mux */ 208 + BTC_FEAT_NEW_BBAPI_FLOW = BIT(3), /* new btg_ctrl/pre_agc_ctrl */ 209 + BTC_FEAT_MLO_SUPPORT = BIT(4), 210 + BTC_FEAT_H2C_MACRO = BIT(5), 211 + }; 212 + 213 + enum btc_wl_mode { 214 + BTC_WL_MODE_11B = 0, 215 + BTC_WL_MODE_11A = 1, 216 + BTC_WL_MODE_11G = 2, 217 + BTC_WL_MODE_HT = 3, 218 + BTC_WL_MODE_VHT = 4, 219 + BTC_WL_MODE_HE = 5, 220 + BTC_WL_MODE_NUM, 221 + }; 222 + 205 223 void rtw89_btc_ntfy_poweron(struct rtw89_dev *rtwdev); 206 224 void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev); 207 225 void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode); ··· 279 259 struct rtw89_btc *btc = &rtwdev->btc; 280 260 281 261 return btc->bt_req_len; 262 + } 263 + 264 + static inline u32 rtw89_get_antpath_type(u8 phy_map, u8 type) 265 + { 266 + return ((phy_map << 8) + type); 267 + } 268 + 269 + static inline 270 + void _slot_set_le(struct rtw89_btc *btc, u8 sid, __le16 dura, __le32 tbl, __le16 type) 271 + { 272 + if (btc->ver->fcxslots == 1) { 273 + btc->dm.slot.v1[sid].dur = dura; 274 + btc->dm.slot.v1[sid].cxtbl = tbl; 275 + btc->dm.slot.v1[sid].cxtype = type; 276 + } else if (btc->ver->fcxslots == 7) { 277 + btc->dm.slot.v7[sid].dur = dura; 278 + btc->dm.slot.v7[sid].cxtype = type; 279 + btc->dm.slot.v7[sid].cxtbl = tbl; 280 + } 281 + } 282 + 283 + static inline 284 + void _slot_set(struct rtw89_btc *btc, u8 sid, u16 dura, u32 tbl, u16 type) 285 + { 286 + _slot_set_le(btc, sid, cpu_to_le16(dura), cpu_to_le32(tbl), cpu_to_le16(type)); 287 + } 288 + 289 + static inline 290 + void _slot_set_dur(struct rtw89_btc *btc, u8 sid, u16 dura) 291 + { 292 + if (btc->ver->fcxslots == 1) 293 + btc->dm.slot.v1[sid].dur = cpu_to_le16(dura); 294 + else if (btc->ver->fcxslots == 7) 295 + btc->dm.slot.v7[sid].dur = cpu_to_le16(dura); 296 + } 297 + 298 + static inline 299 + void _slot_set_type(struct rtw89_btc *btc, u8 sid, u16 type) 300 + { 301 + if (btc->ver->fcxslots == 1) 302 + btc->dm.slot.v1[sid].cxtype = cpu_to_le16(type); 303 + else if (btc->ver->fcxslots == 7) 304 + btc->dm.slot.v7[sid].cxtype = cpu_to_le16(type); 305 + } 306 + 307 + static inline 308 + void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl) 309 + { 310 + if (btc->ver->fcxslots == 1) 311 + btc->dm.slot.v1[sid].cxtbl = cpu_to_le32(tbl); 312 + else if (btc->ver->fcxslots == 7) 313 + btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl); 282 314 } 283 315 284 316 #endif
+105 -3
drivers/net/wireless/realtek/rtw89/core.h
··· 799 799 enum rtw89_mac_idx { 800 800 RTW89_MAC_0 = 0, 801 801 RTW89_MAC_1 = 1, 802 + RTW89_MAC_NUM, 802 803 }; 803 804 804 805 enum rtw89_phy_idx { ··· 1231 1230 BTC_WCNT_RFK_REJECT, 1232 1231 BTC_WCNT_RFK_TIMEOUT, 1233 1232 BTC_WCNT_CH_UPDATE, 1233 + BTC_WCNT_DBCC_ALL_2G, 1234 + BTC_WCNT_DBCC_CHG, 1235 + BTC_WCNT_RX_OK_LAST, 1236 + BTC_WCNT_RX_OK_LAST2S, 1237 + BTC_WCNT_RX_ERR_LAST, 1238 + BTC_WCNT_RX_ERR_LAST2S, 1239 + BTC_WCNT_RX_LAST, 1234 1240 BTC_WCNT_NUM 1235 1241 }; 1236 1242 ··· 1357 1349 u16 rx_rate; 1358 1350 }; 1359 1351 1352 + struct rtw89_btc_chdef { 1353 + u8 center_ch; 1354 + u8 band; 1355 + u8 chan; 1356 + enum rtw89_sc_offset offset; 1357 + enum rtw89_bandwidth bw; 1358 + }; 1359 + 1360 1360 struct rtw89_btc_statistic { 1361 1361 u8 rssi; /* 0%~110% (dBm = rssi -110) */ 1362 1362 struct rtw89_traffic_stats traffic; ··· 1373 1357 #define BTC_WL_RSSI_THMAX 4 1374 1358 1375 1359 struct rtw89_btc_wl_link_info { 1360 + struct rtw89_btc_chdef chdef; 1376 1361 struct rtw89_btc_statistic stat; 1377 1362 enum rtw89_tfc_dir dir; 1378 1363 u8 rssi_state[BTC_WL_RSSI_THMAX]; ··· 1387 1370 u8 phy; 1388 1371 u8 dtim_period; 1389 1372 u8 mode; 1373 + u8 tx_1ss_limit; 1390 1374 1391 1375 u8 mac_id; 1392 1376 u8 tx_retry; ··· 1397 1379 u32 tx_time; 1398 1380 u32 client_cnt; 1399 1381 u32 rx_rate_drop_cnt; 1382 + u32 noa_duration; 1400 1383 1401 1384 u32 active: 1; 1402 1385 u32 noa: 1; ··· 1608 1589 u32 rsvd: 27; 1609 1590 }; 1610 1591 1592 + struct rtw89_btc_wl_rlink { /* H2C info, struct size must be n*4 bytes */ 1593 + u8 connected; 1594 + u8 pid; 1595 + u8 phy; 1596 + u8 noa; 1597 + 1598 + u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */ 1599 + u8 active; /* 0:rlink is under doze */ 1600 + u8 bw; /* enum channel_width */ 1601 + u8 role; /*enum role_type */ 1602 + 1603 + u8 ch; 1604 + u8 noa_dur; /* ms */ 1605 + u8 client_cnt; /* for Role = P2P-Go/AP */ 1606 + u8 mode; /* wifi protocol */ 1607 + } __packed; 1608 + 1609 + #define RTW89_BE_BTC_WL_MAX_ROLE_NUMBER 6 1610 + struct rtw89_btc_wl_role_info_v8 { /* H2C info, struct size must be n*4 bytes */ 1611 + u8 connect_cnt; 1612 + u8 link_mode; 1613 + u8 link_mode_chg; 1614 + u8 p2p_2g; 1615 + 1616 + u8 pta_req_band; 1617 + u8 dbcc_en; /* 1+1 and 2.4G-included */ 1618 + u8 dbcc_chg; 1619 + u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */ 1620 + 1621 + struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; 1622 + 1623 + u32 role_map; 1624 + u32 mrole_type; /* btc_wl_mrole_type */ 1625 + u32 mrole_noa_duration; /* ms */ 1626 + } __packed; 1627 + 1611 1628 struct rtw89_btc_wl_ver_info { 1612 1629 u32 fw_coex; /* match with which coex_ver */ 1613 1630 u32 fw; ··· 1779 1724 1780 1725 struct rtw89_btc_wl_info { 1781 1726 struct rtw89_btc_wl_link_info link_info[RTW89_PORT_NUM]; 1727 + struct rtw89_btc_wl_link_info rlink_info[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; 1782 1728 struct rtw89_btc_wl_rfk_info rfk_info; 1783 1729 struct rtw89_btc_wl_ver_info ver_info; 1784 1730 struct rtw89_btc_wl_afh_info afh_info; 1785 1731 struct rtw89_btc_wl_role_info role_info; 1786 1732 struct rtw89_btc_wl_role_info_v1 role_info_v1; 1787 1733 struct rtw89_btc_wl_role_info_v2 role_info_v2; 1734 + struct rtw89_btc_wl_role_info_v8 role_info_v8; 1788 1735 struct rtw89_btc_wl_scan_info scan_info; 1789 1736 struct rtw89_btc_wl_dbcc_info dbcc_info; 1790 1737 struct rtw89_btc_rf_para rf_para; ··· 1797 1740 u8 rssi_level; 1798 1741 u8 cn_report; 1799 1742 u8 coex_mode; 1743 + u8 pta_req_mac; 1800 1744 1745 + bool is_5g_hi_channel; 1746 + bool pta_reg_mac_chg; 1801 1747 bool bg_mode; 1802 1748 bool scbd_change; 1803 1749 u32 scbd; ··· 2293 2233 struct rtw89_btc_fbtc_slot slot[CXST_MAX]; 2294 2234 } __packed; 2295 2235 2236 + struct rtw89_btc_fbtc_slot_v7 { 2237 + __le16 dur; /* slot duration */ 2238 + __le16 cxtype; 2239 + __le32 cxtbl; 2240 + } __packed; 2241 + 2242 + struct rtw89_btc_fbtc_slot_u16 { 2243 + __le16 dur; /* slot duration */ 2244 + __le16 cxtype; 2245 + __le16 cxtbl_l16; /* coex table [15:0] */ 2246 + __le16 cxtbl_h16; /* coex table [31:16] */ 2247 + } __packed; 2248 + 2249 + struct rtw89_btc_fbtc_1slot_v7 { 2250 + u8 fver; 2251 + u8 sid; /* slot id */ 2252 + __le16 rsvd; 2253 + struct rtw89_btc_fbtc_slot_v7 slot; 2254 + } __packed; 2255 + 2256 + struct rtw89_btc_fbtc_slots_v7 { 2257 + u8 fver; 2258 + u8 slot_cnt; 2259 + u8 rsvd0; 2260 + u8 rsvd1; 2261 + struct rtw89_btc_fbtc_slot_u16 slot[CXST_MAX]; 2262 + __le32 update_map; 2263 + } __packed; 2264 + 2265 + union rtw89_btc_fbtc_slots_info { 2266 + struct rtw89_btc_fbtc_slots v1; 2267 + struct rtw89_btc_fbtc_slots_v7 v7; 2268 + } __packed; 2269 + 2296 2270 struct rtw89_btc_fbtc_step { 2297 2271 u8 type; 2298 2272 u8 val; ··· 2645 2551 u32 rx_err_ratio; 2646 2552 }; 2647 2553 2554 + union rtw89_btc_fbtc_slot_u { 2555 + struct rtw89_btc_fbtc_slot v1[CXST_MAX]; 2556 + struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX]; 2557 + }; 2558 + 2648 2559 struct rtw89_btc_dm { 2649 - struct rtw89_btc_fbtc_slot slot[CXST_MAX]; 2650 - struct rtw89_btc_fbtc_slot slot_now[CXST_MAX]; 2560 + union rtw89_btc_fbtc_slot_u slot; 2561 + union rtw89_btc_fbtc_slot_u slot_now; 2651 2562 struct rtw89_btc_fbtc_tdma tdma; 2652 2563 struct rtw89_btc_fbtc_tdma tdma_now; 2653 2564 struct rtw89_mac_ax_coex_gnt gnt; ··· 2668 2569 2669 2570 u32 update_slot_map; 2670 2571 u32 set_ant_path; 2572 + u32 e2g_slot_limit; 2573 + u32 e2g_slot_nulltx_time; 2671 2574 2672 2575 u32 wl_only: 1; 2673 2576 u32 wl_fw_cx_offload: 1; ··· 2697 2596 u8 wl_pre_agc: 2; 2698 2597 u8 wl_lna2: 1; 2699 2598 u8 wl_pre_agc_rb: 2; 2599 + u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */ 2700 2600 }; 2701 2601 2702 2602 struct rtw89_btc_ctrl { ··· 2793 2691 2794 2692 struct rtw89_btc_rpt_fbtc_slots { 2795 2693 struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ 2796 - struct rtw89_btc_fbtc_slots finfo; /* info from fw */ 2694 + union rtw89_btc_fbtc_slots_info finfo; /* info from fw */ 2797 2695 }; 2798 2696 2799 2697 struct rtw89_btc_rpt_fbtc_cysta {
+42
drivers/net/wireless/realtek/rtw89/fw.c
··· 4120 4120 return ret; 4121 4121 } 4122 4122 4123 + int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type) 4124 + { 4125 + struct rtw89_btc *btc = &rtwdev->btc; 4126 + struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8; 4127 + struct rtw89_h2c_cxrole_v8 *h2c; 4128 + u32 len = sizeof(*h2c); 4129 + struct sk_buff *skb; 4130 + int ret; 4131 + 4132 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 4133 + if (!skb) { 4134 + rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n"); 4135 + return -ENOMEM; 4136 + } 4137 + skb_put(skb, len); 4138 + h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data; 4139 + 4140 + h2c->hdr.type = type; 4141 + h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7; 4142 + memcpy(&h2c->_u8, role, sizeof(h2c->_u8)); 4143 + h2c->_u32.role_map = cpu_to_le32(role->role_map); 4144 + h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type); 4145 + h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration); 4146 + 4147 + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 4148 + H2C_CAT_OUTSRC, BTFC_SET, 4149 + SET_DRV_INFO, 0, 0, 4150 + len); 4151 + 4152 + ret = rtw89_h2c_tx(rtwdev, skb, false); 4153 + if (ret) { 4154 + rtw89_err(rtwdev, "failed to send h2c\n"); 4155 + goto fail; 4156 + } 4157 + 4158 + return 0; 4159 + fail: 4160 + dev_kfree_skb_any(skb); 4161 + 4162 + return ret; 4163 + } 4164 + 4123 4165 #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) 4124 4166 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type) 4125 4167 {
+27
drivers/net/wireless/realtek/rtw89/fw.h
··· 2395 2395 #define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr) 2396 2396 #define H2C_LEN_CXDRVHDR_V7 sizeof(struct rtw89_h2c_cxhdr_v7) 2397 2397 2398 + struct rtw89_btc_wl_role_info_v8_u8 { 2399 + u8 connect_cnt; 2400 + u8 link_mode; 2401 + u8 link_mode_chg; 2402 + u8 p2p_2g; 2403 + 2404 + u8 pta_req_band; 2405 + u8 dbcc_en; 2406 + u8 dbcc_chg; 2407 + u8 dbcc_2g_phy; 2408 + 2409 + struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM]; 2410 + } __packed; 2411 + 2412 + struct rtw89_btc_wl_role_info_v8_u32 { 2413 + __le32 role_map; 2414 + __le32 mrole_type; 2415 + __le32 mrole_noa_duration; 2416 + } __packed; 2417 + 2418 + struct rtw89_h2c_cxrole_v8 { 2419 + struct rtw89_h2c_cxhdr hdr; 2420 + struct rtw89_btc_wl_role_info_v8_u8 _u8; 2421 + struct rtw89_btc_wl_role_info_v8_u32 _u32; 2422 + } __packed; 2423 + 2398 2424 struct rtw89_h2c_cxinit { 2399 2425 struct rtw89_h2c_cxhdr hdr; 2400 2426 u8 ant_type; ··· 4594 4568 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type); 4595 4569 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type); 4596 4570 int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type); 4571 + int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type); 4597 4572 int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type); 4598 4573 int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type); 4599 4574 int rtw89_fw_h2c_cxdrv_trx(struct rtw89_dev *rtwdev, u8 type);
+9 -4
drivers/net/wireless/realtek/rtw89/phy.c
··· 122 122 struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap; 123 123 struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz; 124 124 struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss; 125 + u8 *he_phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; 125 126 126 127 switch (sta->deflink.bandwidth) { 127 128 case IEEE80211_STA_RX_BW_320: ··· 133 132 mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._160; 134 133 /* MCS 9, 11, 13 */ 135 134 return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); 135 + case IEEE80211_STA_RX_BW_20: 136 + if (!(he_phy_cap[0] & 137 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) { 138 + mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz; 139 + /* MCS 7, 9, 11, 13 */ 140 + return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4); 141 + } 142 + fallthrough; 136 143 case IEEE80211_STA_RX_BW_80: 137 144 default: 138 145 mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._80; 139 146 /* MCS 9, 11, 13 */ 140 147 return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3); 141 - case IEEE80211_STA_RX_BW_20: 142 - mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz; 143 - /* MCS 7, 9, 11, 13 */ 144 - return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4); 145 148 } 146 149 } 147 150
+154
drivers/net/wireless/realtek/rtw89/rtw8922a.c
··· 2257 2257 btc->cx.wl.status.map.init_ok = true; 2258 2258 } 2259 2259 2260 + static void 2261 + rtw8922a_btc_set_wl_txpwr_ctrl(struct rtw89_dev *rtwdev, u32 txpwr_val) 2262 + { 2263 + u16 ctrl_all_time = u32_get_bits(txpwr_val, GENMASK(15, 0)); 2264 + u16 ctrl_gnt_bt = u32_get_bits(txpwr_val, GENMASK(31, 16)); 2265 + 2266 + switch (ctrl_all_time) { 2267 + case 0xffff: 2268 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, 2269 + B_BE_FORCE_PWR_BY_RATE_EN, 0x0); 2270 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, 2271 + B_BE_FORCE_PWR_BY_RATE_VAL, 0x0); 2272 + break; 2273 + default: 2274 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, 2275 + B_BE_FORCE_PWR_BY_RATE_VAL, ctrl_all_time); 2276 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_RATE_CTRL, 2277 + B_BE_FORCE_PWR_BY_RATE_EN, 0x1); 2278 + break; 2279 + } 2280 + 2281 + switch (ctrl_gnt_bt) { 2282 + case 0xffff: 2283 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, 2284 + B_BE_PWR_BT_EN, 0x0); 2285 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, 2286 + B_BE_PWR_BT_VAL, 0x0); 2287 + break; 2288 + default: 2289 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_COEX_CTRL, 2290 + B_BE_PWR_BT_VAL, ctrl_gnt_bt); 2291 + rtw89_mac_txpwr_write32_mask(rtwdev, RTW89_PHY_0, R_BE_PWR_REG_CTRL, 2292 + B_BE_PWR_BT_EN, 0x1); 2293 + break; 2294 + } 2295 + } 2296 + 2297 + static 2298 + s8 rtw8922a_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) 2299 + { 2300 + return clamp_t(s8, val, -100, 0) + 100; 2301 + } 2302 + 2303 + static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_ul[] = { 2304 + {255, 0, 0, 7}, /* 0 -> original */ 2305 + {255, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ 2306 + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ 2307 + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ 2308 + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ 2309 + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ 2310 + {6, 1, 0, 7}, 2311 + {13, 1, 0, 7}, 2312 + {13, 1, 0, 7} 2313 + }; 2314 + 2315 + static const struct rtw89_btc_rf_trx_para rtw89_btc_8922a_rf_dl[] = { 2316 + {255, 0, 0, 7}, /* 0 -> original */ 2317 + {255, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ 2318 + {255, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ 2319 + {255, 0, 0, 7}, /* 3- >reserved for shared-antenna */ 2320 + {255, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ 2321 + {255, 1, 0, 7}, /* the below id is for non-shared-antenna free-run */ 2322 + {255, 1, 0, 7}, 2323 + {255, 1, 0, 7}, 2324 + {255, 1, 0, 7} 2325 + }; 2326 + 2327 + static const u8 rtw89_btc_8922a_wl_rssi_thres[BTC_WL_RSSI_THMAX] = {60, 50, 40, 30}; 2328 + static const u8 rtw89_btc_8922a_bt_rssi_thres[BTC_BT_RSSI_THMAX] = {50, 40, 30, 20}; 2329 + 2330 + static const struct rtw89_btc_fbtc_mreg rtw89_btc_8922a_mon_reg[] = { 2331 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe300), 2332 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe320), 2333 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe324), 2334 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe328), 2335 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe32c), 2336 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe330), 2337 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe334), 2338 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe338), 2339 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe344), 2340 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe348), 2341 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe34c), 2342 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0xe350), 2343 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a2c), 2344 + RTW89_DEF_FBTC_MREG(REG_MAC, 4, 0x11a50), 2345 + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x980), 2346 + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x660), 2347 + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x1660), 2348 + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x418c), 2349 + RTW89_DEF_FBTC_MREG(REG_BB, 4, 0x518c), 2350 + }; 2351 + 2352 + static 2353 + void rtw8922a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) 2354 + { 2355 + /* Feature move to firmware */ 2356 + } 2357 + 2358 + static 2359 + void rtw8922a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) 2360 + { 2361 + if (!state) { 2362 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); 2363 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); 2364 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110); 2365 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x01018); 2366 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000); 2367 + 2368 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); 2369 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1); 2370 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110); 2371 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x01018); 2372 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); 2373 + } else { 2374 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x80000); 2375 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); 2376 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD1, RFREG_MASK, 0x0c110); 2377 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x09018); 2378 + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x00000); 2379 + 2380 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); 2381 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x1); 2382 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c110); 2383 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0x09018); 2384 + rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); 2385 + } 2386 + } 2387 + 2388 + static void rtw8922a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) 2389 + { 2390 + } 2391 + 2260 2392 static void rtw8922a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, 2261 2393 struct rtw89_rx_phy_ppdu *phy_ppdu, 2262 2394 struct ieee80211_rx_status *status) ··· 2499 2367 2500 2368 .btc_set_rfe = rtw8922a_btc_set_rfe, 2501 2369 .btc_init_cfg = rtw8922a_btc_init_cfg, 2370 + .btc_set_wl_pri = NULL, 2371 + .btc_set_wl_txpwr_ctrl = rtw8922a_btc_set_wl_txpwr_ctrl, 2372 + .btc_get_bt_rssi = rtw8922a_btc_get_bt_rssi, 2373 + .btc_update_bt_cnt = rtw8922a_btc_update_bt_cnt, 2374 + .btc_wl_s1_standby = rtw8922a_btc_wl_s1_standby, 2375 + .btc_set_wl_rx_gain = rtw8922a_btc_set_wl_rx_gain, 2376 + .btc_set_policy = rtw89_btc_set_policy_v1, 2502 2377 }; 2503 2378 2504 2379 const struct rtw89_chip_info rtw8922a_chip_info = { ··· 2575 2436 .efuse_blocks = rtw8922a_efuse_blocks, 2576 2437 .phycap_addr = 0x1700, 2577 2438 .phycap_size = 0x38, 2439 + .para_ver = 0xf, 2440 + .wlcx_desired = 0x07110000, 2441 + .btcx_desired = 0x7, 2442 + .scbd = 0x1, 2443 + .mailbox = 0x1, 2578 2444 2445 + .afh_guard_ch = 6, 2446 + .wl_rssi_thres = rtw89_btc_8922a_wl_rssi_thres, 2447 + .bt_rssi_thres = rtw89_btc_8922a_bt_rssi_thres, 2448 + .rssi_tol = 2, 2449 + .mon_reg_num = ARRAY_SIZE(rtw89_btc_8922a_mon_reg), 2450 + .mon_reg = rtw89_btc_8922a_mon_reg, 2451 + .rf_para_ulink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_ul), 2452 + .rf_para_ulink = rtw89_btc_8922a_rf_ul, 2453 + .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8922a_rf_dl), 2454 + .rf_para_dlink = rtw89_btc_8922a_rf_dl, 2579 2455 .ps_mode_supported = BIT(RTW89_PS_MODE_RFOFF) | 2580 2456 BIT(RTW89_PS_MODE_CLK_GATED) | 2581 2457 BIT(RTW89_PS_MODE_PWR_GATED),
-2
drivers/net/wireless/ti/wl1251/cmd.h
··· 89 89 struct wl1251_cmd_header { 90 90 u16 id; 91 91 u16 status; 92 - /* payload */ 93 - u8 data[]; 94 92 } __packed; 95 93 96 94 struct wl1251_command {
-1
drivers/net/wireless/ti/wl1251/wl12xx_80211.h
··· 65 65 u8 sa[ETH_ALEN]; 66 66 u8 bssid[ETH_ALEN]; 67 67 __le16 seq_ctl; 68 - u8 payload[]; 69 68 } __packed; 70 69 71 70 struct wl12xx_ie_header {
-2
drivers/net/wireless/ti/wlcore/cmd.h
··· 208 208 struct wl1271_cmd_header { 209 209 __le16 id; 210 210 __le16 status; 211 - /* payload */ 212 - u8 data[]; 213 211 } __packed; 214 212 215 213 #define WL1271_CMD_MAX_PARAMS 572
+3 -8
drivers/net/wireless/ti/wlcore/sysfs.c
··· 19 19 struct wl1271 *wl = dev_get_drvdata(dev); 20 20 ssize_t len; 21 21 22 - len = PAGE_SIZE; 23 - 24 22 mutex_lock(&wl->mutex); 25 - len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", 26 - wl->sg_enabled); 23 + len = sysfs_emit(buf, "%d\n\n0 - off\n1 - on\n", wl->sg_enabled); 27 24 mutex_unlock(&wl->mutex); 28 25 29 26 return len; ··· 75 78 struct wl1271 *wl = dev_get_drvdata(dev); 76 79 ssize_t len; 77 80 78 - len = PAGE_SIZE; 79 - 80 81 mutex_lock(&wl->mutex); 81 82 if (wl->hw_pg_ver >= 0) 82 - len = snprintf(buf, len, "%d\n", wl->hw_pg_ver); 83 + len = sysfs_emit(buf, "%d\n", wl->hw_pg_ver); 83 84 else 84 - len = snprintf(buf, len, "n/a\n"); 85 + len = sysfs_emit(buf, "n/a\n"); 85 86 mutex_unlock(&wl->mutex); 86 87 87 88 return len;
-1
drivers/net/wireless/ti/wlcore/wl12xx_80211.h
··· 66 66 u8 sa[ETH_ALEN]; 67 67 u8 bssid[ETH_ALEN]; 68 68 __le16 seq_ctl; 69 - u8 payload[]; 70 69 } __packed; 71 70 72 71 struct wl12xx_ie_header {
+26 -16
drivers/net/wireless/virtual/mac80211_hwsim.c
··· 216 216 217 217 struct hwsim_vif_priv { 218 218 u32 magic; 219 - u32 skip_beacons; 219 + u32 skip_beacons[IEEE80211_MLD_MAX_NUM_LINKS]; 220 220 u8 bssid[ETH_ALEN]; 221 221 bool assoc; 222 222 bool bcn_en; ··· 1721 1721 sp->active_links_rx &= ~BIT(link_id); 1722 1722 else 1723 1723 sp->active_links_rx |= BIT(link_id); 1724 + 1725 + rx_status->link_valid = true; 1726 + rx_status->link_id = link_id; 1724 1727 } 1725 1728 rcu_read_unlock(); 1726 1729 } ··· 2136 2133 } 2137 2134 2138 2135 #ifdef CONFIG_MAC80211_DEBUGFS 2139 - static void mac80211_hwsim_vif_add_debugfs(struct ieee80211_hw *hw, 2140 - struct ieee80211_vif *vif) 2136 + static void 2137 + mac80211_hwsim_link_add_debugfs(struct ieee80211_hw *hw, 2138 + struct ieee80211_vif *vif, 2139 + struct ieee80211_bss_conf *link_conf, 2140 + struct dentry *dir) 2141 2141 { 2142 2142 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 2143 2143 2144 - debugfs_create_u32("skip_beacons", 0600, vif->debugfs_dir, 2145 - &vp->skip_beacons); 2144 + debugfs_create_u32("skip_beacons", 0600, dir, 2145 + &vp->skip_beacons[link_conf->link_id]); 2146 2146 } 2147 2147 #endif 2148 2148 ··· 2220 2214 /* TODO: get MCS */ 2221 2215 int bitrate = 100; 2222 2216 2223 - if (vp->skip_beacons) { 2224 - vp->skip_beacons--; 2217 + if (vp->skip_beacons[link_conf->link_id]) { 2218 + vp->skip_beacons[link_conf->link_id]--; 2225 2219 dev_kfree_skb(skb); 2226 2220 return; 2227 2221 } ··· 3928 3922 3929 3923 #ifdef CONFIG_MAC80211_DEBUGFS 3930 3924 #define HWSIM_DEBUGFS_OPS \ 3931 - .vif_add_debugfs = mac80211_hwsim_vif_add_debugfs, 3925 + .link_add_debugfs = mac80211_hwsim_link_add_debugfs, 3932 3926 #else 3933 3927 #define HWSIM_DEBUGFS_OPS 3934 3928 #endif ··· 4128 4122 4129 4123 static const struct ieee80211_sband_iftype_data sband_capa_2ghz[] = { 4130 4124 { 4131 - .types_mask = BIT(NL80211_IFTYPE_STATION), 4125 + .types_mask = BIT(NL80211_IFTYPE_STATION) | 4126 + BIT(NL80211_IFTYPE_P2P_CLIENT), 4132 4127 .he_cap = { 4133 4128 .has_he = true, 4134 4129 .he_cap_elem = { ··· 4236 4229 }, 4237 4230 }, 4238 4231 { 4239 - .types_mask = BIT(NL80211_IFTYPE_AP), 4232 + .types_mask = BIT(NL80211_IFTYPE_AP) | 4233 + BIT(NL80211_IFTYPE_P2P_GO), 4240 4234 .he_cap = { 4241 4235 .has_he = true, 4242 4236 .he_cap_elem = { ··· 4388 4380 4389 4381 static const struct ieee80211_sband_iftype_data sband_capa_5ghz[] = { 4390 4382 { 4391 - /* TODO: should we support other types, e.g., P2P? */ 4392 - .types_mask = BIT(NL80211_IFTYPE_STATION), 4383 + .types_mask = BIT(NL80211_IFTYPE_STATION) | 4384 + BIT(NL80211_IFTYPE_P2P_CLIENT), 4393 4385 .he_cap = { 4394 4386 .has_he = true, 4395 4387 .he_cap_elem = { ··· 4513 4505 }, 4514 4506 }, 4515 4507 { 4516 - .types_mask = BIT(NL80211_IFTYPE_AP), 4508 + .types_mask = BIT(NL80211_IFTYPE_AP) | 4509 + BIT(NL80211_IFTYPE_P2P_GO), 4517 4510 .he_cap = { 4518 4511 .has_he = true, 4519 4512 .he_cap_elem = { ··· 4685 4676 4686 4677 static const struct ieee80211_sband_iftype_data sband_capa_6ghz[] = { 4687 4678 { 4688 - /* TODO: should we support other types, e.g., P2P? */ 4689 - .types_mask = BIT(NL80211_IFTYPE_STATION), 4679 + .types_mask = BIT(NL80211_IFTYPE_STATION) | 4680 + BIT(NL80211_IFTYPE_P2P_CLIENT), 4690 4681 .he_6ghz_capa = { 4691 4682 .capa = cpu_to_le16(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START | 4692 4683 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP | ··· 4831 4822 }, 4832 4823 }, 4833 4824 { 4834 - .types_mask = BIT(NL80211_IFTYPE_AP), 4825 + .types_mask = BIT(NL80211_IFTYPE_AP) | 4826 + BIT(NL80211_IFTYPE_P2P_GO), 4835 4827 .he_6ghz_capa = { 4836 4828 .capa = cpu_to_le16(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START | 4837 4829 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP |
+4 -2
drivers/ssb/main.c
··· 341 341 342 342 static int ssb_device_uevent(const struct device *dev, struct kobj_uevent_env *env) 343 343 { 344 - const struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); 344 + const struct ssb_device *ssb_dev; 345 345 346 346 if (!dev) 347 347 return -ENODEV; 348 + 349 + ssb_dev = dev_to_ssb_dev(dev); 348 350 349 351 return add_uevent_var(env, 350 352 "MODALIAS=ssb:v%04Xid%04Xrev%02X", ··· 1146 1144 return SSB_PCI_DMA; 1147 1145 } 1148 1146 default: 1149 - __ssb_dma_not_implemented(dev); 1147 + break; 1150 1148 } 1151 1149 return 0; 1152 1150 }
+7 -5
include/linux/ieee80211.h
··· 2742 2742 #define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000 2743 2743 #define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000 2744 2744 2745 - #define IEEE80211_6GHZ_CTRL_REG_LPI_AP 0 2746 - #define IEEE80211_6GHZ_CTRL_REG_SP_AP 1 2747 - #define IEEE80211_6GHZ_CTRL_REG_VLP_AP 2 2745 + #define IEEE80211_6GHZ_CTRL_REG_LPI_AP 0 2746 + #define IEEE80211_6GHZ_CTRL_REG_SP_AP 1 2747 + #define IEEE80211_6GHZ_CTRL_REG_VLP_AP 2 2748 + #define IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP 3 2749 + #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP 4 2748 2750 2749 2751 /** 2750 2752 * struct ieee80211_he_6ghz_oper - HE 6 GHz operation Information field ··· 5168 5166 bool check_common_len = false; 5169 5167 u16 control; 5170 5168 5171 - if (len < fixed) 5169 + if (!data || len < fixed) 5172 5170 return false; 5173 5171 5174 5172 control = le16_to_cpu(mle->control); ··· 5304 5302 info_len += 1; 5305 5303 5306 5304 return prof->sta_info_len >= info_len && 5307 - fixed + prof->sta_info_len <= len; 5305 + fixed + prof->sta_info_len - 1 <= len; 5308 5306 } 5309 5307 5310 5308 /**
+1
include/linux/mmc/sdio_ids.h
··· 124 124 #define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723 125 125 #define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724 126 126 #define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821 127 + #define SDIO_DEVICE_ID_REALTEK_RTW8723CS 0xb703 127 128 128 129 #define SDIO_VENDOR_ID_SIANO 0x039a 129 130 #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201
-8
include/linux/ssb/ssb.h
··· 621 621 #define SSB_DMA_TRANSLATION_MASK 0xC0000000 622 622 #define SSB_DMA_TRANSLATION_SHIFT 30 623 623 624 - static inline void __cold __ssb_dma_not_implemented(struct ssb_device *dev) 625 - { 626 - #ifdef CONFIG_SSB_DEBUG 627 - printk(KERN_ERR "SSB: BUG! Calling DMA API for " 628 - "unsupported bustype %d\n", dev->bus->bustype); 629 - #endif /* DEBUG */ 630 - } 631 - 632 624 #ifdef CONFIG_SSB_PCIHOST 633 625 /* PCI-host wrapper driver */ 634 626 extern int ssb_pcihost_register(struct pci_driver *driver);
+18 -4
include/net/mac80211.h
··· 361 361 * @BSS_CHANGED_UNSOL_BCAST_PROBE_RESP: Unsolicited broadcast probe response 362 362 * status changed. 363 363 * @BSS_CHANGED_MLD_VALID_LINKS: MLD valid links status changed. 364 - * @BSS_CHANGED_MLD_TTLM: TID to link mapping was changed 364 + * @BSS_CHANGED_MLD_TTLM: negotiated TID to link mapping was changed 365 365 */ 366 366 enum ieee80211_bss_change { 367 367 BSS_CHANGED_ASSOC = 1<<0, ··· 1921 1921 * @active_links: The bitmap of active links, or 0 for non-MLO. 1922 1922 * The driver shouldn't change this directly, but use the 1923 1923 * API calls meant for that purpose. 1924 - * @dormant_links: bitmap of valid but disabled links, or 0 for non-MLO. 1925 - * Must be a subset of valid_links. 1924 + * @dormant_links: subset of the valid links that are disabled/suspended 1925 + * due to advertised or negotiated TTLM respectively. 1926 + * 0 for non-MLO. 1926 1927 * @suspended_links: subset of dormant_links representing links that are 1927 - * suspended. 1928 + * suspended due to negotiated TTLM, and could be activated in the 1929 + * future by tearing down the TTLM negotiation. 1928 1930 * 0 for non-MLO. 1929 1931 * @neg_ttlm: negotiated TID to link mapping info. 1930 1932 * see &struct ieee80211_neg_ttlm. ··· 2779 2777 * 2780 2778 * @IEEE80211_HW_DISALLOW_PUNCTURING: HW requires disabling puncturing in EHT 2781 2779 * and connecting with a lower bandwidth instead 2780 + * @IEEE80211_HW_DISALLOW_PUNCTURING_5GHZ: HW requires disabling puncturing in 2781 + * EHT in 5 GHz and connecting with a lower bandwidth instead 2782 2782 * 2783 2783 * @IEEE80211_HW_HANDLES_QUIET_CSA: HW/driver handles quieting for CSA, so 2784 2784 * no need to stop queues. This really should be set by a driver that ··· 2845 2841 IEEE80211_HW_DETECTS_COLOR_COLLISION, 2846 2842 IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, 2847 2843 IEEE80211_HW_DISALLOW_PUNCTURING, 2844 + IEEE80211_HW_DISALLOW_PUNCTURING_5GHZ, 2848 2845 IEEE80211_HW_HANDLES_QUIET_CSA, 2849 2846 2850 2847 /* keep last, obviously */ ··· 7590 7585 */ 7591 7586 void ieee80211_set_active_links_async(struct ieee80211_vif *vif, 7592 7587 u16 active_links); 7588 + 7589 + /** 7590 + * ieee80211_send_teardown_neg_ttlm - tear down a negotiated TTLM request 7591 + * @vif: the interface on which the tear down request should be sent. 7592 + * 7593 + * This function can be used to tear down a previously accepted negotiated 7594 + * TTLM request. 7595 + */ 7596 + void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif); 7593 7597 7594 7598 /* for older drivers - let's not document these ... */ 7595 7599 int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
+124 -112
include/uapi/linux/nl80211.h
··· 413 413 * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that 414 414 * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, 415 415 * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, 416 - * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, 417 - * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, 416 + * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHER_SUITES_PAIRWISE, 417 + * %NL80211_ATTR_CIPHER_SUITE_GROUP, %NL80211_ATTR_WPA_VERSIONS, 418 418 * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, 419 419 * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT, 420 420 * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS. ··· 442 442 * stations connected and using at least that link as one of its links. 443 443 * 444 444 * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to 445 - * destination %NL80211_ATTR_MAC on the interface identified by 446 - * %NL80211_ATTR_IFINDEX. 445 + * destination %NL80211_ATTR_MAC on the interface identified by 446 + * %NL80211_ATTR_IFINDEX. 447 447 * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to 448 - * destination %NL80211_ATTR_MAC on the interface identified by 449 - * %NL80211_ATTR_IFINDEX. 448 + * destination %NL80211_ATTR_MAC on the interface identified by 449 + * %NL80211_ATTR_IFINDEX. 450 450 * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by 451 451 * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. 452 452 * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by 453 453 * %NL80211_ATTR_MAC. 454 - * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the 455 - * interface identified by %NL80211_ATTR_IFINDEX. 456 - * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC 457 - * or, if no MAC address given, all mesh paths, on the interface identified 458 - * by %NL80211_ATTR_IFINDEX. 459 454 * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by 460 455 * %NL80211_ATTR_IFINDEX. 461 456 * ··· 471 476 * after being queried by the kernel. CRDA replies by sending a regulatory 472 477 * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our 473 478 * current alpha2 if it found a match. It also provides 474 - * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each 475 - * regulatory rule is a nested set of attributes given by 476 - * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and 477 - * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by 478 - * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and 479 - * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. 479 + * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each 480 + * regulatory rule is a nested set of attributes given by 481 + * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and 482 + * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by 483 + * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and 484 + * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. 480 485 * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain 481 - * to the specified ISO/IEC 3166-1 alpha2 country code. The core will 482 - * store this as a valid request and then query userspace for it. 486 + * to the specified ISO/IEC 3166-1 alpha2 country code. The core will 487 + * store this as a valid request and then query userspace for it. 483 488 * 484 489 * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the 485 490 * interface identified by %NL80211_ATTR_IFINDEX ··· 569 574 * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. 570 575 * 571 576 * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain 572 - * has been changed and provides details of the request information 573 - * that caused the change such as who initiated the regulatory request 574 - * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx 575 - * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if 576 - * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or 577 - * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain 578 - * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is 579 - * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on 580 - * to (%NL80211_ATTR_REG_ALPHA2). 577 + * has been changed and provides details of the request information 578 + * that caused the change such as who initiated the regulatory request 579 + * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx 580 + * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if 581 + * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or 582 + * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain 583 + * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is 584 + * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on 585 + * to (%NL80211_ATTR_REG_ALPHA2). 581 586 * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon 582 - * has been found while world roaming thus enabling active scan or 583 - * any mode of operation that initiates TX (beacons) on a channel 584 - * where we would not have been able to do either before. As an example 585 - * if you are world roaming (regulatory domain set to world or if your 586 - * driver is using a custom world roaming regulatory domain) and while 587 - * doing a passive scan on the 5 GHz band you find an AP there (if not 588 - * on a DFS channel) you will now be able to actively scan for that AP 589 - * or use AP mode on your card on that same channel. Note that this will 590 - * never be used for channels 1-11 on the 2 GHz band as they are always 591 - * enabled world wide. This beacon hint is only sent if your device had 592 - * either disabled active scanning or beaconing on a channel. We send to 593 - * userspace the wiphy on which we removed a restriction from 594 - * (%NL80211_ATTR_WIPHY) and the channel on which this occurred 595 - * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) 596 - * the beacon hint was processed. 587 + * has been found while world roaming thus enabling active scan or 588 + * any mode of operation that initiates TX (beacons) on a channel 589 + * where we would not have been able to do either before. As an example 590 + * if you are world roaming (regulatory domain set to world or if your 591 + * driver is using a custom world roaming regulatory domain) and while 592 + * doing a passive scan on the 5 GHz band you find an AP there (if not 593 + * on a DFS channel) you will now be able to actively scan for that AP 594 + * or use AP mode on your card on that same channel. Note that this will 595 + * never be used for channels 1-11 on the 2 GHz band as they are always 596 + * enabled world wide. This beacon hint is only sent if your device had 597 + * either disabled active scanning or beaconing on a channel. We send to 598 + * userspace the wiphy on which we removed a restriction from 599 + * (%NL80211_ATTR_WIPHY) and the channel on which this occurred 600 + * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) 601 + * the beacon hint was processed. 597 602 * 598 603 * @NL80211_CMD_AUTHENTICATE: authentication request and notification. 599 604 * This command is used both as a command (request to authenticate) and ··· 1115 1120 * current configuration is not changed. If it is present but 1116 1121 * set to zero, the configuration is changed to don't-care 1117 1122 * (i.e. the device can decide what to do). 1118 - * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported. 1123 + * @NL80211_CMD_NAN_MATCH: Notification sent when a match is reported. 1119 1124 * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and 1120 1125 * %NL80211_ATTR_COOKIE. 1121 1126 * ··· 1710 1715 * (see &enum nl80211_plink_action). 1711 1716 * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. 1712 1717 * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path 1713 - * info given for %NL80211_CMD_GET_MPATH, nested attribute described at 1718 + * info given for %NL80211_CMD_GET_MPATH, nested attribute described at 1714 1719 * &enum nl80211_mpath_info. 1715 1720 * 1716 1721 * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of 1717 1722 * &enum nl80211_mntr_flags. 1718 1723 * 1719 1724 * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the 1720 - * current regulatory domain should be set to or is already set to. 1721 - * For example, 'CR', for Costa Rica. This attribute is used by the kernel 1722 - * to query the CRDA to retrieve one regulatory domain. This attribute can 1723 - * also be used by userspace to query the kernel for the currently set 1724 - * regulatory domain. We chose an alpha2 as that is also used by the 1725 - * IEEE-802.11 country information element to identify a country. 1726 - * Users can also simply ask the wireless core to set regulatory domain 1727 - * to a specific alpha2. 1725 + * current regulatory domain should be set to or is already set to. 1726 + * For example, 'CR', for Costa Rica. This attribute is used by the kernel 1727 + * to query the CRDA to retrieve one regulatory domain. This attribute can 1728 + * also be used by userspace to query the kernel for the currently set 1729 + * regulatory domain. We chose an alpha2 as that is also used by the 1730 + * IEEE-802.11 country information element to identify a country. 1731 + * Users can also simply ask the wireless core to set regulatory domain 1732 + * to a specific alpha2. 1728 1733 * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory 1729 1734 * rules. 1730 1735 * ··· 1767 1772 * @NL80211_ATTR_BSS: scan result BSS 1768 1773 * 1769 1774 * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain 1770 - * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* 1775 + * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* 1771 1776 * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently 1772 - * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) 1777 + * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) 1773 1778 * 1774 1779 * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies 1775 1780 * an array of command numbers (i.e. a mapping index to command number) ··· 1788 1793 * a u32 1789 1794 * 1790 1795 * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change 1791 - * due to considerations from a beacon hint. This attribute reflects 1792 - * the state of the channel _before_ the beacon hint processing. This 1793 - * attributes consists of a nested attribute containing 1794 - * NL80211_FREQUENCY_ATTR_* 1796 + * due to considerations from a beacon hint. This attribute reflects 1797 + * the state of the channel _before_ the beacon hint processing. This 1798 + * attributes consists of a nested attribute containing 1799 + * NL80211_FREQUENCY_ATTR_* 1795 1800 * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change 1796 - * due to considerations from a beacon hint. This attribute reflects 1797 - * the state of the channel _after_ the beacon hint processing. This 1798 - * attributes consists of a nested attribute containing 1799 - * NL80211_FREQUENCY_ATTR_* 1801 + * due to considerations from a beacon hint. This attribute reflects 1802 + * the state of the channel _after_ the beacon hint processing. This 1803 + * attributes consists of a nested attribute containing 1804 + * NL80211_FREQUENCY_ATTR_* 1800 1805 * 1801 1806 * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported 1802 1807 * cipher suites ··· 1857 1862 * that protected APs should be used. This is also used with NEW_BEACON to 1858 1863 * indicate that the BSS is to use protection. 1859 1864 * 1860 - * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON 1861 - * to indicate which unicast key ciphers will be used with the connection 1862 - * (an array of u32). 1863 - * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to 1864 - * indicate which group key cipher will be used with the connection (a 1865 - * u32). 1866 1865 * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to 1867 1866 * indicate which WPA version(s) the AP we want to associate with is using 1868 1867 * (a u32 with flags from &enum nl80211_wpa_versions). ··· 1887 1898 * with %NL80211_KEY_* sub-attributes 1888 1899 * 1889 1900 * @NL80211_ATTR_PID: Process ID of a network namespace. 1901 + * @NL80211_ATTR_NETNS_FD: File descriptor of a network namespace. 1890 1902 * 1891 1903 * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for 1892 1904 * dumps. This number increases whenever the object list being ··· 1942 1952 * 1943 1953 * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was 1944 1954 * acknowledged by the recipient. 1955 + * @NL80211_ATTR_ACK_SIGNAL: Station's ack signal strength (s32) 1945 1956 * 1946 1957 * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. 1947 1958 * ··· 2140 2149 * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable 2141 2150 * this feature during association. This is a flag attribute. 2142 2151 * Currently only supported in mac80211 drivers. 2152 + * @NL80211_ATTR_DISABLE_EHT: Force EHT capable interfaces to disable 2153 + * this feature during association. This is a flag attribute. 2154 + * Currently only supported in mac80211 drivers. 2143 2155 * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the 2144 2156 * ATTR_HT_CAPABILITY to which attention should be paid. 2145 2157 * Currently, only mac80211 NICs support this feature. ··· 2152 2158 * All values are treated as suggestions and may be ignored 2153 2159 * by the driver as required. The actual values may be seen in 2154 2160 * the station debugfs ht_caps file. 2161 + * @NL80211_ATTR_VHT_CAPABILITY_MASK: Specify which bits of the 2162 + * ATTR_VHT_CAPABILITY to which attention should be paid. 2163 + * Currently, only mac80211 NICs support this feature. 2164 + * All values are treated as suggestions and may be ignored 2165 + * by the driver as required. The actual values may be seen in 2166 + * the station debugfs vht_caps file. 2155 2167 * 2156 2168 * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country 2157 2169 * abides to when initiating radiation on DFS channels. A country maps ··· 2416 2416 * scheduled scan is started. Or the delay before a WoWLAN 2417 2417 * net-detect scan is started, counting from the moment the 2418 2418 * system is suspended. This value is a u32, in seconds. 2419 - 2419 + * 2420 2420 * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device 2421 2421 * is operating in an indoor environment. 2422 2422 * ··· 3565 3565 * enum nl80211_sta_p2p_ps_status - station support of P2P PS 3566 3566 * 3567 3567 * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism 3568 - * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism 3568 + * @NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism 3569 3569 * @NUM_NL80211_P2P_PS_STATUS: number of values 3570 3570 */ 3571 3571 enum nl80211_sta_p2p_ps_status { ··· 3603 3603 3604 3604 /** 3605 3605 * enum nl80211_he_ltf - HE long training field 3606 - * @NL80211_RATE_INFO_HE_1xLTF: 3.2 usec 3607 - * @NL80211_RATE_INFO_HE_2xLTF: 6.4 usec 3608 - * @NL80211_RATE_INFO_HE_4xLTF: 12.8 usec 3606 + * @NL80211_RATE_INFO_HE_1XLTF: 3.2 usec 3607 + * @NL80211_RATE_INFO_HE_2XLTF: 6.4 usec 3608 + * @NL80211_RATE_INFO_HE_4XLTF: 12.8 usec 3609 3609 */ 3610 3610 enum nl80211_he_ltf { 3611 3611 NL80211_RATE_INFO_HE_1XLTF, ··· 3720 3720 * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier 3721 3721 * (u8, see &enum nl80211_he_gi) 3722 3722 * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1) 3723 - * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then 3723 + * @NL80211_RATE_INFO_HE_RU_ALLOC: HE RU allocation, if not present then 3724 3724 * non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc) 3725 3725 * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate 3726 3726 * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15) ··· 3823 3823 * (u64, to this station) 3824 3824 * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) 3825 3825 * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute 3826 - * containing info as possible, see &enum nl80211_rate_info 3826 + * containing info as possible, see &enum nl80211_rate_info 3827 3827 * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs) 3828 3828 * (u32, from this station) 3829 3829 * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs) ··· 3852 3852 * Contains a nested array of signal strength attributes (u8, dBm) 3853 3853 * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average 3854 3854 * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. 3855 - * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the 3856 - * 802.11 header (u32, kbps) 3855 + * @NL80211_STA_INFO_EXPECTED_THROUGHPUT: expected throughput considering also 3856 + * the 802.11 header (u32, kbps) 3857 3857 * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons 3858 3858 * (u64) 3859 3859 * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64) ··· 4039 4039 * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path 4040 4040 * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now 4041 4041 * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in 4042 - * &enum nl80211_mpath_flags; 4042 + * &enum nl80211_mpath_flags; 4043 4043 * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec 4044 4044 * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries 4045 4045 * @NL80211_MPATH_INFO_HOP_COUNT: hop count to destination ··· 4179 4179 * @NL80211_WMMR_CW_MAX: Maximum contention window slot. 4180 4180 * @NL80211_WMMR_AIFSN: Arbitration Inter Frame Space. 4181 4181 * @NL80211_WMMR_TXOP: Maximum allowed tx operation time. 4182 - * @nl80211_WMMR_MAX: highest possible wmm rule. 4182 + * @NL80211_WMMR_MAX: highest possible wmm rule. 4183 4183 * @__NL80211_WMMR_LAST: Internal use. 4184 4184 */ 4185 4185 enum nl80211_wmm_rule { ··· 4201 4201 * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current 4202 4202 * regulatory domain. 4203 4203 * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation 4204 - * are permitted on this channel, this includes sending probe 4205 - * requests, or modes of operation that require beaconing. 4204 + * are permitted on this channel, this includes sending probe 4205 + * requests, or modes of operation that require beaconing. 4206 + * @__NL80211_FREQUENCY_ATTR_NO_IBSS: obsolete, same as _NO_IR 4206 4207 * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory 4207 4208 * on this channel in current regulatory domain. 4208 4209 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm ··· 4358 4357 }; 4359 4358 4360 4359 /** 4361 - * enum nl80211_initiator - Indicates the initiator of a reg domain request 4360 + * enum nl80211_reg_initiator - Indicates the initiator of a reg domain request 4362 4361 * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world 4363 - * regulatory domain. 4362 + * regulatory domain. 4364 4363 * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the 4365 - * regulatory domain. 4364 + * regulatory domain. 4366 4365 * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the 4367 - * wireless core it thinks its knows the regulatory domain we should be in. 4366 + * wireless core it thinks its knows the regulatory domain we should be in. 4368 4367 * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an 4369 - * 802.11 country information element with regulatory information it 4370 - * thinks we should consider. cfg80211 only processes the country 4368 + * 802.11 country information element with regulatory information it 4369 + * thinks we should consider. cfg80211 only processes the country 4371 4370 * code from the IE, and relies on the regulatory domain information 4372 4371 * structure passed by userspace (CRDA) from our wireless-regdb. 4373 4372 * If a channel is enabled but the country code indicates it should ··· 4386 4385 * to a specific country. When this is set you can count on the 4387 4386 * ISO / IEC 3166 alpha2 country code being valid. 4388 4387 * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory 4389 - * domain. 4388 + * domain. 4390 4389 * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom 4391 - * driver specific world regulatory domain. These do not apply system-wide 4392 - * and are only applicable to the individual devices which have requested 4393 - * them to be applied. 4390 + * driver specific world regulatory domain. These do not apply system-wide 4391 + * and are only applicable to the individual devices which have requested 4392 + * them to be applied. 4394 4393 * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product 4395 4394 * of an intersection between two regulatory domains -- the previously 4396 4395 * set regulatory domain on the system and the last accepted regulatory ··· 4407 4406 * enum nl80211_reg_rule_attr - regulatory rule attributes 4408 4407 * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved 4409 4408 * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional 4410 - * considerations for a given frequency range. These are the 4411 - * &enum nl80211_reg_rule_flags. 4409 + * considerations for a given frequency range. These are the 4410 + * &enum nl80211_reg_rule_flags. 4412 4411 * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory 4413 - * rule in KHz. This is not a center of frequency but an actual regulatory 4414 - * band edge. 4412 + * rule in KHz. This is not a center of frequency but an actual regulatory 4413 + * band edge. 4415 4414 * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule 4416 - * in KHz. This is not a center a frequency but an actual regulatory 4417 - * band edge. 4415 + * in KHz. This is not a center a frequency but an actual regulatory 4416 + * band edge. 4418 4417 * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this 4419 4418 * frequency range, in KHz. 4420 4419 * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain 4421 - * for a given frequency range. The value is in mBi (100 * dBi). 4422 - * If you don't have one then don't send this. 4420 + * for a given frequency range. The value is in mBi (100 * dBi). 4421 + * If you don't have one then don't send this. 4423 4422 * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for 4424 - * a given frequency range. The value is in mBm (100 * dBm). 4423 + * a given frequency range. The value is in mBm (100 * dBm). 4425 4424 * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. 4426 4425 * If not present or 0 default CAC time will be used. 4427 4426 * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm). ··· 4508 4507 * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links 4509 4508 * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links 4510 4509 * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, 4511 - * this includes probe requests or modes of operation that require 4512 - * beaconing. 4510 + * this includes probe requests or modes of operation that require 4511 + * beaconing. 4512 + * @__NL80211_RRF_NO_IBSS: obsolete, same as NO_IR 4513 4513 * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated 4514 4514 * base on contiguous rules and wider channels will be allowed to cross 4515 4515 * multiple contiguous/overlapping frequency ranges. ··· 4524 4522 * @NL80211_RRF_NO_EHT: EHT operation not allowed 4525 4523 * @NL80211_RRF_PSD: Ruleset has power spectral density value 4526 4524 * @NL80211_RRF_DFS_CONCURRENT: Operation on this channel is allowed for 4527 - peer-to-peer or adhoc communication under the control of a DFS master 4528 - which operates on the same channel (FCC-594280 D01 Section B.3). 4529 - Should be used together with %NL80211_RRF_DFS only. 4525 + * peer-to-peer or adhoc communication under the control of a DFS master 4526 + * which operates on the same channel (FCC-594280 D01 Section B.3). 4527 + * Should be used together with %NL80211_RRF_DFS only. 4530 4528 * @NL80211_RRF_NO_6GHZ_VLP_CLIENT: Client connection to VLP AP not allowed 4531 4529 * @NL80211_RRF_NO_6GHZ_AFC_CLIENT: Client connection to AFC AP not allowed 4532 4530 */ ··· 4709 4707 * alternate between Active and Doze states, but may not wake up 4710 4708 * for neighbor's beacons. 4711 4709 * 4712 - * @__NL80211_MESH_POWER_AFTER_LAST - internal use 4713 - * @NL80211_MESH_POWER_MAX - highest possible power save level 4710 + * @__NL80211_MESH_POWER_AFTER_LAST: internal use 4711 + * @NL80211_MESH_POWER_MAX: highest possible power save level 4714 4712 */ 4715 4713 4716 4714 enum nl80211_mesh_power_mode { ··· 5730 5728 * "TCP connection wakeup" for more details. This is a nested attribute 5731 5729 * containing the exact information for establishing and keeping alive 5732 5730 * the TCP connection. 5733 - * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the 5731 + * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH: For wakeup reporting only, the 5734 5732 * wakeup packet was received on the TCP connection 5735 5733 * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the 5736 5734 * TCP connection was lost or failed to be established ··· 6079 6077 * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer 6080 6078 * @NUM_NL80211_PLINK_ACTIONS: number of possible actions 6081 6079 */ 6082 - enum plink_actions { 6080 + enum nl80211_plink_action { 6083 6081 NL80211_PLINK_ACTION_NO_ACTION, 6084 6082 NL80211_PLINK_ACTION_OPEN, 6085 6083 NL80211_PLINK_ACTION_BLOCK, ··· 6406 6404 * receiving control port frames over nl80211 instead of the netdevice. 6407 6405 * @NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT: This driver/device supports 6408 6406 * (average) ACK signal strength reporting. 6407 + * @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: Backward-compatible ID 6409 6408 * @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate 6410 6409 * TXQs. 6411 6410 * @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the ··· 6790 6787 * @NL80211_SMPS_STATIC: static SMPS (use a single antenna) 6791 6788 * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and 6792 6789 * turn on other antennas after CTS/RTS). 6790 + * @__NL80211_SMPS_AFTER_LAST: internal 6791 + * @NL80211_SMPS_MAX: highest used enumeration 6793 6792 */ 6794 6793 enum nl80211_smps_mode { 6795 6794 NL80211_SMPS_OFF, ··· 7013 7008 * @NL80211_NAN_FUNC_PUBLISH: function is publish 7014 7009 * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe 7015 7010 * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up 7011 + * @__NL80211_NAN_FUNC_TYPE_AFTER_LAST: internal use 7012 + * @NL80211_NAN_FUNC_MAX_TYPE: internal use 7016 7013 */ 7017 7014 enum nl80211_nan_function_type { 7018 7015 NL80211_NAN_FUNC_PUBLISH, ··· 7175 7168 }; 7176 7169 7177 7170 /** 7178 - * nl80211_external_auth_action - Action to perform with external 7171 + * enum nl80211_external_auth_action - Action to perform with external 7179 7172 * authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION. 7180 7173 * @NL80211_EXTERNAL_AUTH_START: Start the authentication. 7181 7174 * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication. ··· 7193 7186 * @NL80211_FTM_RESP_ATTR_LCI: The content of Measurement Report Element 7194 7187 * (9.4.2.22 in 802.11-2016) with type 8 - LCI (9.4.2.22.10), 7195 7188 * i.e. starting with the measurement token 7196 - * @NL80211_FTM_RESP_ATTR_CIVIC: The content of Measurement Report Element 7189 + * @NL80211_FTM_RESP_ATTR_CIVICLOC: The content of Measurement Report Element 7197 7190 * (9.4.2.22 in 802.11-2016) with type 11 - Civic (Section 9.4.2.22.13), 7198 7191 * i.e. starting with the measurement token 7199 7192 * @__NL80211_FTM_RESP_ATTR_LAST: Internal ··· 7836 7829 * 7837 7830 * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit 7838 7831 * 7832 + * @NUM_NL80211_SAR_TYPE: internal 7839 7833 */ 7840 7834 enum nl80211_sar_type { 7841 7835 NL80211_SAR_TYPE_POWER, ··· 7849 7841 7850 7842 /** 7851 7843 * enum nl80211_sar_attrs - Attributes for SAR spec 7844 + * 7845 + * @__NL80211_SAR_ATTR_INVALID: Invalid 7852 7846 * 7853 7847 * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type. 7854 7848 * ··· 7882 7872 7883 7873 /** 7884 7874 * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs 7875 + * 7876 + * @__NL80211_SAR_ATTR_SPECS_INVALID: Invalid 7885 7877 * 7886 7878 * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual 7887 7879 * power limit value in units of 0.25 dBm if type is
+19 -15
net/mac80211/chan.c
··· 695 695 } 696 696 697 697 static void ieee80211_del_chanctx(struct ieee80211_local *local, 698 - struct ieee80211_chanctx *ctx) 698 + struct ieee80211_chanctx *ctx, 699 + bool skip_idle_recalc) 699 700 { 700 701 lockdep_assert_wiphy(local->hw.wiphy); 701 702 702 703 drv_remove_chanctx(local, ctx); 703 704 704 - ieee80211_recalc_idle(local); 705 + if (!skip_idle_recalc) 706 + ieee80211_recalc_idle(local); 705 707 706 708 ieee80211_remove_wbrf(local, &ctx->conf.def); 707 709 } 708 710 709 711 static void ieee80211_free_chanctx(struct ieee80211_local *local, 710 - struct ieee80211_chanctx *ctx) 712 + struct ieee80211_chanctx *ctx, 713 + bool skip_idle_recalc) 711 714 { 712 715 lockdep_assert_wiphy(local->hw.wiphy); 713 716 714 717 WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0); 715 718 716 719 list_del_rcu(&ctx->list); 717 - ieee80211_del_chanctx(local, ctx); 720 + ieee80211_del_chanctx(local, ctx, skip_idle_recalc); 718 721 kfree_rcu(ctx, rcu_head); 719 722 } 720 723 ··· 1005 1002 list_del_rcu(&ctx->list); 1006 1003 kfree_rcu(ctx, rcu_head); 1007 1004 } else { 1008 - ieee80211_free_chanctx(sdata->local, ctx); 1005 + ieee80211_free_chanctx(sdata->local, ctx, false); 1009 1006 } 1010 1007 } 1011 1008 ··· 1221 1218 CHANCTX_SWMODE_REASSIGN_VIF); 1222 1219 if (err) { 1223 1220 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1224 - ieee80211_free_chanctx(local, new_ctx); 1221 + ieee80211_free_chanctx(local, new_ctx, false); 1225 1222 1226 1223 goto out; 1227 1224 } ··· 1235 1232 ieee80211_check_fast_xmit_iface(sdata); 1236 1233 1237 1234 if (ieee80211_chanctx_refcount(local, old_ctx) == 0) 1238 - ieee80211_free_chanctx(local, old_ctx); 1235 + ieee80211_free_chanctx(local, old_ctx, false); 1239 1236 1240 1237 ieee80211_recalc_chanctx_min_def(local, new_ctx, NULL); 1241 1238 ieee80211_recalc_smps_chanctx(local, new_ctx); ··· 1289 1286 err = ieee80211_assign_link_chanctx(link, new_ctx); 1290 1287 if (err) { 1291 1288 if (ieee80211_chanctx_refcount(local, new_ctx) == 0) 1292 - ieee80211_free_chanctx(local, new_ctx); 1289 + ieee80211_free_chanctx(local, new_ctx, false); 1293 1290 1294 1291 goto out; 1295 1292 } ··· 1386 1383 if (!list_empty(&ctx->replace_ctx->assigned_links)) 1387 1384 continue; 1388 1385 1389 - ieee80211_del_chanctx(local, ctx->replace_ctx); 1386 + ieee80211_del_chanctx(local, ctx->replace_ctx, false); 1390 1387 err = ieee80211_add_chanctx(local, ctx); 1391 1388 if (err) 1392 1389 goto err; ··· 1403 1400 if (!list_empty(&ctx->replace_ctx->assigned_links)) 1404 1401 continue; 1405 1402 1406 - ieee80211_del_chanctx(local, ctx); 1403 + ieee80211_del_chanctx(local, ctx, false); 1407 1404 WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx)); 1408 1405 } 1409 1406 ··· 1655 1652 return err; 1656 1653 } 1657 1654 1658 - static void __ieee80211_link_release_channel(struct ieee80211_link_data *link) 1655 + void __ieee80211_link_release_channel(struct ieee80211_link_data *link, 1656 + bool skip_idle_recalc) 1659 1657 { 1660 1658 struct ieee80211_sub_if_data *sdata = link->sdata; 1661 1659 struct ieee80211_bss_conf *link_conf = link->conf; ··· 1684 1680 1685 1681 ieee80211_assign_link_chanctx(link, NULL); 1686 1682 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1687 - ieee80211_free_chanctx(local, ctx); 1683 + ieee80211_free_chanctx(local, ctx, skip_idle_recalc); 1688 1684 1689 1685 link->radar_required = false; 1690 1686 ··· 1725 1721 if (ret < 0) 1726 1722 goto out; 1727 1723 1728 - __ieee80211_link_release_channel(link); 1724 + __ieee80211_link_release_channel(link, false); 1729 1725 1730 1726 ctx = ieee80211_find_chanctx(local, chanreq, mode); 1731 1727 if (!ctx) ··· 1741 1737 if (ret) { 1742 1738 /* if assign fails refcount stays the same */ 1743 1739 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1744 - ieee80211_free_chanctx(local, ctx); 1740 + ieee80211_free_chanctx(local, ctx, false); 1745 1741 goto out; 1746 1742 } 1747 1743 ··· 1934 1930 lockdep_assert_wiphy(sdata->local->hw.wiphy); 1935 1931 1936 1932 if (rcu_access_pointer(link->conf->chanctx_conf)) 1937 - __ieee80211_link_release_channel(link); 1933 + __ieee80211_link_release_channel(link, false); 1938 1934 } 1939 1935 1940 1936 void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link)
+1
net/mac80211/debugfs.c
··· 498 498 FLAG(DETECTS_COLOR_COLLISION), 499 499 FLAG(MLO_MCAST_MULTI_LINK_TX), 500 500 FLAG(DISALLOW_PUNCTURING), 501 + FLAG(DISALLOW_PUNCTURING_5GHZ), 501 502 FLAG(HANDLES_QUIET_CSA), 502 503 #undef FLAG 503 504 };
+2 -1
net/mac80211/drop.h
··· 2 2 /* 3 3 * mac80211 drop reason list 4 4 * 5 - * Copyright (C) 2023 Intel Corporation 5 + * Copyright (C) 2023-2024 Intel Corporation 6 6 */ 7 7 8 8 #ifndef MAC80211_DROP_H ··· 66 66 R(RX_DROP_U_UNEXPECTED_STA_4ADDR) \ 67 67 R(RX_DROP_U_UNEXPECTED_VLAN_MCAST) \ 68 68 R(RX_DROP_U_NOT_PORT_CONTROL) \ 69 + R(RX_DROP_U_UNKNOWN_ACTION_REJECTED) \ 69 70 /* this line for the trailing \ - add before this */ 70 71 71 72 /* having two enums allows for checking ieee80211_rx_result use with sparse */
+1 -1
net/mac80211/ht.c
··· 580 580 /* we'll do more on status of this frame */ 581 581 info = IEEE80211_SKB_CB(skb); 582 582 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 583 - /* we have 12 bits, and need 6: link_id 4, smps 2 */ 583 + /* we have 13 bits, and need 6: link_id 4, smps 2 */ 584 584 info->status_data = IEEE80211_STATUS_TYPE_SMPS | 585 585 u16_encode_bits(status_link_id << 2 | smps, 586 586 IEEE80211_STATUS_SUBDATA_MASK);
+7 -1
net/mac80211/ieee80211_i.h
··· 89 89 IEEE80211_STATUS_TYPE_MASK = 0x00f, 90 90 IEEE80211_STATUS_TYPE_INVALID = 0, 91 91 IEEE80211_STATUS_TYPE_SMPS = 1, 92 - IEEE80211_STATUS_SUBDATA_MASK = 0xff0, 92 + IEEE80211_STATUS_TYPE_NEG_TTLM = 2, 93 + IEEE80211_STATUS_SUBDATA_MASK = 0x1ff0, 93 94 }; 94 95 95 96 static inline bool ··· 596 595 /* TID-to-link mapping support */ 597 596 struct wiphy_delayed_work ttlm_work; 598 597 struct ieee80211_adv_ttlm_info ttlm_info; 598 + struct wiphy_work teardown_ttlm_work; 599 599 600 600 /* dialog token enumerator for neg TTLM request */ 601 601 u8 dialog_token_alloc; ··· 1160 1158 /* for ieee80211_set_active_links_async() */ 1161 1159 struct wiphy_work activate_links_work; 1162 1160 u16 desired_active_links; 1161 + 1162 + u16 restart_active_links; 1163 1163 1164 1164 #ifdef CONFIG_MAC80211_DEBUGFS 1165 1165 struct { ··· 2569 2565 ieee80211_link_change_chanreq(struct ieee80211_link_data *link, 2570 2566 const struct ieee80211_chan_req *req, 2571 2567 u64 *changed); 2568 + void __ieee80211_link_release_channel(struct ieee80211_link_data *link, 2569 + bool skip_idle_recalc); 2572 2570 void ieee80211_link_release_channel(struct ieee80211_link_data *link); 2573 2571 void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link); 2574 2572 void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link,
+5 -2
net/mac80211/link.c
··· 358 358 359 359 ieee80211_teardown_tdls_peers(link); 360 360 361 - ieee80211_link_release_channel(link); 361 + __ieee80211_link_release_channel(link, true); 362 362 } 363 363 364 364 list_for_each_entry(sta, &local->sta_list, list) { ··· 450 450 if (WARN_ON(!active_links)) 451 451 return -EINVAL; 452 452 453 + old_active = sdata->vif.active_links; 454 + if (old_active == active_links) 455 + return 0; 456 + 453 457 if (!drv_can_activate_links(local, sdata, active_links)) 454 458 return -EINVAL; 455 459 456 - old_active = sdata->vif.active_links; 457 460 if (old_active & active_links) { 458 461 /* 459 462 * if there's at least one link that stays active across
+74 -8
net/mac80211/mlme.c
··· 599 599 ieee80211_hw_check(&sdata->local->hw, DISALLOW_PUNCTURING)) 600 600 return false; 601 601 602 + if (chandef->punctured && chandef->chan->band == NL80211_BAND_5GHZ && 603 + ieee80211_hw_check(&sdata->local->hw, DISALLOW_PUNCTURING_5GHZ)) 604 + return false; 605 + 602 606 return true; 603 607 } 604 608 ··· 4433 4429 switch (u8_get_bits(he_6ghz_oper->control, 4434 4430 IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { 4435 4431 case IEEE80211_6GHZ_CTRL_REG_LPI_AP: 4432 + case IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP: 4436 4433 bss_conf->power_type = IEEE80211_REG_LPI_AP; 4437 4434 break; 4438 4435 case IEEE80211_6GHZ_CTRL_REG_SP_AP: 4436 + case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP: 4439 4437 bss_conf->power_type = IEEE80211_REG_SP_AP; 4440 4438 break; 4441 4439 case IEEE80211_6GHZ_CTRL_REG_VLP_AP: ··· 6798 6792 __ieee80211_disconnect(sdata); 6799 6793 } 6800 6794 6795 + static void ieee80211_teardown_ttlm_work(struct wiphy *wiphy, 6796 + struct wiphy_work *work) 6797 + { 6798 + u16 new_dormant_links; 6799 + struct ieee80211_sub_if_data *sdata = 6800 + container_of(work, struct ieee80211_sub_if_data, 6801 + u.mgd.neg_ttlm_timeout_work.work); 6802 + 6803 + if (!sdata->vif.neg_ttlm.valid) 6804 + return; 6805 + 6806 + memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm)); 6807 + new_dormant_links = 6808 + sdata->vif.dormant_links & ~sdata->vif.suspended_links; 6809 + sdata->vif.suspended_links = 0; 6810 + ieee80211_vif_set_links(sdata, sdata->vif.valid_links, 6811 + new_dormant_links); 6812 + ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_MLD_TTLM | 6813 + BSS_CHANGED_MLD_VALID_LINKS); 6814 + } 6815 + 6816 + void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif) 6817 + { 6818 + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 6819 + struct ieee80211_local *local = sdata->local; 6820 + struct ieee80211_mgmt *mgmt; 6821 + struct sk_buff *skb; 6822 + int frame_len = offsetofend(struct ieee80211_mgmt, 6823 + u.action.u.ttlm_tear_down); 6824 + struct ieee80211_tx_info *info; 6825 + 6826 + skb = dev_alloc_skb(local->hw.extra_tx_headroom + frame_len); 6827 + if (!skb) 6828 + return; 6829 + 6830 + skb_reserve(skb, local->hw.extra_tx_headroom); 6831 + mgmt = skb_put_zero(skb, frame_len); 6832 + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 6833 + IEEE80211_STYPE_ACTION); 6834 + memcpy(mgmt->da, sdata->vif.cfg.ap_addr, ETH_ALEN); 6835 + memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 6836 + memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 6837 + 6838 + mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 6839 + mgmt->u.action.u.ttlm_tear_down.action_code = 6840 + WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN; 6841 + 6842 + info = IEEE80211_SKB_CB(skb); 6843 + info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 6844 + info->status_data = IEEE80211_STATUS_TYPE_NEG_TTLM; 6845 + ieee80211_tx_skb(sdata, skb); 6846 + } 6847 + EXPORT_SYMBOL(ieee80211_send_teardown_neg_ttlm); 6848 + 6801 6849 void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, 6802 6850 struct sk_buff *skb) 6803 6851 { ··· 7483 7423 ieee80211_tid_to_link_map_work); 7484 7424 wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work, 7485 7425 ieee80211_neg_ttlm_timeout_work); 7426 + wiphy_work_init(&ifmgd->teardown_ttlm_work, 7427 + ieee80211_teardown_ttlm_work); 7486 7428 7487 7429 ifmgd->flags = 0; 7488 7430 ifmgd->powersave = sdata->wdev.ps; ··· 8271 8209 if (req->ap_mld_addr) { 8272 8210 uapsd_supported = true; 8273 8211 8212 + if (req->flags & (ASSOC_REQ_DISABLE_HT | 8213 + ASSOC_REQ_DISABLE_VHT | 8214 + ASSOC_REQ_DISABLE_HE | 8215 + ASSOC_REQ_DISABLE_EHT)) { 8216 + err = -EINVAL; 8217 + goto err_free; 8218 + } 8219 + 8274 8220 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 8275 8221 struct ieee80211_supported_band *sband; 8276 8222 struct cfg80211_bss *link_cbss = req->links[i].bss; ··· 8291 8221 8292 8222 if (!bss->wmm_used) { 8293 8223 err = -EINVAL; 8294 - goto err_free; 8295 - } 8296 - 8297 - if (req->flags & (ASSOC_REQ_DISABLE_HT | 8298 - ASSOC_REQ_DISABLE_VHT | 8299 - ASSOC_REQ_DISABLE_HE | 8300 - ASSOC_REQ_DISABLE_EHT)) { 8301 - err = -EINVAL; 8224 + req->links[i].error = err; 8302 8225 goto err_free; 8303 8226 } 8304 8227 8305 8228 if (link_cbss->channel->band == NL80211_BAND_S1GHZ) { 8306 8229 err = -EINVAL; 8230 + req->links[i].error = err; 8307 8231 goto err_free; 8308 8232 } 8309 8233 ··· 8674 8610 &ifmgd->beacon_connection_loss_work); 8675 8611 wiphy_work_cancel(sdata->local->hw.wiphy, 8676 8612 &ifmgd->csa_connection_drop_work); 8613 + wiphy_work_cancel(sdata->local->hw.wiphy, 8614 + &ifmgd->teardown_ttlm_work); 8677 8615 wiphy_delayed_work_cancel(sdata->local->hw.wiphy, 8678 8616 &ifmgd->tdls_peer_del_work); 8679 8617 wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+2 -2
net/mac80211/rx.c
··· 3958 3958 __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, -1, 3959 3959 status->band); 3960 3960 } 3961 - dev_kfree_skb(rx->skb); 3962 - return RX_QUEUED; 3961 + 3962 + return RX_DROP_U_UNKNOWN_ACTION_REJECTED; 3963 3963 } 3964 3964 3965 3965 static ieee80211_rx_result debug_noinline
+4 -12
net/mac80211/scan.c
··· 707 707 return -EBUSY; 708 708 709 709 /* For an MLO connection, if a link ID was specified, validate that it 710 - * is indeed active. If no link ID was specified, select one of the 711 - * active links. 710 + * is indeed active. 712 711 */ 713 - if (ieee80211_vif_is_mld(&sdata->vif)) { 714 - if (req->tsf_report_link_id >= 0) { 715 - if (!(sdata->vif.active_links & 716 - BIT(req->tsf_report_link_id))) 717 - return -EINVAL; 718 - } else { 719 - req->tsf_report_link_id = 720 - __ffs(sdata->vif.active_links); 721 - } 722 - } 712 + if (ieee80211_vif_is_mld(&sdata->vif) && req->tsf_report_link_id >= 0 && 713 + !(sdata->vif.active_links & BIT(req->tsf_report_link_id))) 714 + return -EINVAL; 723 715 724 716 if (!__ieee80211_can_leave_ch(sdata)) 725 717 return -EBUSY;
+11 -7
net/mac80211/spectmgmt.c
··· 155 155 struct ieee80211_eht_operation _oper; 156 156 struct ieee80211_eht_operation_info _oper_info; 157 157 } __packed eht; 158 + const struct ieee80211_eht_operation *eht_oper; 158 159 159 160 if (conn->mode < IEEE80211_CONN_MODE_HE) { 160 161 chandef->chan = NULL; ··· 204 203 } 205 204 206 205 if (conn->mode < IEEE80211_CONN_MODE_EHT) { 207 - if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper, 208 - NULL, chandef)) 209 - chandef->chan = NULL; 206 + eht_oper = NULL; 210 207 } else { 211 208 eht._oper.params = IEEE80211_EHT_OPER_INFO_PRESENT; 212 209 eht._oper_info.control = he._6ghz_oper.control; 213 210 eht._oper_info.ccfs0 = he._6ghz_oper.ccfs0; 214 211 eht._oper_info.ccfs1 = he._6ghz_oper.ccfs1; 215 - 216 - if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper, 217 - &eht._oper, chandef)) 218 - chandef->chan = NULL; 212 + eht_oper = &eht._oper; 219 213 } 214 + 215 + if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper, 216 + eht_oper, chandef)) 217 + chandef->chan = NULL; 220 218 } 221 219 222 220 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, ··· 348 348 new_chandef = csa_ie->chanreq.oper; 349 349 /* and update the width accordingly */ 350 350 ieee80211_chandef_eht_oper(&bwi->info, &new_chandef); 351 + 352 + if (bwi->params & IEEE80211_BW_IND_DIS_SUBCH_PRESENT) 353 + new_chandef.punctured = 354 + get_unaligned_le16(bwi->info.optional); 351 355 } else if (!wide_bw_chansw_ie || !wbcs_elem_to_chandef(wide_bw_chansw_ie, 352 356 &new_chandef)) { 353 357 if (!ieee80211_operating_class_to_chandef(new_op_class, new_chan,
+21 -1
net/mac80211/status.c
··· 5 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 6 6 * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net> 7 7 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 - * Copyright 2021-2023 Intel Corporation 8 + * Copyright 2021-2024 Intel Corporation 9 9 */ 10 10 11 11 #include <linux/export.h> ··· 696 696 wiphy_work_queue(sdata->local->hw.wiphy, &link->u.mgd.recalc_smps); 697 697 } 698 698 699 + static void 700 + ieee80211_handle_teardown_ttlm_status(struct ieee80211_sub_if_data *sdata, 701 + bool acked) 702 + { 703 + if (!sdata || !ieee80211_sdata_running(sdata)) 704 + return; 705 + 706 + if (!acked) 707 + return; 708 + 709 + if (sdata->vif.type != NL80211_IFTYPE_STATION) 710 + return; 711 + 712 + wiphy_work_queue(sdata->local->hw.wiphy, 713 + &sdata->u.mgd.teardown_ttlm_work); 714 + } 715 + 699 716 static void ieee80211_report_used_skb(struct ieee80211_local *local, 700 717 struct sk_buff *skb, bool dropped, 701 718 ktime_t ack_hwtstamp) ··· 789 772 case IEEE80211_STATUS_TYPE_SMPS: 790 773 ieee80211_handle_smps_status(sdata, acked, 791 774 info->status_data); 775 + break; 776 + case IEEE80211_STATUS_TYPE_NEG_TTLM: 777 + ieee80211_handle_teardown_ttlm_status(sdata, acked); 792 778 break; 793 779 } 794 780 rcu_read_unlock();
+3 -3
net/mac80211/tx.c
··· 1604 1604 local->cparams.target = MS2TIME(20); 1605 1605 local->cparams.ecn = true; 1606 1606 1607 - local->cvars = kcalloc(fq->flows_cnt, sizeof(local->cvars[0]), 1608 - GFP_KERNEL); 1607 + local->cvars = kvcalloc(fq->flows_cnt, sizeof(local->cvars[0]), 1608 + GFP_KERNEL); 1609 1609 if (!local->cvars) { 1610 1610 spin_lock_bh(&fq->lock); 1611 1611 fq_reset(fq, fq_skb_free_func); ··· 1625 1625 { 1626 1626 struct fq *fq = &local->fq; 1627 1627 1628 - kfree(local->cvars); 1628 + kvfree(local->cvars); 1629 1629 local->cvars = NULL; 1630 1630 1631 1631 spin_lock_bh(&fq->lock);
+11 -3
net/mac80211/util.c
··· 1932 1932 old); 1933 1933 } 1934 1934 1935 + sdata->restart_active_links = active_links; 1936 + 1935 1937 for (link_id = 0; 1936 1938 link_id < ARRAY_SIZE(sdata->vif.link_conf); 1937 1939 link_id++) { ··· 2061 2059 WARN_ON(1); 2062 2060 break; 2063 2061 } 2064 - 2065 - if (active_links) 2066 - ieee80211_set_active_links(&sdata->vif, active_links); 2067 2062 } 2068 2063 2069 2064 ieee80211_recalc_ps(local); ··· 2100 2101 /* add back keys */ 2101 2102 list_for_each_entry(sdata, &local->interfaces, list) 2102 2103 ieee80211_reenable_keys(sdata); 2104 + 2105 + /* re-enable multi-link for client interfaces */ 2106 + list_for_each_entry(sdata, &local->interfaces, list) { 2107 + if (sdata->restart_active_links) 2108 + ieee80211_set_active_links(&sdata->vif, 2109 + sdata->restart_active_links); 2110 + } 2103 2111 2104 2112 /* Reconfigure sched scan if it was interrupted by FW restart */ 2105 2113 sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, ··· 3142 3136 } else { 3143 3137 ieee80211_chandef_eht_oper((const void *)eht_oper->optional, 3144 3138 &he_chandef); 3139 + he_chandef.punctured = 3140 + ieee80211_eht_oper_dis_subchan_bitmap(eht_oper); 3145 3141 } 3146 3142 3147 3143 if (!cfg80211_chandef_valid(&he_chandef))
+2 -4
net/rfkill/rfkill-gpio.c
··· 156 156 return ret; 157 157 } 158 158 159 - static int rfkill_gpio_remove(struct platform_device *pdev) 159 + static void rfkill_gpio_remove(struct platform_device *pdev) 160 160 { 161 161 struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); 162 162 163 163 rfkill_unregister(rfkill->rfkill_dev); 164 164 rfkill_destroy(rfkill->rfkill_dev); 165 - 166 - return 0; 167 165 } 168 166 169 167 #ifdef CONFIG_ACPI ··· 181 183 182 184 static struct platform_driver rfkill_gpio_driver = { 183 185 .probe = rfkill_gpio_probe, 184 - .remove = rfkill_gpio_remove, 186 + .remove_new = rfkill_gpio_remove, 185 187 .driver = { 186 188 .name = "rfkill_gpio", 187 189 .acpi_match_table = ACPI_PTR(rfkill_acpi_match),
+44 -10
net/wireless/scan.c
··· 2140 2140 switch (u8_get_bits(he_6ghz_oper->control, 2141 2141 IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { 2142 2142 case IEEE80211_6GHZ_CTRL_REG_LPI_AP: 2143 + case IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP: 2143 2144 return true; 2144 2145 case IEEE80211_6GHZ_CTRL_REG_SP_AP: 2146 + case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP: 2145 2147 return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT); 2146 2148 case IEEE80211_6GHZ_CTRL_REG_VLP_AP: 2147 2149 return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT); 2150 + default: 2151 + return false; 2148 2152 } 2149 2153 } 2150 2154 return false; ··· 2211 2207 tmp.pub.use_for = data->use_for; 2212 2208 tmp.pub.cannot_use_reasons = data->cannot_use_reasons; 2213 2209 2214 - if (data->bss_source != BSS_SOURCE_DIRECT) { 2210 + switch (data->bss_source) { 2211 + case BSS_SOURCE_MBSSID: 2215 2212 tmp.pub.transmitted_bss = data->source_bss; 2213 + fallthrough; 2214 + case BSS_SOURCE_STA_PROFILE: 2216 2215 ts = bss_from_pub(data->source_bss)->ts; 2217 2216 tmp.pub.bssid_index = data->bssid_index; 2218 2217 tmp.pub.max_bssid_indicator = data->max_bssid_indicator; 2219 - } else { 2218 + break; 2219 + case BSS_SOURCE_DIRECT: 2220 2220 ts = jiffies; 2221 2221 2222 2222 if (channel->band == NL80211_BAND_60GHZ) { ··· 2235 2227 regulatory_hint_found_beacon(wiphy, channel, 2236 2228 gfp); 2237 2229 } 2230 + break; 2238 2231 } 2239 2232 2240 2233 /* ··· 2452 2443 profile, profile_len); 2453 2444 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || 2454 2445 mbssid_index_ie[2] == 0 || 2455 - mbssid_index_ie[2] > 46) { 2446 + mbssid_index_ie[2] > 46 || 2447 + mbssid_index_ie[2] >= (1 << elem->data[0])) { 2456 2448 /* No valid Multiple BSSID-Index element */ 2457 2449 continue; 2458 2450 } ··· 2665 2655 u8 param_ch_count; 2666 2656 u32 use_for; 2667 2657 u8 mld_id, link_id; 2658 + bool non_tx; 2668 2659 }; 2669 2660 2670 2661 static enum cfg80211_rnr_iter_ret ··· 2676 2665 const struct ieee80211_rnr_mld_params *mld_params; 2677 2666 struct tbtt_info_iter_data *data = _data; 2678 2667 u8 link_id; 2668 + bool non_tx = false; 2679 2669 2680 2670 if (type == IEEE80211_TBTT_INFO_TYPE_TBTT && 2681 2671 tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11, 2682 - mld_params)) 2683 - mld_params = (void *)(tbtt_info + 2684 - offsetof(struct ieee80211_tbtt_info_ge_11, 2685 - mld_params)); 2686 - else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && 2672 + mld_params)) { 2673 + const struct ieee80211_tbtt_info_ge_11 *tbtt_info_ge_11 = 2674 + (void *)tbtt_info; 2675 + 2676 + non_tx = (tbtt_info_ge_11->bss_params & 2677 + (IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID | 2678 + IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID)) == 2679 + IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID; 2680 + mld_params = &tbtt_info_ge_11->mld_params; 2681 + } else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && 2687 2682 tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params)) 2688 2683 mld_params = (void *)tbtt_info; 2689 2684 else ··· 2708 2691 data->param_ch_count = 2709 2692 le16_get_bits(mld_params->params, 2710 2693 IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); 2694 + data->non_tx = non_tx; 2711 2695 2712 2696 if (type == IEEE80211_TBTT_INFO_TYPE_TBTT) 2713 2697 data->use_for = NL80211_BSS_USE_FOR_ALL; ··· 2720 2702 static u8 2721 2703 cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, 2722 2704 const struct ieee80211_neighbor_ap_info **ap_info, 2723 - u8 *param_ch_count) 2705 + u8 *param_ch_count, bool *non_tx) 2724 2706 { 2725 2707 struct tbtt_info_iter_data data = { 2726 2708 .mld_id = mld_id, ··· 2731 2713 2732 2714 *ap_info = data.ap_info; 2733 2715 *param_ch_count = data.param_ch_count; 2716 + *non_tx = data.non_tx; 2734 2717 2735 2718 return data.use_for; 2736 2719 } ··· 2911 2892 ssize_t profile_len; 2912 2893 u8 param_ch_count; 2913 2894 u8 link_id, use_for; 2895 + bool non_tx; 2914 2896 2915 2897 if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i], 2916 2898 mle->sta_prof_len[i])) ··· 2957 2937 tx_data->ielen, 2958 2938 mld_id, link_id, 2959 2939 &ap_info, 2960 - &param_ch_count); 2940 + &param_ch_count, 2941 + &non_tx); 2961 2942 if (!use_for) 2943 + continue; 2944 + 2945 + /* 2946 + * As of 802.11be_D5.0, the specification does not give us any 2947 + * way of discovering both the MaxBSSID and the Multiple-BSSID 2948 + * Index. It does seem like the Multiple-BSSID Index element 2949 + * may be provided, but section 9.4.2.45 explicitly forbids 2950 + * including a Multiple-BSSID Element (in this case without any 2951 + * subelements). 2952 + * Without both pieces of information we cannot calculate the 2953 + * reference BSSID, so simply ignore the BSS. 2954 + */ 2955 + if (non_tx) 2962 2956 continue; 2963 2957 2964 2958 /* We could sanity check the BSSID is included */