diff options
106 files changed, 6783 insertions, 2249 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt index 7fd4e8ce4149..2196d1ab3c8c 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt | |||
| @@ -56,6 +56,11 @@ Optional properties: | |||
| 56 | the length can vary between hw versions. | 56 | the length can vary between hw versions. |
| 57 | - <supply-name>-supply: handle to the regulator device tree node | 57 | - <supply-name>-supply: handle to the regulator device tree node |
| 58 | optional "supply-name" is "vdd-0.8-cx-mx". | 58 | optional "supply-name" is "vdd-0.8-cx-mx". |
| 59 | - memory-region: | ||
| 60 | Usage: optional | ||
| 61 | Value type: <phandle> | ||
| 62 | Definition: reference to the reserved-memory for the msa region | ||
| 63 | used by the wifi firmware running in Q6. | ||
| 59 | 64 | ||
| 60 | Example (to supply the calibration data alone): | 65 | Example (to supply the calibration data alone): |
| 61 | 66 | ||
| @@ -149,4 +154,5 @@ wifi@18000000 { | |||
| 149 | <0 140 0 /* CE10 */ >, | 154 | <0 140 0 /* CE10 */ >, |
| 150 | <0 141 0 /* CE11 */ >; | 155 | <0 141 0 /* CE11 */ >; |
| 151 | vdd-0.8-cx-mx-supply = <&pm8998_l5>; | 156 | vdd-0.8-cx-mx-supply = <&pm8998_l5>; |
| 157 | memory-region = <&wifi_msa_mem>; | ||
| 152 | }; | 158 | }; |
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index 6572a43590a8..e1ad6b9166a6 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig | |||
| @@ -44,6 +44,7 @@ config ATH10K_SNOC | |||
| 44 | tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)" | 44 | tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)" |
| 45 | depends on ATH10K | 45 | depends on ATH10K |
| 46 | depends on ARCH_QCOM || COMPILE_TEST | 46 | depends on ARCH_QCOM || COMPILE_TEST |
| 47 | select QCOM_QMI_HELPERS | ||
| 47 | ---help--- | 48 | ---help--- |
| 48 | This module adds support for integrated WCN3990 chip connected | 49 | This module adds support for integrated WCN3990 chip connected |
| 49 | to system NOC(SNOC). Currently work in progress and will not | 50 | to system NOC(SNOC). Currently work in progress and will not |
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index 44d60a61b242..66326b949ab1 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile | |||
| @@ -36,7 +36,9 @@ obj-$(CONFIG_ATH10K_USB) += ath10k_usb.o | |||
| 36 | ath10k_usb-y += usb.o | 36 | ath10k_usb-y += usb.o |
| 37 | 37 | ||
| 38 | obj-$(CONFIG_ATH10K_SNOC) += ath10k_snoc.o | 38 | obj-$(CONFIG_ATH10K_SNOC) += ath10k_snoc.o |
| 39 | ath10k_snoc-y += snoc.o | 39 | ath10k_snoc-y += qmi.o \ |
| 40 | qmi_wlfw_v01.o \ | ||
| 41 | snoc.o | ||
| 40 | 42 | ||
| 41 | # for tracing framework to find trace.h | 43 | # for tracing framework to find trace.h |
| 42 | CFLAGS_trace.o := -I$(src) | 44 | CFLAGS_trace.o := -I$(src) |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 203f30992c26..da607febfd82 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
| @@ -989,7 +989,7 @@ static int ath10k_download_fw(struct ath10k *ar) | |||
| 989 | data, data_len); | 989 | data, data_len); |
| 990 | } | 990 | } |
| 991 | 991 | ||
| 992 | static void ath10k_core_free_board_files(struct ath10k *ar) | 992 | void ath10k_core_free_board_files(struct ath10k *ar) |
| 993 | { | 993 | { |
| 994 | if (!IS_ERR(ar->normal_mode_fw.board)) | 994 | if (!IS_ERR(ar->normal_mode_fw.board)) |
| 995 | release_firmware(ar->normal_mode_fw.board); | 995 | release_firmware(ar->normal_mode_fw.board); |
| @@ -1004,6 +1004,7 @@ static void ath10k_core_free_board_files(struct ath10k *ar) | |||
| 1004 | ar->normal_mode_fw.ext_board_data = NULL; | 1004 | ar->normal_mode_fw.ext_board_data = NULL; |
| 1005 | ar->normal_mode_fw.ext_board_len = 0; | 1005 | ar->normal_mode_fw.ext_board_len = 0; |
| 1006 | } | 1006 | } |
| 1007 | EXPORT_SYMBOL(ath10k_core_free_board_files); | ||
| 1007 | 1008 | ||
| 1008 | static void ath10k_core_free_firmware_files(struct ath10k *ar) | 1009 | static void ath10k_core_free_firmware_files(struct ath10k *ar) |
| 1009 | { | 1010 | { |
| @@ -1331,6 +1332,14 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name, | |||
| 1331 | goto out; | 1332 | goto out; |
| 1332 | } | 1333 | } |
| 1333 | 1334 | ||
| 1335 | if (ar->id.qmi_ids_valid) { | ||
| 1336 | scnprintf(name, name_len, | ||
| 1337 | "bus=%s,qmi-board-id=%x", | ||
| 1338 | ath10k_bus_str(ar->hif.bus), | ||
| 1339 | ar->id.qmi_board_id); | ||
| 1340 | goto out; | ||
| 1341 | } | ||
| 1342 | |||
| 1334 | scnprintf(name, name_len, | 1343 | scnprintf(name, name_len, |
| 1335 | "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s", | 1344 | "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s", |
| 1336 | ath10k_bus_str(ar->hif.bus), | 1345 | ath10k_bus_str(ar->hif.bus), |
| @@ -1359,7 +1368,7 @@ static int ath10k_core_create_eboard_name(struct ath10k *ar, char *name, | |||
| 1359 | return -1; | 1368 | return -1; |
| 1360 | } | 1369 | } |
| 1361 | 1370 | ||
| 1362 | static int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type) | 1371 | int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type) |
| 1363 | { | 1372 | { |
| 1364 | char boardname[100], fallback_boardname[100]; | 1373 | char boardname[100], fallback_boardname[100]; |
| 1365 | int ret; | 1374 | int ret; |
| @@ -1407,6 +1416,7 @@ success: | |||
| 1407 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api); | 1416 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api); |
| 1408 | return 0; | 1417 | return 0; |
| 1409 | } | 1418 | } |
| 1419 | EXPORT_SYMBOL(ath10k_core_fetch_board_file); | ||
| 1410 | 1420 | ||
| 1411 | static int ath10k_core_get_ext_board_id_from_otp(struct ath10k *ar) | 1421 | static int ath10k_core_get_ext_board_id_from_otp(struct ath10k *ar) |
| 1412 | { | 1422 | { |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index c76af343db3d..042418097cf9 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
| @@ -951,6 +951,7 @@ struct ath10k { | |||
| 951 | /* protected by conf_mutex */ | 951 | /* protected by conf_mutex */ |
| 952 | u8 ps_state_enable; | 952 | u8 ps_state_enable; |
| 953 | 953 | ||
| 954 | bool nlo_enabled; | ||
| 954 | bool p2p; | 955 | bool p2p; |
| 955 | 956 | ||
| 956 | struct { | 957 | struct { |
| @@ -988,6 +989,8 @@ struct ath10k { | |||
| 988 | u32 subsystem_device; | 989 | u32 subsystem_device; |
| 989 | 990 | ||
| 990 | bool bmi_ids_valid; | 991 | bool bmi_ids_valid; |
| 992 | bool qmi_ids_valid; | ||
| 993 | u32 qmi_board_id; | ||
| 991 | u8 bmi_board_id; | 994 | u8 bmi_board_id; |
| 992 | u8 bmi_eboard_id; | 995 | u8 bmi_eboard_id; |
| 993 | u8 bmi_chip_id; | 996 | u8 bmi_chip_id; |
| @@ -1215,5 +1218,7 @@ void ath10k_core_stop(struct ath10k *ar); | |||
| 1215 | int ath10k_core_register(struct ath10k *ar, | 1218 | int ath10k_core_register(struct ath10k *ar, |
| 1216 | const struct ath10k_bus_params *bus_params); | 1219 | const struct ath10k_bus_params *bus_params); |
| 1217 | void ath10k_core_unregister(struct ath10k *ar); | 1220 | void ath10k_core_unregister(struct ath10k *ar); |
| 1221 | int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type); | ||
| 1222 | void ath10k_core_free_board_files(struct ath10k *ar); | ||
| 1218 | 1223 | ||
| 1219 | #endif /* _CORE_H_ */ | 1224 | #endif /* _CORE_H_ */ |
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 2c0cb6757fc6..15964b374f68 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
| @@ -2421,7 +2421,7 @@ static ssize_t ath10k_write_ps_state_enable(struct file *file, | |||
| 2421 | if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable)) | 2421 | if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable)) |
| 2422 | return -EINVAL; | 2422 | return -EINVAL; |
| 2423 | 2423 | ||
| 2424 | if (ps_state_enable > 1 || ps_state_enable < 0) | 2424 | if (ps_state_enable > 1) |
| 2425 | return -EINVAL; | 2425 | return -EINVAL; |
| 2426 | 2426 | ||
| 2427 | mutex_lock(&ar->conf_mutex); | 2427 | mutex_lock(&ar->conf_mutex); |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 3a6191cff2f9..5cf16d690724 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
| @@ -44,6 +44,7 @@ enum ath10k_debug_mask { | |||
| 44 | ATH10K_DBG_USB = 0x00040000, | 44 | ATH10K_DBG_USB = 0x00040000, |
| 45 | ATH10K_DBG_USB_BULK = 0x00080000, | 45 | ATH10K_DBG_USB_BULK = 0x00080000, |
| 46 | ATH10K_DBG_SNOC = 0x00100000, | 46 | ATH10K_DBG_SNOC = 0x00100000, |
| 47 | ATH10K_DBG_QMI = 0x00200000, | ||
| 47 | ATH10K_DBG_ANY = 0xffffffff, | 48 | ATH10K_DBG_ANY = 0xffffffff, |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index f2405258a6d3..ffec98f7be50 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
| @@ -2680,8 +2680,6 @@ ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar, | |||
| 2680 | STATS_OP_FMT(RETRY).ht[1][ht_idx] += pstats->retry_pkts; | 2680 | STATS_OP_FMT(RETRY).ht[1][ht_idx] += pstats->retry_pkts; |
| 2681 | } else { | 2681 | } else { |
| 2682 | mcs = legacy_rate_idx; | 2682 | mcs = legacy_rate_idx; |
| 2683 | if (mcs < 0) | ||
| 2684 | return; | ||
| 2685 | 2683 | ||
| 2686 | STATS_OP_FMT(SUCC).legacy[0][mcs] += pstats->succ_bytes; | 2684 | STATS_OP_FMT(SUCC).legacy[0][mcs] += pstats->succ_bytes; |
| 2687 | STATS_OP_FMT(SUCC).legacy[1][mcs] += pstats->succ_pkts; | 2685 | STATS_OP_FMT(SUCC).legacy[1][mcs] += pstats->succ_pkts; |
| @@ -2753,7 +2751,8 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, | |||
| 2753 | struct ath10k_per_peer_tx_stats *peer_stats) | 2751 | struct ath10k_per_peer_tx_stats *peer_stats) |
| 2754 | { | 2752 | { |
| 2755 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; | 2753 | struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; |
| 2756 | u8 rate = 0, rate_idx = 0, sgi; | 2754 | u8 rate = 0, sgi; |
| 2755 | s8 rate_idx = 0; | ||
| 2757 | struct rate_info txrate; | 2756 | struct rate_info txrate; |
| 2758 | 2757 | ||
| 2759 | lockdep_assert_held(&ar->data_lock); | 2758 | lockdep_assert_held(&ar->data_lock); |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3933dd96da55..a1c2801ded10 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
| @@ -164,7 +164,7 @@ static int ath10k_mac_get_rate_hw_value(int bitrate) | |||
| 164 | if (ath10k_mac_bitrate_is_cck(bitrate)) | 164 | if (ath10k_mac_bitrate_is_cck(bitrate)) |
| 165 | hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6; | 165 | hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6; |
| 166 | 166 | ||
| 167 | for (i = 0; i < sizeof(ath10k_rates); i++) { | 167 | for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) { |
| 168 | if (ath10k_rates[i].bitrate == bitrate) | 168 | if (ath10k_rates[i].bitrate == bitrate) |
| 169 | return hw_value_prefix | ath10k_rates[i].hw_value; | 169 | return hw_value_prefix | ath10k_rates[i].hw_value; |
| 170 | } | 170 | } |
| @@ -4697,6 +4697,14 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
| 4697 | goto err_core_stop; | 4697 | goto err_core_stop; |
| 4698 | } | 4698 | } |
| 4699 | 4699 | ||
| 4700 | if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) { | ||
| 4701 | ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr); | ||
| 4702 | if (ret) { | ||
| 4703 | ath10k_err(ar, "failed to set prob req oui: %i\n", ret); | ||
| 4704 | goto err_core_stop; | ||
| 4705 | } | ||
| 4706 | } | ||
| 4707 | |||
| 4700 | if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) { | 4708 | if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) { |
| 4701 | ret = ath10k_wmi_adaptive_qcs(ar, true); | 4709 | ret = ath10k_wmi_adaptive_qcs(ar, true); |
| 4702 | if (ret) { | 4710 | if (ret) { |
| @@ -5682,22 +5690,22 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
| 5682 | return; | 5690 | return; |
| 5683 | } | 5691 | } |
| 5684 | 5692 | ||
| 5685 | sband = ar->hw->wiphy->bands[def.chan->band]; | 5693 | sband = ar->hw->wiphy->bands[def.chan->band]; |
| 5686 | basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; | 5694 | basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; |
| 5687 | bitrate = sband->bitrates[basic_rate_idx].bitrate; | 5695 | bitrate = sband->bitrates[basic_rate_idx].bitrate; |
| 5688 | 5696 | ||
| 5689 | hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate); | 5697 | hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate); |
| 5690 | if (hw_rate_code < 0) { | 5698 | if (hw_rate_code < 0) { |
| 5691 | ath10k_warn(ar, "bitrate not supported %d\n", bitrate); | 5699 | ath10k_warn(ar, "bitrate not supported %d\n", bitrate); |
| 5692 | mutex_unlock(&ar->conf_mutex); | 5700 | mutex_unlock(&ar->conf_mutex); |
| 5693 | return; | 5701 | return; |
| 5694 | } | 5702 | } |
| 5695 | 5703 | ||
| 5696 | vdev_param = ar->wmi.vdev_param->mgmt_rate; | 5704 | vdev_param = ar->wmi.vdev_param->mgmt_rate; |
| 5697 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 5705 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
| 5698 | hw_rate_code); | 5706 | hw_rate_code); |
| 5699 | if (ret) | 5707 | if (ret) |
| 5700 | ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret); | 5708 | ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret); |
| 5701 | } | 5709 | } |
| 5702 | 5710 | ||
| 5703 | mutex_unlock(&ar->conf_mutex); | 5711 | mutex_unlock(&ar->conf_mutex); |
| @@ -6855,9 +6863,20 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 6855 | u32 queues, bool drop) | 6863 | u32 queues, bool drop) |
| 6856 | { | 6864 | { |
| 6857 | struct ath10k *ar = hw->priv; | 6865 | struct ath10k *ar = hw->priv; |
| 6858 | 6866 | struct ath10k_vif *arvif; | |
| 6859 | if (drop) | 6867 | u32 bitmap; |
| 6868 | |||
| 6869 | if (drop) { | ||
| 6870 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
| 6871 | bitmap = ~(1 << WMI_MGMT_TID); | ||
| 6872 | list_for_each_entry(arvif, &ar->arvifs, list) { | ||
| 6873 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) | ||
| 6874 | ath10k_wmi_peer_flush(ar, arvif->vdev_id, | ||
| 6875 | arvif->bssid, bitmap); | ||
| 6876 | } | ||
| 6877 | } | ||
| 6860 | return; | 6878 | return; |
| 6879 | } | ||
| 6861 | 6880 | ||
| 6862 | mutex_lock(&ar->conf_mutex); | 6881 | mutex_lock(&ar->conf_mutex); |
| 6863 | ath10k_mac_wait_tx_complete(ar); | 6882 | ath10k_mac_wait_tx_complete(ar); |
| @@ -8493,6 +8512,18 @@ int ath10k_mac_register(struct ath10k *ar) | |||
| 8493 | ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID; | 8512 | ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID; |
| 8494 | ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN; | 8513 | ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN; |
| 8495 | 8514 | ||
| 8515 | if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) { | ||
| 8516 | ar->hw->wiphy->max_sched_scan_reqs = 1; | ||
| 8517 | ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS; | ||
| 8518 | ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS; | ||
| 8519 | ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH; | ||
| 8520 | ar->hw->wiphy->max_sched_scan_plans = WMI_PNO_MAX_SCHED_SCAN_PLANS; | ||
| 8521 | ar->hw->wiphy->max_sched_scan_plan_interval = | ||
| 8522 | WMI_PNO_MAX_SCHED_SCAN_PLAN_INT; | ||
| 8523 | ar->hw->wiphy->max_sched_scan_plan_iterations = | ||
| 8524 | WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS; | ||
| 8525 | } | ||
| 8526 | |||
| 8496 | ar->hw->vif_data_size = sizeof(struct ath10k_vif); | 8527 | ar->hw->vif_data_size = sizeof(struct ath10k_vif); |
| 8497 | ar->hw->sta_data_size = sizeof(struct ath10k_sta); | 8528 | ar->hw->sta_data_size = sizeof(struct ath10k_sta); |
| 8498 | ar->hw->txq_data_size = sizeof(struct ath10k_txq); | 8529 | ar->hw->txq_data_size = sizeof(struct ath10k_txq); |
| @@ -8542,9 +8573,10 @@ int ath10k_mac_register(struct ath10k *ar) | |||
| 8542 | wiphy_ext_feature_set(ar->hw->wiphy, | 8573 | wiphy_ext_feature_set(ar->hw->wiphy, |
| 8543 | NL80211_EXT_FEATURE_SET_SCAN_DWELL); | 8574 | NL80211_EXT_FEATURE_SET_SCAN_DWELL); |
| 8544 | 8575 | ||
| 8545 | if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map)) | 8576 | if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) || |
| 8577 | test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map)) | ||
| 8546 | wiphy_ext_feature_set(ar->hw->wiphy, | 8578 | wiphy_ext_feature_set(ar->hw->wiphy, |
| 8547 | NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT); | 8579 | NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); |
| 8548 | 8580 | ||
| 8549 | /* | 8581 | /* |
| 8550 | * on LL hardware queues are managed entirely by the FW | 8582 | * on LL hardware queues are managed entirely by the FW |
| @@ -8635,12 +8667,6 @@ int ath10k_mac_register(struct ath10k *ar) | |||
| 8635 | } | 8667 | } |
| 8636 | 8668 | ||
| 8637 | if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) { | 8669 | if (test_bit(WMI_SERVICE_SPOOF_MAC_SUPPORT, ar->wmi.svc_map)) { |
| 8638 | ret = ath10k_wmi_scan_prob_req_oui(ar, ar->mac_addr); | ||
| 8639 | if (ret) { | ||
| 8640 | ath10k_err(ar, "failed to set prob req oui: %i\n", ret); | ||
| 8641 | goto err_dfs_detector_exit; | ||
| 8642 | } | ||
| 8643 | |||
| 8644 | ar->hw->wiphy->features |= | 8670 | ar->hw->wiphy->features |= |
| 8645 | NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; | 8671 | NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; |
| 8646 | } | 8672 | } |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 873dbb65439f..01b4edb00e9e 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
| @@ -1071,10 +1071,9 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1071 | struct ath10k_ce *ce = ath10k_ce_priv(ar); | 1071 | struct ath10k_ce *ce = ath10k_ce_priv(ar); |
| 1072 | int ret = 0; | 1072 | int ret = 0; |
| 1073 | u32 *buf; | 1073 | u32 *buf; |
| 1074 | unsigned int completed_nbytes, orig_nbytes, remaining_bytes; | 1074 | unsigned int completed_nbytes, alloc_nbytes, remaining_bytes; |
| 1075 | struct ath10k_ce_pipe *ce_diag; | 1075 | struct ath10k_ce_pipe *ce_diag; |
| 1076 | void *data_buf = NULL; | 1076 | void *data_buf = NULL; |
| 1077 | u32 ce_data; /* Host buffer address in CE space */ | ||
| 1078 | dma_addr_t ce_data_base = 0; | 1077 | dma_addr_t ce_data_base = 0; |
| 1079 | int i; | 1078 | int i; |
| 1080 | 1079 | ||
| @@ -1088,9 +1087,10 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1088 | * 1) 4-byte alignment | 1087 | * 1) 4-byte alignment |
| 1089 | * 2) Buffer in DMA-able space | 1088 | * 2) Buffer in DMA-able space |
| 1090 | */ | 1089 | */ |
| 1091 | orig_nbytes = nbytes; | 1090 | alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT); |
| 1091 | |||
| 1092 | data_buf = (unsigned char *)dma_alloc_coherent(ar->dev, | 1092 | data_buf = (unsigned char *)dma_alloc_coherent(ar->dev, |
| 1093 | orig_nbytes, | 1093 | alloc_nbytes, |
| 1094 | &ce_data_base, | 1094 | &ce_data_base, |
| 1095 | GFP_ATOMIC); | 1095 | GFP_ATOMIC); |
| 1096 | if (!data_buf) { | 1096 | if (!data_buf) { |
| @@ -1098,9 +1098,6 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1098 | goto done; | 1098 | goto done; |
| 1099 | } | 1099 | } |
| 1100 | 1100 | ||
| 1101 | /* Copy caller's data to allocated DMA buf */ | ||
| 1102 | memcpy(data_buf, data, orig_nbytes); | ||
| 1103 | |||
| 1104 | /* | 1101 | /* |
| 1105 | * The address supplied by the caller is in the | 1102 | * The address supplied by the caller is in the |
| 1106 | * Target CPU virtual address space. | 1103 | * Target CPU virtual address space. |
| @@ -1113,12 +1110,14 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1113 | */ | 1110 | */ |
| 1114 | address = ath10k_pci_targ_cpu_to_ce_addr(ar, address); | 1111 | address = ath10k_pci_targ_cpu_to_ce_addr(ar, address); |
| 1115 | 1112 | ||
| 1116 | remaining_bytes = orig_nbytes; | 1113 | remaining_bytes = nbytes; |
| 1117 | ce_data = ce_data_base; | ||
| 1118 | while (remaining_bytes) { | 1114 | while (remaining_bytes) { |
| 1119 | /* FIXME: check cast */ | 1115 | /* FIXME: check cast */ |
| 1120 | nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); | 1116 | nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); |
| 1121 | 1117 | ||
| 1118 | /* Copy caller's data to allocated DMA buf */ | ||
| 1119 | memcpy(data_buf, data, nbytes); | ||
| 1120 | |||
| 1122 | /* Set up to receive directly into Target(!) address */ | 1121 | /* Set up to receive directly into Target(!) address */ |
| 1123 | ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address); | 1122 | ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address); |
| 1124 | if (ret != 0) | 1123 | if (ret != 0) |
| @@ -1128,7 +1127,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1128 | * Request CE to send caller-supplied data that | 1127 | * Request CE to send caller-supplied data that |
| 1129 | * was copied to bounce buffer to Target(!) address. | 1128 | * was copied to bounce buffer to Target(!) address. |
| 1130 | */ | 1129 | */ |
| 1131 | ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data, | 1130 | ret = ath10k_ce_send_nolock(ce_diag, NULL, ce_data_base, |
| 1132 | nbytes, 0, 0); | 1131 | nbytes, 0, 0); |
| 1133 | if (ret != 0) | 1132 | if (ret != 0) |
| 1134 | goto done; | 1133 | goto done; |
| @@ -1171,12 +1170,12 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
| 1171 | 1170 | ||
| 1172 | remaining_bytes -= nbytes; | 1171 | remaining_bytes -= nbytes; |
| 1173 | address += nbytes; | 1172 | address += nbytes; |
| 1174 | ce_data += nbytes; | 1173 | data += nbytes; |
| 1175 | } | 1174 | } |
| 1176 | 1175 | ||
| 1177 | done: | 1176 | done: |
| 1178 | if (data_buf) { | 1177 | if (data_buf) { |
| 1179 | dma_free_coherent(ar->dev, orig_nbytes, data_buf, | 1178 | dma_free_coherent(ar->dev, alloc_nbytes, data_buf, |
| 1180 | ce_data_base); | 1179 | ce_data_base); |
| 1181 | } | 1180 | } |
| 1182 | 1181 | ||
diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c new file mode 100644 index 000000000000..56cb1831dcdf --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/qmi.c | |||
| @@ -0,0 +1,1019 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2018 The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/completion.h> | ||
| 18 | #include <linux/device.h> | ||
| 19 | #include <linux/debugfs.h> | ||
| 20 | #include <linux/idr.h> | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/net.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/qcom_scm.h> | ||
| 28 | #include <linux/string.h> | ||
| 29 | #include <net/sock.h> | ||
| 30 | |||
| 31 | #include "debug.h" | ||
| 32 | #include "snoc.h" | ||
| 33 | |||
| 34 | #define ATH10K_QMI_CLIENT_ID 0x4b4e454c | ||
| 35 | #define ATH10K_QMI_TIMEOUT 30 | ||
| 36 | |||
| 37 | static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi, | ||
| 38 | struct ath10k_msa_mem_info *mem_info) | ||
| 39 | { | ||
| 40 | struct qcom_scm_vmperm dst_perms[3]; | ||
| 41 | struct ath10k *ar = qmi->ar; | ||
| 42 | unsigned int src_perms; | ||
| 43 | u32 perm_count; | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | src_perms = BIT(QCOM_SCM_VMID_HLOS); | ||
| 47 | |||
| 48 | dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA; | ||
| 49 | dst_perms[0].perm = QCOM_SCM_PERM_RW; | ||
| 50 | dst_perms[1].vmid = QCOM_SCM_VMID_WLAN; | ||
| 51 | dst_perms[1].perm = QCOM_SCM_PERM_RW; | ||
| 52 | |||
| 53 | if (mem_info->secure) { | ||
| 54 | perm_count = 2; | ||
| 55 | } else { | ||
| 56 | dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE; | ||
| 57 | dst_perms[2].perm = QCOM_SCM_PERM_RW; | ||
| 58 | perm_count = 3; | ||
| 59 | } | ||
| 60 | |||
| 61 | ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size, | ||
| 62 | &src_perms, dst_perms, perm_count); | ||
| 63 | if (ret < 0) | ||
| 64 | ath10k_err(ar, "failed to assign msa map permissions: %d\n", ret); | ||
| 65 | |||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int ath10k_qmi_unmap_msa_permission(struct ath10k_qmi *qmi, | ||
| 70 | struct ath10k_msa_mem_info *mem_info) | ||
| 71 | { | ||
| 72 | struct qcom_scm_vmperm dst_perms; | ||
| 73 | struct ath10k *ar = qmi->ar; | ||
| 74 | unsigned int src_perms; | ||
| 75 | int ret; | ||
| 76 | |||
| 77 | src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN); | ||
| 78 | |||
| 79 | if (!mem_info->secure) | ||
| 80 | src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE); | ||
| 81 | |||
| 82 | dst_perms.vmid = QCOM_SCM_VMID_HLOS; | ||
| 83 | dst_perms.perm = QCOM_SCM_PERM_RW; | ||
| 84 | |||
| 85 | ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size, | ||
| 86 | &src_perms, &dst_perms, 1); | ||
| 87 | if (ret < 0) | ||
| 88 | ath10k_err(ar, "failed to unmap msa permissions: %d\n", ret); | ||
| 89 | |||
| 90 | return ret; | ||
| 91 | } | ||
| 92 | |||
| 93 | static int ath10k_qmi_setup_msa_permissions(struct ath10k_qmi *qmi) | ||
| 94 | { | ||
| 95 | int ret; | ||
| 96 | int i; | ||
| 97 | |||
| 98 | for (i = 0; i < qmi->nr_mem_region; i++) { | ||
| 99 | ret = ath10k_qmi_map_msa_permission(qmi, &qmi->mem_region[i]); | ||
| 100 | if (ret) | ||
| 101 | goto err_unmap; | ||
| 102 | } | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | |||
| 106 | err_unmap: | ||
| 107 | for (i--; i >= 0; i--) | ||
| 108 | ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]); | ||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void ath10k_qmi_remove_msa_permission(struct ath10k_qmi *qmi) | ||
| 113 | { | ||
| 114 | int i; | ||
| 115 | |||
| 116 | for (i = 0; i < qmi->nr_mem_region; i++) | ||
| 117 | ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]); | ||
| 118 | } | ||
| 119 | |||
| 120 | static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi) | ||
| 121 | { | ||
| 122 | struct wlfw_msa_info_resp_msg_v01 resp = {}; | ||
| 123 | struct wlfw_msa_info_req_msg_v01 req = {}; | ||
| 124 | struct ath10k *ar = qmi->ar; | ||
| 125 | struct qmi_txn txn; | ||
| 126 | int ret; | ||
| 127 | int i; | ||
| 128 | |||
| 129 | req.msa_addr = qmi->msa_pa; | ||
| 130 | req.size = qmi->msa_mem_size; | ||
| 131 | |||
| 132 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 133 | wlfw_msa_info_resp_msg_v01_ei, &resp); | ||
| 134 | if (ret < 0) | ||
| 135 | goto out; | ||
| 136 | |||
| 137 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 138 | QMI_WLFW_MSA_INFO_REQ_V01, | ||
| 139 | WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 140 | wlfw_msa_info_req_msg_v01_ei, &req); | ||
| 141 | if (ret < 0) { | ||
| 142 | qmi_txn_cancel(&txn); | ||
| 143 | ath10k_err(ar, "failed to send msa mem info req: %d\n", ret); | ||
| 144 | goto out; | ||
| 145 | } | ||
| 146 | |||
| 147 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 148 | if (ret < 0) | ||
| 149 | goto out; | ||
| 150 | |||
| 151 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 152 | ath10k_err(ar, "msa info req rejected: %d\n", resp.resp.error); | ||
| 153 | ret = -EINVAL; | ||
| 154 | goto out; | ||
| 155 | } | ||
| 156 | |||
| 157 | if (resp.mem_region_info_len > QMI_WLFW_MAX_MEM_REG_V01) { | ||
| 158 | ath10k_err(ar, "invalid memory region length received: %d\n", | ||
| 159 | resp.mem_region_info_len); | ||
| 160 | ret = -EINVAL; | ||
| 161 | goto out; | ||
| 162 | } | ||
| 163 | |||
| 164 | qmi->nr_mem_region = resp.mem_region_info_len; | ||
| 165 | for (i = 0; i < resp.mem_region_info_len; i++) { | ||
| 166 | qmi->mem_region[i].addr = resp.mem_region_info[i].region_addr; | ||
| 167 | qmi->mem_region[i].size = resp.mem_region_info[i].size; | ||
| 168 | qmi->mem_region[i].secure = resp.mem_region_info[i].secure_flag; | ||
| 169 | ath10k_dbg(ar, ATH10K_DBG_QMI, | ||
| 170 | "qmi msa mem region %d addr 0x%pa size 0x%x flag 0x%08x\n", | ||
| 171 | i, &qmi->mem_region[i].addr, | ||
| 172 | qmi->mem_region[i].size, | ||
| 173 | qmi->mem_region[i].secure); | ||
| 174 | } | ||
| 175 | |||
| 176 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem info request completed\n"); | ||
| 177 | return 0; | ||
| 178 | |||
| 179 | out: | ||
| 180 | return ret; | ||
| 181 | } | ||
| 182 | |||
| 183 | static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) | ||
| 184 | { | ||
| 185 | struct wlfw_msa_ready_resp_msg_v01 resp = {}; | ||
| 186 | struct wlfw_msa_ready_req_msg_v01 req = {}; | ||
| 187 | struct ath10k *ar = qmi->ar; | ||
| 188 | struct qmi_txn txn; | ||
| 189 | int ret; | ||
| 190 | |||
| 191 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 192 | wlfw_msa_ready_resp_msg_v01_ei, &resp); | ||
| 193 | if (ret < 0) | ||
| 194 | goto out; | ||
| 195 | |||
| 196 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 197 | QMI_WLFW_MSA_READY_REQ_V01, | ||
| 198 | WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 199 | wlfw_msa_ready_req_msg_v01_ei, &req); | ||
| 200 | if (ret < 0) { | ||
| 201 | qmi_txn_cancel(&txn); | ||
| 202 | ath10k_err(ar, "failed to send msa mem ready request: %d\n", ret); | ||
| 203 | goto out; | ||
| 204 | } | ||
| 205 | |||
| 206 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 207 | if (ret < 0) | ||
| 208 | goto out; | ||
| 209 | |||
| 210 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 211 | ath10k_err(ar, "msa ready request rejected: %d\n", resp.resp.error); | ||
| 212 | ret = -EINVAL; | ||
| 213 | } | ||
| 214 | |||
| 215 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem ready request completed\n"); | ||
| 216 | return 0; | ||
| 217 | |||
| 218 | out: | ||
| 219 | return ret; | ||
| 220 | } | ||
| 221 | |||
| 222 | static int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi) | ||
| 223 | { | ||
| 224 | struct wlfw_bdf_download_resp_msg_v01 resp = {}; | ||
| 225 | struct wlfw_bdf_download_req_msg_v01 *req; | ||
| 226 | struct ath10k *ar = qmi->ar; | ||
| 227 | unsigned int remaining; | ||
| 228 | struct qmi_txn txn; | ||
| 229 | const u8 *temp; | ||
| 230 | int ret; | ||
| 231 | |||
| 232 | req = kzalloc(sizeof(*req), GFP_KERNEL); | ||
| 233 | if (!req) | ||
| 234 | return -ENOMEM; | ||
| 235 | |||
| 236 | temp = ar->normal_mode_fw.board_data; | ||
| 237 | remaining = ar->normal_mode_fw.board_len; | ||
| 238 | |||
| 239 | while (remaining) { | ||
| 240 | req->valid = 1; | ||
| 241 | req->file_id_valid = 1; | ||
| 242 | req->file_id = 0; | ||
| 243 | req->total_size_valid = 1; | ||
| 244 | req->total_size = ar->normal_mode_fw.board_len; | ||
| 245 | req->seg_id_valid = 1; | ||
| 246 | req->data_valid = 1; | ||
| 247 | req->end_valid = 1; | ||
| 248 | |||
| 249 | if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) { | ||
| 250 | req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01; | ||
| 251 | } else { | ||
| 252 | req->data_len = remaining; | ||
| 253 | req->end = 1; | ||
| 254 | } | ||
| 255 | |||
| 256 | memcpy(req->data, temp, req->data_len); | ||
| 257 | |||
| 258 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 259 | wlfw_bdf_download_resp_msg_v01_ei, | ||
| 260 | &resp); | ||
| 261 | if (ret < 0) | ||
| 262 | goto out; | ||
| 263 | |||
| 264 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 265 | QMI_WLFW_BDF_DOWNLOAD_REQ_V01, | ||
| 266 | WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 267 | wlfw_bdf_download_req_msg_v01_ei, req); | ||
| 268 | if (ret < 0) { | ||
| 269 | qmi_txn_cancel(&txn); | ||
| 270 | goto out; | ||
| 271 | } | ||
| 272 | |||
| 273 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 274 | |||
| 275 | if (ret < 0) | ||
| 276 | goto out; | ||
| 277 | |||
| 278 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 279 | ath10k_err(ar, "failed to download board data file: %d\n", | ||
| 280 | resp.resp.error); | ||
| 281 | ret = -EINVAL; | ||
| 282 | goto out; | ||
| 283 | } | ||
| 284 | |||
| 285 | remaining -= req->data_len; | ||
| 286 | temp += req->data_len; | ||
| 287 | req->seg_id++; | ||
| 288 | } | ||
| 289 | |||
| 290 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi bdf download request completed\n"); | ||
| 291 | |||
| 292 | kfree(req); | ||
| 293 | return 0; | ||
| 294 | |||
| 295 | out: | ||
| 296 | kfree(req); | ||
| 297 | return ret; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi) | ||
| 301 | { | ||
| 302 | struct wlfw_cal_report_resp_msg_v01 resp = {}; | ||
| 303 | struct wlfw_cal_report_req_msg_v01 req = {}; | ||
| 304 | struct ath10k *ar = qmi->ar; | ||
| 305 | struct qmi_txn txn; | ||
| 306 | int i, j = 0; | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cal_report_resp_msg_v01_ei, | ||
| 310 | &resp); | ||
| 311 | if (ret < 0) | ||
| 312 | goto out; | ||
| 313 | |||
| 314 | for (i = 0; i < QMI_WLFW_MAX_NUM_CAL_V01; i++) { | ||
| 315 | if (qmi->cal_data[i].total_size && | ||
| 316 | qmi->cal_data[i].data) { | ||
| 317 | req.meta_data[j] = qmi->cal_data[i].cal_id; | ||
| 318 | j++; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | req.meta_data_len = j; | ||
| 322 | |||
| 323 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 324 | QMI_WLFW_CAL_REPORT_REQ_V01, | ||
| 325 | WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 326 | wlfw_cal_report_req_msg_v01_ei, &req); | ||
| 327 | if (ret < 0) { | ||
| 328 | qmi_txn_cancel(&txn); | ||
| 329 | ath10k_err(ar, "failed to send calibration request: %d\n", ret); | ||
| 330 | goto out; | ||
| 331 | } | ||
| 332 | |||
| 333 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 334 | if (ret < 0) | ||
| 335 | goto out; | ||
| 336 | |||
| 337 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 338 | ath10k_err(ar, "calibration request rejected: %d\n", resp.resp.error); | ||
| 339 | ret = -EINVAL; | ||
| 340 | goto out; | ||
| 341 | } | ||
| 342 | |||
| 343 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi cal report request completed\n"); | ||
| 344 | return 0; | ||
| 345 | |||
| 346 | out: | ||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | static int | ||
| 351 | ath10k_qmi_mode_send_sync_msg(struct ath10k *ar, enum wlfw_driver_mode_enum_v01 mode) | ||
| 352 | { | ||
| 353 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | ||
| 354 | struct ath10k_qmi *qmi = ar_snoc->qmi; | ||
| 355 | struct wlfw_wlan_mode_resp_msg_v01 resp = {}; | ||
| 356 | struct wlfw_wlan_mode_req_msg_v01 req = {}; | ||
| 357 | struct qmi_txn txn; | ||
| 358 | int ret; | ||
| 359 | |||
| 360 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 361 | wlfw_wlan_mode_resp_msg_v01_ei, | ||
| 362 | &resp); | ||
| 363 | if (ret < 0) | ||
| 364 | goto out; | ||
| 365 | |||
| 366 | req.mode = mode; | ||
| 367 | req.hw_debug_valid = 1; | ||
| 368 | req.hw_debug = 0; | ||
| 369 | |||
| 370 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 371 | QMI_WLFW_WLAN_MODE_REQ_V01, | ||
| 372 | WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 373 | wlfw_wlan_mode_req_msg_v01_ei, &req); | ||
| 374 | if (ret < 0) { | ||
| 375 | qmi_txn_cancel(&txn); | ||
| 376 | ath10k_err(ar, "failed to send wlan mode %d request: %d\n", mode, ret); | ||
| 377 | goto out; | ||
| 378 | } | ||
| 379 | |||
| 380 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 381 | if (ret < 0) | ||
| 382 | goto out; | ||
| 383 | |||
| 384 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 385 | ath10k_err(ar, "more request rejected: %d\n", resp.resp.error); | ||
| 386 | ret = -EINVAL; | ||
| 387 | goto out; | ||
| 388 | } | ||
| 389 | |||
| 390 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wlan mode req completed: %d\n", mode); | ||
| 391 | return 0; | ||
| 392 | |||
| 393 | out: | ||
| 394 | return ret; | ||
| 395 | } | ||
| 396 | |||
| 397 | static int | ||
| 398 | ath10k_qmi_cfg_send_sync_msg(struct ath10k *ar, | ||
| 399 | struct ath10k_qmi_wlan_enable_cfg *config, | ||
| 400 | const char *version) | ||
| 401 | { | ||
| 402 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | ||
| 403 | struct ath10k_qmi *qmi = ar_snoc->qmi; | ||
| 404 | struct wlfw_wlan_cfg_resp_msg_v01 resp = {}; | ||
| 405 | struct wlfw_wlan_cfg_req_msg_v01 *req; | ||
| 406 | struct qmi_txn txn; | ||
| 407 | int ret; | ||
| 408 | u32 i; | ||
| 409 | |||
| 410 | req = kzalloc(sizeof(*req), GFP_KERNEL); | ||
| 411 | if (!req) | ||
| 412 | return -ENOMEM; | ||
| 413 | |||
| 414 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 415 | wlfw_wlan_cfg_resp_msg_v01_ei, | ||
| 416 | &resp); | ||
| 417 | if (ret < 0) | ||
| 418 | goto out; | ||
| 419 | |||
| 420 | req->host_version_valid = 0; | ||
| 421 | |||
| 422 | req->tgt_cfg_valid = 1; | ||
| 423 | if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01) | ||
| 424 | req->tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01; | ||
| 425 | else | ||
| 426 | req->tgt_cfg_len = config->num_ce_tgt_cfg; | ||
| 427 | for (i = 0; i < req->tgt_cfg_len; i++) { | ||
| 428 | req->tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num; | ||
| 429 | req->tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir; | ||
| 430 | req->tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries; | ||
| 431 | req->tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max; | ||
| 432 | req->tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags; | ||
| 433 | } | ||
| 434 | |||
| 435 | req->svc_cfg_valid = 1; | ||
| 436 | if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01) | ||
| 437 | req->svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01; | ||
| 438 | else | ||
| 439 | req->svc_cfg_len = config->num_ce_svc_pipe_cfg; | ||
| 440 | for (i = 0; i < req->svc_cfg_len; i++) { | ||
| 441 | req->svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id; | ||
| 442 | req->svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir; | ||
| 443 | req->svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num; | ||
| 444 | } | ||
| 445 | |||
| 446 | req->shadow_reg_valid = 1; | ||
| 447 | if (config->num_shadow_reg_cfg > | ||
| 448 | QMI_WLFW_MAX_NUM_SHADOW_REG_V01) | ||
| 449 | req->shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01; | ||
| 450 | else | ||
| 451 | req->shadow_reg_len = config->num_shadow_reg_cfg; | ||
| 452 | |||
| 453 | memcpy(req->shadow_reg, config->shadow_reg_cfg, | ||
| 454 | sizeof(struct wlfw_shadow_reg_cfg_s_v01) * req->shadow_reg_len); | ||
| 455 | |||
| 456 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 457 | QMI_WLFW_WLAN_CFG_REQ_V01, | ||
| 458 | WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 459 | wlfw_wlan_cfg_req_msg_v01_ei, req); | ||
| 460 | if (ret < 0) { | ||
| 461 | qmi_txn_cancel(&txn); | ||
| 462 | ath10k_err(ar, "failed to send config request: %d\n", ret); | ||
| 463 | goto out; | ||
| 464 | } | ||
| 465 | |||
| 466 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 467 | if (ret < 0) | ||
| 468 | goto out; | ||
| 469 | |||
| 470 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 471 | ath10k_err(ar, "config request rejected: %d\n", resp.resp.error); | ||
| 472 | ret = -EINVAL; | ||
| 473 | goto out; | ||
| 474 | } | ||
| 475 | |||
| 476 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi config request completed\n"); | ||
| 477 | kfree(req); | ||
| 478 | return 0; | ||
| 479 | |||
| 480 | out: | ||
| 481 | kfree(req); | ||
| 482 | return ret; | ||
| 483 | } | ||
| 484 | |||
| 485 | int ath10k_qmi_wlan_enable(struct ath10k *ar, | ||
| 486 | struct ath10k_qmi_wlan_enable_cfg *config, | ||
| 487 | enum wlfw_driver_mode_enum_v01 mode, | ||
| 488 | const char *version) | ||
| 489 | { | ||
| 490 | int ret; | ||
| 491 | |||
| 492 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi mode %d config %p\n", | ||
| 493 | mode, config); | ||
| 494 | |||
| 495 | ret = ath10k_qmi_cfg_send_sync_msg(ar, config, version); | ||
| 496 | if (ret) { | ||
| 497 | ath10k_err(ar, "failed to send qmi config: %d\n", ret); | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | |||
| 501 | ret = ath10k_qmi_mode_send_sync_msg(ar, mode); | ||
| 502 | if (ret) { | ||
| 503 | ath10k_err(ar, "failed to send qmi mode: %d\n", ret); | ||
| 504 | return ret; | ||
| 505 | } | ||
| 506 | |||
| 507 | return 0; | ||
| 508 | } | ||
| 509 | |||
| 510 | int ath10k_qmi_wlan_disable(struct ath10k *ar) | ||
| 511 | { | ||
| 512 | return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01); | ||
| 513 | } | ||
| 514 | |||
| 515 | static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) | ||
| 516 | { | ||
| 517 | struct wlfw_cap_resp_msg_v01 *resp; | ||
| 518 | struct wlfw_cap_req_msg_v01 req = {}; | ||
| 519 | struct ath10k *ar = qmi->ar; | ||
| 520 | struct qmi_txn txn; | ||
| 521 | int ret; | ||
| 522 | |||
| 523 | resp = kzalloc(sizeof(*resp), GFP_KERNEL); | ||
| 524 | if (!resp) | ||
| 525 | return -ENOMEM; | ||
| 526 | |||
| 527 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp); | ||
| 528 | if (ret < 0) | ||
| 529 | goto out; | ||
| 530 | |||
| 531 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 532 | QMI_WLFW_CAP_REQ_V01, | ||
| 533 | WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 534 | wlfw_cap_req_msg_v01_ei, &req); | ||
| 535 | if (ret < 0) { | ||
| 536 | qmi_txn_cancel(&txn); | ||
| 537 | ath10k_err(ar, "failed to send capability request: %d\n", ret); | ||
| 538 | goto out; | ||
| 539 | } | ||
| 540 | |||
| 541 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 542 | if (ret < 0) | ||
| 543 | goto out; | ||
| 544 | |||
| 545 | if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 546 | ath10k_err(ar, "capablity req rejected: %d\n", resp->resp.error); | ||
| 547 | ret = -EINVAL; | ||
| 548 | goto out; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (resp->chip_info_valid) { | ||
| 552 | qmi->chip_info.chip_id = resp->chip_info.chip_id; | ||
| 553 | qmi->chip_info.chip_family = resp->chip_info.chip_family; | ||
| 554 | } | ||
| 555 | |||
| 556 | if (resp->board_info_valid) | ||
| 557 | qmi->board_info.board_id = resp->board_info.board_id; | ||
| 558 | else | ||
| 559 | qmi->board_info.board_id = 0xFF; | ||
| 560 | |||
| 561 | if (resp->soc_info_valid) | ||
| 562 | qmi->soc_info.soc_id = resp->soc_info.soc_id; | ||
| 563 | |||
| 564 | if (resp->fw_version_info_valid) { | ||
| 565 | qmi->fw_version = resp->fw_version_info.fw_version; | ||
| 566 | strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp, | ||
| 567 | sizeof(qmi->fw_build_timestamp)); | ||
| 568 | } | ||
| 569 | |||
| 570 | if (resp->fw_build_id_valid) | ||
| 571 | strlcpy(qmi->fw_build_id, resp->fw_build_id, | ||
| 572 | MAX_BUILD_ID_LEN + 1); | ||
| 573 | |||
| 574 | ath10k_dbg(ar, ATH10K_DBG_QMI, | ||
| 575 | "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x", | ||
| 576 | qmi->chip_info.chip_id, qmi->chip_info.chip_family, | ||
| 577 | qmi->board_info.board_id, qmi->soc_info.soc_id); | ||
| 578 | ath10k_dbg(ar, ATH10K_DBG_QMI, | ||
| 579 | "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s", | ||
| 580 | qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id); | ||
| 581 | |||
| 582 | kfree(resp); | ||
| 583 | return 0; | ||
| 584 | |||
| 585 | out: | ||
| 586 | kfree(resp); | ||
| 587 | return ret; | ||
| 588 | } | ||
| 589 | |||
| 590 | static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi) | ||
| 591 | { | ||
| 592 | struct wlfw_host_cap_resp_msg_v01 resp = {}; | ||
| 593 | struct wlfw_host_cap_req_msg_v01 req = {}; | ||
| 594 | struct ath10k *ar = qmi->ar; | ||
| 595 | struct qmi_txn txn; | ||
| 596 | int ret; | ||
| 597 | |||
| 598 | req.daemon_support_valid = 1; | ||
| 599 | req.daemon_support = 0; | ||
| 600 | |||
| 601 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 602 | wlfw_host_cap_resp_msg_v01_ei, &resp); | ||
| 603 | if (ret < 0) | ||
| 604 | goto out; | ||
| 605 | |||
| 606 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 607 | QMI_WLFW_HOST_CAP_REQ_V01, | ||
| 608 | WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 609 | wlfw_host_cap_req_msg_v01_ei, &req); | ||
| 610 | if (ret < 0) { | ||
| 611 | qmi_txn_cancel(&txn); | ||
| 612 | ath10k_err(ar, "failed to send host capability request: %d\n", ret); | ||
| 613 | goto out; | ||
| 614 | } | ||
| 615 | |||
| 616 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 617 | if (ret < 0) | ||
| 618 | goto out; | ||
| 619 | |||
| 620 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 621 | ath10k_err(ar, "host capability request rejected: %d\n", resp.resp.error); | ||
| 622 | ret = -EINVAL; | ||
| 623 | goto out; | ||
| 624 | } | ||
| 625 | |||
| 626 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi host capablity request completed\n"); | ||
| 627 | return 0; | ||
| 628 | |||
| 629 | out: | ||
| 630 | return ret; | ||
| 631 | } | ||
| 632 | |||
| 633 | static int | ||
| 634 | ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi) | ||
| 635 | { | ||
| 636 | struct wlfw_ind_register_resp_msg_v01 resp = {}; | ||
| 637 | struct wlfw_ind_register_req_msg_v01 req = {}; | ||
| 638 | struct ath10k *ar = qmi->ar; | ||
| 639 | struct qmi_txn txn; | ||
| 640 | int ret; | ||
| 641 | |||
| 642 | req.client_id_valid = 1; | ||
| 643 | req.client_id = ATH10K_QMI_CLIENT_ID; | ||
| 644 | req.fw_ready_enable_valid = 1; | ||
| 645 | req.fw_ready_enable = 1; | ||
| 646 | req.msa_ready_enable_valid = 1; | ||
| 647 | req.msa_ready_enable = 1; | ||
| 648 | |||
| 649 | ret = qmi_txn_init(&qmi->qmi_hdl, &txn, | ||
| 650 | wlfw_ind_register_resp_msg_v01_ei, &resp); | ||
| 651 | if (ret < 0) | ||
| 652 | goto out; | ||
| 653 | |||
| 654 | ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, | ||
| 655 | QMI_WLFW_IND_REGISTER_REQ_V01, | ||
| 656 | WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 657 | wlfw_ind_register_req_msg_v01_ei, &req); | ||
| 658 | if (ret < 0) { | ||
| 659 | qmi_txn_cancel(&txn); | ||
| 660 | ath10k_err(ar, "failed to send indication registed request: %d\n", ret); | ||
| 661 | goto out; | ||
| 662 | } | ||
| 663 | |||
| 664 | ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); | ||
| 665 | if (ret < 0) | ||
| 666 | goto out; | ||
| 667 | |||
| 668 | if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { | ||
| 669 | ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error); | ||
| 670 | ret = -EINVAL; | ||
| 671 | goto out; | ||
| 672 | } | ||
| 673 | |||
| 674 | if (resp.fw_status_valid) { | ||
| 675 | if (resp.fw_status & QMI_WLFW_FW_READY_V01) | ||
| 676 | qmi->fw_ready = true; | ||
| 677 | } | ||
| 678 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n"); | ||
| 679 | return 0; | ||
| 680 | |||
| 681 | out: | ||
| 682 | return ret; | ||
| 683 | } | ||
| 684 | |||
| 685 | static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi) | ||
| 686 | { | ||
| 687 | struct ath10k *ar = qmi->ar; | ||
| 688 | int ret; | ||
| 689 | |||
| 690 | ret = ath10k_qmi_ind_register_send_sync_msg(qmi); | ||
| 691 | if (ret) | ||
| 692 | return; | ||
| 693 | |||
| 694 | if (qmi->fw_ready) { | ||
| 695 | ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); | ||
| 696 | return; | ||
| 697 | } | ||
| 698 | |||
| 699 | ret = ath10k_qmi_host_cap_send_sync(qmi); | ||
| 700 | if (ret) | ||
| 701 | return; | ||
| 702 | |||
| 703 | ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi); | ||
| 704 | if (ret) | ||
| 705 | return; | ||
| 706 | |||
| 707 | ret = ath10k_qmi_setup_msa_permissions(qmi); | ||
| 708 | if (ret) | ||
| 709 | return; | ||
| 710 | |||
| 711 | ret = ath10k_qmi_msa_ready_send_sync_msg(qmi); | ||
| 712 | if (ret) | ||
| 713 | goto err_setup_msa; | ||
| 714 | |||
| 715 | ret = ath10k_qmi_cap_send_sync_msg(qmi); | ||
| 716 | if (ret) | ||
| 717 | goto err_setup_msa; | ||
| 718 | |||
| 719 | return; | ||
| 720 | |||
| 721 | err_setup_msa: | ||
| 722 | ath10k_qmi_remove_msa_permission(qmi); | ||
| 723 | } | ||
| 724 | |||
| 725 | static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi) | ||
| 726 | { | ||
| 727 | struct ath10k *ar = qmi->ar; | ||
| 728 | |||
| 729 | ar->hif.bus = ATH10K_BUS_SNOC; | ||
| 730 | ar->id.qmi_ids_valid = true; | ||
| 731 | ar->id.qmi_board_id = qmi->board_info.board_id; | ||
| 732 | ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR; | ||
| 733 | |||
| 734 | return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD); | ||
| 735 | } | ||
| 736 | |||
| 737 | static int | ||
| 738 | ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi, | ||
| 739 | enum ath10k_qmi_driver_event_type type, | ||
| 740 | void *data) | ||
| 741 | { | ||
| 742 | struct ath10k_qmi_driver_event *event; | ||
| 743 | |||
| 744 | event = kzalloc(sizeof(*event), GFP_ATOMIC); | ||
| 745 | if (!event) | ||
| 746 | return -ENOMEM; | ||
| 747 | |||
| 748 | event->type = type; | ||
| 749 | event->data = data; | ||
| 750 | |||
| 751 | spin_lock(&qmi->event_lock); | ||
| 752 | list_add_tail(&event->list, &qmi->event_list); | ||
| 753 | spin_unlock(&qmi->event_lock); | ||
| 754 | |||
| 755 | queue_work(qmi->event_wq, &qmi->event_work); | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi) | ||
| 761 | { | ||
| 762 | struct ath10k *ar = qmi->ar; | ||
| 763 | |||
| 764 | ath10k_qmi_remove_msa_permission(qmi); | ||
| 765 | ath10k_core_free_board_files(ar); | ||
| 766 | ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND); | ||
| 767 | ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n"); | ||
| 768 | } | ||
| 769 | |||
| 770 | static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi) | ||
| 771 | { | ||
| 772 | int ret; | ||
| 773 | |||
| 774 | ret = ath10k_qmi_fetch_board_file(qmi); | ||
| 775 | if (ret) | ||
| 776 | goto out; | ||
| 777 | |||
| 778 | ret = ath10k_qmi_bdf_dnld_send_sync(qmi); | ||
| 779 | if (ret) | ||
| 780 | goto out; | ||
| 781 | |||
| 782 | ret = ath10k_qmi_send_cal_report_req(qmi); | ||
| 783 | |||
| 784 | out: | ||
| 785 | return; | ||
| 786 | } | ||
| 787 | |||
| 788 | static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi) | ||
| 789 | { | ||
| 790 | struct ath10k *ar = qmi->ar; | ||
| 791 | |||
| 792 | ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n"); | ||
| 793 | ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); | ||
| 794 | |||
| 795 | return 0; | ||
| 796 | } | ||
| 797 | |||
| 798 | static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl, | ||
| 799 | struct sockaddr_qrtr *sq, | ||
| 800 | struct qmi_txn *txn, const void *data) | ||
| 801 | { | ||
| 802 | struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); | ||
| 803 | |||
| 804 | ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL); | ||
| 805 | } | ||
| 806 | |||
| 807 | static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl, | ||
| 808 | struct sockaddr_qrtr *sq, | ||
| 809 | struct qmi_txn *txn, const void *data) | ||
| 810 | { | ||
| 811 | struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); | ||
| 812 | |||
| 813 | ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL); | ||
| 814 | } | ||
| 815 | |||
| 816 | static struct qmi_msg_handler qmi_msg_handler[] = { | ||
| 817 | { | ||
| 818 | .type = QMI_INDICATION, | ||
| 819 | .msg_id = QMI_WLFW_FW_READY_IND_V01, | ||
| 820 | .ei = wlfw_fw_ready_ind_msg_v01_ei, | ||
| 821 | .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01), | ||
| 822 | .fn = ath10k_qmi_fw_ready_ind, | ||
| 823 | }, | ||
| 824 | { | ||
| 825 | .type = QMI_INDICATION, | ||
| 826 | .msg_id = QMI_WLFW_MSA_READY_IND_V01, | ||
| 827 | .ei = wlfw_msa_ready_ind_msg_v01_ei, | ||
| 828 | .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01), | ||
| 829 | .fn = ath10k_qmi_msa_ready_ind, | ||
| 830 | }, | ||
| 831 | {} | ||
| 832 | }; | ||
| 833 | |||
| 834 | static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl, | ||
| 835 | struct qmi_service *service) | ||
| 836 | { | ||
| 837 | struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); | ||
| 838 | struct sockaddr_qrtr *sq = &qmi->sq; | ||
| 839 | struct ath10k *ar = qmi->ar; | ||
| 840 | int ret; | ||
| 841 | |||
| 842 | sq->sq_family = AF_QIPCRTR; | ||
| 843 | sq->sq_node = service->node; | ||
| 844 | sq->sq_port = service->port; | ||
| 845 | |||
| 846 | ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n"); | ||
| 847 | |||
| 848 | ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq, | ||
| 849 | sizeof(qmi->sq), 0); | ||
| 850 | if (ret) { | ||
| 851 | ath10k_err(ar, "failed to connect to a remote QMI service port\n"); | ||
| 852 | return ret; | ||
| 853 | } | ||
| 854 | |||
| 855 | ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n"); | ||
| 856 | ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL); | ||
| 857 | |||
| 858 | return ret; | ||
| 859 | } | ||
| 860 | |||
| 861 | static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, | ||
| 862 | struct qmi_service *service) | ||
| 863 | { | ||
| 864 | struct ath10k_qmi *qmi = | ||
| 865 | container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); | ||
| 866 | |||
| 867 | qmi->fw_ready = false; | ||
| 868 | ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); | ||
| 869 | } | ||
| 870 | |||
| 871 | static struct qmi_ops ath10k_qmi_ops = { | ||
| 872 | .new_server = ath10k_qmi_new_server, | ||
| 873 | .del_server = ath10k_qmi_del_server, | ||
| 874 | }; | ||
| 875 | |||
| 876 | static void ath10k_qmi_driver_event_work(struct work_struct *work) | ||
| 877 | { | ||
| 878 | struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi, | ||
| 879 | event_work); | ||
| 880 | struct ath10k_qmi_driver_event *event; | ||
| 881 | struct ath10k *ar = qmi->ar; | ||
| 882 | |||
| 883 | spin_lock(&qmi->event_lock); | ||
| 884 | while (!list_empty(&qmi->event_list)) { | ||
| 885 | event = list_first_entry(&qmi->event_list, | ||
| 886 | struct ath10k_qmi_driver_event, list); | ||
| 887 | list_del(&event->list); | ||
| 888 | spin_unlock(&qmi->event_lock); | ||
| 889 | |||
| 890 | switch (event->type) { | ||
| 891 | case ATH10K_QMI_EVENT_SERVER_ARRIVE: | ||
| 892 | ath10k_qmi_event_server_arrive(qmi); | ||
| 893 | break; | ||
| 894 | case ATH10K_QMI_EVENT_SERVER_EXIT: | ||
| 895 | ath10k_qmi_event_server_exit(qmi); | ||
| 896 | break; | ||
| 897 | case ATH10K_QMI_EVENT_FW_READY_IND: | ||
| 898 | ath10k_qmi_event_fw_ready_ind(qmi); | ||
| 899 | break; | ||
| 900 | case ATH10K_QMI_EVENT_MSA_READY_IND: | ||
| 901 | ath10k_qmi_event_msa_ready(qmi); | ||
| 902 | break; | ||
| 903 | default: | ||
| 904 | ath10k_warn(ar, "invalid event type: %d", event->type); | ||
| 905 | break; | ||
| 906 | } | ||
| 907 | kfree(event); | ||
| 908 | spin_lock(&qmi->event_lock); | ||
| 909 | } | ||
| 910 | spin_unlock(&qmi->event_lock); | ||
| 911 | } | ||
| 912 | |||
| 913 | static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size) | ||
| 914 | { | ||
| 915 | struct ath10k *ar = qmi->ar; | ||
| 916 | struct device *dev = ar->dev; | ||
| 917 | struct device_node *node; | ||
| 918 | struct resource r; | ||
| 919 | int ret; | ||
| 920 | |||
| 921 | node = of_parse_phandle(dev->of_node, "memory-region", 0); | ||
| 922 | if (node) { | ||
| 923 | ret = of_address_to_resource(node, 0, &r); | ||
| 924 | if (ret) { | ||
| 925 | dev_err(dev, "failed to resolve msa fixed region\n"); | ||
| 926 | return ret; | ||
| 927 | } | ||
| 928 | of_node_put(node); | ||
| 929 | |||
| 930 | qmi->msa_pa = r.start; | ||
| 931 | qmi->msa_mem_size = resource_size(&r); | ||
| 932 | qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size, | ||
| 933 | MEMREMAP_WT); | ||
| 934 | if (!qmi->msa_pa) { | ||
| 935 | dev_err(dev, "failed to map memory region: %pa\n", &r.start); | ||
| 936 | return -EBUSY; | ||
| 937 | } | ||
| 938 | } else { | ||
| 939 | qmi->msa_va = dmam_alloc_coherent(dev, msa_size, | ||
| 940 | &qmi->msa_pa, GFP_KERNEL); | ||
| 941 | if (!qmi->msa_va) { | ||
| 942 | ath10k_err(ar, "failed to allocate dma memory for msa region\n"); | ||
| 943 | return -ENOMEM; | ||
| 944 | } | ||
| 945 | qmi->msa_mem_size = msa_size; | ||
| 946 | } | ||
| 947 | |||
| 948 | ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n", | ||
| 949 | &qmi->msa_pa, | ||
| 950 | qmi->msa_va); | ||
| 951 | |||
| 952 | return 0; | ||
| 953 | } | ||
| 954 | |||
| 955 | int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) | ||
| 956 | { | ||
| 957 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | ||
| 958 | struct ath10k_qmi *qmi; | ||
| 959 | int ret; | ||
| 960 | |||
| 961 | qmi = kzalloc(sizeof(*qmi), GFP_KERNEL); | ||
| 962 | if (!qmi) | ||
| 963 | return -ENOMEM; | ||
| 964 | |||
| 965 | qmi->ar = ar; | ||
| 966 | ar_snoc->qmi = qmi; | ||
| 967 | |||
| 968 | ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); | ||
| 969 | if (ret) | ||
| 970 | goto err; | ||
| 971 | |||
| 972 | ret = qmi_handle_init(&qmi->qmi_hdl, | ||
| 973 | WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, | ||
| 974 | &ath10k_qmi_ops, qmi_msg_handler); | ||
| 975 | if (ret) | ||
| 976 | goto err; | ||
| 977 | |||
| 978 | qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event", | ||
| 979 | WQ_UNBOUND, 1); | ||
| 980 | if (!qmi->event_wq) { | ||
| 981 | ath10k_err(ar, "failed to allocate workqueue\n"); | ||
| 982 | ret = -EFAULT; | ||
| 983 | goto err_release_qmi_handle; | ||
| 984 | } | ||
| 985 | |||
| 986 | INIT_LIST_HEAD(&qmi->event_list); | ||
| 987 | spin_lock_init(&qmi->event_lock); | ||
| 988 | INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work); | ||
| 989 | |||
| 990 | ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01, | ||
| 991 | WLFW_SERVICE_VERS_V01, 0); | ||
| 992 | if (ret) | ||
| 993 | goto err_qmi_lookup; | ||
| 994 | |||
| 995 | return 0; | ||
| 996 | |||
| 997 | err_qmi_lookup: | ||
| 998 | destroy_workqueue(qmi->event_wq); | ||
| 999 | |||
| 1000 | err_release_qmi_handle: | ||
| 1001 | qmi_handle_release(&qmi->qmi_hdl); | ||
| 1002 | |||
| 1003 | err: | ||
| 1004 | kfree(qmi); | ||
| 1005 | return ret; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | int ath10k_qmi_deinit(struct ath10k *ar) | ||
| 1009 | { | ||
| 1010 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | ||
| 1011 | struct ath10k_qmi *qmi = ar_snoc->qmi; | ||
| 1012 | |||
| 1013 | qmi_handle_release(&qmi->qmi_hdl); | ||
| 1014 | cancel_work_sync(&qmi->event_work); | ||
| 1015 | destroy_workqueue(qmi->event_wq); | ||
| 1016 | ar_snoc->qmi = NULL; | ||
| 1017 | |||
| 1018 | return 0; | ||
| 1019 | } | ||
diff --git a/drivers/net/wireless/ath/ath10k/qmi.h b/drivers/net/wireless/ath/ath10k/qmi.h new file mode 100644 index 000000000000..1efe1d22fc2f --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/qmi.h | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2018 The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #ifndef _ATH10K_QMI_H_ | ||
| 17 | #define _ATH10K_QMI_H_ | ||
| 18 | |||
| 19 | #include <linux/soc/qcom/qmi.h> | ||
| 20 | #include <linux/qrtr.h> | ||
| 21 | #include "qmi_wlfw_v01.h" | ||
| 22 | |||
| 23 | #define MAX_NUM_MEMORY_REGIONS 2 | ||
| 24 | #define MAX_TIMESTAMP_LEN 32 | ||
| 25 | #define MAX_BUILD_ID_LEN 128 | ||
| 26 | #define MAX_NUM_CAL_V01 5 | ||
| 27 | |||
| 28 | enum ath10k_qmi_driver_event_type { | ||
| 29 | ATH10K_QMI_EVENT_SERVER_ARRIVE, | ||
| 30 | ATH10K_QMI_EVENT_SERVER_EXIT, | ||
| 31 | ATH10K_QMI_EVENT_FW_READY_IND, | ||
| 32 | ATH10K_QMI_EVENT_FW_DOWN_IND, | ||
| 33 | ATH10K_QMI_EVENT_MSA_READY_IND, | ||
| 34 | ATH10K_QMI_EVENT_MAX, | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct ath10k_msa_mem_info { | ||
| 38 | phys_addr_t addr; | ||
| 39 | u32 size; | ||
| 40 | bool secure; | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct ath10k_qmi_chip_info { | ||
| 44 | u32 chip_id; | ||
| 45 | u32 chip_family; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct ath10k_qmi_board_info { | ||
| 49 | u32 board_id; | ||
| 50 | }; | ||
| 51 | |||
| 52 | struct ath10k_qmi_soc_info { | ||
| 53 | u32 soc_id; | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct ath10k_qmi_cal_data { | ||
| 57 | u32 cal_id; | ||
| 58 | u32 total_size; | ||
| 59 | u8 *data; | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct ath10k_tgt_pipe_cfg { | ||
| 63 | __le32 pipe_num; | ||
| 64 | __le32 pipe_dir; | ||
| 65 | __le32 nentries; | ||
| 66 | __le32 nbytes_max; | ||
| 67 | __le32 flags; | ||
| 68 | __le32 reserved; | ||
| 69 | }; | ||
| 70 | |||
| 71 | struct ath10k_svc_pipe_cfg { | ||
| 72 | __le32 service_id; | ||
| 73 | __le32 pipe_dir; | ||
| 74 | __le32 pipe_num; | ||
| 75 | }; | ||
| 76 | |||
| 77 | struct ath10k_shadow_reg_cfg { | ||
| 78 | __le16 ce_id; | ||
| 79 | __le16 reg_offset; | ||
| 80 | }; | ||
| 81 | |||
| 82 | struct ath10k_qmi_wlan_enable_cfg { | ||
| 83 | u32 num_ce_tgt_cfg; | ||
| 84 | struct ath10k_tgt_pipe_cfg *ce_tgt_cfg; | ||
| 85 | u32 num_ce_svc_pipe_cfg; | ||
| 86 | struct ath10k_svc_pipe_cfg *ce_svc_cfg; | ||
| 87 | u32 num_shadow_reg_cfg; | ||
| 88 | struct ath10k_shadow_reg_cfg *shadow_reg_cfg; | ||
| 89 | }; | ||
| 90 | |||
| 91 | struct ath10k_qmi_driver_event { | ||
| 92 | struct list_head list; | ||
| 93 | enum ath10k_qmi_driver_event_type type; | ||
| 94 | void *data; | ||
| 95 | }; | ||
| 96 | |||
| 97 | struct ath10k_qmi { | ||
| 98 | struct ath10k *ar; | ||
| 99 | struct qmi_handle qmi_hdl; | ||
| 100 | struct sockaddr_qrtr sq; | ||
| 101 | struct work_struct event_work; | ||
| 102 | struct workqueue_struct *event_wq; | ||
| 103 | struct list_head event_list; | ||
| 104 | spinlock_t event_lock; /* spinlock for qmi event list */ | ||
| 105 | u32 nr_mem_region; | ||
| 106 | struct ath10k_msa_mem_info mem_region[MAX_NUM_MEMORY_REGIONS]; | ||
| 107 | dma_addr_t msa_pa; | ||
| 108 | u32 msa_mem_size; | ||
| 109 | void *msa_va; | ||
| 110 | struct ath10k_qmi_chip_info chip_info; | ||
| 111 | struct ath10k_qmi_board_info board_info; | ||
| 112 | struct ath10k_qmi_soc_info soc_info; | ||
| 113 | char fw_build_id[MAX_BUILD_ID_LEN + 1]; | ||
| 114 | u32 fw_version; | ||
| 115 | bool fw_ready; | ||
| 116 | char fw_build_timestamp[MAX_TIMESTAMP_LEN + 1]; | ||
| 117 | struct ath10k_qmi_cal_data cal_data[MAX_NUM_CAL_V01]; | ||
| 118 | }; | ||
| 119 | |||
| 120 | int ath10k_qmi_wlan_enable(struct ath10k *ar, | ||
| 121 | struct ath10k_qmi_wlan_enable_cfg *config, | ||
| 122 | enum wlfw_driver_mode_enum_v01 mode, | ||
| 123 | const char *version); | ||
| 124 | int ath10k_qmi_wlan_disable(struct ath10k *ar); | ||
| 125 | int ath10k_qmi_register_service_notifier(struct notifier_block *nb); | ||
| 126 | int ath10k_qmi_init(struct ath10k *ar, u32 msa_size); | ||
| 127 | int ath10k_qmi_deinit(struct ath10k *ar); | ||
| 128 | |||
| 129 | #endif /* ATH10K_QMI_H */ | ||
diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c new file mode 100644 index 000000000000..ba79c2e4aed6 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c | |||
| @@ -0,0 +1,2072 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2018 The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/soc/qcom/qmi.h> | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include "qmi_wlfw_v01.h" | ||
| 20 | |||
| 21 | static struct qmi_elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { | ||
| 22 | { | ||
| 23 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 24 | .elem_len = 1, | ||
| 25 | .elem_size = sizeof(u32), | ||
| 26 | .array_type = NO_ARRAY, | ||
| 27 | .tlv_type = 0, | ||
| 28 | .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, | ||
| 29 | pipe_num), | ||
| 30 | }, | ||
| 31 | { | ||
| 32 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 33 | .elem_len = 1, | ||
| 34 | .elem_size = sizeof(enum wlfw_pipedir_enum_v01), | ||
| 35 | .array_type = NO_ARRAY, | ||
| 36 | .tlv_type = 0, | ||
| 37 | .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, | ||
| 38 | pipe_dir), | ||
| 39 | }, | ||
| 40 | { | ||
| 41 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 42 | .elem_len = 1, | ||
| 43 | .elem_size = sizeof(u32), | ||
| 44 | .array_type = NO_ARRAY, | ||
| 45 | .tlv_type = 0, | ||
| 46 | .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, | ||
| 47 | nentries), | ||
| 48 | }, | ||
| 49 | { | ||
| 50 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 51 | .elem_len = 1, | ||
| 52 | .elem_size = sizeof(u32), | ||
| 53 | .array_type = NO_ARRAY, | ||
| 54 | .tlv_type = 0, | ||
| 55 | .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, | ||
| 56 | nbytes_max), | ||
| 57 | }, | ||
| 58 | { | ||
| 59 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 60 | .elem_len = 1, | ||
| 61 | .elem_size = sizeof(u32), | ||
| 62 | .array_type = NO_ARRAY, | ||
| 63 | .tlv_type = 0, | ||
| 64 | .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, | ||
| 65 | flags), | ||
| 66 | }, | ||
| 67 | {} | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct qmi_elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = { | ||
| 71 | { | ||
| 72 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 73 | .elem_len = 1, | ||
| 74 | .elem_size = sizeof(u32), | ||
| 75 | .array_type = NO_ARRAY, | ||
| 76 | .tlv_type = 0, | ||
| 77 | .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01, | ||
| 78 | service_id), | ||
| 79 | }, | ||
| 80 | { | ||
| 81 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 82 | .elem_len = 1, | ||
| 83 | .elem_size = sizeof(enum wlfw_pipedir_enum_v01), | ||
| 84 | .array_type = NO_ARRAY, | ||
| 85 | .tlv_type = 0, | ||
| 86 | .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01, | ||
| 87 | pipe_dir), | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 91 | .elem_len = 1, | ||
| 92 | .elem_size = sizeof(u32), | ||
| 93 | .array_type = NO_ARRAY, | ||
| 94 | .tlv_type = 0, | ||
| 95 | .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01, | ||
| 96 | pipe_num), | ||
| 97 | }, | ||
| 98 | {} | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct qmi_elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = { | ||
| 102 | { | ||
| 103 | .data_type = QMI_UNSIGNED_2_BYTE, | ||
| 104 | .elem_len = 1, | ||
| 105 | .elem_size = sizeof(u16), | ||
| 106 | .array_type = NO_ARRAY, | ||
| 107 | .tlv_type = 0, | ||
| 108 | .offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01, | ||
| 109 | id), | ||
| 110 | }, | ||
| 111 | { | ||
| 112 | .data_type = QMI_UNSIGNED_2_BYTE, | ||
| 113 | .elem_len = 1, | ||
| 114 | .elem_size = sizeof(u16), | ||
| 115 | .array_type = NO_ARRAY, | ||
| 116 | .tlv_type = 0, | ||
| 117 | .offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01, | ||
| 118 | offset), | ||
| 119 | }, | ||
| 120 | {} | ||
| 121 | }; | ||
| 122 | |||
| 123 | static struct qmi_elem_info wlfw_shadow_reg_v2_cfg_s_v01_ei[] = { | ||
| 124 | { | ||
| 125 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 126 | .elem_len = 1, | ||
| 127 | .elem_size = sizeof(u32), | ||
| 128 | .array_type = NO_ARRAY, | ||
| 129 | .tlv_type = 0, | ||
| 130 | .offset = offsetof(struct wlfw_shadow_reg_v2_cfg_s_v01, | ||
| 131 | addr), | ||
| 132 | }, | ||
| 133 | {} | ||
| 134 | }; | ||
| 135 | |||
| 136 | static struct qmi_elem_info wlfw_memory_region_info_s_v01_ei[] = { | ||
| 137 | { | ||
| 138 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 139 | .elem_len = 1, | ||
| 140 | .elem_size = sizeof(u64), | ||
| 141 | .array_type = NO_ARRAY, | ||
| 142 | .tlv_type = 0, | ||
| 143 | .offset = offsetof(struct wlfw_memory_region_info_s_v01, | ||
| 144 | region_addr), | ||
| 145 | }, | ||
| 146 | { | ||
| 147 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 148 | .elem_len = 1, | ||
| 149 | .elem_size = sizeof(u32), | ||
| 150 | .array_type = NO_ARRAY, | ||
| 151 | .tlv_type = 0, | ||
| 152 | .offset = offsetof(struct wlfw_memory_region_info_s_v01, | ||
| 153 | size), | ||
| 154 | }, | ||
| 155 | { | ||
| 156 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 157 | .elem_len = 1, | ||
| 158 | .elem_size = sizeof(u8), | ||
| 159 | .array_type = NO_ARRAY, | ||
| 160 | .tlv_type = 0, | ||
| 161 | .offset = offsetof(struct wlfw_memory_region_info_s_v01, | ||
| 162 | secure_flag), | ||
| 163 | }, | ||
| 164 | {} | ||
| 165 | }; | ||
| 166 | |||
| 167 | static struct qmi_elem_info wlfw_mem_cfg_s_v01_ei[] = { | ||
| 168 | { | ||
| 169 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 170 | .elem_len = 1, | ||
| 171 | .elem_size = sizeof(u64), | ||
| 172 | .array_type = NO_ARRAY, | ||
| 173 | .tlv_type = 0, | ||
| 174 | .offset = offsetof(struct wlfw_mem_cfg_s_v01, | ||
| 175 | offset), | ||
| 176 | }, | ||
| 177 | { | ||
| 178 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 179 | .elem_len = 1, | ||
| 180 | .elem_size = sizeof(u32), | ||
| 181 | .array_type = NO_ARRAY, | ||
| 182 | .tlv_type = 0, | ||
| 183 | .offset = offsetof(struct wlfw_mem_cfg_s_v01, | ||
| 184 | size), | ||
| 185 | }, | ||
| 186 | { | ||
| 187 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 188 | .elem_len = 1, | ||
| 189 | .elem_size = sizeof(u8), | ||
| 190 | .array_type = NO_ARRAY, | ||
| 191 | .tlv_type = 0, | ||
| 192 | .offset = offsetof(struct wlfw_mem_cfg_s_v01, | ||
| 193 | secure_flag), | ||
| 194 | }, | ||
| 195 | {} | ||
| 196 | }; | ||
| 197 | |||
| 198 | static struct qmi_elem_info wlfw_mem_seg_s_v01_ei[] = { | ||
| 199 | { | ||
| 200 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 201 | .elem_len = 1, | ||
| 202 | .elem_size = sizeof(u32), | ||
| 203 | .array_type = NO_ARRAY, | ||
| 204 | .tlv_type = 0, | ||
| 205 | .offset = offsetof(struct wlfw_mem_seg_s_v01, | ||
| 206 | size), | ||
| 207 | }, | ||
| 208 | { | ||
| 209 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 210 | .elem_len = 1, | ||
| 211 | .elem_size = sizeof(enum wlfw_mem_type_enum_v01), | ||
| 212 | .array_type = NO_ARRAY, | ||
| 213 | .tlv_type = 0, | ||
| 214 | .offset = offsetof(struct wlfw_mem_seg_s_v01, | ||
| 215 | type), | ||
| 216 | }, | ||
| 217 | { | ||
| 218 | .data_type = QMI_DATA_LEN, | ||
| 219 | .elem_len = 1, | ||
| 220 | .elem_size = sizeof(u8), | ||
| 221 | .array_type = NO_ARRAY, | ||
| 222 | .tlv_type = 0, | ||
| 223 | .offset = offsetof(struct wlfw_mem_seg_s_v01, | ||
| 224 | mem_cfg_len), | ||
| 225 | }, | ||
| 226 | { | ||
| 227 | .data_type = QMI_STRUCT, | ||
| 228 | .elem_len = QMI_WLFW_MAX_NUM_MEM_CFG_V01, | ||
| 229 | .elem_size = sizeof(struct wlfw_mem_cfg_s_v01), | ||
| 230 | .array_type = VAR_LEN_ARRAY, | ||
| 231 | .tlv_type = 0, | ||
| 232 | .offset = offsetof(struct wlfw_mem_seg_s_v01, | ||
| 233 | mem_cfg), | ||
| 234 | .ei_array = wlfw_mem_cfg_s_v01_ei, | ||
| 235 | }, | ||
| 236 | {} | ||
| 237 | }; | ||
| 238 | |||
| 239 | static struct qmi_elem_info wlfw_mem_seg_resp_s_v01_ei[] = { | ||
| 240 | { | ||
| 241 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 242 | .elem_len = 1, | ||
| 243 | .elem_size = sizeof(u64), | ||
| 244 | .array_type = NO_ARRAY, | ||
| 245 | .tlv_type = 0, | ||
| 246 | .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, | ||
| 247 | addr), | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 251 | .elem_len = 1, | ||
| 252 | .elem_size = sizeof(u32), | ||
| 253 | .array_type = NO_ARRAY, | ||
| 254 | .tlv_type = 0, | ||
| 255 | .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, | ||
| 256 | size), | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 260 | .elem_len = 1, | ||
| 261 | .elem_size = sizeof(enum wlfw_mem_type_enum_v01), | ||
| 262 | .array_type = NO_ARRAY, | ||
| 263 | .tlv_type = 0, | ||
| 264 | .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, | ||
| 265 | type), | ||
| 266 | }, | ||
| 267 | {} | ||
| 268 | }; | ||
| 269 | |||
| 270 | static struct qmi_elem_info wlfw_rf_chip_info_s_v01_ei[] = { | ||
| 271 | { | ||
| 272 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 273 | .elem_len = 1, | ||
| 274 | .elem_size = sizeof(u32), | ||
| 275 | .array_type = NO_ARRAY, | ||
| 276 | .tlv_type = 0, | ||
| 277 | .offset = offsetof(struct wlfw_rf_chip_info_s_v01, | ||
| 278 | chip_id), | ||
| 279 | }, | ||
| 280 | { | ||
| 281 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 282 | .elem_len = 1, | ||
| 283 | .elem_size = sizeof(u32), | ||
| 284 | .array_type = NO_ARRAY, | ||
| 285 | .tlv_type = 0, | ||
| 286 | .offset = offsetof(struct wlfw_rf_chip_info_s_v01, | ||
| 287 | chip_family), | ||
| 288 | }, | ||
| 289 | {} | ||
| 290 | }; | ||
| 291 | |||
| 292 | static struct qmi_elem_info wlfw_rf_board_info_s_v01_ei[] = { | ||
| 293 | { | ||
| 294 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 295 | .elem_len = 1, | ||
| 296 | .elem_size = sizeof(u32), | ||
| 297 | .array_type = NO_ARRAY, | ||
| 298 | .tlv_type = 0, | ||
| 299 | .offset = offsetof(struct wlfw_rf_board_info_s_v01, | ||
| 300 | board_id), | ||
| 301 | }, | ||
| 302 | {} | ||
| 303 | }; | ||
| 304 | |||
| 305 | static struct qmi_elem_info wlfw_soc_info_s_v01_ei[] = { | ||
| 306 | { | ||
| 307 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 308 | .elem_len = 1, | ||
| 309 | .elem_size = sizeof(u32), | ||
| 310 | .array_type = NO_ARRAY, | ||
| 311 | .tlv_type = 0, | ||
| 312 | .offset = offsetof(struct wlfw_soc_info_s_v01, | ||
| 313 | soc_id), | ||
| 314 | }, | ||
| 315 | {} | ||
| 316 | }; | ||
| 317 | |||
| 318 | static struct qmi_elem_info wlfw_fw_version_info_s_v01_ei[] = { | ||
| 319 | { | ||
| 320 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 321 | .elem_len = 1, | ||
| 322 | .elem_size = sizeof(u32), | ||
| 323 | .array_type = NO_ARRAY, | ||
| 324 | .tlv_type = 0, | ||
| 325 | .offset = offsetof(struct wlfw_fw_version_info_s_v01, | ||
| 326 | fw_version), | ||
| 327 | }, | ||
| 328 | { | ||
| 329 | .data_type = QMI_STRING, | ||
| 330 | .elem_len = QMI_WLFW_MAX_TIMESTAMP_LEN_V01 + 1, | ||
| 331 | .elem_size = sizeof(char), | ||
| 332 | .array_type = NO_ARRAY, | ||
| 333 | .tlv_type = 0, | ||
| 334 | .offset = offsetof(struct wlfw_fw_version_info_s_v01, | ||
| 335 | fw_build_timestamp), | ||
| 336 | }, | ||
| 337 | {} | ||
| 338 | }; | ||
| 339 | |||
| 340 | struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = { | ||
| 341 | { | ||
| 342 | .data_type = QMI_OPT_FLAG, | ||
| 343 | .elem_len = 1, | ||
| 344 | .elem_size = sizeof(u8), | ||
| 345 | .array_type = NO_ARRAY, | ||
| 346 | .tlv_type = 0x10, | ||
| 347 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 348 | fw_ready_enable_valid), | ||
| 349 | }, | ||
| 350 | { | ||
| 351 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 352 | .elem_len = 1, | ||
| 353 | .elem_size = sizeof(u8), | ||
| 354 | .array_type = NO_ARRAY, | ||
| 355 | .tlv_type = 0x10, | ||
| 356 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 357 | fw_ready_enable), | ||
| 358 | }, | ||
| 359 | { | ||
| 360 | .data_type = QMI_OPT_FLAG, | ||
| 361 | .elem_len = 1, | ||
| 362 | .elem_size = sizeof(u8), | ||
| 363 | .array_type = NO_ARRAY, | ||
| 364 | .tlv_type = 0x11, | ||
| 365 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 366 | initiate_cal_download_enable_valid), | ||
| 367 | }, | ||
| 368 | { | ||
| 369 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 370 | .elem_len = 1, | ||
| 371 | .elem_size = sizeof(u8), | ||
| 372 | .array_type = NO_ARRAY, | ||
| 373 | .tlv_type = 0x11, | ||
| 374 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 375 | initiate_cal_download_enable), | ||
| 376 | }, | ||
| 377 | { | ||
| 378 | .data_type = QMI_OPT_FLAG, | ||
| 379 | .elem_len = 1, | ||
| 380 | .elem_size = sizeof(u8), | ||
| 381 | .array_type = NO_ARRAY, | ||
| 382 | .tlv_type = 0x12, | ||
| 383 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 384 | initiate_cal_update_enable_valid), | ||
| 385 | }, | ||
| 386 | { | ||
| 387 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 388 | .elem_len = 1, | ||
| 389 | .elem_size = sizeof(u8), | ||
| 390 | .array_type = NO_ARRAY, | ||
| 391 | .tlv_type = 0x12, | ||
| 392 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 393 | initiate_cal_update_enable), | ||
| 394 | }, | ||
| 395 | { | ||
| 396 | .data_type = QMI_OPT_FLAG, | ||
| 397 | .elem_len = 1, | ||
| 398 | .elem_size = sizeof(u8), | ||
| 399 | .array_type = NO_ARRAY, | ||
| 400 | .tlv_type = 0x13, | ||
| 401 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 402 | msa_ready_enable_valid), | ||
| 403 | }, | ||
| 404 | { | ||
| 405 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 406 | .elem_len = 1, | ||
| 407 | .elem_size = sizeof(u8), | ||
| 408 | .array_type = NO_ARRAY, | ||
| 409 | .tlv_type = 0x13, | ||
| 410 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 411 | msa_ready_enable), | ||
| 412 | }, | ||
| 413 | { | ||
| 414 | .data_type = QMI_OPT_FLAG, | ||
| 415 | .elem_len = 1, | ||
| 416 | .elem_size = sizeof(u8), | ||
| 417 | .array_type = NO_ARRAY, | ||
| 418 | .tlv_type = 0x14, | ||
| 419 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 420 | pin_connect_result_enable_valid), | ||
| 421 | }, | ||
| 422 | { | ||
| 423 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 424 | .elem_len = 1, | ||
| 425 | .elem_size = sizeof(u8), | ||
| 426 | .array_type = NO_ARRAY, | ||
| 427 | .tlv_type = 0x14, | ||
| 428 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 429 | pin_connect_result_enable), | ||
| 430 | }, | ||
| 431 | { | ||
| 432 | .data_type = QMI_OPT_FLAG, | ||
| 433 | .elem_len = 1, | ||
| 434 | .elem_size = sizeof(u8), | ||
| 435 | .array_type = NO_ARRAY, | ||
| 436 | .tlv_type = 0x15, | ||
| 437 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 438 | client_id_valid), | ||
| 439 | }, | ||
| 440 | { | ||
| 441 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 442 | .elem_len = 1, | ||
| 443 | .elem_size = sizeof(u32), | ||
| 444 | .array_type = NO_ARRAY, | ||
| 445 | .tlv_type = 0x15, | ||
| 446 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 447 | client_id), | ||
| 448 | }, | ||
| 449 | { | ||
| 450 | .data_type = QMI_OPT_FLAG, | ||
| 451 | .elem_len = 1, | ||
| 452 | .elem_size = sizeof(u8), | ||
| 453 | .array_type = NO_ARRAY, | ||
| 454 | .tlv_type = 0x16, | ||
| 455 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 456 | request_mem_enable_valid), | ||
| 457 | }, | ||
| 458 | { | ||
| 459 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 460 | .elem_len = 1, | ||
| 461 | .elem_size = sizeof(u8), | ||
| 462 | .array_type = NO_ARRAY, | ||
| 463 | .tlv_type = 0x16, | ||
| 464 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 465 | request_mem_enable), | ||
| 466 | }, | ||
| 467 | { | ||
| 468 | .data_type = QMI_OPT_FLAG, | ||
| 469 | .elem_len = 1, | ||
| 470 | .elem_size = sizeof(u8), | ||
| 471 | .array_type = NO_ARRAY, | ||
| 472 | .tlv_type = 0x17, | ||
| 473 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 474 | mem_ready_enable_valid), | ||
| 475 | }, | ||
| 476 | { | ||
| 477 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 478 | .elem_len = 1, | ||
| 479 | .elem_size = sizeof(u8), | ||
| 480 | .array_type = NO_ARRAY, | ||
| 481 | .tlv_type = 0x17, | ||
| 482 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 483 | mem_ready_enable), | ||
| 484 | }, | ||
| 485 | { | ||
| 486 | .data_type = QMI_OPT_FLAG, | ||
| 487 | .elem_len = 1, | ||
| 488 | .elem_size = sizeof(u8), | ||
| 489 | .array_type = NO_ARRAY, | ||
| 490 | .tlv_type = 0x18, | ||
| 491 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 492 | fw_init_done_enable_valid), | ||
| 493 | }, | ||
| 494 | { | ||
| 495 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 496 | .elem_len = 1, | ||
| 497 | .elem_size = sizeof(u8), | ||
| 498 | .array_type = NO_ARRAY, | ||
| 499 | .tlv_type = 0x18, | ||
| 500 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 501 | fw_init_done_enable), | ||
| 502 | }, | ||
| 503 | { | ||
| 504 | .data_type = QMI_OPT_FLAG, | ||
| 505 | .elem_len = 1, | ||
| 506 | .elem_size = sizeof(u8), | ||
| 507 | .array_type = NO_ARRAY, | ||
| 508 | .tlv_type = 0x19, | ||
| 509 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 510 | rejuvenate_enable_valid), | ||
| 511 | }, | ||
| 512 | { | ||
| 513 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 514 | .elem_len = 1, | ||
| 515 | .elem_size = sizeof(u32), | ||
| 516 | .array_type = NO_ARRAY, | ||
| 517 | .tlv_type = 0x19, | ||
| 518 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 519 | rejuvenate_enable), | ||
| 520 | }, | ||
| 521 | { | ||
| 522 | .data_type = QMI_OPT_FLAG, | ||
| 523 | .elem_len = 1, | ||
| 524 | .elem_size = sizeof(u8), | ||
| 525 | .array_type = NO_ARRAY, | ||
| 526 | .tlv_type = 0x1A, | ||
| 527 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 528 | xo_cal_enable_valid), | ||
| 529 | }, | ||
| 530 | { | ||
| 531 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 532 | .elem_len = 1, | ||
| 533 | .elem_size = sizeof(u8), | ||
| 534 | .array_type = NO_ARRAY, | ||
| 535 | .tlv_type = 0x1A, | ||
| 536 | .offset = offsetof(struct wlfw_ind_register_req_msg_v01, | ||
| 537 | xo_cal_enable), | ||
| 538 | }, | ||
| 539 | {} | ||
| 540 | }; | ||
| 541 | |||
| 542 | struct qmi_elem_info wlfw_ind_register_resp_msg_v01_ei[] = { | ||
| 543 | { | ||
| 544 | .data_type = QMI_STRUCT, | ||
| 545 | .elem_len = 1, | ||
| 546 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 547 | .array_type = NO_ARRAY, | ||
| 548 | .tlv_type = 0x02, | ||
| 549 | .offset = offsetof(struct wlfw_ind_register_resp_msg_v01, | ||
| 550 | resp), | ||
| 551 | .ei_array = qmi_response_type_v01_ei, | ||
| 552 | }, | ||
| 553 | { | ||
| 554 | .data_type = QMI_OPT_FLAG, | ||
| 555 | .elem_len = 1, | ||
| 556 | .elem_size = sizeof(u8), | ||
| 557 | .array_type = NO_ARRAY, | ||
| 558 | .tlv_type = 0x10, | ||
| 559 | .offset = offsetof(struct wlfw_ind_register_resp_msg_v01, | ||
| 560 | fw_status_valid), | ||
| 561 | }, | ||
| 562 | { | ||
| 563 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 564 | .elem_len = 1, | ||
| 565 | .elem_size = sizeof(u64), | ||
| 566 | .array_type = NO_ARRAY, | ||
| 567 | .tlv_type = 0x10, | ||
| 568 | .offset = offsetof(struct wlfw_ind_register_resp_msg_v01, | ||
| 569 | fw_status), | ||
| 570 | }, | ||
| 571 | {} | ||
| 572 | }; | ||
| 573 | |||
| 574 | struct qmi_elem_info wlfw_fw_ready_ind_msg_v01_ei[] = { | ||
| 575 | {} | ||
| 576 | }; | ||
| 577 | |||
| 578 | struct qmi_elem_info wlfw_msa_ready_ind_msg_v01_ei[] = { | ||
| 579 | {} | ||
| 580 | }; | ||
| 581 | |||
| 582 | struct qmi_elem_info wlfw_pin_connect_result_ind_msg_v01_ei[] = { | ||
| 583 | { | ||
| 584 | .data_type = QMI_OPT_FLAG, | ||
| 585 | .elem_len = 1, | ||
| 586 | .elem_size = sizeof(u8), | ||
| 587 | .array_type = NO_ARRAY, | ||
| 588 | .tlv_type = 0x10, | ||
| 589 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 590 | pwr_pin_result_valid), | ||
| 591 | }, | ||
| 592 | { | ||
| 593 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 594 | .elem_len = 1, | ||
| 595 | .elem_size = sizeof(u32), | ||
| 596 | .array_type = NO_ARRAY, | ||
| 597 | .tlv_type = 0x10, | ||
| 598 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 599 | pwr_pin_result), | ||
| 600 | }, | ||
| 601 | { | ||
| 602 | .data_type = QMI_OPT_FLAG, | ||
| 603 | .elem_len = 1, | ||
| 604 | .elem_size = sizeof(u8), | ||
| 605 | .array_type = NO_ARRAY, | ||
| 606 | .tlv_type = 0x11, | ||
| 607 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 608 | phy_io_pin_result_valid), | ||
| 609 | }, | ||
| 610 | { | ||
| 611 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 612 | .elem_len = 1, | ||
| 613 | .elem_size = sizeof(u32), | ||
| 614 | .array_type = NO_ARRAY, | ||
| 615 | .tlv_type = 0x11, | ||
| 616 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 617 | phy_io_pin_result), | ||
| 618 | }, | ||
| 619 | { | ||
| 620 | .data_type = QMI_OPT_FLAG, | ||
| 621 | .elem_len = 1, | ||
| 622 | .elem_size = sizeof(u8), | ||
| 623 | .array_type = NO_ARRAY, | ||
| 624 | .tlv_type = 0x12, | ||
| 625 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 626 | rf_pin_result_valid), | ||
| 627 | }, | ||
| 628 | { | ||
| 629 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 630 | .elem_len = 1, | ||
| 631 | .elem_size = sizeof(u32), | ||
| 632 | .array_type = NO_ARRAY, | ||
| 633 | .tlv_type = 0x12, | ||
| 634 | .offset = offsetof(struct wlfw_pin_connect_result_ind_msg_v01, | ||
| 635 | rf_pin_result), | ||
| 636 | }, | ||
| 637 | {} | ||
| 638 | }; | ||
| 639 | |||
| 640 | struct qmi_elem_info wlfw_wlan_mode_req_msg_v01_ei[] = { | ||
| 641 | { | ||
| 642 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 643 | .elem_len = 1, | ||
| 644 | .elem_size = sizeof(enum wlfw_driver_mode_enum_v01), | ||
| 645 | .array_type = NO_ARRAY, | ||
| 646 | .tlv_type = 0x01, | ||
| 647 | .offset = offsetof(struct wlfw_wlan_mode_req_msg_v01, | ||
| 648 | mode), | ||
| 649 | }, | ||
| 650 | { | ||
| 651 | .data_type = QMI_OPT_FLAG, | ||
| 652 | .elem_len = 1, | ||
| 653 | .elem_size = sizeof(u8), | ||
| 654 | .array_type = NO_ARRAY, | ||
| 655 | .tlv_type = 0x10, | ||
| 656 | .offset = offsetof(struct wlfw_wlan_mode_req_msg_v01, | ||
| 657 | hw_debug_valid), | ||
| 658 | }, | ||
| 659 | { | ||
| 660 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 661 | .elem_len = 1, | ||
| 662 | .elem_size = sizeof(u8), | ||
| 663 | .array_type = NO_ARRAY, | ||
| 664 | .tlv_type = 0x10, | ||
| 665 | .offset = offsetof(struct wlfw_wlan_mode_req_msg_v01, | ||
| 666 | hw_debug), | ||
| 667 | }, | ||
| 668 | {} | ||
| 669 | }; | ||
| 670 | |||
| 671 | struct qmi_elem_info wlfw_wlan_mode_resp_msg_v01_ei[] = { | ||
| 672 | { | ||
| 673 | .data_type = QMI_STRUCT, | ||
| 674 | .elem_len = 1, | ||
| 675 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 676 | .array_type = NO_ARRAY, | ||
| 677 | .tlv_type = 0x02, | ||
| 678 | .offset = offsetof(struct wlfw_wlan_mode_resp_msg_v01, | ||
| 679 | resp), | ||
| 680 | .ei_array = qmi_response_type_v01_ei, | ||
| 681 | }, | ||
| 682 | {} | ||
| 683 | }; | ||
| 684 | |||
| 685 | struct qmi_elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { | ||
| 686 | { | ||
| 687 | .data_type = QMI_OPT_FLAG, | ||
| 688 | .elem_len = 1, | ||
| 689 | .elem_size = sizeof(u8), | ||
| 690 | .array_type = NO_ARRAY, | ||
| 691 | .tlv_type = 0x10, | ||
| 692 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 693 | host_version_valid), | ||
| 694 | }, | ||
| 695 | { | ||
| 696 | .data_type = QMI_STRING, | ||
| 697 | .elem_len = QMI_WLFW_MAX_STR_LEN_V01 + 1, | ||
| 698 | .elem_size = sizeof(char), | ||
| 699 | .array_type = NO_ARRAY, | ||
| 700 | .tlv_type = 0x10, | ||
| 701 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 702 | host_version), | ||
| 703 | }, | ||
| 704 | { | ||
| 705 | .data_type = QMI_OPT_FLAG, | ||
| 706 | .elem_len = 1, | ||
| 707 | .elem_size = sizeof(u8), | ||
| 708 | .array_type = NO_ARRAY, | ||
| 709 | .tlv_type = 0x11, | ||
| 710 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 711 | tgt_cfg_valid), | ||
| 712 | }, | ||
| 713 | { | ||
| 714 | .data_type = QMI_DATA_LEN, | ||
| 715 | .elem_len = 1, | ||
| 716 | .elem_size = sizeof(u8), | ||
| 717 | .array_type = NO_ARRAY, | ||
| 718 | .tlv_type = 0x11, | ||
| 719 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 720 | tgt_cfg_len), | ||
| 721 | }, | ||
| 722 | { | ||
| 723 | .data_type = QMI_STRUCT, | ||
| 724 | .elem_len = QMI_WLFW_MAX_NUM_CE_V01, | ||
| 725 | .elem_size = sizeof(struct wlfw_ce_tgt_pipe_cfg_s_v01), | ||
| 726 | .array_type = VAR_LEN_ARRAY, | ||
| 727 | .tlv_type = 0x11, | ||
| 728 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 729 | tgt_cfg), | ||
| 730 | .ei_array = wlfw_ce_tgt_pipe_cfg_s_v01_ei, | ||
| 731 | }, | ||
| 732 | { | ||
| 733 | .data_type = QMI_OPT_FLAG, | ||
| 734 | .elem_len = 1, | ||
| 735 | .elem_size = sizeof(u8), | ||
| 736 | .array_type = NO_ARRAY, | ||
| 737 | .tlv_type = 0x12, | ||
| 738 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 739 | svc_cfg_valid), | ||
| 740 | }, | ||
| 741 | { | ||
| 742 | .data_type = QMI_DATA_LEN, | ||
| 743 | .elem_len = 1, | ||
| 744 | .elem_size = sizeof(u8), | ||
| 745 | .array_type = NO_ARRAY, | ||
| 746 | .tlv_type = 0x12, | ||
| 747 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 748 | svc_cfg_len), | ||
| 749 | }, | ||
| 750 | { | ||
| 751 | .data_type = QMI_STRUCT, | ||
| 752 | .elem_len = QMI_WLFW_MAX_NUM_SVC_V01, | ||
| 753 | .elem_size = sizeof(struct wlfw_ce_svc_pipe_cfg_s_v01), | ||
| 754 | .array_type = VAR_LEN_ARRAY, | ||
| 755 | .tlv_type = 0x12, | ||
| 756 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 757 | svc_cfg), | ||
| 758 | .ei_array = wlfw_ce_svc_pipe_cfg_s_v01_ei, | ||
| 759 | }, | ||
| 760 | { | ||
| 761 | .data_type = QMI_OPT_FLAG, | ||
| 762 | .elem_len = 1, | ||
| 763 | .elem_size = sizeof(u8), | ||
| 764 | .array_type = NO_ARRAY, | ||
| 765 | .tlv_type = 0x13, | ||
| 766 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 767 | shadow_reg_valid), | ||
| 768 | }, | ||
| 769 | { | ||
| 770 | .data_type = QMI_DATA_LEN, | ||
| 771 | .elem_len = 1, | ||
| 772 | .elem_size = sizeof(u8), | ||
| 773 | .array_type = NO_ARRAY, | ||
| 774 | .tlv_type = 0x13, | ||
| 775 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 776 | shadow_reg_len), | ||
| 777 | }, | ||
| 778 | { | ||
| 779 | .data_type = QMI_STRUCT, | ||
| 780 | .elem_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01, | ||
| 781 | .elem_size = sizeof(struct wlfw_shadow_reg_cfg_s_v01), | ||
| 782 | .array_type = VAR_LEN_ARRAY, | ||
| 783 | .tlv_type = 0x13, | ||
| 784 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 785 | shadow_reg), | ||
| 786 | .ei_array = wlfw_shadow_reg_cfg_s_v01_ei, | ||
| 787 | }, | ||
| 788 | { | ||
| 789 | .data_type = QMI_OPT_FLAG, | ||
| 790 | .elem_len = 1, | ||
| 791 | .elem_size = sizeof(u8), | ||
| 792 | .array_type = NO_ARRAY, | ||
| 793 | .tlv_type = 0x14, | ||
| 794 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 795 | shadow_reg_v2_valid), | ||
| 796 | }, | ||
| 797 | { | ||
| 798 | .data_type = QMI_DATA_LEN, | ||
| 799 | .elem_len = 1, | ||
| 800 | .elem_size = sizeof(u8), | ||
| 801 | .array_type = NO_ARRAY, | ||
| 802 | .tlv_type = 0x14, | ||
| 803 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 804 | shadow_reg_v2_len), | ||
| 805 | }, | ||
| 806 | { | ||
| 807 | .data_type = QMI_STRUCT, | ||
| 808 | .elem_len = QMI_WLFW_MAX_SHADOW_REG_V2, | ||
| 809 | .elem_size = sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01), | ||
| 810 | .array_type = VAR_LEN_ARRAY, | ||
| 811 | .tlv_type = 0x14, | ||
| 812 | .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, | ||
| 813 | shadow_reg_v2), | ||
| 814 | .ei_array = wlfw_shadow_reg_v2_cfg_s_v01_ei, | ||
| 815 | }, | ||
| 816 | {} | ||
| 817 | }; | ||
| 818 | |||
| 819 | struct qmi_elem_info wlfw_wlan_cfg_resp_msg_v01_ei[] = { | ||
| 820 | { | ||
| 821 | .data_type = QMI_STRUCT, | ||
| 822 | .elem_len = 1, | ||
| 823 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 824 | .array_type = NO_ARRAY, | ||
| 825 | .tlv_type = 0x02, | ||
| 826 | .offset = offsetof(struct wlfw_wlan_cfg_resp_msg_v01, | ||
| 827 | resp), | ||
| 828 | .ei_array = qmi_response_type_v01_ei, | ||
| 829 | }, | ||
| 830 | {} | ||
| 831 | }; | ||
| 832 | |||
| 833 | struct qmi_elem_info wlfw_cap_req_msg_v01_ei[] = { | ||
| 834 | {} | ||
| 835 | }; | ||
| 836 | |||
| 837 | struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = { | ||
| 838 | { | ||
| 839 | .data_type = QMI_STRUCT, | ||
| 840 | .elem_len = 1, | ||
| 841 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 842 | .array_type = NO_ARRAY, | ||
| 843 | .tlv_type = 0x02, | ||
| 844 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 845 | resp), | ||
| 846 | .ei_array = qmi_response_type_v01_ei, | ||
| 847 | }, | ||
| 848 | { | ||
| 849 | .data_type = QMI_OPT_FLAG, | ||
| 850 | .elem_len = 1, | ||
| 851 | .elem_size = sizeof(u8), | ||
| 852 | .array_type = NO_ARRAY, | ||
| 853 | .tlv_type = 0x10, | ||
| 854 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 855 | chip_info_valid), | ||
| 856 | }, | ||
| 857 | { | ||
| 858 | .data_type = QMI_STRUCT, | ||
| 859 | .elem_len = 1, | ||
| 860 | .elem_size = sizeof(struct wlfw_rf_chip_info_s_v01), | ||
| 861 | .array_type = NO_ARRAY, | ||
| 862 | .tlv_type = 0x10, | ||
| 863 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 864 | chip_info), | ||
| 865 | .ei_array = wlfw_rf_chip_info_s_v01_ei, | ||
| 866 | }, | ||
| 867 | { | ||
| 868 | .data_type = QMI_OPT_FLAG, | ||
| 869 | .elem_len = 1, | ||
| 870 | .elem_size = sizeof(u8), | ||
| 871 | .array_type = NO_ARRAY, | ||
| 872 | .tlv_type = 0x11, | ||
| 873 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 874 | board_info_valid), | ||
| 875 | }, | ||
| 876 | { | ||
| 877 | .data_type = QMI_STRUCT, | ||
| 878 | .elem_len = 1, | ||
| 879 | .elem_size = sizeof(struct wlfw_rf_board_info_s_v01), | ||
| 880 | .array_type = NO_ARRAY, | ||
| 881 | .tlv_type = 0x11, | ||
| 882 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 883 | board_info), | ||
| 884 | .ei_array = wlfw_rf_board_info_s_v01_ei, | ||
| 885 | }, | ||
| 886 | { | ||
| 887 | .data_type = QMI_OPT_FLAG, | ||
| 888 | .elem_len = 1, | ||
| 889 | .elem_size = sizeof(u8), | ||
| 890 | .array_type = NO_ARRAY, | ||
| 891 | .tlv_type = 0x12, | ||
| 892 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 893 | soc_info_valid), | ||
| 894 | }, | ||
| 895 | { | ||
| 896 | .data_type = QMI_STRUCT, | ||
| 897 | .elem_len = 1, | ||
| 898 | .elem_size = sizeof(struct wlfw_soc_info_s_v01), | ||
| 899 | .array_type = NO_ARRAY, | ||
| 900 | .tlv_type = 0x12, | ||
| 901 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 902 | soc_info), | ||
| 903 | .ei_array = wlfw_soc_info_s_v01_ei, | ||
| 904 | }, | ||
| 905 | { | ||
| 906 | .data_type = QMI_OPT_FLAG, | ||
| 907 | .elem_len = 1, | ||
| 908 | .elem_size = sizeof(u8), | ||
| 909 | .array_type = NO_ARRAY, | ||
| 910 | .tlv_type = 0x13, | ||
| 911 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 912 | fw_version_info_valid), | ||
| 913 | }, | ||
| 914 | { | ||
| 915 | .data_type = QMI_STRUCT, | ||
| 916 | .elem_len = 1, | ||
| 917 | .elem_size = sizeof(struct wlfw_fw_version_info_s_v01), | ||
| 918 | .array_type = NO_ARRAY, | ||
| 919 | .tlv_type = 0x13, | ||
| 920 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 921 | fw_version_info), | ||
| 922 | .ei_array = wlfw_fw_version_info_s_v01_ei, | ||
| 923 | }, | ||
| 924 | { | ||
| 925 | .data_type = QMI_OPT_FLAG, | ||
| 926 | .elem_len = 1, | ||
| 927 | .elem_size = sizeof(u8), | ||
| 928 | .array_type = NO_ARRAY, | ||
| 929 | .tlv_type = 0x14, | ||
| 930 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 931 | fw_build_id_valid), | ||
| 932 | }, | ||
| 933 | { | ||
| 934 | .data_type = QMI_STRING, | ||
| 935 | .elem_len = QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1, | ||
| 936 | .elem_size = sizeof(char), | ||
| 937 | .array_type = NO_ARRAY, | ||
| 938 | .tlv_type = 0x14, | ||
| 939 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 940 | fw_build_id), | ||
| 941 | }, | ||
| 942 | { | ||
| 943 | .data_type = QMI_OPT_FLAG, | ||
| 944 | .elem_len = 1, | ||
| 945 | .elem_size = sizeof(u8), | ||
| 946 | .array_type = NO_ARRAY, | ||
| 947 | .tlv_type = 0x15, | ||
| 948 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 949 | num_macs_valid), | ||
| 950 | }, | ||
| 951 | { | ||
| 952 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 953 | .elem_len = 1, | ||
| 954 | .elem_size = sizeof(u8), | ||
| 955 | .array_type = NO_ARRAY, | ||
| 956 | .tlv_type = 0x15, | ||
| 957 | .offset = offsetof(struct wlfw_cap_resp_msg_v01, | ||
| 958 | num_macs), | ||
| 959 | }, | ||
| 960 | {} | ||
| 961 | }; | ||
| 962 | |||
| 963 | struct qmi_elem_info wlfw_bdf_download_req_msg_v01_ei[] = { | ||
| 964 | { | ||
| 965 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 966 | .elem_len = 1, | ||
| 967 | .elem_size = sizeof(u8), | ||
| 968 | .array_type = NO_ARRAY, | ||
| 969 | .tlv_type = 0x01, | ||
| 970 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 971 | valid), | ||
| 972 | }, | ||
| 973 | { | ||
| 974 | .data_type = QMI_OPT_FLAG, | ||
| 975 | .elem_len = 1, | ||
| 976 | .elem_size = sizeof(u8), | ||
| 977 | .array_type = NO_ARRAY, | ||
| 978 | .tlv_type = 0x10, | ||
| 979 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 980 | file_id_valid), | ||
| 981 | }, | ||
| 982 | { | ||
| 983 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 984 | .elem_len = 1, | ||
| 985 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 986 | .array_type = NO_ARRAY, | ||
| 987 | .tlv_type = 0x10, | ||
| 988 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 989 | file_id), | ||
| 990 | }, | ||
| 991 | { | ||
| 992 | .data_type = QMI_OPT_FLAG, | ||
| 993 | .elem_len = 1, | ||
| 994 | .elem_size = sizeof(u8), | ||
| 995 | .array_type = NO_ARRAY, | ||
| 996 | .tlv_type = 0x11, | ||
| 997 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 998 | total_size_valid), | ||
| 999 | }, | ||
| 1000 | { | ||
| 1001 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1002 | .elem_len = 1, | ||
| 1003 | .elem_size = sizeof(u32), | ||
| 1004 | .array_type = NO_ARRAY, | ||
| 1005 | .tlv_type = 0x11, | ||
| 1006 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1007 | total_size), | ||
| 1008 | }, | ||
| 1009 | { | ||
| 1010 | .data_type = QMI_OPT_FLAG, | ||
| 1011 | .elem_len = 1, | ||
| 1012 | .elem_size = sizeof(u8), | ||
| 1013 | .array_type = NO_ARRAY, | ||
| 1014 | .tlv_type = 0x12, | ||
| 1015 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1016 | seg_id_valid), | ||
| 1017 | }, | ||
| 1018 | { | ||
| 1019 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1020 | .elem_len = 1, | ||
| 1021 | .elem_size = sizeof(u32), | ||
| 1022 | .array_type = NO_ARRAY, | ||
| 1023 | .tlv_type = 0x12, | ||
| 1024 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1025 | seg_id), | ||
| 1026 | }, | ||
| 1027 | { | ||
| 1028 | .data_type = QMI_OPT_FLAG, | ||
| 1029 | .elem_len = 1, | ||
| 1030 | .elem_size = sizeof(u8), | ||
| 1031 | .array_type = NO_ARRAY, | ||
| 1032 | .tlv_type = 0x13, | ||
| 1033 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1034 | data_valid), | ||
| 1035 | }, | ||
| 1036 | { | ||
| 1037 | .data_type = QMI_DATA_LEN, | ||
| 1038 | .elem_len = 1, | ||
| 1039 | .elem_size = sizeof(u16), | ||
| 1040 | .array_type = NO_ARRAY, | ||
| 1041 | .tlv_type = 0x13, | ||
| 1042 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1043 | data_len), | ||
| 1044 | }, | ||
| 1045 | { | ||
| 1046 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1047 | .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, | ||
| 1048 | .elem_size = sizeof(u8), | ||
| 1049 | .array_type = VAR_LEN_ARRAY, | ||
| 1050 | .tlv_type = 0x13, | ||
| 1051 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1052 | data), | ||
| 1053 | }, | ||
| 1054 | { | ||
| 1055 | .data_type = QMI_OPT_FLAG, | ||
| 1056 | .elem_len = 1, | ||
| 1057 | .elem_size = sizeof(u8), | ||
| 1058 | .array_type = NO_ARRAY, | ||
| 1059 | .tlv_type = 0x14, | ||
| 1060 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1061 | end_valid), | ||
| 1062 | }, | ||
| 1063 | { | ||
| 1064 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1065 | .elem_len = 1, | ||
| 1066 | .elem_size = sizeof(u8), | ||
| 1067 | .array_type = NO_ARRAY, | ||
| 1068 | .tlv_type = 0x14, | ||
| 1069 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1070 | end), | ||
| 1071 | }, | ||
| 1072 | { | ||
| 1073 | .data_type = QMI_OPT_FLAG, | ||
| 1074 | .elem_len = 1, | ||
| 1075 | .elem_size = sizeof(u8), | ||
| 1076 | .array_type = NO_ARRAY, | ||
| 1077 | .tlv_type = 0x15, | ||
| 1078 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1079 | bdf_type_valid), | ||
| 1080 | }, | ||
| 1081 | { | ||
| 1082 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1083 | .elem_len = 1, | ||
| 1084 | .elem_size = sizeof(u8), | ||
| 1085 | .array_type = NO_ARRAY, | ||
| 1086 | .tlv_type = 0x15, | ||
| 1087 | .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, | ||
| 1088 | bdf_type), | ||
| 1089 | }, | ||
| 1090 | {} | ||
| 1091 | }; | ||
| 1092 | |||
| 1093 | struct qmi_elem_info wlfw_bdf_download_resp_msg_v01_ei[] = { | ||
| 1094 | { | ||
| 1095 | .data_type = QMI_STRUCT, | ||
| 1096 | .elem_len = 1, | ||
| 1097 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1098 | .array_type = NO_ARRAY, | ||
| 1099 | .tlv_type = 0x02, | ||
| 1100 | .offset = offsetof(struct wlfw_bdf_download_resp_msg_v01, | ||
| 1101 | resp), | ||
| 1102 | .ei_array = qmi_response_type_v01_ei, | ||
| 1103 | }, | ||
| 1104 | {} | ||
| 1105 | }; | ||
| 1106 | |||
| 1107 | struct qmi_elem_info wlfw_cal_report_req_msg_v01_ei[] = { | ||
| 1108 | { | ||
| 1109 | .data_type = QMI_DATA_LEN, | ||
| 1110 | .elem_len = 1, | ||
| 1111 | .elem_size = sizeof(u8), | ||
| 1112 | .array_type = NO_ARRAY, | ||
| 1113 | .tlv_type = 0x01, | ||
| 1114 | .offset = offsetof(struct wlfw_cal_report_req_msg_v01, | ||
| 1115 | meta_data_len), | ||
| 1116 | }, | ||
| 1117 | { | ||
| 1118 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1119 | .elem_len = QMI_WLFW_MAX_NUM_CAL_V01, | ||
| 1120 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1121 | .array_type = VAR_LEN_ARRAY, | ||
| 1122 | .tlv_type = 0x01, | ||
| 1123 | .offset = offsetof(struct wlfw_cal_report_req_msg_v01, | ||
| 1124 | meta_data), | ||
| 1125 | }, | ||
| 1126 | { | ||
| 1127 | .data_type = QMI_OPT_FLAG, | ||
| 1128 | .elem_len = 1, | ||
| 1129 | .elem_size = sizeof(u8), | ||
| 1130 | .array_type = NO_ARRAY, | ||
| 1131 | .tlv_type = 0x10, | ||
| 1132 | .offset = offsetof(struct wlfw_cal_report_req_msg_v01, | ||
| 1133 | xo_cal_data_valid), | ||
| 1134 | }, | ||
| 1135 | { | ||
| 1136 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1137 | .elem_len = 1, | ||
| 1138 | .elem_size = sizeof(u8), | ||
| 1139 | .array_type = NO_ARRAY, | ||
| 1140 | .tlv_type = 0x10, | ||
| 1141 | .offset = offsetof(struct wlfw_cal_report_req_msg_v01, | ||
| 1142 | xo_cal_data), | ||
| 1143 | }, | ||
| 1144 | {} | ||
| 1145 | }; | ||
| 1146 | |||
| 1147 | struct qmi_elem_info wlfw_cal_report_resp_msg_v01_ei[] = { | ||
| 1148 | { | ||
| 1149 | .data_type = QMI_STRUCT, | ||
| 1150 | .elem_len = 1, | ||
| 1151 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1152 | .array_type = NO_ARRAY, | ||
| 1153 | .tlv_type = 0x02, | ||
| 1154 | .offset = offsetof(struct wlfw_cal_report_resp_msg_v01, | ||
| 1155 | resp), | ||
| 1156 | .ei_array = qmi_response_type_v01_ei, | ||
| 1157 | }, | ||
| 1158 | {} | ||
| 1159 | }; | ||
| 1160 | |||
| 1161 | struct qmi_elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = { | ||
| 1162 | { | ||
| 1163 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1164 | .elem_len = 1, | ||
| 1165 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1166 | .array_type = NO_ARRAY, | ||
| 1167 | .tlv_type = 0x01, | ||
| 1168 | .offset = offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, | ||
| 1169 | cal_id), | ||
| 1170 | }, | ||
| 1171 | {} | ||
| 1172 | }; | ||
| 1173 | |||
| 1174 | struct qmi_elem_info wlfw_cal_download_req_msg_v01_ei[] = { | ||
| 1175 | { | ||
| 1176 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1177 | .elem_len = 1, | ||
| 1178 | .elem_size = sizeof(u8), | ||
| 1179 | .array_type = NO_ARRAY, | ||
| 1180 | .tlv_type = 0x01, | ||
| 1181 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1182 | valid), | ||
| 1183 | }, | ||
| 1184 | { | ||
| 1185 | .data_type = QMI_OPT_FLAG, | ||
| 1186 | .elem_len = 1, | ||
| 1187 | .elem_size = sizeof(u8), | ||
| 1188 | .array_type = NO_ARRAY, | ||
| 1189 | .tlv_type = 0x10, | ||
| 1190 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1191 | file_id_valid), | ||
| 1192 | }, | ||
| 1193 | { | ||
| 1194 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1195 | .elem_len = 1, | ||
| 1196 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1197 | .array_type = NO_ARRAY, | ||
| 1198 | .tlv_type = 0x10, | ||
| 1199 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1200 | file_id), | ||
| 1201 | }, | ||
| 1202 | { | ||
| 1203 | .data_type = QMI_OPT_FLAG, | ||
| 1204 | .elem_len = 1, | ||
| 1205 | .elem_size = sizeof(u8), | ||
| 1206 | .array_type = NO_ARRAY, | ||
| 1207 | .tlv_type = 0x11, | ||
| 1208 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1209 | total_size_valid), | ||
| 1210 | }, | ||
| 1211 | { | ||
| 1212 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1213 | .elem_len = 1, | ||
| 1214 | .elem_size = sizeof(u32), | ||
| 1215 | .array_type = NO_ARRAY, | ||
| 1216 | .tlv_type = 0x11, | ||
| 1217 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1218 | total_size), | ||
| 1219 | }, | ||
| 1220 | { | ||
| 1221 | .data_type = QMI_OPT_FLAG, | ||
| 1222 | .elem_len = 1, | ||
| 1223 | .elem_size = sizeof(u8), | ||
| 1224 | .array_type = NO_ARRAY, | ||
| 1225 | .tlv_type = 0x12, | ||
| 1226 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1227 | seg_id_valid), | ||
| 1228 | }, | ||
| 1229 | { | ||
| 1230 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1231 | .elem_len = 1, | ||
| 1232 | .elem_size = sizeof(u32), | ||
| 1233 | .array_type = NO_ARRAY, | ||
| 1234 | .tlv_type = 0x12, | ||
| 1235 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1236 | seg_id), | ||
| 1237 | }, | ||
| 1238 | { | ||
| 1239 | .data_type = QMI_OPT_FLAG, | ||
| 1240 | .elem_len = 1, | ||
| 1241 | .elem_size = sizeof(u8), | ||
| 1242 | .array_type = NO_ARRAY, | ||
| 1243 | .tlv_type = 0x13, | ||
| 1244 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1245 | data_valid), | ||
| 1246 | }, | ||
| 1247 | { | ||
| 1248 | .data_type = QMI_DATA_LEN, | ||
| 1249 | .elem_len = 1, | ||
| 1250 | .elem_size = sizeof(u16), | ||
| 1251 | .array_type = NO_ARRAY, | ||
| 1252 | .tlv_type = 0x13, | ||
| 1253 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1254 | data_len), | ||
| 1255 | }, | ||
| 1256 | { | ||
| 1257 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1258 | .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, | ||
| 1259 | .elem_size = sizeof(u8), | ||
| 1260 | .array_type = VAR_LEN_ARRAY, | ||
| 1261 | .tlv_type = 0x13, | ||
| 1262 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1263 | data), | ||
| 1264 | }, | ||
| 1265 | { | ||
| 1266 | .data_type = QMI_OPT_FLAG, | ||
| 1267 | .elem_len = 1, | ||
| 1268 | .elem_size = sizeof(u8), | ||
| 1269 | .array_type = NO_ARRAY, | ||
| 1270 | .tlv_type = 0x14, | ||
| 1271 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1272 | end_valid), | ||
| 1273 | }, | ||
| 1274 | { | ||
| 1275 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1276 | .elem_len = 1, | ||
| 1277 | .elem_size = sizeof(u8), | ||
| 1278 | .array_type = NO_ARRAY, | ||
| 1279 | .tlv_type = 0x14, | ||
| 1280 | .offset = offsetof(struct wlfw_cal_download_req_msg_v01, | ||
| 1281 | end), | ||
| 1282 | }, | ||
| 1283 | {} | ||
| 1284 | }; | ||
| 1285 | |||
| 1286 | struct qmi_elem_info wlfw_cal_download_resp_msg_v01_ei[] = { | ||
| 1287 | { | ||
| 1288 | .data_type = QMI_STRUCT, | ||
| 1289 | .elem_len = 1, | ||
| 1290 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1291 | .array_type = NO_ARRAY, | ||
| 1292 | .tlv_type = 0x02, | ||
| 1293 | .offset = offsetof(struct wlfw_cal_download_resp_msg_v01, | ||
| 1294 | resp), | ||
| 1295 | .ei_array = qmi_response_type_v01_ei, | ||
| 1296 | }, | ||
| 1297 | {} | ||
| 1298 | }; | ||
| 1299 | |||
| 1300 | struct qmi_elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = { | ||
| 1301 | { | ||
| 1302 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1303 | .elem_len = 1, | ||
| 1304 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1305 | .array_type = NO_ARRAY, | ||
| 1306 | .tlv_type = 0x01, | ||
| 1307 | .offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, | ||
| 1308 | cal_id), | ||
| 1309 | }, | ||
| 1310 | { | ||
| 1311 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1312 | .elem_len = 1, | ||
| 1313 | .elem_size = sizeof(u32), | ||
| 1314 | .array_type = NO_ARRAY, | ||
| 1315 | .tlv_type = 0x02, | ||
| 1316 | .offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, | ||
| 1317 | total_size), | ||
| 1318 | }, | ||
| 1319 | {} | ||
| 1320 | }; | ||
| 1321 | |||
| 1322 | struct qmi_elem_info wlfw_cal_update_req_msg_v01_ei[] = { | ||
| 1323 | { | ||
| 1324 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1325 | .elem_len = 1, | ||
| 1326 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1327 | .array_type = NO_ARRAY, | ||
| 1328 | .tlv_type = 0x01, | ||
| 1329 | .offset = offsetof(struct wlfw_cal_update_req_msg_v01, | ||
| 1330 | cal_id), | ||
| 1331 | }, | ||
| 1332 | { | ||
| 1333 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1334 | .elem_len = 1, | ||
| 1335 | .elem_size = sizeof(u32), | ||
| 1336 | .array_type = NO_ARRAY, | ||
| 1337 | .tlv_type = 0x02, | ||
| 1338 | .offset = offsetof(struct wlfw_cal_update_req_msg_v01, | ||
| 1339 | seg_id), | ||
| 1340 | }, | ||
| 1341 | {} | ||
| 1342 | }; | ||
| 1343 | |||
| 1344 | struct qmi_elem_info wlfw_cal_update_resp_msg_v01_ei[] = { | ||
| 1345 | { | ||
| 1346 | .data_type = QMI_STRUCT, | ||
| 1347 | .elem_len = 1, | ||
| 1348 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1349 | .array_type = NO_ARRAY, | ||
| 1350 | .tlv_type = 0x02, | ||
| 1351 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1352 | resp), | ||
| 1353 | .ei_array = qmi_response_type_v01_ei, | ||
| 1354 | }, | ||
| 1355 | { | ||
| 1356 | .data_type = QMI_OPT_FLAG, | ||
| 1357 | .elem_len = 1, | ||
| 1358 | .elem_size = sizeof(u8), | ||
| 1359 | .array_type = NO_ARRAY, | ||
| 1360 | .tlv_type = 0x10, | ||
| 1361 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1362 | file_id_valid), | ||
| 1363 | }, | ||
| 1364 | { | ||
| 1365 | .data_type = QMI_SIGNED_4_BYTE_ENUM, | ||
| 1366 | .elem_len = 1, | ||
| 1367 | .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), | ||
| 1368 | .array_type = NO_ARRAY, | ||
| 1369 | .tlv_type = 0x10, | ||
| 1370 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1371 | file_id), | ||
| 1372 | }, | ||
| 1373 | { | ||
| 1374 | .data_type = QMI_OPT_FLAG, | ||
| 1375 | .elem_len = 1, | ||
| 1376 | .elem_size = sizeof(u8), | ||
| 1377 | .array_type = NO_ARRAY, | ||
| 1378 | .tlv_type = 0x11, | ||
| 1379 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1380 | total_size_valid), | ||
| 1381 | }, | ||
| 1382 | { | ||
| 1383 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1384 | .elem_len = 1, | ||
| 1385 | .elem_size = sizeof(u32), | ||
| 1386 | .array_type = NO_ARRAY, | ||
| 1387 | .tlv_type = 0x11, | ||
| 1388 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1389 | total_size), | ||
| 1390 | }, | ||
| 1391 | { | ||
| 1392 | .data_type = QMI_OPT_FLAG, | ||
| 1393 | .elem_len = 1, | ||
| 1394 | .elem_size = sizeof(u8), | ||
| 1395 | .array_type = NO_ARRAY, | ||
| 1396 | .tlv_type = 0x12, | ||
| 1397 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1398 | seg_id_valid), | ||
| 1399 | }, | ||
| 1400 | { | ||
| 1401 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1402 | .elem_len = 1, | ||
| 1403 | .elem_size = sizeof(u32), | ||
| 1404 | .array_type = NO_ARRAY, | ||
| 1405 | .tlv_type = 0x12, | ||
| 1406 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1407 | seg_id), | ||
| 1408 | }, | ||
| 1409 | { | ||
| 1410 | .data_type = QMI_OPT_FLAG, | ||
| 1411 | .elem_len = 1, | ||
| 1412 | .elem_size = sizeof(u8), | ||
| 1413 | .array_type = NO_ARRAY, | ||
| 1414 | .tlv_type = 0x13, | ||
| 1415 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1416 | data_valid), | ||
| 1417 | }, | ||
| 1418 | { | ||
| 1419 | .data_type = QMI_DATA_LEN, | ||
| 1420 | .elem_len = 1, | ||
| 1421 | .elem_size = sizeof(u16), | ||
| 1422 | .array_type = NO_ARRAY, | ||
| 1423 | .tlv_type = 0x13, | ||
| 1424 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1425 | data_len), | ||
| 1426 | }, | ||
| 1427 | { | ||
| 1428 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1429 | .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, | ||
| 1430 | .elem_size = sizeof(u8), | ||
| 1431 | .array_type = VAR_LEN_ARRAY, | ||
| 1432 | .tlv_type = 0x13, | ||
| 1433 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1434 | data), | ||
| 1435 | }, | ||
| 1436 | { | ||
| 1437 | .data_type = QMI_OPT_FLAG, | ||
| 1438 | .elem_len = 1, | ||
| 1439 | .elem_size = sizeof(u8), | ||
| 1440 | .array_type = NO_ARRAY, | ||
| 1441 | .tlv_type = 0x14, | ||
| 1442 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1443 | end_valid), | ||
| 1444 | }, | ||
| 1445 | { | ||
| 1446 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1447 | .elem_len = 1, | ||
| 1448 | .elem_size = sizeof(u8), | ||
| 1449 | .array_type = NO_ARRAY, | ||
| 1450 | .tlv_type = 0x14, | ||
| 1451 | .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, | ||
| 1452 | end), | ||
| 1453 | }, | ||
| 1454 | {} | ||
| 1455 | }; | ||
| 1456 | |||
| 1457 | struct qmi_elem_info wlfw_msa_info_req_msg_v01_ei[] = { | ||
| 1458 | { | ||
| 1459 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 1460 | .elem_len = 1, | ||
| 1461 | .elem_size = sizeof(u64), | ||
| 1462 | .array_type = NO_ARRAY, | ||
| 1463 | .tlv_type = 0x01, | ||
| 1464 | .offset = offsetof(struct wlfw_msa_info_req_msg_v01, | ||
| 1465 | msa_addr), | ||
| 1466 | }, | ||
| 1467 | { | ||
| 1468 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1469 | .elem_len = 1, | ||
| 1470 | .elem_size = sizeof(u32), | ||
| 1471 | .array_type = NO_ARRAY, | ||
| 1472 | .tlv_type = 0x02, | ||
| 1473 | .offset = offsetof(struct wlfw_msa_info_req_msg_v01, | ||
| 1474 | size), | ||
| 1475 | }, | ||
| 1476 | {} | ||
| 1477 | }; | ||
| 1478 | |||
| 1479 | struct qmi_elem_info wlfw_msa_info_resp_msg_v01_ei[] = { | ||
| 1480 | { | ||
| 1481 | .data_type = QMI_STRUCT, | ||
| 1482 | .elem_len = 1, | ||
| 1483 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1484 | .array_type = NO_ARRAY, | ||
| 1485 | .tlv_type = 0x02, | ||
| 1486 | .offset = offsetof(struct wlfw_msa_info_resp_msg_v01, | ||
| 1487 | resp), | ||
| 1488 | .ei_array = qmi_response_type_v01_ei, | ||
| 1489 | }, | ||
| 1490 | { | ||
| 1491 | .data_type = QMI_DATA_LEN, | ||
| 1492 | .elem_len = 1, | ||
| 1493 | .elem_size = sizeof(u8), | ||
| 1494 | .array_type = NO_ARRAY, | ||
| 1495 | .tlv_type = 0x03, | ||
| 1496 | .offset = offsetof(struct wlfw_msa_info_resp_msg_v01, | ||
| 1497 | mem_region_info_len), | ||
| 1498 | }, | ||
| 1499 | { | ||
| 1500 | .data_type = QMI_STRUCT, | ||
| 1501 | .elem_len = QMI_WLFW_MAX_MEM_REG_V01, | ||
| 1502 | .elem_size = sizeof(struct wlfw_memory_region_info_s_v01), | ||
| 1503 | .array_type = VAR_LEN_ARRAY, | ||
| 1504 | .tlv_type = 0x03, | ||
| 1505 | .offset = offsetof(struct wlfw_msa_info_resp_msg_v01, | ||
| 1506 | mem_region_info), | ||
| 1507 | .ei_array = wlfw_memory_region_info_s_v01_ei, | ||
| 1508 | }, | ||
| 1509 | {} | ||
| 1510 | }; | ||
| 1511 | |||
| 1512 | struct qmi_elem_info wlfw_msa_ready_req_msg_v01_ei[] = { | ||
| 1513 | {} | ||
| 1514 | }; | ||
| 1515 | |||
| 1516 | struct qmi_elem_info wlfw_msa_ready_resp_msg_v01_ei[] = { | ||
| 1517 | { | ||
| 1518 | .data_type = QMI_STRUCT, | ||
| 1519 | .elem_len = 1, | ||
| 1520 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1521 | .array_type = NO_ARRAY, | ||
| 1522 | .tlv_type = 0x02, | ||
| 1523 | .offset = offsetof(struct wlfw_msa_ready_resp_msg_v01, | ||
| 1524 | resp), | ||
| 1525 | .ei_array = qmi_response_type_v01_ei, | ||
| 1526 | }, | ||
| 1527 | {} | ||
| 1528 | }; | ||
| 1529 | |||
| 1530 | struct qmi_elem_info wlfw_ini_req_msg_v01_ei[] = { | ||
| 1531 | { | ||
| 1532 | .data_type = QMI_OPT_FLAG, | ||
| 1533 | .elem_len = 1, | ||
| 1534 | .elem_size = sizeof(u8), | ||
| 1535 | .array_type = NO_ARRAY, | ||
| 1536 | .tlv_type = 0x10, | ||
| 1537 | .offset = offsetof(struct wlfw_ini_req_msg_v01, | ||
| 1538 | enablefwlog_valid), | ||
| 1539 | }, | ||
| 1540 | { | ||
| 1541 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1542 | .elem_len = 1, | ||
| 1543 | .elem_size = sizeof(u8), | ||
| 1544 | .array_type = NO_ARRAY, | ||
| 1545 | .tlv_type = 0x10, | ||
| 1546 | .offset = offsetof(struct wlfw_ini_req_msg_v01, | ||
| 1547 | enablefwlog), | ||
| 1548 | }, | ||
| 1549 | {} | ||
| 1550 | }; | ||
| 1551 | |||
| 1552 | struct qmi_elem_info wlfw_ini_resp_msg_v01_ei[] = { | ||
| 1553 | { | ||
| 1554 | .data_type = QMI_STRUCT, | ||
| 1555 | .elem_len = 1, | ||
| 1556 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1557 | .array_type = NO_ARRAY, | ||
| 1558 | .tlv_type = 0x02, | ||
| 1559 | .offset = offsetof(struct wlfw_ini_resp_msg_v01, | ||
| 1560 | resp), | ||
| 1561 | .ei_array = qmi_response_type_v01_ei, | ||
| 1562 | }, | ||
| 1563 | {} | ||
| 1564 | }; | ||
| 1565 | |||
| 1566 | struct qmi_elem_info wlfw_athdiag_read_req_msg_v01_ei[] = { | ||
| 1567 | { | ||
| 1568 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1569 | .elem_len = 1, | ||
| 1570 | .elem_size = sizeof(u32), | ||
| 1571 | .array_type = NO_ARRAY, | ||
| 1572 | .tlv_type = 0x01, | ||
| 1573 | .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, | ||
| 1574 | offset), | ||
| 1575 | }, | ||
| 1576 | { | ||
| 1577 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1578 | .elem_len = 1, | ||
| 1579 | .elem_size = sizeof(u32), | ||
| 1580 | .array_type = NO_ARRAY, | ||
| 1581 | .tlv_type = 0x02, | ||
| 1582 | .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, | ||
| 1583 | mem_type), | ||
| 1584 | }, | ||
| 1585 | { | ||
| 1586 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1587 | .elem_len = 1, | ||
| 1588 | .elem_size = sizeof(u32), | ||
| 1589 | .array_type = NO_ARRAY, | ||
| 1590 | .tlv_type = 0x03, | ||
| 1591 | .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, | ||
| 1592 | data_len), | ||
| 1593 | }, | ||
| 1594 | {} | ||
| 1595 | }; | ||
| 1596 | |||
| 1597 | struct qmi_elem_info wlfw_athdiag_read_resp_msg_v01_ei[] = { | ||
| 1598 | { | ||
| 1599 | .data_type = QMI_STRUCT, | ||
| 1600 | .elem_len = 1, | ||
| 1601 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1602 | .array_type = NO_ARRAY, | ||
| 1603 | .tlv_type = 0x02, | ||
| 1604 | .offset = offsetof(struct wlfw_athdiag_read_resp_msg_v01, | ||
| 1605 | resp), | ||
| 1606 | .ei_array = qmi_response_type_v01_ei, | ||
| 1607 | }, | ||
| 1608 | { | ||
| 1609 | .data_type = QMI_OPT_FLAG, | ||
| 1610 | .elem_len = 1, | ||
| 1611 | .elem_size = sizeof(u8), | ||
| 1612 | .array_type = NO_ARRAY, | ||
| 1613 | .tlv_type = 0x10, | ||
| 1614 | .offset = offsetof(struct wlfw_athdiag_read_resp_msg_v01, | ||
| 1615 | data_valid), | ||
| 1616 | }, | ||
| 1617 | { | ||
| 1618 | .data_type = QMI_DATA_LEN, | ||
| 1619 | .elem_len = 1, | ||
| 1620 | .elem_size = sizeof(u16), | ||
| 1621 | .array_type = NO_ARRAY, | ||
| 1622 | .tlv_type = 0x10, | ||
| 1623 | .offset = offsetof(struct wlfw_athdiag_read_resp_msg_v01, | ||
| 1624 | data_len), | ||
| 1625 | }, | ||
| 1626 | { | ||
| 1627 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1628 | .elem_len = QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01, | ||
| 1629 | .elem_size = sizeof(u8), | ||
| 1630 | .array_type = VAR_LEN_ARRAY, | ||
| 1631 | .tlv_type = 0x10, | ||
| 1632 | .offset = offsetof(struct wlfw_athdiag_read_resp_msg_v01, | ||
| 1633 | data), | ||
| 1634 | }, | ||
| 1635 | {} | ||
| 1636 | }; | ||
| 1637 | |||
| 1638 | struct qmi_elem_info wlfw_athdiag_write_req_msg_v01_ei[] = { | ||
| 1639 | { | ||
| 1640 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1641 | .elem_len = 1, | ||
| 1642 | .elem_size = sizeof(u32), | ||
| 1643 | .array_type = NO_ARRAY, | ||
| 1644 | .tlv_type = 0x01, | ||
| 1645 | .offset = offsetof(struct wlfw_athdiag_write_req_msg_v01, | ||
| 1646 | offset), | ||
| 1647 | }, | ||
| 1648 | { | ||
| 1649 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 1650 | .elem_len = 1, | ||
| 1651 | .elem_size = sizeof(u32), | ||
| 1652 | .array_type = NO_ARRAY, | ||
| 1653 | .tlv_type = 0x02, | ||
| 1654 | .offset = offsetof(struct wlfw_athdiag_write_req_msg_v01, | ||
| 1655 | mem_type), | ||
| 1656 | }, | ||
| 1657 | { | ||
| 1658 | .data_type = QMI_DATA_LEN, | ||
| 1659 | .elem_len = 1, | ||
| 1660 | .elem_size = sizeof(u16), | ||
| 1661 | .array_type = NO_ARRAY, | ||
| 1662 | .tlv_type = 0x03, | ||
| 1663 | .offset = offsetof(struct wlfw_athdiag_write_req_msg_v01, | ||
| 1664 | data_len), | ||
| 1665 | }, | ||
| 1666 | { | ||
| 1667 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1668 | .elem_len = QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01, | ||
| 1669 | .elem_size = sizeof(u8), | ||
| 1670 | .array_type = VAR_LEN_ARRAY, | ||
| 1671 | .tlv_type = 0x03, | ||
| 1672 | .offset = offsetof(struct wlfw_athdiag_write_req_msg_v01, | ||
| 1673 | data), | ||
| 1674 | }, | ||
| 1675 | {} | ||
| 1676 | }; | ||
| 1677 | |||
| 1678 | struct qmi_elem_info wlfw_athdiag_write_resp_msg_v01_ei[] = { | ||
| 1679 | { | ||
| 1680 | .data_type = QMI_STRUCT, | ||
| 1681 | .elem_len = 1, | ||
| 1682 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1683 | .array_type = NO_ARRAY, | ||
| 1684 | .tlv_type = 0x02, | ||
| 1685 | .offset = offsetof(struct wlfw_athdiag_write_resp_msg_v01, | ||
| 1686 | resp), | ||
| 1687 | .ei_array = qmi_response_type_v01_ei, | ||
| 1688 | }, | ||
| 1689 | {} | ||
| 1690 | }; | ||
| 1691 | |||
| 1692 | struct qmi_elem_info wlfw_vbatt_req_msg_v01_ei[] = { | ||
| 1693 | { | ||
| 1694 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 1695 | .elem_len = 1, | ||
| 1696 | .elem_size = sizeof(u64), | ||
| 1697 | .array_type = NO_ARRAY, | ||
| 1698 | .tlv_type = 0x01, | ||
| 1699 | .offset = offsetof(struct wlfw_vbatt_req_msg_v01, | ||
| 1700 | voltage_uv), | ||
| 1701 | }, | ||
| 1702 | {} | ||
| 1703 | }; | ||
| 1704 | |||
| 1705 | struct qmi_elem_info wlfw_vbatt_resp_msg_v01_ei[] = { | ||
| 1706 | { | ||
| 1707 | .data_type = QMI_STRUCT, | ||
| 1708 | .elem_len = 1, | ||
| 1709 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1710 | .array_type = NO_ARRAY, | ||
| 1711 | .tlv_type = 0x02, | ||
| 1712 | .offset = offsetof(struct wlfw_vbatt_resp_msg_v01, | ||
| 1713 | resp), | ||
| 1714 | .ei_array = qmi_response_type_v01_ei, | ||
| 1715 | }, | ||
| 1716 | {} | ||
| 1717 | }; | ||
| 1718 | |||
| 1719 | struct qmi_elem_info wlfw_mac_addr_req_msg_v01_ei[] = { | ||
| 1720 | { | ||
| 1721 | .data_type = QMI_OPT_FLAG, | ||
| 1722 | .elem_len = 1, | ||
| 1723 | .elem_size = sizeof(u8), | ||
| 1724 | .array_type = NO_ARRAY, | ||
| 1725 | .tlv_type = 0x10, | ||
| 1726 | .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, | ||
| 1727 | mac_addr_valid), | ||
| 1728 | }, | ||
| 1729 | { | ||
| 1730 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1731 | .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01, | ||
| 1732 | .elem_size = sizeof(u8), | ||
| 1733 | .array_type = STATIC_ARRAY, | ||
| 1734 | .tlv_type = 0x10, | ||
| 1735 | .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, | ||
| 1736 | mac_addr), | ||
| 1737 | }, | ||
| 1738 | {} | ||
| 1739 | }; | ||
| 1740 | |||
| 1741 | struct qmi_elem_info wlfw_mac_addr_resp_msg_v01_ei[] = { | ||
| 1742 | { | ||
| 1743 | .data_type = QMI_STRUCT, | ||
| 1744 | .elem_len = 1, | ||
| 1745 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1746 | .array_type = NO_ARRAY, | ||
| 1747 | .tlv_type = 0x02, | ||
| 1748 | .offset = offsetof(struct wlfw_mac_addr_resp_msg_v01, | ||
| 1749 | resp), | ||
| 1750 | .ei_array = qmi_response_type_v01_ei, | ||
| 1751 | }, | ||
| 1752 | {} | ||
| 1753 | }; | ||
| 1754 | |||
| 1755 | struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = { | ||
| 1756 | { | ||
| 1757 | .data_type = QMI_OPT_FLAG, | ||
| 1758 | .elem_len = 1, | ||
| 1759 | .elem_size = sizeof(u8), | ||
| 1760 | .array_type = NO_ARRAY, | ||
| 1761 | .tlv_type = 0x10, | ||
| 1762 | .offset = offsetof(struct wlfw_host_cap_req_msg_v01, | ||
| 1763 | daemon_support_valid), | ||
| 1764 | }, | ||
| 1765 | { | ||
| 1766 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1767 | .elem_len = 1, | ||
| 1768 | .elem_size = sizeof(u8), | ||
| 1769 | .array_type = NO_ARRAY, | ||
| 1770 | .tlv_type = 0x10, | ||
| 1771 | .offset = offsetof(struct wlfw_host_cap_req_msg_v01, | ||
| 1772 | daemon_support), | ||
| 1773 | }, | ||
| 1774 | {} | ||
| 1775 | }; | ||
| 1776 | |||
| 1777 | struct qmi_elem_info wlfw_host_cap_resp_msg_v01_ei[] = { | ||
| 1778 | { | ||
| 1779 | .data_type = QMI_STRUCT, | ||
| 1780 | .elem_len = 1, | ||
| 1781 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1782 | .array_type = NO_ARRAY, | ||
| 1783 | .tlv_type = 0x02, | ||
| 1784 | .offset = offsetof(struct wlfw_host_cap_resp_msg_v01, | ||
| 1785 | resp), | ||
| 1786 | .ei_array = qmi_response_type_v01_ei, | ||
| 1787 | }, | ||
| 1788 | {} | ||
| 1789 | }; | ||
| 1790 | |||
| 1791 | struct qmi_elem_info wlfw_request_mem_ind_msg_v01_ei[] = { | ||
| 1792 | { | ||
| 1793 | .data_type = QMI_DATA_LEN, | ||
| 1794 | .elem_len = 1, | ||
| 1795 | .elem_size = sizeof(u8), | ||
| 1796 | .array_type = NO_ARRAY, | ||
| 1797 | .tlv_type = 0x01, | ||
| 1798 | .offset = offsetof(struct wlfw_request_mem_ind_msg_v01, | ||
| 1799 | mem_seg_len), | ||
| 1800 | }, | ||
| 1801 | { | ||
| 1802 | .data_type = QMI_STRUCT, | ||
| 1803 | .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, | ||
| 1804 | .elem_size = sizeof(struct wlfw_mem_seg_s_v01), | ||
| 1805 | .array_type = VAR_LEN_ARRAY, | ||
| 1806 | .tlv_type = 0x01, | ||
| 1807 | .offset = offsetof(struct wlfw_request_mem_ind_msg_v01, | ||
| 1808 | mem_seg), | ||
| 1809 | .ei_array = wlfw_mem_seg_s_v01_ei, | ||
| 1810 | }, | ||
| 1811 | {} | ||
| 1812 | }; | ||
| 1813 | |||
| 1814 | struct qmi_elem_info wlfw_respond_mem_req_msg_v01_ei[] = { | ||
| 1815 | { | ||
| 1816 | .data_type = QMI_DATA_LEN, | ||
| 1817 | .elem_len = 1, | ||
| 1818 | .elem_size = sizeof(u8), | ||
| 1819 | .array_type = NO_ARRAY, | ||
| 1820 | .tlv_type = 0x01, | ||
| 1821 | .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, | ||
| 1822 | mem_seg_len), | ||
| 1823 | }, | ||
| 1824 | { | ||
| 1825 | .data_type = QMI_STRUCT, | ||
| 1826 | .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, | ||
| 1827 | .elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01), | ||
| 1828 | .array_type = VAR_LEN_ARRAY, | ||
| 1829 | .tlv_type = 0x01, | ||
| 1830 | .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, | ||
| 1831 | mem_seg), | ||
| 1832 | .ei_array = wlfw_mem_seg_resp_s_v01_ei, | ||
| 1833 | }, | ||
| 1834 | {} | ||
| 1835 | }; | ||
| 1836 | |||
| 1837 | struct qmi_elem_info wlfw_respond_mem_resp_msg_v01_ei[] = { | ||
| 1838 | { | ||
| 1839 | .data_type = QMI_STRUCT, | ||
| 1840 | .elem_len = 1, | ||
| 1841 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1842 | .array_type = NO_ARRAY, | ||
| 1843 | .tlv_type = 0x02, | ||
| 1844 | .offset = offsetof(struct wlfw_respond_mem_resp_msg_v01, | ||
| 1845 | resp), | ||
| 1846 | .ei_array = qmi_response_type_v01_ei, | ||
| 1847 | }, | ||
| 1848 | {} | ||
| 1849 | }; | ||
| 1850 | |||
| 1851 | struct qmi_elem_info wlfw_mem_ready_ind_msg_v01_ei[] = { | ||
| 1852 | {} | ||
| 1853 | }; | ||
| 1854 | |||
| 1855 | struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { | ||
| 1856 | {} | ||
| 1857 | }; | ||
| 1858 | |||
| 1859 | struct qmi_elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { | ||
| 1860 | { | ||
| 1861 | .data_type = QMI_OPT_FLAG, | ||
| 1862 | .elem_len = 1, | ||
| 1863 | .elem_size = sizeof(u8), | ||
| 1864 | .array_type = NO_ARRAY, | ||
| 1865 | .tlv_type = 0x10, | ||
| 1866 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1867 | cause_for_rejuvenation_valid), | ||
| 1868 | }, | ||
| 1869 | { | ||
| 1870 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1871 | .elem_len = 1, | ||
| 1872 | .elem_size = sizeof(u8), | ||
| 1873 | .array_type = NO_ARRAY, | ||
| 1874 | .tlv_type = 0x10, | ||
| 1875 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1876 | cause_for_rejuvenation), | ||
| 1877 | }, | ||
| 1878 | { | ||
| 1879 | .data_type = QMI_OPT_FLAG, | ||
| 1880 | .elem_len = 1, | ||
| 1881 | .elem_size = sizeof(u8), | ||
| 1882 | .array_type = NO_ARRAY, | ||
| 1883 | .tlv_type = 0x11, | ||
| 1884 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1885 | requesting_sub_system_valid), | ||
| 1886 | }, | ||
| 1887 | { | ||
| 1888 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 1889 | .elem_len = 1, | ||
| 1890 | .elem_size = sizeof(u8), | ||
| 1891 | .array_type = NO_ARRAY, | ||
| 1892 | .tlv_type = 0x11, | ||
| 1893 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1894 | requesting_sub_system), | ||
| 1895 | }, | ||
| 1896 | { | ||
| 1897 | .data_type = QMI_OPT_FLAG, | ||
| 1898 | .elem_len = 1, | ||
| 1899 | .elem_size = sizeof(u8), | ||
| 1900 | .array_type = NO_ARRAY, | ||
| 1901 | .tlv_type = 0x12, | ||
| 1902 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1903 | line_number_valid), | ||
| 1904 | }, | ||
| 1905 | { | ||
| 1906 | .data_type = QMI_UNSIGNED_2_BYTE, | ||
| 1907 | .elem_len = 1, | ||
| 1908 | .elem_size = sizeof(u16), | ||
| 1909 | .array_type = NO_ARRAY, | ||
| 1910 | .tlv_type = 0x12, | ||
| 1911 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1912 | line_number), | ||
| 1913 | }, | ||
| 1914 | { | ||
| 1915 | .data_type = QMI_OPT_FLAG, | ||
| 1916 | .elem_len = 1, | ||
| 1917 | .elem_size = sizeof(u8), | ||
| 1918 | .array_type = NO_ARRAY, | ||
| 1919 | .tlv_type = 0x13, | ||
| 1920 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1921 | function_name_valid), | ||
| 1922 | }, | ||
| 1923 | { | ||
| 1924 | .data_type = QMI_STRING, | ||
| 1925 | .elem_len = QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1, | ||
| 1926 | .elem_size = sizeof(char), | ||
| 1927 | .array_type = NO_ARRAY, | ||
| 1928 | .tlv_type = 0x13, | ||
| 1929 | .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, | ||
| 1930 | function_name), | ||
| 1931 | }, | ||
| 1932 | {} | ||
| 1933 | }; | ||
| 1934 | |||
| 1935 | struct qmi_elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[] = { | ||
| 1936 | {} | ||
| 1937 | }; | ||
| 1938 | |||
| 1939 | struct qmi_elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[] = { | ||
| 1940 | { | ||
| 1941 | .data_type = QMI_STRUCT, | ||
| 1942 | .elem_len = 1, | ||
| 1943 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1944 | .array_type = NO_ARRAY, | ||
| 1945 | .tlv_type = 0x02, | ||
| 1946 | .offset = offsetof(struct wlfw_rejuvenate_ack_resp_msg_v01, | ||
| 1947 | resp), | ||
| 1948 | .ei_array = qmi_response_type_v01_ei, | ||
| 1949 | }, | ||
| 1950 | {} | ||
| 1951 | }; | ||
| 1952 | |||
| 1953 | struct qmi_elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[] = { | ||
| 1954 | { | ||
| 1955 | .data_type = QMI_OPT_FLAG, | ||
| 1956 | .elem_len = 1, | ||
| 1957 | .elem_size = sizeof(u8), | ||
| 1958 | .array_type = NO_ARRAY, | ||
| 1959 | .tlv_type = 0x10, | ||
| 1960 | .offset = offsetof(struct wlfw_dynamic_feature_mask_req_msg_v01, | ||
| 1961 | mask_valid), | ||
| 1962 | }, | ||
| 1963 | { | ||
| 1964 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 1965 | .elem_len = 1, | ||
| 1966 | .elem_size = sizeof(u64), | ||
| 1967 | .array_type = NO_ARRAY, | ||
| 1968 | .tlv_type = 0x10, | ||
| 1969 | .offset = offsetof(struct wlfw_dynamic_feature_mask_req_msg_v01, | ||
| 1970 | mask), | ||
| 1971 | }, | ||
| 1972 | {} | ||
| 1973 | }; | ||
| 1974 | |||
| 1975 | struct qmi_elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[] = { | ||
| 1976 | { | ||
| 1977 | .data_type = QMI_STRUCT, | ||
| 1978 | .elem_len = 1, | ||
| 1979 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 1980 | .array_type = NO_ARRAY, | ||
| 1981 | .tlv_type = 0x02, | ||
| 1982 | .offset = offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, | ||
| 1983 | resp), | ||
| 1984 | .ei_array = qmi_response_type_v01_ei, | ||
| 1985 | }, | ||
| 1986 | { | ||
| 1987 | .data_type = QMI_OPT_FLAG, | ||
| 1988 | .elem_len = 1, | ||
| 1989 | .elem_size = sizeof(u8), | ||
| 1990 | .array_type = NO_ARRAY, | ||
| 1991 | .tlv_type = 0x10, | ||
| 1992 | .offset = offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, | ||
| 1993 | prev_mask_valid), | ||
| 1994 | }, | ||
| 1995 | { | ||
| 1996 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 1997 | .elem_len = 1, | ||
| 1998 | .elem_size = sizeof(u64), | ||
| 1999 | .array_type = NO_ARRAY, | ||
| 2000 | .tlv_type = 0x10, | ||
| 2001 | .offset = offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, | ||
| 2002 | prev_mask), | ||
| 2003 | }, | ||
| 2004 | { | ||
| 2005 | .data_type = QMI_OPT_FLAG, | ||
| 2006 | .elem_len = 1, | ||
| 2007 | .elem_size = sizeof(u8), | ||
| 2008 | .array_type = NO_ARRAY, | ||
| 2009 | .tlv_type = 0x11, | ||
| 2010 | .offset = offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, | ||
| 2011 | curr_mask_valid), | ||
| 2012 | }, | ||
| 2013 | { | ||
| 2014 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 2015 | .elem_len = 1, | ||
| 2016 | .elem_size = sizeof(u64), | ||
| 2017 | .array_type = NO_ARRAY, | ||
| 2018 | .tlv_type = 0x11, | ||
| 2019 | .offset = offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, | ||
| 2020 | curr_mask), | ||
| 2021 | }, | ||
| 2022 | {} | ||
| 2023 | }; | ||
| 2024 | |||
| 2025 | struct qmi_elem_info wlfw_m3_info_req_msg_v01_ei[] = { | ||
| 2026 | { | ||
| 2027 | .data_type = QMI_UNSIGNED_8_BYTE, | ||
| 2028 | .elem_len = 1, | ||
| 2029 | .elem_size = sizeof(u64), | ||
| 2030 | .array_type = NO_ARRAY, | ||
| 2031 | .tlv_type = 0x01, | ||
| 2032 | .offset = offsetof(struct wlfw_m3_info_req_msg_v01, | ||
| 2033 | addr), | ||
| 2034 | }, | ||
| 2035 | { | ||
| 2036 | .data_type = QMI_UNSIGNED_4_BYTE, | ||
| 2037 | .elem_len = 1, | ||
| 2038 | .elem_size = sizeof(u32), | ||
| 2039 | .array_type = NO_ARRAY, | ||
| 2040 | .tlv_type = 0x02, | ||
| 2041 | .offset = offsetof(struct wlfw_m3_info_req_msg_v01, | ||
| 2042 | size), | ||
| 2043 | }, | ||
| 2044 | {} | ||
| 2045 | }; | ||
| 2046 | |||
| 2047 | struct qmi_elem_info wlfw_m3_info_resp_msg_v01_ei[] = { | ||
| 2048 | { | ||
| 2049 | .data_type = QMI_STRUCT, | ||
| 2050 | .elem_len = 1, | ||
| 2051 | .elem_size = sizeof(struct qmi_response_type_v01), | ||
| 2052 | .array_type = NO_ARRAY, | ||
| 2053 | .tlv_type = 0x02, | ||
| 2054 | .offset = offsetof(struct wlfw_m3_info_resp_msg_v01, | ||
| 2055 | resp), | ||
| 2056 | .ei_array = qmi_response_type_v01_ei, | ||
| 2057 | }, | ||
| 2058 | {} | ||
| 2059 | }; | ||
| 2060 | |||
| 2061 | struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[] = { | ||
| 2062 | { | ||
| 2063 | .data_type = QMI_UNSIGNED_1_BYTE, | ||
| 2064 | .elem_len = 1, | ||
| 2065 | .elem_size = sizeof(u8), | ||
| 2066 | .array_type = NO_ARRAY, | ||
| 2067 | .tlv_type = 0x01, | ||
| 2068 | .offset = offsetof(struct wlfw_xo_cal_ind_msg_v01, | ||
| 2069 | xo_cal_data), | ||
| 2070 | }, | ||
| 2071 | {} | ||
| 2072 | }; | ||
diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h new file mode 100644 index 000000000000..c5e3870b8871 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h | |||
| @@ -0,0 +1,677 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2018 The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef WCN3990_QMI_SVC_V01_H | ||
| 18 | #define WCN3990_QMI_SVC_V01_H | ||
| 19 | |||
| 20 | #define WLFW_SERVICE_ID_V01 0x45 | ||
| 21 | #define WLFW_SERVICE_VERS_V01 0x01 | ||
| 22 | |||
| 23 | #define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025 | ||
| 24 | #define QMI_WLFW_MEM_READY_IND_V01 0x0037 | ||
| 25 | #define QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01 0x003B | ||
| 26 | #define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A | ||
| 27 | #define QMI_WLFW_HOST_CAP_REQ_V01 0x0034 | ||
| 28 | #define QMI_WLFW_M3_INFO_REQ_V01 0x003C | ||
| 29 | #define QMI_WLFW_CAP_REQ_V01 0x0024 | ||
| 30 | #define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 | ||
| 31 | #define QMI_WLFW_CAL_REPORT_REQ_V01 0x0026 | ||
| 32 | #define QMI_WLFW_M3_INFO_RESP_V01 0x003C | ||
| 33 | #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 | ||
| 34 | #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 | ||
| 35 | #define QMI_WLFW_XO_CAL_IND_V01 0x003D | ||
| 36 | #define QMI_WLFW_INI_RESP_V01 0x002F | ||
| 37 | #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 | ||
| 38 | #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 | ||
| 39 | #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 | ||
| 40 | #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 | ||
| 41 | #define QMI_WLFW_MSA_READY_IND_V01 0x002B | ||
| 42 | #define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031 | ||
| 43 | #define QMI_WLFW_WLAN_MODE_REQ_V01 0x0022 | ||
| 44 | #define QMI_WLFW_IND_REGISTER_REQ_V01 0x0020 | ||
| 45 | #define QMI_WLFW_WLAN_CFG_RESP_V01 0x0023 | ||
| 46 | #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 | ||
| 47 | #define QMI_WLFW_REJUVENATE_IND_V01 0x0039 | ||
| 48 | #define QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01 0x003B | ||
| 49 | #define QMI_WLFW_ATHDIAG_WRITE_REQ_V01 0x0031 | ||
| 50 | #define QMI_WLFW_WLAN_MODE_RESP_V01 0x0022 | ||
| 51 | #define QMI_WLFW_RESPOND_MEM_REQ_V01 0x0036 | ||
| 52 | #define QMI_WLFW_PIN_CONNECT_RESULT_IND_V01 0x002C | ||
| 53 | #define QMI_WLFW_FW_READY_IND_V01 0x0021 | ||
| 54 | #define QMI_WLFW_MSA_READY_RESP_V01 0x002E | ||
| 55 | #define QMI_WLFW_CAL_UPDATE_REQ_V01 0x0029 | ||
| 56 | #define QMI_WLFW_INI_REQ_V01 0x002F | ||
| 57 | #define QMI_WLFW_BDF_DOWNLOAD_RESP_V01 0x0025 | ||
| 58 | #define QMI_WLFW_REJUVENATE_ACK_RESP_V01 0x003A | ||
| 59 | #define QMI_WLFW_MSA_INFO_RESP_V01 0x002D | ||
| 60 | #define QMI_WLFW_MSA_READY_REQ_V01 0x002E | ||
| 61 | #define QMI_WLFW_CAP_RESP_V01 0x0024 | ||
| 62 | #define QMI_WLFW_REJUVENATE_ACK_REQ_V01 0x003A | ||
| 63 | #define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030 | ||
| 64 | #define QMI_WLFW_VBATT_REQ_V01 0x0032 | ||
| 65 | #define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033 | ||
| 66 | #define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036 | ||
| 67 | #define QMI_WLFW_VBATT_RESP_V01 0x0032 | ||
| 68 | #define QMI_WLFW_MSA_INFO_REQ_V01 0x002D | ||
| 69 | #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 | ||
| 70 | #define QMI_WLFW_ATHDIAG_READ_REQ_V01 0x0030 | ||
| 71 | #define QMI_WLFW_WLAN_CFG_REQ_V01 0x0023 | ||
| 72 | #define QMI_WLFW_IND_REGISTER_RESP_V01 0x0020 | ||
| 73 | |||
| 74 | #define QMI_WLFW_MAX_MEM_REG_V01 2 | ||
| 75 | #define QMI_WLFW_MAX_NUM_MEM_SEG_V01 16 | ||
| 76 | #define QMI_WLFW_MAX_NUM_CAL_V01 5 | ||
| 77 | #define QMI_WLFW_MAX_DATA_SIZE_V01 6144 | ||
| 78 | #define QMI_WLFW_FUNCTION_NAME_LEN_V01 128 | ||
| 79 | #define QMI_WLFW_MAX_NUM_CE_V01 12 | ||
| 80 | #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 | ||
| 81 | #define QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01 6144 | ||
| 82 | #define QMI_WLFW_MAX_NUM_GPIO_V01 32 | ||
| 83 | #define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 | ||
| 84 | #define QMI_WLFW_MAX_NUM_MEM_CFG_V01 2 | ||
| 85 | #define QMI_WLFW_MAX_STR_LEN_V01 16 | ||
| 86 | #define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24 | ||
| 87 | #define QMI_WLFW_MAC_ADDR_SIZE_V01 6 | ||
| 88 | #define QMI_WLFW_MAX_SHADOW_REG_V2 36 | ||
| 89 | #define QMI_WLFW_MAX_NUM_SVC_V01 24 | ||
| 90 | |||
| 91 | enum wlfw_driver_mode_enum_v01 { | ||
| 92 | QMI_WLFW_MISSION_V01 = 0, | ||
| 93 | QMI_WLFW_FTM_V01 = 1, | ||
| 94 | QMI_WLFW_EPPING_V01 = 2, | ||
| 95 | QMI_WLFW_WALTEST_V01 = 3, | ||
| 96 | QMI_WLFW_OFF_V01 = 4, | ||
| 97 | QMI_WLFW_CCPM_V01 = 5, | ||
| 98 | QMI_WLFW_QVIT_V01 = 6, | ||
| 99 | QMI_WLFW_CALIBRATION_V01 = 7, | ||
| 100 | }; | ||
| 101 | |||
| 102 | enum wlfw_cal_temp_id_enum_v01 { | ||
| 103 | QMI_WLFW_CAL_TEMP_IDX_0_V01 = 0, | ||
| 104 | QMI_WLFW_CAL_TEMP_IDX_1_V01 = 1, | ||
| 105 | QMI_WLFW_CAL_TEMP_IDX_2_V01 = 2, | ||
| 106 | QMI_WLFW_CAL_TEMP_IDX_3_V01 = 3, | ||
| 107 | QMI_WLFW_CAL_TEMP_IDX_4_V01 = 4, | ||
| 108 | }; | ||
| 109 | |||
| 110 | enum wlfw_pipedir_enum_v01 { | ||
| 111 | QMI_WLFW_PIPEDIR_NONE_V01 = 0, | ||
| 112 | QMI_WLFW_PIPEDIR_IN_V01 = 1, | ||
| 113 | QMI_WLFW_PIPEDIR_OUT_V01 = 2, | ||
| 114 | QMI_WLFW_PIPEDIR_INOUT_V01 = 3, | ||
| 115 | }; | ||
| 116 | |||
| 117 | enum wlfw_mem_type_enum_v01 { | ||
| 118 | QMI_WLFW_MEM_TYPE_MSA_V01 = 0, | ||
| 119 | QMI_WLFW_MEM_TYPE_DDR_V01 = 1, | ||
| 120 | }; | ||
| 121 | |||
| 122 | #define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00) | ||
| 123 | #define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01) | ||
| 124 | #define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02) | ||
| 125 | #define QMI_WLFW_CE_ATTR_SWIZZLE_DESCRIPTORS_V01 ((u32)0x04) | ||
| 126 | #define QMI_WLFW_CE_ATTR_DISABLE_INTR_V01 ((u32)0x08) | ||
| 127 | #define QMI_WLFW_CE_ATTR_ENABLE_POLL_V01 ((u32)0x10) | ||
| 128 | |||
| 129 | #define QMI_WLFW_ALREADY_REGISTERED_V01 ((u64)0x01ULL) | ||
| 130 | #define QMI_WLFW_FW_READY_V01 ((u64)0x02ULL) | ||
| 131 | #define QMI_WLFW_MSA_READY_V01 ((u64)0x04ULL) | ||
| 132 | #define QMI_WLFW_MEM_READY_V01 ((u64)0x08ULL) | ||
| 133 | #define QMI_WLFW_FW_INIT_DONE_V01 ((u64)0x10ULL) | ||
| 134 | |||
| 135 | #define QMI_WLFW_FW_REJUVENATE_V01 ((u64)0x01ULL) | ||
| 136 | |||
| 137 | struct wlfw_ce_tgt_pipe_cfg_s_v01 { | ||
| 138 | __le32 pipe_num; | ||
| 139 | __le32 pipe_dir; | ||
| 140 | __le32 nentries; | ||
| 141 | __le32 nbytes_max; | ||
| 142 | __le32 flags; | ||
| 143 | }; | ||
| 144 | |||
| 145 | struct wlfw_ce_svc_pipe_cfg_s_v01 { | ||
| 146 | __le32 service_id; | ||
| 147 | __le32 pipe_dir; | ||
| 148 | __le32 pipe_num; | ||
| 149 | }; | ||
| 150 | |||
| 151 | struct wlfw_shadow_reg_cfg_s_v01 { | ||
| 152 | u16 id; | ||
| 153 | u16 offset; | ||
| 154 | }; | ||
| 155 | |||
| 156 | struct wlfw_shadow_reg_v2_cfg_s_v01 { | ||
| 157 | u32 addr; | ||
| 158 | }; | ||
| 159 | |||
| 160 | struct wlfw_memory_region_info_s_v01 { | ||
| 161 | u64 region_addr; | ||
| 162 | u32 size; | ||
| 163 | u8 secure_flag; | ||
| 164 | }; | ||
| 165 | |||
| 166 | struct wlfw_mem_cfg_s_v01 { | ||
| 167 | u64 offset; | ||
| 168 | u32 size; | ||
| 169 | u8 secure_flag; | ||
| 170 | }; | ||
| 171 | |||
| 172 | struct wlfw_mem_seg_s_v01 { | ||
| 173 | u32 size; | ||
| 174 | enum wlfw_mem_type_enum_v01 type; | ||
| 175 | u32 mem_cfg_len; | ||
| 176 | struct wlfw_mem_cfg_s_v01 mem_cfg[QMI_WLFW_MAX_NUM_MEM_CFG_V01]; | ||
| 177 | }; | ||
| 178 | |||
| 179 | struct wlfw_mem_seg_resp_s_v01 { | ||
| 180 | u64 addr; | ||
| 181 | u32 size; | ||
| 182 | enum wlfw_mem_type_enum_v01 type; | ||
| 183 | }; | ||
| 184 | |||
| 185 | struct wlfw_rf_chip_info_s_v01 { | ||
| 186 | u32 chip_id; | ||
| 187 | u32 chip_family; | ||
| 188 | }; | ||
| 189 | |||
| 190 | struct wlfw_rf_board_info_s_v01 { | ||
| 191 | u32 board_id; | ||
| 192 | }; | ||
| 193 | |||
| 194 | struct wlfw_soc_info_s_v01 { | ||
| 195 | u32 soc_id; | ||
| 196 | }; | ||
| 197 | |||
| 198 | struct wlfw_fw_version_info_s_v01 { | ||
| 199 | u32 fw_version; | ||
| 200 | char fw_build_timestamp[QMI_WLFW_MAX_TIMESTAMP_LEN_V01 + 1]; | ||
| 201 | }; | ||
| 202 | |||
| 203 | struct wlfw_ind_register_req_msg_v01 { | ||
| 204 | u8 fw_ready_enable_valid; | ||
| 205 | u8 fw_ready_enable; | ||
| 206 | u8 initiate_cal_download_enable_valid; | ||
| 207 | u8 initiate_cal_download_enable; | ||
| 208 | u8 initiate_cal_update_enable_valid; | ||
| 209 | u8 initiate_cal_update_enable; | ||
| 210 | u8 msa_ready_enable_valid; | ||
| 211 | u8 msa_ready_enable; | ||
| 212 | u8 pin_connect_result_enable_valid; | ||
| 213 | u8 pin_connect_result_enable; | ||
| 214 | u8 client_id_valid; | ||
| 215 | u32 client_id; | ||
| 216 | u8 request_mem_enable_valid; | ||
| 217 | u8 request_mem_enable; | ||
| 218 | u8 mem_ready_enable_valid; | ||
| 219 | u8 mem_ready_enable; | ||
| 220 | u8 fw_init_done_enable_valid; | ||
| 221 | u8 fw_init_done_enable; | ||
| 222 | u8 rejuvenate_enable_valid; | ||
| 223 | u32 rejuvenate_enable; | ||
| 224 | u8 xo_cal_enable_valid; | ||
| 225 | u8 xo_cal_enable; | ||
| 226 | }; | ||
| 227 | |||
| 228 | #define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 50 | ||
| 229 | extern struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[]; | ||
| 230 | |||
| 231 | struct wlfw_ind_register_resp_msg_v01 { | ||
| 232 | struct qmi_response_type_v01 resp; | ||
| 233 | u8 fw_status_valid; | ||
| 234 | u64 fw_status; | ||
| 235 | }; | ||
| 236 | |||
| 237 | #define WLFW_IND_REGISTER_RESP_MSG_V01_MAX_MSG_LEN 18 | ||
| 238 | extern struct qmi_elem_info wlfw_ind_register_resp_msg_v01_ei[]; | ||
| 239 | |||
| 240 | struct wlfw_fw_ready_ind_msg_v01 { | ||
| 241 | char placeholder; | ||
| 242 | }; | ||
| 243 | |||
| 244 | #define WLFW_FW_READY_IND_MSG_V01_MAX_MSG_LEN 0 | ||
| 245 | extern struct qmi_elem_info wlfw_fw_ready_ind_msg_v01_ei[]; | ||
| 246 | |||
| 247 | struct wlfw_msa_ready_ind_msg_v01 { | ||
| 248 | char placeholder; | ||
| 249 | }; | ||
| 250 | |||
| 251 | #define WLFW_MSA_READY_IND_MSG_V01_MAX_MSG_LEN 0 | ||
| 252 | extern struct qmi_elem_info wlfw_msa_ready_ind_msg_v01_ei[]; | ||
| 253 | |||
| 254 | struct wlfw_pin_connect_result_ind_msg_v01 { | ||
| 255 | u8 pwr_pin_result_valid; | ||
| 256 | u32 pwr_pin_result; | ||
| 257 | u8 phy_io_pin_result_valid; | ||
| 258 | u32 phy_io_pin_result; | ||
| 259 | u8 rf_pin_result_valid; | ||
| 260 | u32 rf_pin_result; | ||
| 261 | }; | ||
| 262 | |||
| 263 | #define WLFW_PIN_CONNECT_RESULT_IND_MSG_V01_MAX_MSG_LEN 21 | ||
| 264 | extern struct qmi_elem_info wlfw_pin_connect_result_ind_msg_v01_ei[]; | ||
| 265 | |||
| 266 | struct wlfw_wlan_mode_req_msg_v01 { | ||
| 267 | enum wlfw_driver_mode_enum_v01 mode; | ||
| 268 | u8 hw_debug_valid; | ||
| 269 | u8 hw_debug; | ||
| 270 | }; | ||
| 271 | |||
| 272 | #define WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN 11 | ||
| 273 | extern struct qmi_elem_info wlfw_wlan_mode_req_msg_v01_ei[]; | ||
| 274 | |||
| 275 | struct wlfw_wlan_mode_resp_msg_v01 { | ||
| 276 | struct qmi_response_type_v01 resp; | ||
| 277 | }; | ||
| 278 | |||
| 279 | #define WLFW_WLAN_MODE_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 280 | extern struct qmi_elem_info wlfw_wlan_mode_resp_msg_v01_ei[]; | ||
| 281 | |||
| 282 | struct wlfw_wlan_cfg_req_msg_v01 { | ||
| 283 | u8 host_version_valid; | ||
| 284 | char host_version[QMI_WLFW_MAX_STR_LEN_V01 + 1]; | ||
| 285 | u8 tgt_cfg_valid; | ||
| 286 | u32 tgt_cfg_len; | ||
| 287 | struct wlfw_ce_tgt_pipe_cfg_s_v01 tgt_cfg[QMI_WLFW_MAX_NUM_CE_V01]; | ||
| 288 | u8 svc_cfg_valid; | ||
| 289 | u32 svc_cfg_len; | ||
| 290 | struct wlfw_ce_svc_pipe_cfg_s_v01 svc_cfg[QMI_WLFW_MAX_NUM_SVC_V01]; | ||
| 291 | u8 shadow_reg_valid; | ||
| 292 | u32 shadow_reg_len; | ||
| 293 | struct wlfw_shadow_reg_cfg_s_v01 shadow_reg[QMI_WLFW_MAX_NUM_SHADOW_REG_V01]; | ||
| 294 | u8 shadow_reg_v2_valid; | ||
| 295 | u32 shadow_reg_v2_len; | ||
| 296 | struct wlfw_shadow_reg_v2_cfg_s_v01 shadow_reg_v2[QMI_WLFW_MAX_SHADOW_REG_V2]; | ||
| 297 | }; | ||
| 298 | |||
| 299 | #define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 803 | ||
| 300 | extern struct qmi_elem_info wlfw_wlan_cfg_req_msg_v01_ei[]; | ||
| 301 | |||
| 302 | struct wlfw_wlan_cfg_resp_msg_v01 { | ||
| 303 | struct qmi_response_type_v01 resp; | ||
| 304 | }; | ||
| 305 | |||
| 306 | #define WLFW_WLAN_CFG_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 307 | extern struct qmi_elem_info wlfw_wlan_cfg_resp_msg_v01_ei[]; | ||
| 308 | |||
| 309 | struct wlfw_cap_req_msg_v01 { | ||
| 310 | char placeholder; | ||
| 311 | }; | ||
| 312 | |||
| 313 | #define WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN 0 | ||
| 314 | extern struct qmi_elem_info wlfw_cap_req_msg_v01_ei[]; | ||
| 315 | |||
| 316 | struct wlfw_cap_resp_msg_v01 { | ||
| 317 | struct qmi_response_type_v01 resp; | ||
| 318 | u8 chip_info_valid; | ||
| 319 | struct wlfw_rf_chip_info_s_v01 chip_info; | ||
| 320 | u8 board_info_valid; | ||
| 321 | struct wlfw_rf_board_info_s_v01 board_info; | ||
| 322 | u8 soc_info_valid; | ||
| 323 | struct wlfw_soc_info_s_v01 soc_info; | ||
| 324 | u8 fw_version_info_valid; | ||
| 325 | struct wlfw_fw_version_info_s_v01 fw_version_info; | ||
| 326 | u8 fw_build_id_valid; | ||
| 327 | char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; | ||
| 328 | u8 num_macs_valid; | ||
| 329 | u8 num_macs; | ||
| 330 | }; | ||
| 331 | |||
| 332 | #define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 207 | ||
| 333 | extern struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[]; | ||
| 334 | |||
| 335 | struct wlfw_bdf_download_req_msg_v01 { | ||
| 336 | u8 valid; | ||
| 337 | u8 file_id_valid; | ||
| 338 | enum wlfw_cal_temp_id_enum_v01 file_id; | ||
| 339 | u8 total_size_valid; | ||
| 340 | u32 total_size; | ||
| 341 | u8 seg_id_valid; | ||
| 342 | u32 seg_id; | ||
| 343 | u8 data_valid; | ||
| 344 | u32 data_len; | ||
| 345 | u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; | ||
| 346 | u8 end_valid; | ||
| 347 | u8 end; | ||
| 348 | u8 bdf_type_valid; | ||
| 349 | u8 bdf_type; | ||
| 350 | }; | ||
| 351 | |||
| 352 | #define WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6182 | ||
| 353 | extern struct qmi_elem_info wlfw_bdf_download_req_msg_v01_ei[]; | ||
| 354 | |||
| 355 | struct wlfw_bdf_download_resp_msg_v01 { | ||
| 356 | struct qmi_response_type_v01 resp; | ||
| 357 | }; | ||
| 358 | |||
| 359 | #define WLFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 360 | extern struct qmi_elem_info wlfw_bdf_download_resp_msg_v01_ei[]; | ||
| 361 | |||
| 362 | struct wlfw_cal_report_req_msg_v01 { | ||
| 363 | u32 meta_data_len; | ||
| 364 | enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; | ||
| 365 | u8 xo_cal_data_valid; | ||
| 366 | u8 xo_cal_data; | ||
| 367 | }; | ||
| 368 | |||
| 369 | #define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 28 | ||
| 370 | extern struct qmi_elem_info wlfw_cal_report_req_msg_v01_ei[]; | ||
| 371 | |||
| 372 | struct wlfw_cal_report_resp_msg_v01 { | ||
| 373 | struct qmi_response_type_v01 resp; | ||
| 374 | }; | ||
| 375 | |||
| 376 | #define WLFW_CAL_REPORT_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 377 | extern struct qmi_elem_info wlfw_cal_report_resp_msg_v01_ei[]; | ||
| 378 | |||
| 379 | struct wlfw_initiate_cal_download_ind_msg_v01 { | ||
| 380 | enum wlfw_cal_temp_id_enum_v01 cal_id; | ||
| 381 | }; | ||
| 382 | |||
| 383 | #define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 7 | ||
| 384 | extern struct qmi_elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[]; | ||
| 385 | |||
| 386 | struct wlfw_cal_download_req_msg_v01 { | ||
| 387 | u8 valid; | ||
| 388 | u8 file_id_valid; | ||
| 389 | enum wlfw_cal_temp_id_enum_v01 file_id; | ||
| 390 | u8 total_size_valid; | ||
| 391 | u32 total_size; | ||
| 392 | u8 seg_id_valid; | ||
| 393 | u32 seg_id; | ||
| 394 | u8 data_valid; | ||
| 395 | u32 data_len; | ||
| 396 | u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; | ||
| 397 | u8 end_valid; | ||
| 398 | u8 end; | ||
| 399 | }; | ||
| 400 | |||
| 401 | #define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178 | ||
| 402 | extern struct qmi_elem_info wlfw_cal_download_req_msg_v01_ei[]; | ||
| 403 | |||
| 404 | struct wlfw_cal_download_resp_msg_v01 { | ||
| 405 | struct qmi_response_type_v01 resp; | ||
| 406 | }; | ||
| 407 | |||
| 408 | #define WLFW_CAL_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 409 | extern struct qmi_elem_info wlfw_cal_download_resp_msg_v01_ei[]; | ||
| 410 | |||
| 411 | struct wlfw_initiate_cal_update_ind_msg_v01 { | ||
| 412 | enum wlfw_cal_temp_id_enum_v01 cal_id; | ||
| 413 | u32 total_size; | ||
| 414 | }; | ||
| 415 | |||
| 416 | #define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 14 | ||
| 417 | extern struct qmi_elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[]; | ||
| 418 | |||
| 419 | struct wlfw_cal_update_req_msg_v01 { | ||
| 420 | enum wlfw_cal_temp_id_enum_v01 cal_id; | ||
| 421 | u32 seg_id; | ||
| 422 | }; | ||
| 423 | |||
| 424 | #define WLFW_CAL_UPDATE_REQ_MSG_V01_MAX_MSG_LEN 14 | ||
| 425 | extern struct qmi_elem_info wlfw_cal_update_req_msg_v01_ei[]; | ||
| 426 | |||
| 427 | struct wlfw_cal_update_resp_msg_v01 { | ||
| 428 | struct qmi_response_type_v01 resp; | ||
| 429 | u8 file_id_valid; | ||
| 430 | enum wlfw_cal_temp_id_enum_v01 file_id; | ||
| 431 | u8 total_size_valid; | ||
| 432 | u32 total_size; | ||
| 433 | u8 seg_id_valid; | ||
| 434 | u32 seg_id; | ||
| 435 | u8 data_valid; | ||
| 436 | u32 data_len; | ||
| 437 | u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; | ||
| 438 | u8 end_valid; | ||
| 439 | u8 end; | ||
| 440 | }; | ||
| 441 | |||
| 442 | #define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6181 | ||
| 443 | extern struct qmi_elem_info wlfw_cal_update_resp_msg_v01_ei[]; | ||
| 444 | |||
| 445 | struct wlfw_msa_info_req_msg_v01 { | ||
| 446 | u64 msa_addr; | ||
| 447 | u32 size; | ||
| 448 | }; | ||
| 449 | |||
| 450 | #define WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 | ||
| 451 | extern struct qmi_elem_info wlfw_msa_info_req_msg_v01_ei[]; | ||
| 452 | |||
| 453 | struct wlfw_msa_info_resp_msg_v01 { | ||
| 454 | struct qmi_response_type_v01 resp; | ||
| 455 | u32 mem_region_info_len; | ||
| 456 | struct wlfw_memory_region_info_s_v01 mem_region_info[QMI_WLFW_MAX_MEM_REG_V01]; | ||
| 457 | }; | ||
| 458 | |||
| 459 | #define WLFW_MSA_INFO_RESP_MSG_V01_MAX_MSG_LEN 37 | ||
| 460 | extern struct qmi_elem_info wlfw_msa_info_resp_msg_v01_ei[]; | ||
| 461 | |||
| 462 | struct wlfw_msa_ready_req_msg_v01 { | ||
| 463 | char placeholder; | ||
| 464 | }; | ||
| 465 | |||
| 466 | #define WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN 0 | ||
| 467 | extern struct qmi_elem_info wlfw_msa_ready_req_msg_v01_ei[]; | ||
| 468 | |||
| 469 | struct wlfw_msa_ready_resp_msg_v01 { | ||
| 470 | struct qmi_response_type_v01 resp; | ||
| 471 | }; | ||
| 472 | |||
| 473 | #define WLFW_MSA_READY_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 474 | extern struct qmi_elem_info wlfw_msa_ready_resp_msg_v01_ei[]; | ||
| 475 | |||
| 476 | struct wlfw_ini_req_msg_v01 { | ||
| 477 | u8 enablefwlog_valid; | ||
| 478 | u8 enablefwlog; | ||
| 479 | }; | ||
| 480 | |||
| 481 | #define WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN 4 | ||
| 482 | extern struct qmi_elem_info wlfw_ini_req_msg_v01_ei[]; | ||
| 483 | |||
| 484 | struct wlfw_ini_resp_msg_v01 { | ||
| 485 | struct qmi_response_type_v01 resp; | ||
| 486 | }; | ||
| 487 | |||
| 488 | #define WLFW_INI_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 489 | extern struct qmi_elem_info wlfw_ini_resp_msg_v01_ei[]; | ||
| 490 | |||
| 491 | struct wlfw_athdiag_read_req_msg_v01 { | ||
| 492 | u32 offset; | ||
| 493 | u32 mem_type; | ||
| 494 | u32 data_len; | ||
| 495 | }; | ||
| 496 | |||
| 497 | #define WLFW_ATHDIAG_READ_REQ_MSG_V01_MAX_MSG_LEN 21 | ||
| 498 | extern struct qmi_elem_info wlfw_athdiag_read_req_msg_v01_ei[]; | ||
| 499 | |||
| 500 | struct wlfw_athdiag_read_resp_msg_v01 { | ||
| 501 | struct qmi_response_type_v01 resp; | ||
| 502 | u8 data_valid; | ||
| 503 | u32 data_len; | ||
| 504 | u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01]; | ||
| 505 | }; | ||
| 506 | |||
| 507 | #define WLFW_ATHDIAG_READ_RESP_MSG_V01_MAX_MSG_LEN 6156 | ||
| 508 | extern struct qmi_elem_info wlfw_athdiag_read_resp_msg_v01_ei[]; | ||
| 509 | |||
| 510 | struct wlfw_athdiag_write_req_msg_v01 { | ||
| 511 | u32 offset; | ||
| 512 | u32 mem_type; | ||
| 513 | u32 data_len; | ||
| 514 | u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01]; | ||
| 515 | }; | ||
| 516 | |||
| 517 | #define WLFW_ATHDIAG_WRITE_REQ_MSG_V01_MAX_MSG_LEN 6163 | ||
| 518 | extern struct qmi_elem_info wlfw_athdiag_write_req_msg_v01_ei[]; | ||
| 519 | |||
| 520 | struct wlfw_athdiag_write_resp_msg_v01 { | ||
| 521 | struct qmi_response_type_v01 resp; | ||
| 522 | }; | ||
| 523 | |||
| 524 | #define WLFW_ATHDIAG_WRITE_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 525 | extern struct qmi_elem_info wlfw_athdiag_write_resp_msg_v01_ei[]; | ||
| 526 | |||
| 527 | struct wlfw_vbatt_req_msg_v01 { | ||
| 528 | u64 voltage_uv; | ||
| 529 | }; | ||
| 530 | |||
| 531 | #define WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN 11 | ||
| 532 | extern struct qmi_elem_info wlfw_vbatt_req_msg_v01_ei[]; | ||
| 533 | |||
| 534 | struct wlfw_vbatt_resp_msg_v01 { | ||
| 535 | struct qmi_response_type_v01 resp; | ||
| 536 | }; | ||
| 537 | |||
| 538 | #define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 539 | extern struct qmi_elem_info wlfw_vbatt_resp_msg_v01_ei[]; | ||
| 540 | |||
| 541 | struct wlfw_mac_addr_req_msg_v01 { | ||
| 542 | u8 mac_addr_valid; | ||
| 543 | u8 mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01]; | ||
| 544 | }; | ||
| 545 | |||
| 546 | #define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9 | ||
| 547 | extern struct qmi_elem_info wlfw_mac_addr_req_msg_v01_ei[]; | ||
| 548 | |||
| 549 | struct wlfw_mac_addr_resp_msg_v01 { | ||
| 550 | struct qmi_response_type_v01 resp; | ||
| 551 | }; | ||
| 552 | |||
| 553 | #define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 554 | extern struct qmi_elem_info wlfw_mac_addr_resp_msg_v01_ei[]; | ||
| 555 | |||
| 556 | struct wlfw_host_cap_req_msg_v01 { | ||
| 557 | u8 daemon_support_valid; | ||
| 558 | u8 daemon_support; | ||
| 559 | }; | ||
| 560 | |||
| 561 | #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 | ||
| 562 | extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[]; | ||
| 563 | |||
| 564 | struct wlfw_host_cap_resp_msg_v01 { | ||
| 565 | struct qmi_response_type_v01 resp; | ||
| 566 | }; | ||
| 567 | |||
| 568 | #define WLFW_HOST_CAP_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 569 | extern struct qmi_elem_info wlfw_host_cap_resp_msg_v01_ei[]; | ||
| 570 | |||
| 571 | struct wlfw_request_mem_ind_msg_v01 { | ||
| 572 | u32 mem_seg_len; | ||
| 573 | struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; | ||
| 574 | }; | ||
| 575 | |||
| 576 | #define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 564 | ||
| 577 | extern struct qmi_elem_info wlfw_request_mem_ind_msg_v01_ei[]; | ||
| 578 | |||
| 579 | struct wlfw_respond_mem_req_msg_v01 { | ||
| 580 | u32 mem_seg_len; | ||
| 581 | struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; | ||
| 582 | }; | ||
| 583 | |||
| 584 | #define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 260 | ||
| 585 | extern struct qmi_elem_info wlfw_respond_mem_req_msg_v01_ei[]; | ||
| 586 | |||
| 587 | struct wlfw_respond_mem_resp_msg_v01 { | ||
| 588 | struct qmi_response_type_v01 resp; | ||
| 589 | }; | ||
| 590 | |||
| 591 | #define WLFW_RESPOND_MEM_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 592 | extern struct qmi_elem_info wlfw_respond_mem_resp_msg_v01_ei[]; | ||
| 593 | |||
| 594 | struct wlfw_mem_ready_ind_msg_v01 { | ||
| 595 | char placeholder; | ||
| 596 | }; | ||
| 597 | |||
| 598 | #define WLFW_MEM_READY_IND_MSG_V01_MAX_MSG_LEN 0 | ||
| 599 | extern struct qmi_elem_info wlfw_mem_ready_ind_msg_v01_ei[]; | ||
| 600 | |||
| 601 | struct wlfw_fw_init_done_ind_msg_v01 { | ||
| 602 | char placeholder; | ||
| 603 | }; | ||
| 604 | |||
| 605 | #define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 0 | ||
| 606 | extern struct qmi_elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; | ||
| 607 | |||
| 608 | struct wlfw_rejuvenate_ind_msg_v01 { | ||
| 609 | u8 cause_for_rejuvenation_valid; | ||
| 610 | u8 cause_for_rejuvenation; | ||
| 611 | u8 requesting_sub_system_valid; | ||
| 612 | u8 requesting_sub_system; | ||
| 613 | u8 line_number_valid; | ||
| 614 | u16 line_number; | ||
| 615 | u8 function_name_valid; | ||
| 616 | char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; | ||
| 617 | }; | ||
| 618 | |||
| 619 | #define WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN 144 | ||
| 620 | extern struct qmi_elem_info wlfw_rejuvenate_ind_msg_v01_ei[]; | ||
| 621 | |||
| 622 | struct wlfw_rejuvenate_ack_req_msg_v01 { | ||
| 623 | char placeholder; | ||
| 624 | }; | ||
| 625 | |||
| 626 | #define WLFW_REJUVENATE_ACK_REQ_MSG_V01_MAX_MSG_LEN 0 | ||
| 627 | extern struct qmi_elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[]; | ||
| 628 | |||
| 629 | struct wlfw_rejuvenate_ack_resp_msg_v01 { | ||
| 630 | struct qmi_response_type_v01 resp; | ||
| 631 | }; | ||
| 632 | |||
| 633 | #define WLFW_REJUVENATE_ACK_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 634 | extern struct qmi_elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[]; | ||
| 635 | |||
| 636 | struct wlfw_dynamic_feature_mask_req_msg_v01 { | ||
| 637 | u8 mask_valid; | ||
| 638 | u64 mask; | ||
| 639 | }; | ||
| 640 | |||
| 641 | #define WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN 11 | ||
| 642 | extern struct qmi_elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[]; | ||
| 643 | |||
| 644 | struct wlfw_dynamic_feature_mask_resp_msg_v01 { | ||
| 645 | struct qmi_response_type_v01 resp; | ||
| 646 | u8 prev_mask_valid; | ||
| 647 | u64 prev_mask; | ||
| 648 | u8 curr_mask_valid; | ||
| 649 | u64 curr_mask; | ||
| 650 | }; | ||
| 651 | |||
| 652 | #define WLFW_DYNAMIC_FEATURE_MASK_RESP_MSG_V01_MAX_MSG_LEN 29 | ||
| 653 | extern struct qmi_elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[]; | ||
| 654 | |||
| 655 | struct wlfw_m3_info_req_msg_v01 { | ||
| 656 | u64 addr; | ||
| 657 | u32 size; | ||
| 658 | }; | ||
| 659 | |||
| 660 | #define WLFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 | ||
| 661 | extern struct qmi_elem_info wlfw_m3_info_req_msg_v01_ei[]; | ||
| 662 | |||
| 663 | struct wlfw_m3_info_resp_msg_v01 { | ||
| 664 | struct qmi_response_type_v01 resp; | ||
| 665 | }; | ||
| 666 | |||
| 667 | #define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 | ||
| 668 | extern struct qmi_elem_info wlfw_m3_info_resp_msg_v01_ei[]; | ||
| 669 | |||
| 670 | struct wlfw_xo_cal_ind_msg_v01 { | ||
| 671 | u8 xo_cal_data; | ||
| 672 | }; | ||
| 673 | |||
| 674 | #define WLFW_XO_CAL_IND_MSG_V01_MAX_MSG_LEN 4 | ||
| 675 | extern struct qmi_elem_info wlfw_xo_cal_ind_msg_v01_ei[]; | ||
| 676 | |||
| 677 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index f7b5b855aab2..8d3d9bca410f 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c | |||
| @@ -67,6 +67,72 @@ static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state); | |||
| 67 | static const struct ath10k_snoc_drv_priv drv_priv = { | 67 | static const struct ath10k_snoc_drv_priv drv_priv = { |
| 68 | .hw_rev = ATH10K_HW_WCN3990, | 68 | .hw_rev = ATH10K_HW_WCN3990, |
| 69 | .dma_mask = DMA_BIT_MASK(37), | 69 | .dma_mask = DMA_BIT_MASK(37), |
| 70 | .msa_size = 0x100000, | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define WCN3990_SRC_WR_IDX_OFFSET 0x3C | ||
| 74 | #define WCN3990_DST_WR_IDX_OFFSET 0x40 | ||
| 75 | |||
| 76 | static struct ath10k_shadow_reg_cfg target_shadow_reg_cfg_map[] = { | ||
| 77 | { | ||
| 78 | .ce_id = __cpu_to_le16(0), | ||
| 79 | .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), | ||
| 80 | }, | ||
| 81 | |||
| 82 | { | ||
| 83 | .ce_id = __cpu_to_le16(3), | ||
| 84 | .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), | ||
| 85 | }, | ||
| 86 | |||
| 87 | { | ||
| 88 | .ce_id = __cpu_to_le16(4), | ||
| 89 | .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), | ||
| 90 | }, | ||
| 91 | |||
| 92 | { | ||
| 93 | .ce_id = __cpu_to_le16(5), | ||
| 94 | .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), | ||
| 95 | }, | ||
| 96 | |||
| 97 | { | ||
| 98 | .ce_id = __cpu_to_le16(7), | ||
| 99 | .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), | ||
| 100 | }, | ||
| 101 | |||
| 102 | { | ||
| 103 | .ce_id = __cpu_to_le16(1), | ||
| 104 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 105 | }, | ||
| 106 | |||
| 107 | { | ||
| 108 | .ce_id = __cpu_to_le16(2), | ||
| 109 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 110 | }, | ||
| 111 | |||
| 112 | { | ||
| 113 | .ce_id = __cpu_to_le16(7), | ||
| 114 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 115 | }, | ||
| 116 | |||
| 117 | { | ||
| 118 | .ce_id = __cpu_to_le16(8), | ||
| 119 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 120 | }, | ||
| 121 | |||
| 122 | { | ||
| 123 | .ce_id = __cpu_to_le16(9), | ||
| 124 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 125 | }, | ||
| 126 | |||
| 127 | { | ||
| 128 | .ce_id = __cpu_to_le16(10), | ||
| 129 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 130 | }, | ||
| 131 | |||
| 132 | { | ||
| 133 | .ce_id = __cpu_to_le16(11), | ||
| 134 | .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), | ||
| 135 | }, | ||
| 70 | }; | 136 | }; |
| 71 | 137 | ||
| 72 | static struct ce_attr host_ce_config_wlan[] = { | 138 | static struct ce_attr host_ce_config_wlan[] = { |
| @@ -176,6 +242,128 @@ static struct ce_attr host_ce_config_wlan[] = { | |||
| 176 | }, | 242 | }, |
| 177 | }; | 243 | }; |
| 178 | 244 | ||
| 245 | static struct ce_pipe_config target_ce_config_wlan[] = { | ||
| 246 | /* CE0: host->target HTC control and raw streams */ | ||
| 247 | { | ||
| 248 | .pipenum = __cpu_to_le32(0), | ||
| 249 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), | ||
| 250 | .nentries = __cpu_to_le32(32), | ||
| 251 | .nbytes_max = __cpu_to_le32(2048), | ||
| 252 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 253 | .reserved = __cpu_to_le32(0), | ||
| 254 | }, | ||
| 255 | |||
| 256 | /* CE1: target->host HTT + HTC control */ | ||
| 257 | { | ||
| 258 | .pipenum = __cpu_to_le32(1), | ||
| 259 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 260 | .nentries = __cpu_to_le32(32), | ||
| 261 | .nbytes_max = __cpu_to_le32(2048), | ||
| 262 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 263 | .reserved = __cpu_to_le32(0), | ||
| 264 | }, | ||
| 265 | |||
| 266 | /* CE2: target->host WMI */ | ||
| 267 | { | ||
| 268 | .pipenum = __cpu_to_le32(2), | ||
| 269 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 270 | .nentries = __cpu_to_le32(64), | ||
| 271 | .nbytes_max = __cpu_to_le32(2048), | ||
| 272 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 273 | .reserved = __cpu_to_le32(0), | ||
| 274 | }, | ||
| 275 | |||
| 276 | /* CE3: host->target WMI */ | ||
| 277 | { | ||
| 278 | .pipenum = __cpu_to_le32(3), | ||
| 279 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), | ||
| 280 | .nentries = __cpu_to_le32(32), | ||
| 281 | .nbytes_max = __cpu_to_le32(2048), | ||
| 282 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 283 | .reserved = __cpu_to_le32(0), | ||
| 284 | }, | ||
| 285 | |||
| 286 | /* CE4: host->target HTT */ | ||
| 287 | { | ||
| 288 | .pipenum = __cpu_to_le32(4), | ||
| 289 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), | ||
| 290 | .nentries = __cpu_to_le32(256), | ||
| 291 | .nbytes_max = __cpu_to_le32(256), | ||
| 292 | .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), | ||
| 293 | .reserved = __cpu_to_le32(0), | ||
| 294 | }, | ||
| 295 | |||
| 296 | /* CE5: target->host HTT (HIF->HTT) */ | ||
| 297 | { | ||
| 298 | .pipenum = __cpu_to_le32(5), | ||
| 299 | .pipedir = __cpu_to_le32(PIPEDIR_OUT), | ||
| 300 | .nentries = __cpu_to_le32(1024), | ||
| 301 | .nbytes_max = __cpu_to_le32(64), | ||
| 302 | .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), | ||
| 303 | .reserved = __cpu_to_le32(0), | ||
| 304 | }, | ||
| 305 | |||
| 306 | /* CE6: Reserved for target autonomous hif_memcpy */ | ||
| 307 | { | ||
| 308 | .pipenum = __cpu_to_le32(6), | ||
| 309 | .pipedir = __cpu_to_le32(PIPEDIR_INOUT), | ||
| 310 | .nentries = __cpu_to_le32(32), | ||
| 311 | .nbytes_max = __cpu_to_le32(16384), | ||
| 312 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 313 | .reserved = __cpu_to_le32(0), | ||
| 314 | }, | ||
| 315 | |||
| 316 | /* CE7 used only by Host */ | ||
| 317 | { | ||
| 318 | .pipenum = __cpu_to_le32(7), | ||
| 319 | .pipedir = __cpu_to_le32(4), | ||
| 320 | .nentries = __cpu_to_le32(0), | ||
| 321 | .nbytes_max = __cpu_to_le32(0), | ||
| 322 | .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), | ||
| 323 | .reserved = __cpu_to_le32(0), | ||
| 324 | }, | ||
| 325 | |||
| 326 | /* CE8 Target to uMC */ | ||
| 327 | { | ||
| 328 | .pipenum = __cpu_to_le32(8), | ||
| 329 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 330 | .nentries = __cpu_to_le32(32), | ||
| 331 | .nbytes_max = __cpu_to_le32(2048), | ||
| 332 | .flags = __cpu_to_le32(0), | ||
| 333 | .reserved = __cpu_to_le32(0), | ||
| 334 | }, | ||
| 335 | |||
| 336 | /* CE9 target->host HTT */ | ||
| 337 | { | ||
| 338 | .pipenum = __cpu_to_le32(9), | ||
| 339 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 340 | .nentries = __cpu_to_le32(32), | ||
| 341 | .nbytes_max = __cpu_to_le32(2048), | ||
| 342 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 343 | .reserved = __cpu_to_le32(0), | ||
| 344 | }, | ||
| 345 | |||
| 346 | /* CE10 target->host HTT */ | ||
| 347 | { | ||
| 348 | .pipenum = __cpu_to_le32(10), | ||
| 349 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 350 | .nentries = __cpu_to_le32(32), | ||
| 351 | .nbytes_max = __cpu_to_le32(2048), | ||
| 352 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 353 | .reserved = __cpu_to_le32(0), | ||
| 354 | }, | ||
| 355 | |||
| 356 | /* CE11 target autonomous qcache memcpy */ | ||
| 357 | { | ||
| 358 | .pipenum = __cpu_to_le32(11), | ||
| 359 | .pipedir = __cpu_to_le32(PIPEDIR_IN), | ||
| 360 | .nentries = __cpu_to_le32(32), | ||
| 361 | .nbytes_max = __cpu_to_le32(2048), | ||
| 362 | .flags = __cpu_to_le32(CE_ATTR_FLAGS), | ||
| 363 | .reserved = __cpu_to_le32(0), | ||
| 364 | }, | ||
| 365 | }; | ||
| 366 | |||
| 179 | static struct service_to_pipe target_service_to_ce_map_wlan[] = { | 367 | static struct service_to_pipe target_service_to_ce_map_wlan[] = { |
| 180 | { | 368 | { |
| 181 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), | 369 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), |
| @@ -766,11 +954,47 @@ static int ath10k_snoc_init_pipes(struct ath10k *ar) | |||
| 766 | 954 | ||
| 767 | static int ath10k_snoc_wlan_enable(struct ath10k *ar) | 955 | static int ath10k_snoc_wlan_enable(struct ath10k *ar) |
| 768 | { | 956 | { |
| 769 | return 0; | 957 | struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX]; |
| 958 | struct ath10k_qmi_wlan_enable_cfg cfg; | ||
| 959 | enum wlfw_driver_mode_enum_v01 mode; | ||
| 960 | int pipe_num; | ||
| 961 | |||
| 962 | for (pipe_num = 0; pipe_num < CE_COUNT_MAX; pipe_num++) { | ||
| 963 | tgt_cfg[pipe_num].pipe_num = | ||
| 964 | target_ce_config_wlan[pipe_num].pipenum; | ||
| 965 | tgt_cfg[pipe_num].pipe_dir = | ||
| 966 | target_ce_config_wlan[pipe_num].pipedir; | ||
| 967 | tgt_cfg[pipe_num].nentries = | ||
| 968 | target_ce_config_wlan[pipe_num].nentries; | ||
| 969 | tgt_cfg[pipe_num].nbytes_max = | ||
| 970 | target_ce_config_wlan[pipe_num].nbytes_max; | ||
| 971 | tgt_cfg[pipe_num].flags = | ||
| 972 | target_ce_config_wlan[pipe_num].flags; | ||
| 973 | tgt_cfg[pipe_num].reserved = 0; | ||
| 974 | } | ||
| 975 | |||
| 976 | cfg.num_ce_tgt_cfg = sizeof(target_ce_config_wlan) / | ||
| 977 | sizeof(struct ath10k_tgt_pipe_cfg); | ||
| 978 | cfg.ce_tgt_cfg = (struct ath10k_tgt_pipe_cfg *) | ||
| 979 | &tgt_cfg; | ||
| 980 | cfg.num_ce_svc_pipe_cfg = sizeof(target_service_to_ce_map_wlan) / | ||
| 981 | sizeof(struct ath10k_svc_pipe_cfg); | ||
| 982 | cfg.ce_svc_cfg = (struct ath10k_svc_pipe_cfg *) | ||
| 983 | &target_service_to_ce_map_wlan; | ||
| 984 | cfg.num_shadow_reg_cfg = sizeof(target_shadow_reg_cfg_map) / | ||
| 985 | sizeof(struct ath10k_shadow_reg_cfg); | ||
| 986 | cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *) | ||
| 987 | &target_shadow_reg_cfg_map; | ||
| 988 | |||
| 989 | mode = QMI_WLFW_MISSION_V01; | ||
| 990 | |||
| 991 | return ath10k_qmi_wlan_enable(ar, &cfg, mode, | ||
| 992 | NULL); | ||
| 770 | } | 993 | } |
| 771 | 994 | ||
| 772 | static void ath10k_snoc_wlan_disable(struct ath10k *ar) | 995 | static void ath10k_snoc_wlan_disable(struct ath10k *ar) |
| 773 | { | 996 | { |
| 997 | ath10k_qmi_wlan_disable(ar); | ||
| 774 | } | 998 | } |
| 775 | 999 | ||
| 776 | static void ath10k_snoc_hif_power_down(struct ath10k *ar) | 1000 | static void ath10k_snoc_hif_power_down(struct ath10k *ar) |
| @@ -957,6 +1181,32 @@ out: | |||
| 957 | return ret; | 1181 | return ret; |
| 958 | } | 1182 | } |
| 959 | 1183 | ||
| 1184 | int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type) | ||
| 1185 | { | ||
| 1186 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | ||
| 1187 | struct ath10k_bus_params bus_params; | ||
| 1188 | int ret; | ||
| 1189 | |||
| 1190 | switch (type) { | ||
| 1191 | case ATH10K_QMI_EVENT_FW_READY_IND: | ||
| 1192 | bus_params.dev_type = ATH10K_DEV_TYPE_LL; | ||
| 1193 | bus_params.chip_id = ar_snoc->target_info.soc_version; | ||
| 1194 | ret = ath10k_core_register(ar, &bus_params); | ||
| 1195 | if (ret) { | ||
| 1196 | ath10k_err(ar, "failed to register driver core: %d\n", | ||
| 1197 | ret); | ||
| 1198 | } | ||
| 1199 | break; | ||
| 1200 | case ATH10K_QMI_EVENT_FW_DOWN_IND: | ||
| 1201 | break; | ||
| 1202 | default: | ||
| 1203 | ath10k_err(ar, "invalid fw indication: %llx\n", type); | ||
| 1204 | return -EINVAL; | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | return 0; | ||
| 1208 | } | ||
| 1209 | |||
| 960 | static int ath10k_snoc_setup_resource(struct ath10k *ar) | 1210 | static int ath10k_snoc_setup_resource(struct ath10k *ar) |
| 961 | { | 1211 | { |
| 962 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); | 1212 | struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); |
| @@ -1281,9 +1531,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev) | |||
| 1281 | struct ath10k_snoc *ar_snoc; | 1531 | struct ath10k_snoc *ar_snoc; |
| 1282 | struct device *dev; | 1532 | struct device *dev; |
| 1283 | struct ath10k *ar; | 1533 | struct ath10k *ar; |
| 1534 | u32 msa_size; | ||
| 1284 | int ret; | 1535 | int ret; |
| 1285 | u32 i; | 1536 | u32 i; |
| 1286 | struct ath10k_bus_params bus_params; | ||
| 1287 | 1537 | ||
| 1288 | of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev); | 1538 | of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev); |
| 1289 | if (!of_id) { | 1539 | if (!of_id) { |
| @@ -1313,6 +1563,7 @@ static int ath10k_snoc_probe(struct platform_device *pdev) | |||
| 1313 | ar_snoc->ar = ar; | 1563 | ar_snoc->ar = ar; |
| 1314 | ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops; | 1564 | ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops; |
| 1315 | ar->ce_priv = &ar_snoc->ce; | 1565 | ar->ce_priv = &ar_snoc->ce; |
| 1566 | msa_size = drv_data->msa_size; | ||
| 1316 | 1567 | ||
| 1317 | ret = ath10k_snoc_resource_init(ar); | 1568 | ret = ath10k_snoc_resource_init(ar); |
| 1318 | if (ret) { | 1569 | if (ret) { |
| @@ -1351,12 +1602,10 @@ static int ath10k_snoc_probe(struct platform_device *pdev) | |||
| 1351 | goto err_free_irq; | 1602 | goto err_free_irq; |
| 1352 | } | 1603 | } |
| 1353 | 1604 | ||
| 1354 | bus_params.dev_type = ATH10K_DEV_TYPE_LL; | 1605 | ret = ath10k_qmi_init(ar, msa_size); |
| 1355 | bus_params.chip_id = drv_data->hw_rev; | ||
| 1356 | ret = ath10k_core_register(ar, &bus_params); | ||
| 1357 | if (ret) { | 1606 | if (ret) { |
| 1358 | ath10k_err(ar, "failed to register driver core: %d\n", ret); | 1607 | ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret); |
| 1359 | goto err_hw_power_off; | 1608 | goto err_core_destroy; |
| 1360 | } | 1609 | } |
| 1361 | 1610 | ||
| 1362 | ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n"); | 1611 | ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n"); |
| @@ -1364,9 +1613,6 @@ static int ath10k_snoc_probe(struct platform_device *pdev) | |||
| 1364 | 1613 | ||
| 1365 | return 0; | 1614 | return 0; |
| 1366 | 1615 | ||
| 1367 | err_hw_power_off: | ||
| 1368 | ath10k_hw_power_off(ar); | ||
| 1369 | |||
| 1370 | err_free_irq: | 1616 | err_free_irq: |
| 1371 | ath10k_snoc_free_irq(ar); | 1617 | ath10k_snoc_free_irq(ar); |
| 1372 | 1618 | ||
| @@ -1388,6 +1634,7 @@ static int ath10k_snoc_remove(struct platform_device *pdev) | |||
| 1388 | ath10k_hw_power_off(ar); | 1634 | ath10k_hw_power_off(ar); |
| 1389 | ath10k_snoc_free_irq(ar); | 1635 | ath10k_snoc_free_irq(ar); |
| 1390 | ath10k_snoc_release_resource(ar); | 1636 | ath10k_snoc_release_resource(ar); |
| 1637 | ath10k_qmi_deinit(ar); | ||
| 1391 | ath10k_core_destroy(ar); | 1638 | ath10k_core_destroy(ar); |
| 1392 | 1639 | ||
| 1393 | return 0; | 1640 | return 0; |
diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h index f9e530189d48..e1d2d6675556 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.h +++ b/drivers/net/wireless/ath/ath10k/snoc.h | |||
| @@ -19,10 +19,12 @@ | |||
| 19 | 19 | ||
| 20 | #include "hw.h" | 20 | #include "hw.h" |
| 21 | #include "ce.h" | 21 | #include "ce.h" |
| 22 | #include "qmi.h" | ||
| 22 | 23 | ||
| 23 | struct ath10k_snoc_drv_priv { | 24 | struct ath10k_snoc_drv_priv { |
| 24 | enum ath10k_hw_rev hw_rev; | 25 | enum ath10k_hw_rev hw_rev; |
| 25 | u64 dma_mask; | 26 | u64 dma_mask; |
| 27 | u32 msa_size; | ||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | struct snoc_state { | 30 | struct snoc_state { |
| @@ -81,6 +83,7 @@ struct ath10k_snoc { | |||
| 81 | struct timer_list rx_post_retry; | 83 | struct timer_list rx_post_retry; |
| 82 | struct ath10k_wcn3990_vreg_info *vreg; | 84 | struct ath10k_wcn3990_vreg_info *vreg; |
| 83 | struct ath10k_wcn3990_clk_info *clk; | 85 | struct ath10k_wcn3990_clk_info *clk; |
| 86 | struct ath10k_qmi *qmi; | ||
| 84 | }; | 87 | }; |
| 85 | 88 | ||
| 86 | static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) | 89 | static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) |
| @@ -90,5 +93,6 @@ static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) | |||
| 90 | 93 | ||
| 91 | void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value); | 94 | void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value); |
| 92 | u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset); | 95 | u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset); |
| 96 | int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type); | ||
| 93 | 97 | ||
| 94 | #endif /* _SNOC_H_ */ | 98 | #endif /* _SNOC_H_ */ |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 7fd63bbf8e24..7978a7783f90 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h | |||
| @@ -210,6 +210,9 @@ struct wmi_ops { | |||
| 210 | u32 fw_feature_bitmap); | 210 | u32 fw_feature_bitmap); |
| 211 | int (*get_vdev_subtype)(struct ath10k *ar, | 211 | int (*get_vdev_subtype)(struct ath10k *ar, |
| 212 | enum wmi_vdev_subtype subtype); | 212 | enum wmi_vdev_subtype subtype); |
| 213 | struct sk_buff *(*gen_wow_config_pno)(struct ath10k *ar, | ||
| 214 | u32 vdev_id, | ||
| 215 | struct wmi_pno_scan_req *pno_scan); | ||
| 213 | struct sk_buff *(*gen_pdev_bss_chan_info_req) | 216 | struct sk_buff *(*gen_pdev_bss_chan_info_req) |
| 214 | (struct ath10k *ar, | 217 | (struct ath10k *ar, |
| 215 | enum wmi_bss_survey_req_type type); | 218 | enum wmi_bss_survey_req_type type); |
| @@ -1361,6 +1364,24 @@ ath10k_wmi_wow_del_pattern(struct ath10k *ar, u32 vdev_id, u32 pattern_id) | |||
| 1361 | } | 1364 | } |
| 1362 | 1365 | ||
| 1363 | static inline int | 1366 | static inline int |
| 1367 | ath10k_wmi_wow_config_pno(struct ath10k *ar, u32 vdev_id, | ||
| 1368 | struct wmi_pno_scan_req *pno_scan) | ||
| 1369 | { | ||
| 1370 | struct sk_buff *skb; | ||
| 1371 | u32 cmd_id; | ||
| 1372 | |||
| 1373 | if (!ar->wmi.ops->gen_wow_config_pno) | ||
| 1374 | return -EOPNOTSUPP; | ||
| 1375 | |||
| 1376 | skb = ar->wmi.ops->gen_wow_config_pno(ar, vdev_id, pno_scan); | ||
| 1377 | if (IS_ERR(skb)) | ||
| 1378 | return PTR_ERR(skb); | ||
| 1379 | |||
| 1380 | cmd_id = ar->wmi.cmd->network_list_offload_config_cmdid; | ||
| 1381 | return ath10k_wmi_cmd_send(ar, skb, cmd_id); | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | static inline int | ||
| 1364 | ath10k_wmi_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, | 1385 | ath10k_wmi_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id, |
| 1365 | enum wmi_tdls_state state) | 1386 | enum wmi_tdls_state state) |
| 1366 | { | 1387 | { |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 731ceaed4d5a..bab8b2527fb8 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | |||
| @@ -3441,6 +3441,192 @@ ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id, | |||
| 3441 | return skb; | 3441 | return skb; |
| 3442 | } | 3442 | } |
| 3443 | 3443 | ||
| 3444 | /* Request FW to start PNO operation */ | ||
| 3445 | static struct sk_buff * | ||
| 3446 | ath10k_wmi_tlv_op_gen_config_pno_start(struct ath10k *ar, | ||
| 3447 | u32 vdev_id, | ||
| 3448 | struct wmi_pno_scan_req *pno) | ||
| 3449 | { | ||
| 3450 | struct nlo_configured_parameters *nlo_list; | ||
| 3451 | struct wmi_tlv_wow_nlo_config_cmd *cmd; | ||
| 3452 | struct wmi_tlv *tlv; | ||
| 3453 | struct sk_buff *skb; | ||
| 3454 | __le32 *channel_list; | ||
| 3455 | u16 tlv_len; | ||
| 3456 | size_t len; | ||
| 3457 | void *ptr; | ||
| 3458 | u32 i; | ||
| 3459 | |||
| 3460 | len = sizeof(*tlv) + sizeof(*cmd) + | ||
| 3461 | sizeof(*tlv) + | ||
| 3462 | /* TLV place holder for array of structures | ||
| 3463 | * nlo_configured_parameters(nlo_list) | ||
| 3464 | */ | ||
| 3465 | sizeof(*tlv); | ||
| 3466 | /* TLV place holder for array of uint32 channel_list */ | ||
| 3467 | |||
| 3468 | len += sizeof(u32) * min_t(u8, pno->a_networks[0].channel_count, | ||
| 3469 | WMI_NLO_MAX_CHAN); | ||
| 3470 | len += sizeof(struct nlo_configured_parameters) * | ||
| 3471 | min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS); | ||
| 3472 | |||
| 3473 | skb = ath10k_wmi_alloc_skb(ar, len); | ||
| 3474 | if (!skb) | ||
| 3475 | return ERR_PTR(-ENOMEM); | ||
| 3476 | |||
| 3477 | ptr = (void *)skb->data; | ||
| 3478 | tlv = ptr; | ||
| 3479 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); | ||
| 3480 | tlv->len = __cpu_to_le16(sizeof(*cmd)); | ||
| 3481 | cmd = (void *)tlv->value; | ||
| 3482 | |||
| 3483 | /* wmi_tlv_wow_nlo_config_cmd parameters*/ | ||
| 3484 | cmd->vdev_id = __cpu_to_le32(pno->vdev_id); | ||
| 3485 | cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_START | WMI_NLO_CONFIG_SSID_HIDE_EN); | ||
| 3486 | |||
| 3487 | /* current FW does not support min-max range for dwell time */ | ||
| 3488 | cmd->active_dwell_time = __cpu_to_le32(pno->active_max_time); | ||
| 3489 | cmd->passive_dwell_time = __cpu_to_le32(pno->passive_max_time); | ||
| 3490 | |||
| 3491 | if (pno->do_passive_scan) | ||
| 3492 | cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SCAN_PASSIVE); | ||
| 3493 | |||
| 3494 | /* copy scan interval */ | ||
| 3495 | cmd->fast_scan_period = __cpu_to_le32(pno->fast_scan_period); | ||
| 3496 | cmd->slow_scan_period = __cpu_to_le32(pno->slow_scan_period); | ||
| 3497 | cmd->fast_scan_max_cycles = __cpu_to_le32(pno->fast_scan_max_cycles); | ||
| 3498 | cmd->delay_start_time = __cpu_to_le32(pno->delay_start_time); | ||
| 3499 | |||
| 3500 | if (pno->enable_pno_scan_randomization) { | ||
| 3501 | cmd->flags |= __cpu_to_le32(WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | | ||
| 3502 | WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ); | ||
| 3503 | ether_addr_copy(cmd->mac_addr.addr, pno->mac_addr); | ||
| 3504 | ether_addr_copy(cmd->mac_mask.addr, pno->mac_addr_mask); | ||
| 3505 | } | ||
| 3506 | |||
| 3507 | ptr += sizeof(*tlv); | ||
| 3508 | ptr += sizeof(*cmd); | ||
| 3509 | |||
| 3510 | /* nlo_configured_parameters(nlo_list) */ | ||
| 3511 | cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count, | ||
| 3512 | WMI_NLO_MAX_SSIDS)); | ||
| 3513 | tlv_len = __le32_to_cpu(cmd->no_of_ssids) * | ||
| 3514 | sizeof(struct nlo_configured_parameters); | ||
| 3515 | |||
| 3516 | tlv = ptr; | ||
| 3517 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); | ||
| 3518 | tlv->len = __cpu_to_le16(len); | ||
| 3519 | |||
| 3520 | ptr += sizeof(*tlv); | ||
| 3521 | nlo_list = ptr; | ||
| 3522 | for (i = 0; i < __le32_to_cpu(cmd->no_of_ssids); i++) { | ||
| 3523 | tlv = (struct wmi_tlv *)(&nlo_list[i].tlv_header); | ||
| 3524 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); | ||
| 3525 | tlv->len = __cpu_to_le16(sizeof(struct nlo_configured_parameters) - | ||
| 3526 | sizeof(*tlv)); | ||
| 3527 | |||
| 3528 | /* copy ssid and it's length */ | ||
| 3529 | nlo_list[i].ssid.valid = __cpu_to_le32(true); | ||
| 3530 | nlo_list[i].ssid.ssid.ssid_len = pno->a_networks[i].ssid.ssid_len; | ||
| 3531 | memcpy(nlo_list[i].ssid.ssid.ssid, | ||
| 3532 | pno->a_networks[i].ssid.ssid, | ||
| 3533 | __le32_to_cpu(nlo_list[i].ssid.ssid.ssid_len)); | ||
| 3534 | |||
| 3535 | /* copy rssi threshold */ | ||
| 3536 | if (pno->a_networks[i].rssi_threshold && | ||
| 3537 | pno->a_networks[i].rssi_threshold > -300) { | ||
| 3538 | nlo_list[i].rssi_cond.valid = __cpu_to_le32(true); | ||
| 3539 | nlo_list[i].rssi_cond.rssi = | ||
| 3540 | __cpu_to_le32(pno->a_networks[i].rssi_threshold); | ||
| 3541 | } | ||
| 3542 | |||
| 3543 | nlo_list[i].bcast_nw_type.valid = __cpu_to_le32(true); | ||
| 3544 | nlo_list[i].bcast_nw_type.bcast_nw_type = | ||
| 3545 | __cpu_to_le32(pno->a_networks[i].bcast_nw_type); | ||
| 3546 | } | ||
| 3547 | |||
| 3548 | ptr += __le32_to_cpu(cmd->no_of_ssids) * sizeof(struct nlo_configured_parameters); | ||
| 3549 | |||
| 3550 | /* copy channel info */ | ||
| 3551 | cmd->num_of_channels = __cpu_to_le32(min_t(u8, | ||
| 3552 | pno->a_networks[0].channel_count, | ||
| 3553 | WMI_NLO_MAX_CHAN)); | ||
| 3554 | |||
| 3555 | tlv = ptr; | ||
| 3556 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); | ||
| 3557 | tlv->len = __cpu_to_le16(__le32_to_cpu(cmd->num_of_channels) * | ||
| 3558 | sizeof(u_int32_t)); | ||
| 3559 | ptr += sizeof(*tlv); | ||
| 3560 | |||
| 3561 | channel_list = (__le32 *)ptr; | ||
| 3562 | for (i = 0; i < __le32_to_cpu(cmd->num_of_channels); i++) | ||
| 3563 | channel_list[i] = __cpu_to_le32(pno->a_networks[0].channels[i]); | ||
| 3564 | |||
| 3565 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start pno config vdev_id %d\n", | ||
| 3566 | vdev_id); | ||
| 3567 | |||
| 3568 | return skb; | ||
| 3569 | } | ||
| 3570 | |||
| 3571 | /* Request FW to stop ongoing PNO operation */ | ||
| 3572 | static struct sk_buff *ath10k_wmi_tlv_op_gen_config_pno_stop(struct ath10k *ar, | ||
| 3573 | u32 vdev_id) | ||
| 3574 | { | ||
| 3575 | struct wmi_tlv_wow_nlo_config_cmd *cmd; | ||
| 3576 | struct wmi_tlv *tlv; | ||
| 3577 | struct sk_buff *skb; | ||
| 3578 | void *ptr; | ||
| 3579 | size_t len; | ||
| 3580 | |||
| 3581 | len = sizeof(*tlv) + sizeof(*cmd) + | ||
| 3582 | sizeof(*tlv) + | ||
| 3583 | /* TLV place holder for array of structures | ||
| 3584 | * nlo_configured_parameters(nlo_list) | ||
| 3585 | */ | ||
| 3586 | sizeof(*tlv); | ||
| 3587 | /* TLV place holder for array of uint32 channel_list */ | ||
| 3588 | skb = ath10k_wmi_alloc_skb(ar, len); | ||
| 3589 | if (!skb) | ||
| 3590 | return ERR_PTR(-ENOMEM); | ||
| 3591 | |||
| 3592 | ptr = (void *)skb->data; | ||
| 3593 | tlv = ptr; | ||
| 3594 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD); | ||
| 3595 | tlv->len = __cpu_to_le16(sizeof(*cmd)); | ||
| 3596 | cmd = (void *)tlv->value; | ||
| 3597 | |||
| 3598 | cmd->vdev_id = __cpu_to_le32(vdev_id); | ||
| 3599 | cmd->flags = __cpu_to_le32(WMI_NLO_CONFIG_STOP); | ||
| 3600 | |||
| 3601 | ptr += sizeof(*tlv); | ||
| 3602 | ptr += sizeof(*cmd); | ||
| 3603 | |||
| 3604 | /* nlo_configured_parameters(nlo_list) */ | ||
| 3605 | tlv = ptr; | ||
| 3606 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); | ||
| 3607 | tlv->len = __cpu_to_le16(0); | ||
| 3608 | |||
| 3609 | ptr += sizeof(*tlv); | ||
| 3610 | |||
| 3611 | /* channel list */ | ||
| 3612 | tlv = ptr; | ||
| 3613 | tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); | ||
| 3614 | tlv->len = __cpu_to_le16(0); | ||
| 3615 | |||
| 3616 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop pno config vdev_id %d\n", vdev_id); | ||
| 3617 | return skb; | ||
| 3618 | } | ||
| 3619 | |||
| 3620 | static struct sk_buff * | ||
| 3621 | ath10k_wmi_tlv_op_gen_config_pno(struct ath10k *ar, u32 vdev_id, | ||
| 3622 | struct wmi_pno_scan_req *pno_scan) | ||
| 3623 | { | ||
| 3624 | if (pno_scan->enable) | ||
| 3625 | return ath10k_wmi_tlv_op_gen_config_pno_start(ar, vdev_id, pno_scan); | ||
| 3626 | else | ||
| 3627 | return ath10k_wmi_tlv_op_gen_config_pno_stop(ar, vdev_id); | ||
| 3628 | } | ||
| 3629 | |||
| 3444 | static struct sk_buff * | 3630 | static struct sk_buff * |
| 3445 | ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable) | 3631 | ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable) |
| 3446 | { | 3632 | { |
| @@ -3973,6 +4159,7 @@ static const struct wmi_ops wmi_tlv_ops = { | |||
| 3973 | .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, | 4159 | .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, |
| 3974 | .gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern, | 4160 | .gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern, |
| 3975 | .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern, | 4161 | .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern, |
| 4162 | .gen_wow_config_pno = ath10k_wmi_tlv_op_gen_config_pno, | ||
| 3976 | .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state, | 4163 | .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state, |
| 3977 | .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, | 4164 | .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, |
| 3978 | .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, | 4165 | .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, |
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index 4f0c20c90642..92c25f51bf86 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h | |||
| @@ -2146,6 +2146,260 @@ struct wmi_tlv_tdls_peer_event { | |||
| 2146 | 2146 | ||
| 2147 | void ath10k_wmi_tlv_attach(struct ath10k *ar); | 2147 | void ath10k_wmi_tlv_attach(struct ath10k *ar); |
| 2148 | 2148 | ||
| 2149 | enum wmi_nlo_auth_algorithm { | ||
| 2150 | WMI_NLO_AUTH_ALGO_80211_OPEN = 1, | ||
| 2151 | WMI_NLO_AUTH_ALGO_80211_SHARED_KEY = 2, | ||
| 2152 | WMI_NLO_AUTH_ALGO_WPA = 3, | ||
| 2153 | WMI_NLO_AUTH_ALGO_WPA_PSK = 4, | ||
| 2154 | WMI_NLO_AUTH_ALGO_WPA_NONE = 5, | ||
| 2155 | WMI_NLO_AUTH_ALGO_RSNA = 6, | ||
| 2156 | WMI_NLO_AUTH_ALGO_RSNA_PSK = 7, | ||
| 2157 | }; | ||
| 2158 | |||
| 2159 | enum wmi_nlo_cipher_algorithm { | ||
| 2160 | WMI_NLO_CIPHER_ALGO_NONE = 0x00, | ||
| 2161 | WMI_NLO_CIPHER_ALGO_WEP40 = 0x01, | ||
| 2162 | WMI_NLO_CIPHER_ALGO_TKIP = 0x02, | ||
| 2163 | WMI_NLO_CIPHER_ALGO_CCMP = 0x04, | ||
| 2164 | WMI_NLO_CIPHER_ALGO_WEP104 = 0x05, | ||
| 2165 | WMI_NLO_CIPHER_ALGO_BIP = 0x06, | ||
| 2166 | WMI_NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, | ||
| 2167 | WMI_NLO_CIPHER_ALGO_WEP = 0x101, | ||
| 2168 | }; | ||
| 2169 | |||
| 2170 | /* SSID broadcast type passed in NLO params */ | ||
| 2171 | enum wmi_nlo_ssid_bcastnwtype { | ||
| 2172 | WMI_NLO_BCAST_UNKNOWN = 0, | ||
| 2173 | WMI_NLO_BCAST_NORMAL = 1, | ||
| 2174 | WMI_NLO_BCAST_HIDDEN = 2, | ||
| 2175 | }; | ||
| 2176 | |||
| 2177 | #define WMI_NLO_MAX_SSIDS 16 | ||
| 2178 | #define WMI_NLO_MAX_CHAN 48 | ||
| 2179 | |||
| 2180 | #define WMI_NLO_CONFIG_STOP (0x1 << 0) | ||
| 2181 | #define WMI_NLO_CONFIG_START (0x1 << 1) | ||
| 2182 | #define WMI_NLO_CONFIG_RESET (0x1 << 2) | ||
| 2183 | #define WMI_NLO_CONFIG_SLOW_SCAN (0x1 << 4) | ||
| 2184 | #define WMI_NLO_CONFIG_FAST_SCAN (0x1 << 5) | ||
| 2185 | #define WMI_NLO_CONFIG_SSID_HIDE_EN (0x1 << 6) | ||
| 2186 | |||
| 2187 | /* This bit is used to indicate if EPNO or supplicant PNO is enabled. | ||
| 2188 | * Only one of them can be enabled at a given time | ||
| 2189 | */ | ||
| 2190 | #define WMI_NLO_CONFIG_ENLO (0x1 << 7) | ||
| 2191 | #define WMI_NLO_CONFIG_SCAN_PASSIVE (0x1 << 8) | ||
| 2192 | #define WMI_NLO_CONFIG_ENLO_RESET (0x1 << 9) | ||
| 2193 | #define WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ (0x1 << 10) | ||
| 2194 | #define WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ (0x1 << 11) | ||
| 2195 | #define WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ (0x1 << 12) | ||
| 2196 | #define WMI_NLO_CONFIG_ENABLE_CNLO_RSSI_CONFIG (0x1 << 13) | ||
| 2197 | |||
| 2198 | /* Whether directed scan needs to be performed (for hidden SSIDs) */ | ||
| 2199 | #define WMI_ENLO_FLAG_DIRECTED_SCAN 1 | ||
| 2200 | |||
| 2201 | /* Whether PNO event shall be triggered if the network is found on A band */ | ||
| 2202 | #define WMI_ENLO_FLAG_A_BAND 2 | ||
| 2203 | |||
| 2204 | /* Whether PNO event shall be triggered if the network is found on G band */ | ||
| 2205 | #define WMI_ENLO_FLAG_G_BAND 4 | ||
| 2206 | |||
| 2207 | /* Whether strict matching is required (i.e. firmware shall not | ||
| 2208 | * match on the entire SSID) | ||
| 2209 | */ | ||
| 2210 | #define WMI_ENLO_FLAG_STRICT_MATCH 8 | ||
| 2211 | |||
| 2212 | /* Code for matching the beacon AUTH IE - additional codes TBD */ | ||
| 2213 | /* open */ | ||
| 2214 | #define WMI_ENLO_AUTH_CODE_OPEN 1 | ||
| 2215 | |||
| 2216 | /* WPA_PSK or WPA2PSK */ | ||
| 2217 | #define WMI_ENLO_AUTH_CODE_PSK 2 | ||
| 2218 | |||
| 2219 | /* any EAPOL */ | ||
| 2220 | #define WMI_ENLO_AUTH_CODE_EAPOL 4 | ||
| 2221 | |||
| 2222 | struct wmi_nlo_ssid_param { | ||
| 2223 | __le32 valid; | ||
| 2224 | struct wmi_ssid ssid; | ||
| 2225 | } __packed; | ||
| 2226 | |||
| 2227 | struct wmi_nlo_enc_param { | ||
| 2228 | __le32 valid; | ||
| 2229 | __le32 enc_type; | ||
| 2230 | } __packed; | ||
| 2231 | |||
| 2232 | struct wmi_nlo_auth_param { | ||
| 2233 | __le32 valid; | ||
| 2234 | __le32 auth_type; | ||
| 2235 | } __packed; | ||
| 2236 | |||
| 2237 | struct wmi_nlo_bcast_nw_param { | ||
| 2238 | __le32 valid; | ||
| 2239 | |||
| 2240 | /* If WMI_NLO_CONFIG_EPNO is not set. Supplicant PNO is enabled. | ||
| 2241 | * The value should be true/false. Otherwise EPNO is enabled. | ||
| 2242 | * bcast_nw_type would be used as a bit flag contains WMI_ENLO_FLAG_XXX | ||
| 2243 | */ | ||
| 2244 | __le32 bcast_nw_type; | ||
| 2245 | } __packed; | ||
| 2246 | |||
| 2247 | struct wmi_nlo_rssi_param { | ||
| 2248 | __le32 valid; | ||
| 2249 | __le32 rssi; | ||
| 2250 | } __packed; | ||
| 2251 | |||
| 2252 | struct nlo_configured_parameters { | ||
| 2253 | /* TLV tag and len;*/ | ||
| 2254 | __le32 tlv_header; | ||
| 2255 | struct wmi_nlo_ssid_param ssid; | ||
| 2256 | struct wmi_nlo_enc_param enc_type; | ||
| 2257 | struct wmi_nlo_auth_param auth_type; | ||
| 2258 | struct wmi_nlo_rssi_param rssi_cond; | ||
| 2259 | |||
| 2260 | /* indicates if the SSID is hidden or not */ | ||
| 2261 | struct wmi_nlo_bcast_nw_param bcast_nw_type; | ||
| 2262 | } __packed; | ||
| 2263 | |||
| 2264 | /* Support channel prediction for PNO scan after scanning top_k_num channels | ||
| 2265 | * if stationary_threshold is met. | ||
| 2266 | */ | ||
| 2267 | struct nlo_channel_prediction_cfg { | ||
| 2268 | __le32 tlv_header; | ||
| 2269 | |||
| 2270 | /* Enable or disable this feature. */ | ||
| 2271 | __le32 enable; | ||
| 2272 | |||
| 2273 | /* Top K channels will be scanned before deciding whether to further scan | ||
| 2274 | * or stop. Minimum value is 3 and maximum is 5. | ||
| 2275 | */ | ||
| 2276 | __le32 top_k_num; | ||
| 2277 | |||
| 2278 | /* Preconfigured stationary threshold. | ||
| 2279 | * Lesser value means more conservative. Bigger value means more aggressive. | ||
| 2280 | * Maximum is 100 and mininum is 0. | ||
| 2281 | */ | ||
| 2282 | __le32 stationary_threshold; | ||
| 2283 | |||
| 2284 | /* Periodic full channel scan in milliseconds unit. | ||
| 2285 | * After full_scan_period_ms since last full scan, channel prediction | ||
| 2286 | * scan is suppressed and will do full scan. | ||
| 2287 | * This is to help detecting sudden AP power-on or -off. Value 0 means no | ||
| 2288 | * full scan at all (not recommended). | ||
| 2289 | */ | ||
| 2290 | __le32 full_scan_period_ms; | ||
| 2291 | } __packed; | ||
| 2292 | |||
| 2293 | struct enlo_candidate_score_params_t { | ||
| 2294 | __le32 tlv_header; /* TLV tag and len; */ | ||
| 2295 | |||
| 2296 | /* minimum 5GHz RSSI for a BSSID to be considered (units = dBm) */ | ||
| 2297 | __le32 min_5ghz_rssi; | ||
| 2298 | |||
| 2299 | /* minimum 2.4GHz RSSI for a BSSID to be considered (units = dBm) */ | ||
| 2300 | __le32 min_24ghz_rssi; | ||
| 2301 | |||
| 2302 | /* the maximum score that a network can have before bonuses */ | ||
| 2303 | __le32 initial_score_max; | ||
| 2304 | |||
| 2305 | /* current_connection_bonus: | ||
| 2306 | * only report when there is a network's score this much higher | ||
| 2307 | * than the current connection | ||
| 2308 | */ | ||
| 2309 | __le32 current_connection_bonus; | ||
| 2310 | |||
| 2311 | /* score bonus for all networks with the same network flag */ | ||
| 2312 | __le32 same_network_bonus; | ||
| 2313 | |||
| 2314 | /* score bonus for networks that are not open */ | ||
| 2315 | __le32 secure_bonus; | ||
| 2316 | |||
| 2317 | /* 5GHz RSSI score bonus (applied to all 5GHz networks) */ | ||
| 2318 | __le32 band_5ghz_bonus; | ||
| 2319 | } __packed; | ||
| 2320 | |||
| 2321 | struct connected_nlo_bss_band_rssi_pref_t { | ||
| 2322 | __le32 tlv_header; /* TLV tag and len;*/ | ||
| 2323 | |||
| 2324 | /* band which needs to get preference over other band | ||
| 2325 | * - see wmi_set_vdev_ie_band enum | ||
| 2326 | */ | ||
| 2327 | __le32 band; | ||
| 2328 | |||
| 2329 | /* Amount of RSSI preference (in dB) that can be given to a band */ | ||
| 2330 | __le32 rssi_pref; | ||
| 2331 | } __packed; | ||
| 2332 | |||
| 2333 | struct connected_nlo_rssi_params_t { | ||
| 2334 | __le32 tlv_header; /* TLV tag and len;*/ | ||
| 2335 | |||
| 2336 | /* Relative rssi threshold (in dB) by which new BSS should have | ||
| 2337 | * better rssi than the current connected BSS. | ||
| 2338 | */ | ||
| 2339 | __le32 relative_rssi; | ||
| 2340 | |||
| 2341 | /* The amount of rssi preference (in dB) that can be given | ||
| 2342 | * to a 5G BSS over 2.4G BSS. | ||
| 2343 | */ | ||
| 2344 | __le32 relative_rssi_5g_pref; | ||
| 2345 | } __packed; | ||
| 2346 | |||
| 2347 | struct wmi_tlv_wow_nlo_config_cmd { | ||
| 2348 | __le32 flags; | ||
| 2349 | __le32 vdev_id; | ||
| 2350 | __le32 fast_scan_max_cycles; | ||
| 2351 | __le32 active_dwell_time; | ||
| 2352 | __le32 passive_dwell_time; /* PDT in msecs */ | ||
| 2353 | __le32 probe_bundle_size; | ||
| 2354 | |||
| 2355 | /* ART = IRT */ | ||
| 2356 | __le32 rest_time; | ||
| 2357 | |||
| 2358 | /* Max value that can be reached after SBM */ | ||
| 2359 | __le32 max_rest_time; | ||
| 2360 | |||
| 2361 | /* SBM */ | ||
| 2362 | __le32 scan_backoff_multiplier; | ||
| 2363 | |||
| 2364 | /* SCBM */ | ||
| 2365 | __le32 fast_scan_period; | ||
| 2366 | |||
| 2367 | /* specific to windows */ | ||
| 2368 | __le32 slow_scan_period; | ||
| 2369 | |||
| 2370 | __le32 no_of_ssids; | ||
| 2371 | |||
| 2372 | __le32 num_of_channels; | ||
| 2373 | |||
| 2374 | /* NLO scan start delay time in milliseconds */ | ||
| 2375 | __le32 delay_start_time; | ||
| 2376 | |||
| 2377 | /** MAC Address to use in Probe Req as SA **/ | ||
| 2378 | struct wmi_mac_addr mac_addr; | ||
| 2379 | |||
| 2380 | /** Mask on which MAC has to be randomized **/ | ||
| 2381 | struct wmi_mac_addr mac_mask; | ||
| 2382 | |||
| 2383 | /** IE bitmap to use in Probe Req **/ | ||
| 2384 | __le32 ie_bitmap[8]; | ||
| 2385 | |||
| 2386 | /** Number of vendor OUIs. In the TLV vendor_oui[] **/ | ||
| 2387 | __le32 num_vendor_oui; | ||
| 2388 | |||
| 2389 | /** Number of connected NLO band preferences **/ | ||
| 2390 | __le32 num_cnlo_band_pref; | ||
| 2391 | |||
| 2392 | /* The TLVs will follow. | ||
| 2393 | * nlo_configured_parameters nlo_list[]; | ||
| 2394 | * A_UINT32 channel_list[num_of_channels]; | ||
| 2395 | * nlo_channel_prediction_cfg ch_prediction_cfg; | ||
| 2396 | * enlo_candidate_score_params candidate_score_params; | ||
| 2397 | * wmi_vendor_oui vendor_oui[num_vendor_oui]; | ||
| 2398 | * connected_nlo_rssi_params cnlo_rssi_params; | ||
| 2399 | * connected_nlo_bss_band_rssi_pref cnlo_bss_band_rssi_pref[num_cnlo_band_pref]; | ||
| 2400 | */ | ||
| 2401 | } __packed; | ||
| 2402 | |||
| 2149 | struct wmi_tlv_mgmt_tx_cmd { | 2403 | struct wmi_tlv_mgmt_tx_cmd { |
| 2150 | __le32 vdev_id; | 2404 | __le32 vdev_id; |
| 2151 | __le32 desc_id; | 2405 | __le32 desc_id; |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index f67c52757ea6..f7badd079051 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
| @@ -7068,6 +7068,63 @@ struct wmi_pdev_set_adaptive_cca_params { | |||
| 7068 | __le32 cca_detect_margin; | 7068 | __le32 cca_detect_margin; |
| 7069 | } __packed; | 7069 | } __packed; |
| 7070 | 7070 | ||
| 7071 | #define WMI_PNO_MAX_SCHED_SCAN_PLANS 2 | ||
| 7072 | #define WMI_PNO_MAX_SCHED_SCAN_PLAN_INT 7200 | ||
| 7073 | #define WMI_PNO_MAX_SCHED_SCAN_PLAN_ITRNS 100 | ||
| 7074 | #define WMI_PNO_MAX_NETW_CHANNELS 26 | ||
| 7075 | #define WMI_PNO_MAX_NETW_CHANNELS_EX 60 | ||
| 7076 | #define WMI_PNO_MAX_SUPP_NETWORKS WLAN_SCAN_PARAMS_MAX_SSID | ||
| 7077 | #define WMI_PNO_MAX_IE_LENGTH WLAN_SCAN_PARAMS_MAX_IE_LEN | ||
| 7078 | |||
| 7079 | /*size based of dot11 declaration without extra IEs as we will not carry those for PNO*/ | ||
| 7080 | #define WMI_PNO_MAX_PB_REQ_SIZE 450 | ||
| 7081 | |||
| 7082 | #define WMI_PNO_24G_DEFAULT_CH 1 | ||
| 7083 | #define WMI_PNO_5G_DEFAULT_CH 36 | ||
| 7084 | |||
| 7085 | #define WMI_ACTIVE_MAX_CHANNEL_TIME 40 | ||
| 7086 | #define WMI_PASSIVE_MAX_CHANNEL_TIME 110 | ||
| 7087 | |||
| 7088 | /* SSID broadcast type */ | ||
| 7089 | enum wmi_SSID_bcast_type { | ||
| 7090 | BCAST_UNKNOWN = 0, | ||
| 7091 | BCAST_NORMAL = 1, | ||
| 7092 | BCAST_HIDDEN = 2, | ||
| 7093 | }; | ||
| 7094 | |||
| 7095 | struct wmi_network_type { | ||
| 7096 | struct wmi_ssid ssid; | ||
| 7097 | u32 authentication; | ||
| 7098 | u32 encryption; | ||
| 7099 | u32 bcast_nw_type; | ||
| 7100 | u8 channel_count; | ||
| 7101 | u16 channels[WMI_PNO_MAX_NETW_CHANNELS_EX]; | ||
| 7102 | s32 rssi_threshold; | ||
| 7103 | } __packed; | ||
| 7104 | |||
| 7105 | struct wmi_pno_scan_req { | ||
| 7106 | u8 enable; | ||
| 7107 | u8 vdev_id; | ||
| 7108 | u8 uc_networks_count; | ||
| 7109 | struct wmi_network_type a_networks[WMI_PNO_MAX_SUPP_NETWORKS]; | ||
| 7110 | u32 fast_scan_period; | ||
| 7111 | u32 slow_scan_period; | ||
| 7112 | u8 fast_scan_max_cycles; | ||
| 7113 | |||
| 7114 | bool do_passive_scan; | ||
| 7115 | |||
| 7116 | u32 delay_start_time; | ||
| 7117 | u32 active_min_time; | ||
| 7118 | u32 active_max_time; | ||
| 7119 | u32 passive_min_time; | ||
| 7120 | u32 passive_max_time; | ||
| 7121 | |||
| 7122 | /* mac address randomization attributes */ | ||
| 7123 | u32 enable_pno_scan_randomization; | ||
| 7124 | u8 mac_addr[ETH_ALEN]; | ||
| 7125 | u8 mac_addr_mask[ETH_ALEN]; | ||
| 7126 | } __packed; | ||
| 7127 | |||
| 7071 | enum wmi_host_platform_type { | 7128 | enum wmi_host_platform_type { |
| 7072 | WMI_HOST_PLATFORM_HIGH_PERF, | 7129 | WMI_HOST_PLATFORM_HIGH_PERF, |
| 7073 | WMI_HOST_PLATFORM_LOW_PERF, | 7130 | WMI_HOST_PLATFORM_LOW_PERF, |
diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c index af444dfecae9..51b26b305885 100644 --- a/drivers/net/wireless/ath/ath10k/wow.c +++ b/drivers/net/wireless/ath/ath10k/wow.c | |||
| @@ -180,6 +180,100 @@ static void ath10k_wow_convert_8023_to_80211 | |||
| 180 | } | 180 | } |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | static int ath10k_wmi_pno_check(struct ath10k *ar, u32 vdev_id, | ||
| 184 | struct cfg80211_sched_scan_request *nd_config, | ||
| 185 | struct wmi_pno_scan_req *pno) | ||
| 186 | { | ||
| 187 | int i, j, ret = 0; | ||
| 188 | u8 ssid_len; | ||
| 189 | |||
| 190 | pno->enable = 1; | ||
| 191 | pno->vdev_id = vdev_id; | ||
| 192 | pno->uc_networks_count = nd_config->n_match_sets; | ||
| 193 | |||
| 194 | if (!pno->uc_networks_count || | ||
| 195 | pno->uc_networks_count > WMI_PNO_MAX_SUPP_NETWORKS) | ||
| 196 | return -EINVAL; | ||
| 197 | |||
| 198 | if (nd_config->n_channels > WMI_PNO_MAX_NETW_CHANNELS_EX) | ||
| 199 | return -EINVAL; | ||
| 200 | |||
| 201 | /* Filling per profile params */ | ||
| 202 | for (i = 0; i < pno->uc_networks_count; i++) { | ||
| 203 | ssid_len = nd_config->match_sets[i].ssid.ssid_len; | ||
| 204 | |||
| 205 | if (ssid_len == 0 || ssid_len > 32) | ||
| 206 | return -EINVAL; | ||
| 207 | |||
| 208 | pno->a_networks[i].ssid.ssid_len = __cpu_to_le32(ssid_len); | ||
| 209 | |||
| 210 | memcpy(pno->a_networks[i].ssid.ssid, | ||
| 211 | nd_config->match_sets[i].ssid.ssid, | ||
| 212 | nd_config->match_sets[i].ssid.ssid_len); | ||
| 213 | pno->a_networks[i].authentication = 0; | ||
| 214 | pno->a_networks[i].encryption = 0; | ||
| 215 | pno->a_networks[i].bcast_nw_type = 0; | ||
| 216 | |||
| 217 | /*Copying list of valid channel into request */ | ||
| 218 | pno->a_networks[i].channel_count = nd_config->n_channels; | ||
| 219 | pno->a_networks[i].rssi_threshold = nd_config->match_sets[i].rssi_thold; | ||
| 220 | |||
| 221 | for (j = 0; j < nd_config->n_channels; j++) { | ||
| 222 | pno->a_networks[i].channels[j] = | ||
| 223 | nd_config->channels[j]->center_freq; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | /* set scan to passive if no SSIDs are specified in the request */ | ||
| 228 | if (nd_config->n_ssids == 0) | ||
| 229 | pno->do_passive_scan = true; | ||
| 230 | else | ||
| 231 | pno->do_passive_scan = false; | ||
| 232 | |||
| 233 | for (i = 0; i < nd_config->n_ssids; i++) { | ||
| 234 | j = 0; | ||
| 235 | while (j < pno->uc_networks_count) { | ||
| 236 | if (__le32_to_cpu(pno->a_networks[j].ssid.ssid_len) == | ||
| 237 | nd_config->ssids[i].ssid_len && | ||
| 238 | (memcmp(pno->a_networks[j].ssid.ssid, | ||
| 239 | nd_config->ssids[i].ssid, | ||
| 240 | __le32_to_cpu(pno->a_networks[j].ssid.ssid_len)) == 0)) { | ||
| 241 | pno->a_networks[j].bcast_nw_type = BCAST_HIDDEN; | ||
| 242 | break; | ||
| 243 | } | ||
| 244 | j++; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | if (nd_config->n_scan_plans == 2) { | ||
| 249 | pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; | ||
| 250 | pno->fast_scan_max_cycles = nd_config->scan_plans[0].iterations; | ||
| 251 | pno->slow_scan_period = | ||
| 252 | nd_config->scan_plans[1].interval * MSEC_PER_SEC; | ||
| 253 | } else if (nd_config->n_scan_plans == 1) { | ||
| 254 | pno->fast_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; | ||
| 255 | pno->fast_scan_max_cycles = 1; | ||
| 256 | pno->slow_scan_period = nd_config->scan_plans[0].interval * MSEC_PER_SEC; | ||
| 257 | } else { | ||
| 258 | ath10k_warn(ar, "Invalid number of scan plans %d !!", | ||
| 259 | nd_config->n_scan_plans); | ||
| 260 | } | ||
| 261 | |||
| 262 | if (nd_config->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { | ||
| 263 | /* enable mac randomization */ | ||
| 264 | pno->enable_pno_scan_randomization = 1; | ||
| 265 | memcpy(pno->mac_addr, nd_config->mac_addr, ETH_ALEN); | ||
| 266 | memcpy(pno->mac_addr_mask, nd_config->mac_addr_mask, ETH_ALEN); | ||
| 267 | } | ||
| 268 | |||
| 269 | pno->delay_start_time = nd_config->delay; | ||
| 270 | |||
| 271 | /* Current FW does not support min-max range for dwell time */ | ||
| 272 | pno->active_max_time = WMI_ACTIVE_MAX_CHANNEL_TIME; | ||
| 273 | pno->passive_max_time = WMI_PASSIVE_MAX_CHANNEL_TIME; | ||
| 274 | return ret; | ||
| 275 | } | ||
| 276 | |||
| 183 | static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, | 277 | static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, |
| 184 | struct cfg80211_wowlan *wowlan) | 278 | struct cfg80211_wowlan *wowlan) |
| 185 | { | 279 | { |
| @@ -213,6 +307,26 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, | |||
| 213 | 307 | ||
| 214 | if (wowlan->magic_pkt) | 308 | if (wowlan->magic_pkt) |
| 215 | __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); | 309 | __set_bit(WOW_MAGIC_PKT_RECVD_EVENT, &wow_mask); |
| 310 | |||
| 311 | if (wowlan->nd_config) { | ||
| 312 | struct wmi_pno_scan_req *pno; | ||
| 313 | int ret; | ||
| 314 | |||
| 315 | pno = kzalloc(sizeof(*pno), GFP_KERNEL); | ||
| 316 | if (!pno) | ||
| 317 | return -ENOMEM; | ||
| 318 | |||
| 319 | ar->nlo_enabled = true; | ||
| 320 | |||
| 321 | ret = ath10k_wmi_pno_check(ar, arvif->vdev_id, | ||
| 322 | wowlan->nd_config, pno); | ||
| 323 | if (!ret) { | ||
| 324 | ath10k_wmi_wow_config_pno(ar, arvif->vdev_id, pno); | ||
| 325 | __set_bit(WOW_NLO_DETECTED_EVENT, &wow_mask); | ||
| 326 | } | ||
| 327 | |||
| 328 | kfree(pno); | ||
| 329 | } | ||
| 216 | break; | 330 | break; |
| 217 | default: | 331 | default: |
| 218 | break; | 332 | break; |
| @@ -299,6 +413,51 @@ static int ath10k_wow_set_wakeups(struct ath10k *ar, | |||
| 299 | return 0; | 413 | return 0; |
| 300 | } | 414 | } |
| 301 | 415 | ||
| 416 | static int ath10k_vif_wow_clean_nlo(struct ath10k_vif *arvif) | ||
| 417 | { | ||
| 418 | int ret = 0; | ||
| 419 | struct ath10k *ar = arvif->ar; | ||
| 420 | |||
| 421 | switch (arvif->vdev_type) { | ||
| 422 | case WMI_VDEV_TYPE_STA: | ||
| 423 | if (ar->nlo_enabled) { | ||
| 424 | struct wmi_pno_scan_req *pno; | ||
| 425 | |||
| 426 | pno = kzalloc(sizeof(*pno), GFP_KERNEL); | ||
| 427 | if (!pno) | ||
| 428 | return -ENOMEM; | ||
| 429 | |||
| 430 | pno->enable = 0; | ||
| 431 | ar->nlo_enabled = false; | ||
| 432 | ret = ath10k_wmi_wow_config_pno(ar, arvif->vdev_id, pno); | ||
| 433 | kfree(pno); | ||
| 434 | } | ||
| 435 | break; | ||
| 436 | default: | ||
| 437 | break; | ||
| 438 | } | ||
| 439 | return ret; | ||
| 440 | } | ||
| 441 | |||
| 442 | static int ath10k_wow_nlo_cleanup(struct ath10k *ar) | ||
| 443 | { | ||
| 444 | struct ath10k_vif *arvif; | ||
| 445 | int ret = 0; | ||
| 446 | |||
| 447 | lockdep_assert_held(&ar->conf_mutex); | ||
| 448 | |||
| 449 | list_for_each_entry(arvif, &ar->arvifs, list) { | ||
| 450 | ret = ath10k_vif_wow_clean_nlo(arvif); | ||
| 451 | if (ret) { | ||
| 452 | ath10k_warn(ar, "failed to clean nlo settings on vdev %i: %d\n", | ||
| 453 | arvif->vdev_id, ret); | ||
| 454 | return ret; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | return 0; | ||
| 459 | } | ||
| 460 | |||
| 302 | static int ath10k_wow_enable(struct ath10k *ar) | 461 | static int ath10k_wow_enable(struct ath10k *ar) |
| 303 | { | 462 | { |
| 304 | int ret; | 463 | int ret; |
| @@ -436,6 +595,10 @@ int ath10k_wow_op_resume(struct ieee80211_hw *hw) | |||
| 436 | if (ret) | 595 | if (ret) |
| 437 | ath10k_warn(ar, "failed to wakeup from wow: %d\n", ret); | 596 | ath10k_warn(ar, "failed to wakeup from wow: %d\n", ret); |
| 438 | 597 | ||
| 598 | ret = ath10k_wow_nlo_cleanup(ar); | ||
| 599 | if (ret) | ||
| 600 | ath10k_warn(ar, "failed to cleanup nlo: %d\n", ret); | ||
| 601 | |||
| 439 | exit: | 602 | exit: |
| 440 | if (ret) { | 603 | if (ret) { |
| 441 | switch (ar->state) { | 604 | switch (ar->state) { |
| @@ -475,6 +638,11 @@ int ath10k_wow_init(struct ath10k *ar) | |||
| 475 | ar->wow.wowlan_support.max_pkt_offset -= WOW_MAX_REDUCE; | 638 | ar->wow.wowlan_support.max_pkt_offset -= WOW_MAX_REDUCE; |
| 476 | } | 639 | } |
| 477 | 640 | ||
| 641 | if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) { | ||
| 642 | ar->wow.wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; | ||
| 643 | ar->wow.wowlan_support.max_nd_match_sets = WMI_PNO_MAX_SUPP_NETWORKS; | ||
| 644 | } | ||
| 645 | |||
| 478 | ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns; | 646 | ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns; |
| 479 | ar->hw->wiphy->wowlan = &ar->wow.wowlan_support; | 647 | ar->hw->wiphy->wowlan = &ar->wow.wowlan_support; |
| 480 | 648 | ||
diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c index a3668433dc02..988222cea9df 100644 --- a/drivers/net/wireless/ath/ath9k/antenna.c +++ b/drivers/net/wireless/ath/ath9k/antenna.c | |||
| @@ -755,11 +755,11 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
| 755 | } | 755 | } |
| 756 | 756 | ||
| 757 | if (main_ant_conf == rx_ant_conf) { | 757 | if (main_ant_conf == rx_ant_conf) { |
| 758 | ANT_STAT_INC(ANT_MAIN, recv_cnt); | 758 | ANT_STAT_INC(sc, ANT_MAIN, recv_cnt); |
| 759 | ANT_LNA_INC(ANT_MAIN, rx_ant_conf); | 759 | ANT_LNA_INC(sc, ANT_MAIN, rx_ant_conf); |
| 760 | } else { | 760 | } else { |
| 761 | ANT_STAT_INC(ANT_ALT, recv_cnt); | 761 | ANT_STAT_INC(sc, ANT_ALT, recv_cnt); |
| 762 | ANT_LNA_INC(ANT_ALT, rx_ant_conf); | 762 | ANT_LNA_INC(sc, ANT_ALT, rx_ant_conf); |
| 763 | } | 763 | } |
| 764 | 764 | ||
| 765 | /* Short scan check */ | 765 | /* Short scan check */ |
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c index 6a43d26276e5..6aa3ec024ffa 100644 --- a/drivers/net/wireless/ath/ath9k/common-spectral.c +++ b/drivers/net/wireless/ath/ath9k/common-spectral.c | |||
| @@ -624,9 +624,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h | |||
| 624 | tsf, freq, chan_type); | 624 | tsf, freq, chan_type); |
| 625 | 625 | ||
| 626 | if (ret == 0) | 626 | if (ret == 0) |
| 627 | RX_STAT_INC(rx_spectral_sample_good); | 627 | RX_STAT_INC(sc, rx_spectral_sample_good); |
| 628 | else | 628 | else |
| 629 | RX_STAT_INC(rx_spectral_sample_err); | 629 | RX_STAT_INC(sc, rx_spectral_sample_err); |
| 630 | 630 | ||
| 631 | memset(sample_buf, 0, SPECTRAL_SAMPLE_MAX_LEN); | 631 | memset(sample_buf, 0, SPECTRAL_SAMPLE_MAX_LEN); |
| 632 | 632 | ||
| @@ -642,9 +642,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h | |||
| 642 | tsf, freq, chan_type); | 642 | tsf, freq, chan_type); |
| 643 | 643 | ||
| 644 | if (ret == 0) | 644 | if (ret == 0) |
| 645 | RX_STAT_INC(rx_spectral_sample_good); | 645 | RX_STAT_INC(sc, rx_spectral_sample_good); |
| 646 | else | 646 | else |
| 647 | RX_STAT_INC(rx_spectral_sample_err); | 647 | RX_STAT_INC(sc, rx_spectral_sample_err); |
| 648 | 648 | ||
| 649 | /* Mix the received bins to the /dev/random | 649 | /* Mix the received bins to the /dev/random |
| 650 | * pool | 650 | * pool |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c871b7ec5011..4399e9ad058f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
| @@ -785,35 +785,35 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
| 785 | { | 785 | { |
| 786 | int qnum = txq->axq_qnum; | 786 | int qnum = txq->axq_qnum; |
| 787 | 787 | ||
| 788 | TX_STAT_INC(qnum, tx_pkts_all); | 788 | TX_STAT_INC(sc, qnum, tx_pkts_all); |
| 789 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; | 789 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; |
| 790 | 790 | ||
| 791 | if (bf_isampdu(bf)) { | 791 | if (bf_isampdu(bf)) { |
| 792 | if (flags & ATH_TX_ERROR) | 792 | if (flags & ATH_TX_ERROR) |
| 793 | TX_STAT_INC(qnum, a_xretries); | 793 | TX_STAT_INC(sc, qnum, a_xretries); |
| 794 | else | 794 | else |
| 795 | TX_STAT_INC(qnum, a_completed); | 795 | TX_STAT_INC(sc, qnum, a_completed); |
| 796 | } else { | 796 | } else { |
| 797 | if (ts->ts_status & ATH9K_TXERR_XRETRY) | 797 | if (ts->ts_status & ATH9K_TXERR_XRETRY) |
| 798 | TX_STAT_INC(qnum, xretries); | 798 | TX_STAT_INC(sc, qnum, xretries); |
| 799 | else | 799 | else |
| 800 | TX_STAT_INC(qnum, completed); | 800 | TX_STAT_INC(sc, qnum, completed); |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | if (ts->ts_status & ATH9K_TXERR_FILT) | 803 | if (ts->ts_status & ATH9K_TXERR_FILT) |
| 804 | TX_STAT_INC(qnum, txerr_filtered); | 804 | TX_STAT_INC(sc, qnum, txerr_filtered); |
| 805 | if (ts->ts_status & ATH9K_TXERR_FIFO) | 805 | if (ts->ts_status & ATH9K_TXERR_FIFO) |
| 806 | TX_STAT_INC(qnum, fifo_underrun); | 806 | TX_STAT_INC(sc, qnum, fifo_underrun); |
| 807 | if (ts->ts_status & ATH9K_TXERR_XTXOP) | 807 | if (ts->ts_status & ATH9K_TXERR_XTXOP) |
| 808 | TX_STAT_INC(qnum, xtxop); | 808 | TX_STAT_INC(sc, qnum, xtxop); |
| 809 | if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) | 809 | if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) |
| 810 | TX_STAT_INC(qnum, timer_exp); | 810 | TX_STAT_INC(sc, qnum, timer_exp); |
| 811 | if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) | 811 | if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) |
| 812 | TX_STAT_INC(qnum, desc_cfg_err); | 812 | TX_STAT_INC(sc, qnum, desc_cfg_err); |
| 813 | if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) | 813 | if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) |
| 814 | TX_STAT_INC(qnum, data_underrun); | 814 | TX_STAT_INC(sc, qnum, data_underrun); |
| 815 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 815 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
| 816 | TX_STAT_INC(qnum, delim_underrun); | 816 | TX_STAT_INC(sc, qnum, delim_underrun); |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | 819 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 249f8141cd00..79607db14387 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
| @@ -25,17 +25,17 @@ struct ath_buf; | |||
| 25 | struct fft_sample_tlv; | 25 | struct fft_sample_tlv; |
| 26 | 26 | ||
| 27 | #ifdef CONFIG_ATH9K_DEBUGFS | 27 | #ifdef CONFIG_ATH9K_DEBUGFS |
| 28 | #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ | 28 | #define TX_STAT_INC(sc, q, c) do { (sc)->debug.stats.txstats[q].c++; } while (0) |
| 29 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) | 29 | #define RX_STAT_INC(sc, c) do { (sc)->debug.stats.rxstats.c++; } while (0) |
| 30 | #define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ | 30 | #define RESET_STAT_INC(sc, type) do { (sc)->debug.stats.reset[type]++; } while (0) |
| 31 | #define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++ | 31 | #define ANT_STAT_INC(sc, i, c) do { (sc)->debug.stats.ant_stats[i].c++; } while (0) |
| 32 | #define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++; | 32 | #define ANT_LNA_INC(sc, i, c) do { (sc)->debug.stats.ant_stats[i].lna_recv_cnt[c]++; } while (0) |
| 33 | #else | 33 | #else |
| 34 | #define TX_STAT_INC(q, c) do { } while (0) | 34 | #define TX_STAT_INC(sc, q, c) do { (void)(sc); } while (0) |
| 35 | #define RX_STAT_INC(c) | 35 | #define RX_STAT_INC(sc, c) do { (void)(sc); } while (0) |
| 36 | #define RESET_STAT_INC(sc, type) do { } while (0) | 36 | #define RESET_STAT_INC(sc, type) do { (void)(sc); } while (0) |
| 37 | #define ANT_STAT_INC(i, c) do { } while (0) | 37 | #define ANT_STAT_INC(sc, i, c) do { (void)(sc); } while (0) |
| 38 | #define ANT_LNA_INC(i, c) do { } while (0) | 38 | #define ANT_LNA_INC(sc, i, c) do { (void)(sc); } while (0) |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | enum ath_reset_type { | 41 | enum ath_reset_type { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c85f613e8ceb..1e3b5f4a4cf9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -809,7 +809,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, | |||
| 809 | 809 | ||
| 810 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 810 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
| 811 | ath_dbg(common, XMIT, "TX failed\n"); | 811 | ath_dbg(common, XMIT, "TX failed\n"); |
| 812 | TX_STAT_INC(txctl.txq->axq_qnum, txfailed); | 812 | TX_STAT_INC(sc, txctl.txq->axq_qnum, txfailed); |
| 813 | goto exit; | 813 | goto exit; |
| 814 | } | 814 | } |
| 815 | 815 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a8ac42c96d71..30d1bd832d90 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -829,7 +829,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 829 | * Discard zero-length packets and packets smaller than an ACK | 829 | * Discard zero-length packets and packets smaller than an ACK |
| 830 | */ | 830 | */ |
| 831 | if (rx_stats->rs_datalen < 10) { | 831 | if (rx_stats->rs_datalen < 10) { |
| 832 | RX_STAT_INC(rx_len_err); | 832 | RX_STAT_INC(sc, rx_len_err); |
| 833 | goto corrupt; | 833 | goto corrupt; |
| 834 | } | 834 | } |
| 835 | 835 | ||
| @@ -839,7 +839,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 839 | * those frames. | 839 | * those frames. |
| 840 | */ | 840 | */ |
| 841 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { | 841 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { |
| 842 | RX_STAT_INC(rx_len_err); | 842 | RX_STAT_INC(sc, rx_len_err); |
| 843 | goto corrupt; | 843 | goto corrupt; |
| 844 | } | 844 | } |
| 845 | 845 | ||
| @@ -880,7 +880,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 880 | } else if (sc->spec_priv.spectral_mode != SPECTRAL_DISABLED && | 880 | } else if (sc->spec_priv.spectral_mode != SPECTRAL_DISABLED && |
| 881 | ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, | 881 | ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, |
| 882 | rx_status->mactime)) { | 882 | rx_status->mactime)) { |
| 883 | RX_STAT_INC(rx_spectral); | 883 | RX_STAT_INC(sc, rx_spectral); |
| 884 | } | 884 | } |
| 885 | return -EINVAL; | 885 | return -EINVAL; |
| 886 | } | 886 | } |
| @@ -898,7 +898,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 898 | spin_unlock_bh(&sc->chan_lock); | 898 | spin_unlock_bh(&sc->chan_lock); |
| 899 | 899 | ||
| 900 | if (ath_is_mybeacon(common, hdr)) { | 900 | if (ath_is_mybeacon(common, hdr)) { |
| 901 | RX_STAT_INC(rx_beacons); | 901 | RX_STAT_INC(sc, rx_beacons); |
| 902 | rx_stats->is_mybeacon = true; | 902 | rx_stats->is_mybeacon = true; |
| 903 | } | 903 | } |
| 904 | 904 | ||
| @@ -915,7 +915,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
| 915 | */ | 915 | */ |
| 916 | ath_dbg(common, ANY, "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", | 916 | ath_dbg(common, ANY, "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", |
| 917 | rx_stats->rs_rate); | 917 | rx_stats->rs_rate); |
| 918 | RX_STAT_INC(rx_rate_err); | 918 | RX_STAT_INC(sc, rx_rate_err); |
| 919 | return -EINVAL; | 919 | return -EINVAL; |
| 920 | } | 920 | } |
| 921 | 921 | ||
| @@ -1136,7 +1136,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1136 | * skb and put it at the tail of the sc->rx.rxbuf list for | 1136 | * skb and put it at the tail of the sc->rx.rxbuf list for |
| 1137 | * processing. */ | 1137 | * processing. */ |
| 1138 | if (!requeue_skb) { | 1138 | if (!requeue_skb) { |
| 1139 | RX_STAT_INC(rx_oom_err); | 1139 | RX_STAT_INC(sc, rx_oom_err); |
| 1140 | goto requeue_drop_frag; | 1140 | goto requeue_drop_frag; |
| 1141 | } | 1141 | } |
| 1142 | 1142 | ||
| @@ -1164,7 +1164,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1164 | rxs, decrypt_error); | 1164 | rxs, decrypt_error); |
| 1165 | 1165 | ||
| 1166 | if (rs.rs_more) { | 1166 | if (rs.rs_more) { |
| 1167 | RX_STAT_INC(rx_frags); | 1167 | RX_STAT_INC(sc, rx_frags); |
| 1168 | /* | 1168 | /* |
| 1169 | * rs_more indicates chained descriptors which can be | 1169 | * rs_more indicates chained descriptors which can be |
| 1170 | * used to link buffers together for a sort of | 1170 | * used to link buffers together for a sort of |
| @@ -1174,7 +1174,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1174 | /* too many fragments - cannot handle frame */ | 1174 | /* too many fragments - cannot handle frame */ |
| 1175 | dev_kfree_skb_any(sc->rx.frag); | 1175 | dev_kfree_skb_any(sc->rx.frag); |
| 1176 | dev_kfree_skb_any(skb); | 1176 | dev_kfree_skb_any(skb); |
| 1177 | RX_STAT_INC(rx_too_many_frags_err); | 1177 | RX_STAT_INC(sc, rx_too_many_frags_err); |
| 1178 | skb = NULL; | 1178 | skb = NULL; |
| 1179 | } | 1179 | } |
| 1180 | sc->rx.frag = skb; | 1180 | sc->rx.frag = skb; |
| @@ -1186,7 +1186,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1186 | 1186 | ||
| 1187 | if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) { | 1187 | if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) { |
| 1188 | dev_kfree_skb(skb); | 1188 | dev_kfree_skb(skb); |
| 1189 | RX_STAT_INC(rx_oom_err); | 1189 | RX_STAT_INC(sc, rx_oom_err); |
| 1190 | goto requeue_drop_frag; | 1190 | goto requeue_drop_frag; |
| 1191 | } | 1191 | } |
| 1192 | 1192 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 43b6c8508e49..25b3fc82d4ac 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -391,7 +391,7 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, | |||
| 391 | struct ieee80211_hdr *hdr; | 391 | struct ieee80211_hdr *hdr; |
| 392 | int prev = fi->retries; | 392 | int prev = fi->retries; |
| 393 | 393 | ||
| 394 | TX_STAT_INC(txq->axq_qnum, a_retries); | 394 | TX_STAT_INC(sc, txq->axq_qnum, a_retries); |
| 395 | fi->retries += count; | 395 | fi->retries += count; |
| 396 | 396 | ||
| 397 | if (prev > 0) | 397 | if (prev > 0) |
| @@ -1105,7 +1105,7 @@ finish: | |||
| 1105 | al = get_frame_info(bf->bf_mpdu)->framelen; | 1105 | al = get_frame_info(bf->bf_mpdu)->framelen; |
| 1106 | bf->bf_state.bf_type = BUF_AMPDU; | 1106 | bf->bf_state.bf_type = BUF_AMPDU; |
| 1107 | } else { | 1107 | } else { |
| 1108 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 1108 | TX_STAT_INC(sc, txq->axq_qnum, a_aggr); |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | return al; | 1111 | return al; |
| @@ -1727,7 +1727,7 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
| 1727 | bf_tail = bf; | 1727 | bf_tail = bf; |
| 1728 | nframes--; | 1728 | nframes--; |
| 1729 | sent++; | 1729 | sent++; |
| 1730 | TX_STAT_INC(txq->axq_qnum, a_queued_hw); | 1730 | TX_STAT_INC(sc, txq->axq_qnum, a_queued_hw); |
| 1731 | 1731 | ||
| 1732 | if (an->sta && skb_queue_empty(&tid->retry_q)) | 1732 | if (an->sta && skb_queue_empty(&tid->retry_q)) |
| 1733 | ieee80211_sta_set_buffered(an->sta, i, false); | 1733 | ieee80211_sta_set_buffered(an->sta, i, false); |
| @@ -2110,14 +2110,14 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
| 2110 | } | 2110 | } |
| 2111 | 2111 | ||
| 2112 | if (puttxbuf) { | 2112 | if (puttxbuf) { |
| 2113 | TX_STAT_INC(txq->axq_qnum, puttxbuf); | 2113 | TX_STAT_INC(sc, txq->axq_qnum, puttxbuf); |
| 2114 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | 2114 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
| 2115 | ath_dbg(common, XMIT, "TXDP[%u] = %llx (%p)\n", | 2115 | ath_dbg(common, XMIT, "TXDP[%u] = %llx (%p)\n", |
| 2116 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | 2116 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); |
| 2117 | } | 2117 | } |
| 2118 | 2118 | ||
| 2119 | if (!edma || sc->tx99_state) { | 2119 | if (!edma || sc->tx99_state) { |
| 2120 | TX_STAT_INC(txq->axq_qnum, txstart); | 2120 | TX_STAT_INC(sc, txq->axq_qnum, txstart); |
| 2121 | ath9k_hw_txstart(ah, txq->axq_qnum); | 2121 | ath9k_hw_txstart(ah, txq->axq_qnum); |
| 2122 | } | 2122 | } |
| 2123 | 2123 | ||
| @@ -2154,7 +2154,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
| 2154 | bf->bf_lastbf = bf; | 2154 | bf->bf_lastbf = bf; |
| 2155 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); | 2155 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); |
| 2156 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); | 2156 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); |
| 2157 | TX_STAT_INC(txq->axq_qnum, queued); | 2157 | TX_STAT_INC(sc, txq->axq_qnum, queued); |
| 2158 | } | 2158 | } |
| 2159 | 2159 | ||
| 2160 | static void setup_frame_info(struct ieee80211_hw *hw, | 2160 | static void setup_frame_info(struct ieee80211_hw *hw, |
| @@ -2486,7 +2486,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 2486 | ath_txq_lock(sc, txctl.txq); | 2486 | ath_txq_lock(sc, txctl.txq); |
| 2487 | ath_tx_fill_desc(sc, bf, txctl.txq, 0); | 2487 | ath_tx_fill_desc(sc, bf, txctl.txq, 0); |
| 2488 | ath_tx_txqaddbuf(sc, txctl.txq, &bf_q, false); | 2488 | ath_tx_txqaddbuf(sc, txctl.txq, &bf_q, false); |
| 2489 | TX_STAT_INC(txctl.txq->axq_qnum, queued); | 2489 | TX_STAT_INC(sc, txctl.txq->axq_qnum, queued); |
| 2490 | ath_txq_unlock(sc, txctl.txq); | 2490 | ath_txq_unlock(sc, txctl.txq); |
| 2491 | } | 2491 | } |
| 2492 | 2492 | ||
| @@ -2699,7 +2699,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2699 | if (status == -EINPROGRESS) | 2699 | if (status == -EINPROGRESS) |
| 2700 | break; | 2700 | break; |
| 2701 | 2701 | ||
| 2702 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | 2702 | TX_STAT_INC(sc, txq->axq_qnum, txprocdesc); |
| 2703 | 2703 | ||
| 2704 | /* | 2704 | /* |
| 2705 | * Remove ath_buf's of the same transmit unit from txq, | 2705 | * Remove ath_buf's of the same transmit unit from txq, |
| @@ -2778,7 +2778,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2778 | 2778 | ||
| 2779 | ath_txq_lock(sc, txq); | 2779 | ath_txq_lock(sc, txq); |
| 2780 | 2780 | ||
| 2781 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | 2781 | TX_STAT_INC(sc, txq->axq_qnum, txprocdesc); |
| 2782 | 2782 | ||
| 2783 | fifo_list = &txq->txq_fifo[txq->txq_tailidx]; | 2783 | fifo_list = &txq->txq_fifo[txq->txq_tailidx]; |
| 2784 | if (list_empty(fifo_list)) { | 2784 | if (list_empty(fifo_list)) { |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 66ffae2de86e..aa50813a0595 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
| @@ -416,8 +416,8 @@ static int wil_debugfs_iomem_x32_get(void *data, u64 *val) | |||
| 416 | return 0; | 416 | return 0; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, | 419 | DEFINE_DEBUGFS_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get, |
| 420 | wil_debugfs_iomem_x32_set, "0x%08llx\n"); | 420 | wil_debugfs_iomem_x32_set, "0x%08llx\n"); |
| 421 | 421 | ||
| 422 | static struct dentry *wil_debugfs_create_iomem_x32(const char *name, | 422 | static struct dentry *wil_debugfs_create_iomem_x32(const char *name, |
| 423 | umode_t mode, | 423 | umode_t mode, |
| @@ -432,7 +432,8 @@ static struct dentry *wil_debugfs_create_iomem_x32(const char *name, | |||
| 432 | data->wil = wil; | 432 | data->wil = wil; |
| 433 | data->offset = value; | 433 | data->offset = value; |
| 434 | 434 | ||
| 435 | file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32); | 435 | file = debugfs_create_file_unsafe(name, mode, parent, data, |
| 436 | &fops_iomem_x32); | ||
| 436 | if (!IS_ERR_OR_NULL(file)) | 437 | if (!IS_ERR_OR_NULL(file)) |
| 437 | wil->dbg_data.iomem_data_count++; | 438 | wil->dbg_data.iomem_data_count++; |
| 438 | 439 | ||
| @@ -451,14 +452,15 @@ static int wil_debugfs_ulong_get(void *data, u64 *val) | |||
| 451 | return 0; | 452 | return 0; |
| 452 | } | 453 | } |
| 453 | 454 | ||
| 454 | DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get, | 455 | DEFINE_DEBUGFS_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get, |
| 455 | wil_debugfs_ulong_set, "0x%llx\n"); | 456 | wil_debugfs_ulong_set, "0x%llx\n"); |
| 456 | 457 | ||
| 457 | static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode, | 458 | static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode, |
| 458 | struct dentry *parent, | 459 | struct dentry *parent, |
| 459 | ulong *value) | 460 | ulong *value) |
| 460 | { | 461 | { |
| 461 | return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong); | 462 | return debugfs_create_file_unsafe(name, mode, parent, value, |
| 463 | &wil_fops_ulong); | ||
| 462 | } | 464 | } |
| 463 | 465 | ||
| 464 | /** | 466 | /** |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index 6255fb6d97a7..81ff558046a8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | |||
| @@ -502,6 +502,7 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | spin_lock_bh(&wl->lock); | 504 | spin_lock_bh(&wl->lock); |
| 505 | wl->wlc->vif = vif; | ||
| 505 | wl->mute_tx = false; | 506 | wl->mute_tx = false; |
| 506 | brcms_c_mute(wl->wlc, false); | 507 | brcms_c_mute(wl->wlc, false); |
| 507 | if (vif->type == NL80211_IFTYPE_STATION) | 508 | if (vif->type == NL80211_IFTYPE_STATION) |
| @@ -519,6 +520,11 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 519 | static void | 520 | static void |
| 520 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 521 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
| 521 | { | 522 | { |
| 523 | struct brcms_info *wl = hw->priv; | ||
| 524 | |||
| 525 | spin_lock_bh(&wl->lock); | ||
| 526 | wl->wlc->vif = NULL; | ||
| 527 | spin_unlock_bh(&wl->lock); | ||
| 522 | } | 528 | } |
| 523 | 529 | ||
| 524 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | 530 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) |
| @@ -937,6 +943,25 @@ static void brcms_ops_set_tsf(struct ieee80211_hw *hw, | |||
| 937 | spin_unlock_bh(&wl->lock); | 943 | spin_unlock_bh(&wl->lock); |
| 938 | } | 944 | } |
| 939 | 945 | ||
| 946 | static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw, | ||
| 947 | struct ieee80211_sta *sta, bool set) | ||
| 948 | { | ||
| 949 | struct brcms_info *wl = hw->priv; | ||
| 950 | struct sk_buff *beacon = NULL; | ||
| 951 | u16 tim_offset = 0; | ||
| 952 | |||
| 953 | spin_lock_bh(&wl->lock); | ||
| 954 | if (wl->wlc->vif) | ||
| 955 | beacon = ieee80211_beacon_get_tim(hw, wl->wlc->vif, | ||
| 956 | &tim_offset, NULL); | ||
| 957 | if (beacon) | ||
| 958 | brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset, | ||
| 959 | wl->wlc->vif->bss_conf.dtim_period); | ||
| 960 | spin_unlock_bh(&wl->lock); | ||
| 961 | |||
| 962 | return 0; | ||
| 963 | } | ||
| 964 | |||
| 940 | static const struct ieee80211_ops brcms_ops = { | 965 | static const struct ieee80211_ops brcms_ops = { |
| 941 | .tx = brcms_ops_tx, | 966 | .tx = brcms_ops_tx, |
| 942 | .start = brcms_ops_start, | 967 | .start = brcms_ops_start, |
| @@ -955,6 +980,7 @@ static const struct ieee80211_ops brcms_ops = { | |||
| 955 | .flush = brcms_ops_flush, | 980 | .flush = brcms_ops_flush, |
| 956 | .get_tsf = brcms_ops_get_tsf, | 981 | .get_tsf = brcms_ops_get_tsf, |
| 957 | .set_tsf = brcms_ops_set_tsf, | 982 | .set_tsf = brcms_ops_set_tsf, |
| 983 | .set_tim = brcms_ops_beacon_set_tim, | ||
| 958 | }; | 984 | }; |
| 959 | 985 | ||
| 960 | void brcms_dpc(unsigned long data) | 986 | void brcms_dpc(unsigned long data) |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h index c4d135cff04a..9f76b880814e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.h | |||
| @@ -563,6 +563,7 @@ struct brcms_c_info { | |||
| 563 | 563 | ||
| 564 | struct wiphy *wiphy; | 564 | struct wiphy *wiphy; |
| 565 | struct scb pri_scb; | 565 | struct scb pri_scb; |
| 566 | struct ieee80211_vif *vif; | ||
| 566 | 567 | ||
| 567 | struct sk_buff *beacon; | 568 | struct sk_buff *beacon; |
| 568 | u16 beacon_tim_offset; | 569 | u16 beacon_tim_offset; |
diff --git a/drivers/net/wireless/intel/iwlegacy/4965.c b/drivers/net/wireless/intel/iwlegacy/4965.c index c3c638ed0ed7..ce4144a89217 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965.c +++ b/drivers/net/wireless/intel/iwlegacy/4965.c | |||
| @@ -1297,6 +1297,8 @@ il4965_send_rxon_assoc(struct il_priv *il) | |||
| 1297 | const struct il_rxon_cmd *rxon1 = &il->staging; | 1297 | const struct il_rxon_cmd *rxon1 = &il->staging; |
| 1298 | const struct il_rxon_cmd *rxon2 = &il->active; | 1298 | const struct il_rxon_cmd *rxon2 = &il->active; |
| 1299 | 1299 | ||
| 1300 | lockdep_assert_held(&il->mutex); | ||
| 1301 | |||
| 1300 | if (rxon1->flags == rxon2->flags && | 1302 | if (rxon1->flags == rxon2->flags && |
| 1301 | rxon1->filter_flags == rxon2->filter_flags && | 1303 | rxon1->filter_flags == rxon2->filter_flags && |
| 1302 | rxon1->cck_basic_rates == rxon2->cck_basic_rates && | 1304 | rxon1->cck_basic_rates == rxon2->cck_basic_rates && |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index f44c716b1130..c16757051f16 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c | |||
| @@ -1154,14 +1154,14 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id) | |||
| 1154 | } | 1154 | } |
| 1155 | IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf); | 1155 | IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf); |
| 1156 | 1156 | ||
| 1157 | void iwl_fw_error_dump_wk(struct work_struct *work) | 1157 | /* this function assumes dump_start was called beforehand and dump_end will be |
| 1158 | * called afterwards | ||
| 1159 | */ | ||
| 1160 | void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt) | ||
| 1158 | { | 1161 | { |
| 1159 | struct iwl_fw_runtime *fwrt = | ||
| 1160 | container_of(work, struct iwl_fw_runtime, dump.wk.work); | ||
| 1161 | struct iwl_fw_dbg_params params = {0}; | 1162 | struct iwl_fw_dbg_params params = {0}; |
| 1162 | 1163 | ||
| 1163 | if (fwrt->ops && fwrt->ops->dump_start && | 1164 | if (!test_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status)) |
| 1164 | fwrt->ops->dump_start(fwrt->ops_ctx)) | ||
| 1165 | return; | 1165 | return; |
| 1166 | 1166 | ||
| 1167 | if (fwrt->ops && fwrt->ops->fw_running && | 1167 | if (fwrt->ops && fwrt->ops->fw_running && |
| @@ -1169,7 +1169,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work) | |||
| 1169 | IWL_ERR(fwrt, "Firmware not running - cannot dump error\n"); | 1169 | IWL_ERR(fwrt, "Firmware not running - cannot dump error\n"); |
| 1170 | iwl_fw_free_dump_desc(fwrt); | 1170 | iwl_fw_free_dump_desc(fwrt); |
| 1171 | clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status); | 1171 | clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status); |
| 1172 | goto out; | 1172 | return; |
| 1173 | } | 1173 | } |
| 1174 | 1174 | ||
| 1175 | iwl_fw_dbg_stop_recording(fwrt, ¶ms); | 1175 | iwl_fw_dbg_stop_recording(fwrt, ¶ms); |
| @@ -1183,7 +1183,20 @@ void iwl_fw_error_dump_wk(struct work_struct *work) | |||
| 1183 | udelay(500); | 1183 | udelay(500); |
| 1184 | iwl_fw_dbg_restart_recording(fwrt, ¶ms); | 1184 | iwl_fw_dbg_restart_recording(fwrt, ¶ms); |
| 1185 | } | 1185 | } |
| 1186 | out: | 1186 | } |
| 1187 | IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_sync); | ||
| 1188 | |||
| 1189 | void iwl_fw_error_dump_wk(struct work_struct *work) | ||
| 1190 | { | ||
| 1191 | struct iwl_fw_runtime *fwrt = | ||
| 1192 | container_of(work, struct iwl_fw_runtime, dump.wk.work); | ||
| 1193 | |||
| 1194 | if (fwrt->ops && fwrt->ops->dump_start && | ||
| 1195 | fwrt->ops->dump_start(fwrt->ops_ctx)) | ||
| 1196 | return; | ||
| 1197 | |||
| 1198 | iwl_fw_dbg_collect_sync(fwrt); | ||
| 1199 | |||
| 1187 | if (fwrt->ops && fwrt->ops->dump_end) | 1200 | if (fwrt->ops && fwrt->ops->dump_end) |
| 1188 | fwrt->ops->dump_end(fwrt->ops_ctx); | 1201 | fwrt->ops->dump_end(fwrt->ops_ctx); |
| 1189 | } | 1202 | } |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index d9578dcec24c..6f8d3256f7b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h | |||
| @@ -367,4 +367,5 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} | |||
| 367 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 367 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
| 368 | 368 | ||
| 369 | void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt); | 369 | void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt); |
| 370 | void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt); | ||
| 370 | #endif /* __iwl_fw_dbg_h__ */ | 371 | #endif /* __iwl_fw_dbg_h__ */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h index 2cc6c019d0e1..420e6d745f77 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h | |||
| @@ -30,38 +30,20 @@ | |||
| 30 | #undef TRACE_SYSTEM | 30 | #undef TRACE_SYSTEM |
| 31 | #define TRACE_SYSTEM iwlwifi_data | 31 | #define TRACE_SYSTEM iwlwifi_data |
| 32 | 32 | ||
| 33 | TRACE_EVENT(iwlwifi_dev_tx_data, | 33 | TRACE_EVENT(iwlwifi_dev_tx_tb, |
| 34 | TP_PROTO(const struct device *dev, | 34 | TP_PROTO(const struct device *dev, struct sk_buff *skb, |
| 35 | struct sk_buff *skb, u8 hdr_len), | 35 | u8 *data_src, size_t data_len), |
| 36 | TP_ARGS(dev, skb, hdr_len), | 36 | TP_ARGS(dev, skb, data_src, data_len), |
| 37 | TP_STRUCT__entry( | 37 | TP_STRUCT__entry( |
| 38 | DEV_ENTRY | 38 | DEV_ENTRY |
| 39 | 39 | ||
| 40 | __dynamic_array(u8, data, | 40 | __dynamic_array(u8, data, |
| 41 | iwl_trace_data(skb) ? skb->len - hdr_len : 0) | 41 | iwl_trace_data(skb) ? data_len : 0) |
| 42 | ), | 42 | ), |
| 43 | TP_fast_assign( | 43 | TP_fast_assign( |
| 44 | DEV_ASSIGN; | 44 | DEV_ASSIGN; |
| 45 | if (iwl_trace_data(skb)) | 45 | if (iwl_trace_data(skb)) |
| 46 | skb_copy_bits(skb, hdr_len, | 46 | memcpy(__get_dynamic_array(data), data_src, data_len); |
| 47 | __get_dynamic_array(data), | ||
| 48 | skb->len - hdr_len); | ||
| 49 | ), | ||
| 50 | TP_printk("[%s] TX frame data", __get_str(dev)) | ||
| 51 | ); | ||
| 52 | |||
| 53 | TRACE_EVENT(iwlwifi_dev_tx_tso_chunk, | ||
| 54 | TP_PROTO(const struct device *dev, | ||
| 55 | u8 *data_src, size_t data_len), | ||
| 56 | TP_ARGS(dev, data_src, data_len), | ||
| 57 | TP_STRUCT__entry( | ||
| 58 | DEV_ENTRY | ||
| 59 | |||
| 60 | __dynamic_array(u8, data, data_len) | ||
| 61 | ), | ||
| 62 | TP_fast_assign( | ||
| 63 | DEV_ASSIGN; | ||
| 64 | memcpy(__get_dynamic_array(data), data_src, data_len); | ||
| 65 | ), | 47 | ), |
| 66 | TP_printk("[%s] TX frame data", __get_str(dev)) | 48 | TP_printk("[%s] TX frame data", __get_str(dev)) |
| 67 | ); | 49 | ); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 210be26aadaa..843f3b41b72e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c | |||
| @@ -722,8 +722,10 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, | |||
| 722 | { | 722 | { |
| 723 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; | 723 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; |
| 724 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; | 724 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; |
| 725 | bool unified = fw_has_capa(&mvm->fw->ucode_capa, | ||
| 726 | IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); | ||
| 725 | struct wowlan_key_data key_data = { | 727 | struct wowlan_key_data key_data = { |
| 726 | .configure_keys = !d0i3, | 728 | .configure_keys = !d0i3 && !unified, |
| 727 | .use_rsc_tsc = false, | 729 | .use_rsc_tsc = false, |
| 728 | .tkip = &tkip_cmd, | 730 | .tkip = &tkip_cmd, |
| 729 | .use_tkip = false, | 731 | .use_tkip = false, |
| @@ -1636,32 +1638,10 @@ out_free_resp: | |||
| 1636 | } | 1638 | } |
| 1637 | 1639 | ||
| 1638 | static struct iwl_wowlan_status * | 1640 | static struct iwl_wowlan_status * |
| 1639 | iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 1641 | iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm) |
| 1640 | { | 1642 | { |
| 1641 | u32 base = mvm->error_event_table[0]; | ||
| 1642 | struct error_table_start { | ||
| 1643 | /* cf. struct iwl_error_event_table */ | ||
| 1644 | u32 valid; | ||
| 1645 | u32 error_id; | ||
| 1646 | } err_info; | ||
| 1647 | int ret; | 1643 | int ret; |
| 1648 | 1644 | ||
| 1649 | iwl_trans_read_mem_bytes(mvm->trans, base, | ||
| 1650 | &err_info, sizeof(err_info)); | ||
| 1651 | |||
| 1652 | if (err_info.valid) { | ||
| 1653 | IWL_INFO(mvm, "error table is valid (%d) with error (%d)\n", | ||
| 1654 | err_info.valid, err_info.error_id); | ||
| 1655 | if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { | ||
| 1656 | struct cfg80211_wowlan_wakeup wakeup = { | ||
| 1657 | .rfkill_release = true, | ||
| 1658 | }; | ||
| 1659 | ieee80211_report_wowlan_wakeup(vif, &wakeup, | ||
| 1660 | GFP_KERNEL); | ||
| 1661 | } | ||
| 1662 | return ERR_PTR(-EIO); | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | /* only for tracing for now */ | 1645 | /* only for tracing for now */ |
| 1666 | ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, 0, NULL); | 1646 | ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, 0, NULL); |
| 1667 | if (ret) | 1647 | if (ret) |
| @@ -1680,7 +1660,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, | |||
| 1680 | bool keep; | 1660 | bool keep; |
| 1681 | struct iwl_mvm_sta *mvm_ap_sta; | 1661 | struct iwl_mvm_sta *mvm_ap_sta; |
| 1682 | 1662 | ||
| 1683 | fw_status = iwl_mvm_get_wakeup_status(mvm, vif); | 1663 | fw_status = iwl_mvm_get_wakeup_status(mvm); |
| 1684 | if (IS_ERR_OR_NULL(fw_status)) | 1664 | if (IS_ERR_OR_NULL(fw_status)) |
| 1685 | goto out_unlock; | 1665 | goto out_unlock; |
| 1686 | 1666 | ||
| @@ -1805,7 +1785,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, | |||
| 1805 | u32 reasons = 0; | 1785 | u32 reasons = 0; |
| 1806 | int i, j, n_matches, ret; | 1786 | int i, j, n_matches, ret; |
| 1807 | 1787 | ||
| 1808 | fw_status = iwl_mvm_get_wakeup_status(mvm, vif); | 1788 | fw_status = iwl_mvm_get_wakeup_status(mvm); |
| 1809 | if (!IS_ERR_OR_NULL(fw_status)) { | 1789 | if (!IS_ERR_OR_NULL(fw_status)) { |
| 1810 | reasons = le32_to_cpu(fw_status->wakeup_reasons); | 1790 | reasons = le32_to_cpu(fw_status->wakeup_reasons); |
| 1811 | kfree(fw_status); | 1791 | kfree(fw_status); |
| @@ -1918,6 +1898,29 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac, | |||
| 1918 | ieee80211_resume_disconnect(vif); | 1898 | ieee80211_resume_disconnect(vif); |
| 1919 | } | 1899 | } |
| 1920 | 1900 | ||
| 1901 | static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm, | ||
| 1902 | struct ieee80211_vif *vif) | ||
| 1903 | { | ||
| 1904 | u32 base = mvm->error_event_table[0]; | ||
| 1905 | struct error_table_start { | ||
| 1906 | /* cf. struct iwl_error_event_table */ | ||
| 1907 | u32 valid; | ||
| 1908 | u32 error_id; | ||
| 1909 | } err_info; | ||
| 1910 | |||
| 1911 | iwl_trans_read_mem_bytes(mvm->trans, base, | ||
| 1912 | &err_info, sizeof(err_info)); | ||
| 1913 | |||
| 1914 | if (err_info.valid && | ||
| 1915 | err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { | ||
| 1916 | struct cfg80211_wowlan_wakeup wakeup = { | ||
| 1917 | .rfkill_release = true, | ||
| 1918 | }; | ||
| 1919 | ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL); | ||
| 1920 | } | ||
| 1921 | return err_info.valid; | ||
| 1922 | } | ||
| 1923 | |||
| 1921 | static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) | 1924 | static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) |
| 1922 | { | 1925 | { |
| 1923 | struct ieee80211_vif *vif = NULL; | 1926 | struct ieee80211_vif *vif = NULL; |
| @@ -1949,6 +1952,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) | |||
| 1949 | /* query SRAM first in case we want event logging */ | 1952 | /* query SRAM first in case we want event logging */ |
| 1950 | iwl_mvm_read_d3_sram(mvm); | 1953 | iwl_mvm_read_d3_sram(mvm); |
| 1951 | 1954 | ||
| 1955 | if (iwl_mvm_check_rt_status(mvm, vif)) { | ||
| 1956 | set_bit(STATUS_FW_ERROR, &mvm->trans->status); | ||
| 1957 | iwl_mvm_dump_nic_error_log(mvm); | ||
| 1958 | iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, | ||
| 1959 | NULL, 0); | ||
| 1960 | ret = 1; | ||
| 1961 | goto err; | ||
| 1962 | } | ||
| 1963 | |||
| 1952 | if (d0i3_first) { | 1964 | if (d0i3_first) { |
| 1953 | ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL); | 1965 | ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL); |
| 1954 | if (ret < 0) { | 1966 | if (ret < 0) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index c5df73231ba3..dade206d5511 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
| @@ -364,7 +364,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, | |||
| 364 | */ | 364 | */ |
| 365 | 365 | ||
| 366 | memset(&mvm->queue_info, 0, sizeof(mvm->queue_info)); | 366 | memset(&mvm->queue_info, 0, sizeof(mvm->queue_info)); |
| 367 | mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].hw_queue_refcount = 1; | 367 | /* |
| 368 | * Set a 'fake' TID for the command queue, since we use the | ||
| 369 | * hweight() of the tid_bitmap as a refcount now. Not that | ||
| 370 | * we ever even consider the command queue as one we might | ||
| 371 | * want to reuse, but be safe nevertheless. | ||
| 372 | */ | ||
| 373 | mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].tid_bitmap = | ||
| 374 | BIT(IWL_MAX_TID_COUNT + 2); | ||
| 368 | 375 | ||
| 369 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) | 376 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) |
| 370 | atomic_set(&mvm->mac80211_queue_stop_count[i], 0); | 377 | atomic_set(&mvm->mac80211_queue_stop_count[i], 0); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 8f71eeed50d9..7ba5bc2ed1c4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
| @@ -512,6 +512,7 @@ enum iwl_mvm_scan_type { | |||
| 512 | IWL_SCAN_TYPE_WILD, | 512 | IWL_SCAN_TYPE_WILD, |
| 513 | IWL_SCAN_TYPE_MILD, | 513 | IWL_SCAN_TYPE_MILD, |
| 514 | IWL_SCAN_TYPE_FRAGMENTED, | 514 | IWL_SCAN_TYPE_FRAGMENTED, |
| 515 | IWL_SCAN_TYPE_FAST_BALANCE, | ||
| 515 | }; | 516 | }; |
| 516 | 517 | ||
| 517 | enum iwl_mvm_sched_scan_pass_all_states { | 518 | enum iwl_mvm_sched_scan_pass_all_states { |
| @@ -753,24 +754,12 @@ iwl_mvm_baid_data_from_reorder_buf(struct iwl_mvm_reorder_buffer *buf) | |||
| 753 | * This is a state in which a single queue serves more than one TID, all of | 754 | * This is a state in which a single queue serves more than one TID, all of |
| 754 | * which are not aggregated. Note that the queue is only associated to one | 755 | * which are not aggregated. Note that the queue is only associated to one |
| 755 | * RA. | 756 | * RA. |
| 756 | * @IWL_MVM_QUEUE_INACTIVE: queue is allocated but no traffic on it | ||
| 757 | * This is a state of a queue that has had traffic on it, but during the | ||
| 758 | * last %IWL_MVM_DQA_QUEUE_TIMEOUT time period there has been no traffic on | ||
| 759 | * it. In this state, when a new queue is needed to be allocated but no | ||
| 760 | * such free queue exists, an inactive queue might be freed and given to | ||
| 761 | * the new RA/TID. | ||
| 762 | * @IWL_MVM_QUEUE_RECONFIGURING: queue is being reconfigured | ||
| 763 | * This is the state of a queue that has had traffic pass through it, but | ||
| 764 | * needs to be reconfigured for some reason, e.g. the queue needs to | ||
| 765 | * become unshared and aggregations re-enabled on. | ||
| 766 | */ | 757 | */ |
| 767 | enum iwl_mvm_queue_status { | 758 | enum iwl_mvm_queue_status { |
| 768 | IWL_MVM_QUEUE_FREE, | 759 | IWL_MVM_QUEUE_FREE, |
| 769 | IWL_MVM_QUEUE_RESERVED, | 760 | IWL_MVM_QUEUE_RESERVED, |
| 770 | IWL_MVM_QUEUE_READY, | 761 | IWL_MVM_QUEUE_READY, |
| 771 | IWL_MVM_QUEUE_SHARED, | 762 | IWL_MVM_QUEUE_SHARED, |
| 772 | IWL_MVM_QUEUE_INACTIVE, | ||
| 773 | IWL_MVM_QUEUE_RECONFIGURING, | ||
| 774 | }; | 763 | }; |
| 775 | 764 | ||
| 776 | #define IWL_MVM_DQA_QUEUE_TIMEOUT (5 * HZ) | 765 | #define IWL_MVM_DQA_QUEUE_TIMEOUT (5 * HZ) |
| @@ -787,6 +776,17 @@ struct iwl_mvm_geo_profile { | |||
| 787 | u8 values[ACPI_GEO_TABLE_SIZE]; | 776 | u8 values[ACPI_GEO_TABLE_SIZE]; |
| 788 | }; | 777 | }; |
| 789 | 778 | ||
| 779 | struct iwl_mvm_dqa_txq_info { | ||
| 780 | u8 ra_sta_id; /* The RA this queue is mapped to, if exists */ | ||
| 781 | bool reserved; /* Is this the TXQ reserved for a STA */ | ||
| 782 | u8 mac80211_ac; /* The mac80211 AC this queue is mapped to */ | ||
| 783 | u8 txq_tid; /* The TID "owner" of this queue*/ | ||
| 784 | u16 tid_bitmap; /* Bitmap of the TIDs mapped to this queue */ | ||
| 785 | /* Timestamp for inactivation per TID of this queue */ | ||
| 786 | unsigned long last_frame_time[IWL_MAX_TID_COUNT + 1]; | ||
| 787 | enum iwl_mvm_queue_status status; | ||
| 788 | }; | ||
| 789 | |||
| 790 | struct iwl_mvm { | 790 | struct iwl_mvm { |
| 791 | /* for logger access */ | 791 | /* for logger access */ |
| 792 | struct device *dev; | 792 | struct device *dev; |
| @@ -843,17 +843,7 @@ struct iwl_mvm { | |||
| 843 | 843 | ||
| 844 | u16 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES]; | 844 | u16 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES]; |
| 845 | 845 | ||
| 846 | struct { | 846 | struct iwl_mvm_dqa_txq_info queue_info[IWL_MAX_HW_QUEUES]; |
| 847 | u8 hw_queue_refcount; | ||
| 848 | u8 ra_sta_id; /* The RA this queue is mapped to, if exists */ | ||
| 849 | bool reserved; /* Is this the TXQ reserved for a STA */ | ||
| 850 | u8 mac80211_ac; /* The mac80211 AC this queue is mapped to */ | ||
| 851 | u8 txq_tid; /* The TID "owner" of this queue*/ | ||
| 852 | u16 tid_bitmap; /* Bitmap of the TIDs mapped to this queue */ | ||
| 853 | /* Timestamp for inactivation per TID of this queue */ | ||
| 854 | unsigned long last_frame_time[IWL_MAX_TID_COUNT + 1]; | ||
| 855 | enum iwl_mvm_queue_status status; | ||
| 856 | } queue_info[IWL_MAX_HW_QUEUES]; | ||
| 857 | spinlock_t queue_info_lock; /* For syncing queue mgmt operations */ | 847 | spinlock_t queue_info_lock; /* For syncing queue mgmt operations */ |
| 858 | struct work_struct add_stream_wk; /* To add streams to queues */ | 848 | struct work_struct add_stream_wk; /* To add streams to queues */ |
| 859 | 849 | ||
| @@ -1883,17 +1873,6 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, | |||
| 1883 | mvmvif->low_latency &= ~cause; | 1873 | mvmvif->low_latency &= ~cause; |
| 1884 | } | 1874 | } |
| 1885 | 1875 | ||
| 1886 | /* hw scheduler queue config */ | ||
| 1887 | bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, | ||
| 1888 | u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg, | ||
| 1889 | unsigned int wdg_timeout); | ||
| 1890 | int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, | ||
| 1891 | u8 sta_id, u8 tid, unsigned int timeout); | ||
| 1892 | |||
| 1893 | int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, | ||
| 1894 | u8 tid, u8 flags); | ||
| 1895 | int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq); | ||
| 1896 | |||
| 1897 | /* Return a bitmask with all the hw supported queues, except for the | 1876 | /* Return a bitmask with all the hw supported queues, except for the |
| 1898 | * command queue, which can't be flushed. | 1877 | * command queue, which can't be flushed. |
| 1899 | */ | 1878 | */ |
| @@ -1905,6 +1884,11 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) | |||
| 1905 | 1884 | ||
| 1906 | static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) | 1885 | static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) |
| 1907 | { | 1886 | { |
| 1887 | lockdep_assert_held(&mvm->mutex); | ||
| 1888 | /* calling this function without using dump_start/end since at this | ||
| 1889 | * point we already hold the op mode mutex | ||
| 1890 | */ | ||
| 1891 | iwl_fw_dbg_collect_sync(&mvm->fwrt); | ||
| 1908 | iwl_fw_cancel_timestamp(&mvm->fwrt); | 1892 | iwl_fw_cancel_timestamp(&mvm->fwrt); |
| 1909 | iwl_free_fw_paging(&mvm->fwrt); | 1893 | iwl_free_fw_paging(&mvm->fwrt); |
| 1910 | clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); | 1894 | clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); |
| @@ -1990,8 +1974,6 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t); | |||
| 1990 | struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); | 1974 | struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); |
| 1991 | bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); | 1975 | bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); |
| 1992 | 1976 | ||
| 1993 | void iwl_mvm_inactivity_check(struct iwl_mvm *mvm); | ||
| 1994 | |||
| 1995 | #define MVM_TCM_PERIOD_MSEC 500 | 1977 | #define MVM_TCM_PERIOD_MSEC 500 |
| 1996 | #define MVM_TCM_PERIOD (HZ * MVM_TCM_PERIOD_MSEC / 1000) | 1978 | #define MVM_TCM_PERIOD (HZ * MVM_TCM_PERIOD_MSEC / 1000) |
| 1997 | #define MVM_LL_PERIOD (10 * HZ) | 1979 | #define MVM_LL_PERIOD (10 * HZ) |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 2c75f51a04e4..089972280daa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c | |||
| @@ -1239,7 +1239,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 1239 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 1239 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
| 1240 | return; | 1240 | return; |
| 1241 | 1241 | ||
| 1242 | rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate); | 1242 | if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, |
| 1243 | &tx_resp_rate)) { | ||
| 1244 | WARN_ON_ONCE(1); | ||
| 1245 | return; | ||
| 1246 | } | ||
| 1243 | 1247 | ||
| 1244 | #ifdef CONFIG_MAC80211_DEBUGFS | 1248 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 1245 | /* Disable last tx check if we are debugging with fixed rate but | 1249 | /* Disable last tx check if we are debugging with fixed rate but |
| @@ -1290,7 +1294,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 1290 | */ | 1294 | */ |
| 1291 | table = &lq_sta->lq; | 1295 | table = &lq_sta->lq; |
| 1292 | lq_hwrate = le32_to_cpu(table->rs_table[0]); | 1296 | lq_hwrate = le32_to_cpu(table->rs_table[0]); |
| 1293 | rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); | 1297 | if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) { |
| 1298 | WARN_ON_ONCE(1); | ||
| 1299 | return; | ||
| 1300 | } | ||
| 1294 | 1301 | ||
| 1295 | /* Here we actually compare this rate to the latest LQ command */ | 1302 | /* Here we actually compare this rate to the latest LQ command */ |
| 1296 | if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { | 1303 | if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { |
| @@ -1392,8 +1399,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 1392 | /* Collect data for each rate used during failed TX attempts */ | 1399 | /* Collect data for each rate used during failed TX attempts */ |
| 1393 | for (i = 0; i <= retries; ++i) { | 1400 | for (i = 0; i <= retries; ++i) { |
| 1394 | lq_hwrate = le32_to_cpu(table->rs_table[i]); | 1401 | lq_hwrate = le32_to_cpu(table->rs_table[i]); |
| 1395 | rs_rate_from_ucode_rate(lq_hwrate, info->band, | 1402 | if (rs_rate_from_ucode_rate(lq_hwrate, info->band, |
| 1396 | &lq_rate); | 1403 | &lq_rate)) { |
| 1404 | WARN_ON_ONCE(1); | ||
| 1405 | return; | ||
| 1406 | } | ||
| 1407 | |||
| 1397 | /* | 1408 | /* |
| 1398 | * Only collect stats if retried rate is in the same RS | 1409 | * Only collect stats if retried rate is in the same RS |
| 1399 | * table as active/search. | 1410 | * table as active/search. |
| @@ -3260,7 +3271,10 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, | |||
| 3260 | for (i = 0; i < num_rates; i++) | 3271 | for (i = 0; i < num_rates; i++) |
| 3261 | lq_cmd->rs_table[i] = ucode_rate_le32; | 3272 | lq_cmd->rs_table[i] = ucode_rate_le32; |
| 3262 | 3273 | ||
| 3263 | rs_rate_from_ucode_rate(ucode_rate, band, &rate); | 3274 | if (rs_rate_from_ucode_rate(ucode_rate, band, &rate)) { |
| 3275 | WARN_ON_ONCE(1); | ||
| 3276 | return; | ||
| 3277 | } | ||
| 3264 | 3278 | ||
| 3265 | if (is_mimo(&rate)) | 3279 | if (is_mimo(&rate)) |
| 3266 | lq_cmd->mimo_delim = num_rates - 1; | 3280 | lq_cmd->mimo_delim = num_rates - 1; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index ffcd0ca86041..cfb784fea77b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c | |||
| @@ -110,6 +110,10 @@ static struct iwl_mvm_scan_timing_params scan_timing[] = { | |||
| 110 | .suspend_time = 95, | 110 | .suspend_time = 95, |
| 111 | .max_out_time = 44, | 111 | .max_out_time = 44, |
| 112 | }, | 112 | }, |
| 113 | [IWL_SCAN_TYPE_FAST_BALANCE] = { | ||
| 114 | .suspend_time = 30, | ||
| 115 | .max_out_time = 37, | ||
| 116 | }, | ||
| 113 | }; | 117 | }; |
| 114 | 118 | ||
| 115 | struct iwl_mvm_scan_params { | 119 | struct iwl_mvm_scan_params { |
| @@ -235,8 +239,32 @@ iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum nl80211_band band) | |||
| 235 | return mvm->tcm.result.band_load[band]; | 239 | return mvm->tcm.result.band_load[band]; |
| 236 | } | 240 | } |
| 237 | 241 | ||
| 242 | struct iwl_is_dcm_with_go_iterator_data { | ||
| 243 | struct ieee80211_vif *current_vif; | ||
| 244 | bool is_dcm_with_p2p_go; | ||
| 245 | }; | ||
| 246 | |||
| 247 | static void iwl_mvm_is_dcm_with_go_iterator(void *_data, u8 *mac, | ||
| 248 | struct ieee80211_vif *vif) | ||
| 249 | { | ||
| 250 | struct iwl_is_dcm_with_go_iterator_data *data = _data; | ||
| 251 | struct iwl_mvm_vif *other_mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 252 | struct iwl_mvm_vif *curr_mvmvif = | ||
| 253 | iwl_mvm_vif_from_mac80211(data->current_vif); | ||
| 254 | |||
| 255 | /* exclude the given vif */ | ||
| 256 | if (vif == data->current_vif) | ||
| 257 | return; | ||
| 258 | |||
| 259 | if (vif->type == NL80211_IFTYPE_AP && vif->p2p && | ||
| 260 | other_mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt && | ||
| 261 | other_mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id) | ||
| 262 | data->is_dcm_with_p2p_go = true; | ||
| 263 | } | ||
| 264 | |||
| 238 | static enum | 265 | static enum |
| 239 | iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device, | 266 | iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, |
| 267 | struct ieee80211_vif *vif, | ||
| 240 | enum iwl_mvm_traffic_load load, | 268 | enum iwl_mvm_traffic_load load, |
| 241 | bool low_latency) | 269 | bool low_latency) |
| 242 | { | 270 | { |
| @@ -249,9 +277,30 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device, | |||
| 249 | if (!global_cnt) | 277 | if (!global_cnt) |
| 250 | return IWL_SCAN_TYPE_UNASSOC; | 278 | return IWL_SCAN_TYPE_UNASSOC; |
| 251 | 279 | ||
| 252 | if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) && !p2p_device && | 280 | if (fw_has_api(&mvm->fw->ucode_capa, |
| 253 | fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) | 281 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) { |
| 254 | return IWL_SCAN_TYPE_FRAGMENTED; | 282 | if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) && |
| 283 | (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE)) | ||
| 284 | return IWL_SCAN_TYPE_FRAGMENTED; | ||
| 285 | |||
| 286 | /* in case of DCM with GO where BSS DTIM interval < 220msec | ||
| 287 | * set all scan requests as fast-balance scan | ||
| 288 | * */ | ||
| 289 | if (vif && vif->type == NL80211_IFTYPE_STATION && | ||
| 290 | vif->bss_conf.dtim_period < 220) { | ||
| 291 | struct iwl_is_dcm_with_go_iterator_data data = { | ||
| 292 | .current_vif = vif, | ||
| 293 | .is_dcm_with_p2p_go = false, | ||
| 294 | }; | ||
| 295 | |||
| 296 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
| 297 | IEEE80211_IFACE_ITER_NORMAL, | ||
| 298 | iwl_mvm_is_dcm_with_go_iterator, | ||
| 299 | &data); | ||
| 300 | if (data.is_dcm_with_p2p_go) | ||
| 301 | return IWL_SCAN_TYPE_FAST_BALANCE; | ||
| 302 | } | ||
| 303 | } | ||
| 255 | 304 | ||
| 256 | if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency) | 305 | if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency) |
| 257 | return IWL_SCAN_TYPE_MILD; | 306 | return IWL_SCAN_TYPE_MILD; |
| @@ -260,7 +309,8 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device, | |||
| 260 | } | 309 | } |
| 261 | 310 | ||
| 262 | static enum | 311 | static enum |
| 263 | iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device) | 312 | iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, |
| 313 | struct ieee80211_vif *vif) | ||
| 264 | { | 314 | { |
| 265 | enum iwl_mvm_traffic_load load; | 315 | enum iwl_mvm_traffic_load load; |
| 266 | bool low_latency; | 316 | bool low_latency; |
| @@ -268,12 +318,12 @@ iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device) | |||
| 268 | load = iwl_mvm_get_traffic_load(mvm); | 318 | load = iwl_mvm_get_traffic_load(mvm); |
| 269 | low_latency = iwl_mvm_low_latency(mvm); | 319 | low_latency = iwl_mvm_low_latency(mvm); |
| 270 | 320 | ||
| 271 | return _iwl_mvm_get_scan_type(mvm, p2p_device, load, low_latency); | 321 | return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency); |
| 272 | } | 322 | } |
| 273 | 323 | ||
| 274 | static enum | 324 | static enum |
| 275 | iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm, | 325 | iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm, |
| 276 | bool p2p_device, | 326 | struct ieee80211_vif *vif, |
| 277 | enum nl80211_band band) | 327 | enum nl80211_band band) |
| 278 | { | 328 | { |
| 279 | enum iwl_mvm_traffic_load load; | 329 | enum iwl_mvm_traffic_load load; |
| @@ -282,7 +332,7 @@ iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm, | |||
| 282 | load = iwl_mvm_get_traffic_load_band(mvm, band); | 332 | load = iwl_mvm_get_traffic_load_band(mvm, band); |
| 283 | low_latency = iwl_mvm_low_latency_band(mvm, band); | 333 | low_latency = iwl_mvm_low_latency_band(mvm, band); |
| 284 | 334 | ||
| 285 | return _iwl_mvm_get_scan_type(mvm, p2p_device, load, low_latency); | 335 | return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency); |
| 286 | } | 336 | } |
| 287 | 337 | ||
| 288 | static int | 338 | static int |
| @@ -860,6 +910,12 @@ static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params *params) | |||
| 860 | params->scan_plans[0].iterations == 1; | 910 | params->scan_plans[0].iterations == 1; |
| 861 | } | 911 | } |
| 862 | 912 | ||
| 913 | static bool iwl_mvm_is_scan_fragmented(enum iwl_mvm_scan_type type) | ||
| 914 | { | ||
| 915 | return (type == IWL_SCAN_TYPE_FRAGMENTED || | ||
| 916 | type == IWL_SCAN_TYPE_FAST_BALANCE); | ||
| 917 | } | ||
| 918 | |||
| 863 | static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, | 919 | static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, |
| 864 | struct iwl_mvm_scan_params *params, | 920 | struct iwl_mvm_scan_params *params, |
| 865 | struct ieee80211_vif *vif) | 921 | struct ieee80211_vif *vif) |
| @@ -872,7 +928,7 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, | |||
| 872 | if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0) | 928 | if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0) |
| 873 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; | 929 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; |
| 874 | 930 | ||
| 875 | if (params->type == IWL_SCAN_TYPE_FRAGMENTED) | 931 | if (iwl_mvm_is_scan_fragmented(params->type)) |
| 876 | flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED; | 932 | flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED; |
| 877 | 933 | ||
| 878 | if (iwl_mvm_rrm_scan_needed(mvm) && | 934 | if (iwl_mvm_rrm_scan_needed(mvm) && |
| @@ -895,7 +951,7 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, | |||
| 895 | 951 | ||
| 896 | if (iwl_mvm_is_regular_scan(params) && | 952 | if (iwl_mvm_is_regular_scan(params) && |
| 897 | vif->type != NL80211_IFTYPE_P2P_DEVICE && | 953 | vif->type != NL80211_IFTYPE_P2P_DEVICE && |
| 898 | params->type != IWL_SCAN_TYPE_FRAGMENTED) | 954 | !iwl_mvm_is_scan_fragmented(params->type)) |
| 899 | flags |= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL; | 955 | flags |= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL; |
| 900 | 956 | ||
| 901 | return flags; | 957 | return flags; |
| @@ -1044,7 +1100,7 @@ static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels) | |||
| 1044 | static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config, | 1100 | static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config, |
| 1045 | u32 flags, u8 channel_flags) | 1101 | u32 flags, u8 channel_flags) |
| 1046 | { | 1102 | { |
| 1047 | enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, false); | 1103 | enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL); |
| 1048 | struct iwl_scan_config_v1 *cfg = config; | 1104 | struct iwl_scan_config_v1 *cfg = config; |
| 1049 | 1105 | ||
| 1050 | cfg->flags = cpu_to_le32(flags); | 1106 | cfg->flags = cpu_to_le32(flags); |
| @@ -1077,9 +1133,9 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config, | |||
| 1077 | if (iwl_mvm_is_cdb_supported(mvm)) { | 1133 | if (iwl_mvm_is_cdb_supported(mvm)) { |
| 1078 | enum iwl_mvm_scan_type lb_type, hb_type; | 1134 | enum iwl_mvm_scan_type lb_type, hb_type; |
| 1079 | 1135 | ||
| 1080 | lb_type = iwl_mvm_get_scan_type_band(mvm, false, | 1136 | lb_type = iwl_mvm_get_scan_type_band(mvm, NULL, |
| 1081 | NL80211_BAND_2GHZ); | 1137 | NL80211_BAND_2GHZ); |
| 1082 | hb_type = iwl_mvm_get_scan_type_band(mvm, false, | 1138 | hb_type = iwl_mvm_get_scan_type_band(mvm, NULL, |
| 1083 | NL80211_BAND_5GHZ); | 1139 | NL80211_BAND_5GHZ); |
| 1084 | 1140 | ||
| 1085 | cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] = | 1141 | cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] = |
| @@ -1093,7 +1149,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config, | |||
| 1093 | cpu_to_le32(scan_timing[hb_type].suspend_time); | 1149 | cpu_to_le32(scan_timing[hb_type].suspend_time); |
| 1094 | } else { | 1150 | } else { |
| 1095 | enum iwl_mvm_scan_type type = | 1151 | enum iwl_mvm_scan_type type = |
| 1096 | iwl_mvm_get_scan_type(mvm, false); | 1152 | iwl_mvm_get_scan_type(mvm, NULL); |
| 1097 | 1153 | ||
| 1098 | cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] = | 1154 | cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] = |
| 1099 | cpu_to_le32(scan_timing[type].max_out_time); | 1155 | cpu_to_le32(scan_timing[type].max_out_time); |
| @@ -1130,14 +1186,14 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) | |||
| 1130 | return -ENOBUFS; | 1186 | return -ENOBUFS; |
| 1131 | 1187 | ||
| 1132 | if (iwl_mvm_is_cdb_supported(mvm)) { | 1188 | if (iwl_mvm_is_cdb_supported(mvm)) { |
| 1133 | type = iwl_mvm_get_scan_type_band(mvm, false, | 1189 | type = iwl_mvm_get_scan_type_band(mvm, NULL, |
| 1134 | NL80211_BAND_2GHZ); | 1190 | NL80211_BAND_2GHZ); |
| 1135 | hb_type = iwl_mvm_get_scan_type_band(mvm, false, | 1191 | hb_type = iwl_mvm_get_scan_type_band(mvm, NULL, |
| 1136 | NL80211_BAND_5GHZ); | 1192 | NL80211_BAND_5GHZ); |
| 1137 | if (type == mvm->scan_type && hb_type == mvm->hb_scan_type) | 1193 | if (type == mvm->scan_type && hb_type == mvm->hb_scan_type) |
| 1138 | return 0; | 1194 | return 0; |
| 1139 | } else { | 1195 | } else { |
| 1140 | type = iwl_mvm_get_scan_type(mvm, false); | 1196 | type = iwl_mvm_get_scan_type(mvm, NULL); |
| 1141 | if (type == mvm->scan_type) | 1197 | if (type == mvm->scan_type) |
| 1142 | return 0; | 1198 | return 0; |
| 1143 | } | 1199 | } |
| @@ -1162,7 +1218,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) | |||
| 1162 | SCAN_CONFIG_FLAG_SET_MAC_ADDR | | 1218 | SCAN_CONFIG_FLAG_SET_MAC_ADDR | |
| 1163 | SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS | | 1219 | SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS | |
| 1164 | SCAN_CONFIG_N_CHANNELS(num_channels) | | 1220 | SCAN_CONFIG_N_CHANNELS(num_channels) | |
| 1165 | (type == IWL_SCAN_TYPE_FRAGMENTED ? | 1221 | (iwl_mvm_is_scan_fragmented(type) ? |
| 1166 | SCAN_CONFIG_FLAG_SET_FRAGMENTED : | 1222 | SCAN_CONFIG_FLAG_SET_FRAGMENTED : |
| 1167 | SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED); | 1223 | SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED); |
| 1168 | 1224 | ||
| @@ -1177,7 +1233,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) | |||
| 1177 | */ | 1233 | */ |
| 1178 | if (iwl_mvm_cdb_scan_api(mvm)) { | 1234 | if (iwl_mvm_cdb_scan_api(mvm)) { |
| 1179 | if (iwl_mvm_is_cdb_supported(mvm)) | 1235 | if (iwl_mvm_is_cdb_supported(mvm)) |
| 1180 | flags |= (hb_type == IWL_SCAN_TYPE_FRAGMENTED) ? | 1236 | flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ? |
| 1181 | SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED : | 1237 | SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED : |
| 1182 | SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED; | 1238 | SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED; |
| 1183 | iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags); | 1239 | iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags); |
| @@ -1338,11 +1394,11 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm, | |||
| 1338 | if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0) | 1394 | if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0) |
| 1339 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT; | 1395 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT; |
| 1340 | 1396 | ||
| 1341 | if (params->type == IWL_SCAN_TYPE_FRAGMENTED) | 1397 | if (iwl_mvm_is_scan_fragmented(params->type)) |
| 1342 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED; | 1398 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED; |
| 1343 | 1399 | ||
| 1344 | if (iwl_mvm_is_cdb_supported(mvm) && | 1400 | if (iwl_mvm_is_cdb_supported(mvm) && |
| 1345 | params->hb_type == IWL_SCAN_TYPE_FRAGMENTED) | 1401 | iwl_mvm_is_scan_fragmented(params->hb_type)) |
| 1346 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED; | 1402 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED; |
| 1347 | 1403 | ||
| 1348 | if (iwl_mvm_rrm_scan_needed(mvm) && | 1404 | if (iwl_mvm_rrm_scan_needed(mvm) && |
| @@ -1380,7 +1436,7 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm, | |||
| 1380 | */ | 1436 | */ |
| 1381 | if (iwl_mvm_is_regular_scan(params) && | 1437 | if (iwl_mvm_is_regular_scan(params) && |
| 1382 | vif->type != NL80211_IFTYPE_P2P_DEVICE && | 1438 | vif->type != NL80211_IFTYPE_P2P_DEVICE && |
| 1383 | params->type != IWL_SCAN_TYPE_FRAGMENTED && | 1439 | !iwl_mvm_is_scan_fragmented(params->type) && |
| 1384 | !iwl_mvm_is_adaptive_dwell_supported(mvm) && | 1440 | !iwl_mvm_is_adaptive_dwell_supported(mvm) && |
| 1385 | !iwl_mvm_is_oce_supported(mvm)) | 1441 | !iwl_mvm_is_oce_supported(mvm)) |
| 1386 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL; | 1442 | flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL; |
| @@ -1589,19 +1645,20 @@ void iwl_mvm_scan_timeout_wk(struct work_struct *work) | |||
| 1589 | 1645 | ||
| 1590 | static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm, | 1646 | static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm, |
| 1591 | struct iwl_mvm_scan_params *params, | 1647 | struct iwl_mvm_scan_params *params, |
| 1592 | bool p2p) | 1648 | struct ieee80211_vif *vif) |
| 1593 | { | 1649 | { |
| 1594 | if (iwl_mvm_is_cdb_supported(mvm)) { | 1650 | if (iwl_mvm_is_cdb_supported(mvm)) { |
| 1595 | params->type = | 1651 | params->type = |
| 1596 | iwl_mvm_get_scan_type_band(mvm, p2p, | 1652 | iwl_mvm_get_scan_type_band(mvm, vif, |
| 1597 | NL80211_BAND_2GHZ); | 1653 | NL80211_BAND_2GHZ); |
| 1598 | params->hb_type = | 1654 | params->hb_type = |
| 1599 | iwl_mvm_get_scan_type_band(mvm, p2p, | 1655 | iwl_mvm_get_scan_type_band(mvm, vif, |
| 1600 | NL80211_BAND_5GHZ); | 1656 | NL80211_BAND_5GHZ); |
| 1601 | } else { | 1657 | } else { |
| 1602 | params->type = iwl_mvm_get_scan_type(mvm, p2p); | 1658 | params->type = iwl_mvm_get_scan_type(mvm, vif); |
| 1603 | } | 1659 | } |
| 1604 | } | 1660 | } |
| 1661 | |||
| 1605 | int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1662 | int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
| 1606 | struct cfg80211_scan_request *req, | 1663 | struct cfg80211_scan_request *req, |
| 1607 | struct ieee80211_scan_ies *ies) | 1664 | struct ieee80211_scan_ies *ies) |
| @@ -1649,8 +1706,7 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 1649 | params.scan_plans = &scan_plan; | 1706 | params.scan_plans = &scan_plan; |
| 1650 | params.n_scan_plans = 1; | 1707 | params.n_scan_plans = 1; |
| 1651 | 1708 | ||
| 1652 | iwl_mvm_fill_scan_type(mvm, ¶ms, | 1709 | iwl_mvm_fill_scan_type(mvm, ¶ms, vif); |
| 1653 | vif->type == NL80211_IFTYPE_P2P_DEVICE); | ||
| 1654 | 1710 | ||
| 1655 | ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms); | 1711 | ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms); |
| 1656 | if (ret < 0) | 1712 | if (ret < 0) |
| @@ -1745,8 +1801,7 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, | |||
| 1745 | params.n_scan_plans = req->n_scan_plans; | 1801 | params.n_scan_plans = req->n_scan_plans; |
| 1746 | params.scan_plans = req->scan_plans; | 1802 | params.scan_plans = req->scan_plans; |
| 1747 | 1803 | ||
| 1748 | iwl_mvm_fill_scan_type(mvm, ¶ms, | 1804 | iwl_mvm_fill_scan_type(mvm, ¶ms, vif); |
| 1749 | vif->type == NL80211_IFTYPE_P2P_DEVICE); | ||
| 1750 | 1805 | ||
| 1751 | /* In theory, LMAC scans can handle a 32-bit delay, but since | 1806 | /* In theory, LMAC scans can handle a 32-bit delay, but since |
| 1752 | * waiting for over 18 hours to start the scan is a bit silly | 1807 | * waiting for over 18 hours to start the scan is a bit silly |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 8f929c774e70..1887d2b9f185 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c | |||
| @@ -358,6 +358,108 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm *mvm, int queue, | |||
| 358 | return ret; | 358 | return ret; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, | ||
| 362 | int mac80211_queue, u8 tid, u8 flags) | ||
| 363 | { | ||
| 364 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 365 | .scd_queue = queue, | ||
| 366 | .action = SCD_CFG_DISABLE_QUEUE, | ||
| 367 | }; | ||
| 368 | bool remove_mac_queue = mac80211_queue != IEEE80211_INVAL_HW_QUEUE; | ||
| 369 | int ret; | ||
| 370 | |||
| 371 | if (WARN_ON(remove_mac_queue && mac80211_queue >= IEEE80211_MAX_QUEUES)) | ||
| 372 | return -EINVAL; | ||
| 373 | |||
| 374 | if (iwl_mvm_has_new_tx_api(mvm)) { | ||
| 375 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 376 | |||
| 377 | if (remove_mac_queue) | ||
| 378 | mvm->hw_queue_to_mac80211[queue] &= | ||
| 379 | ~BIT(mac80211_queue); | ||
| 380 | |||
| 381 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 382 | |||
| 383 | iwl_trans_txq_free(mvm->trans, queue); | ||
| 384 | |||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 389 | |||
| 390 | if (WARN_ON(mvm->queue_info[queue].tid_bitmap == 0)) { | ||
| 391 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 392 | return 0; | ||
| 393 | } | ||
| 394 | |||
| 395 | mvm->queue_info[queue].tid_bitmap &= ~BIT(tid); | ||
| 396 | |||
| 397 | /* | ||
| 398 | * If there is another TID with the same AC - don't remove the MAC queue | ||
| 399 | * from the mapping | ||
| 400 | */ | ||
| 401 | if (tid < IWL_MAX_TID_COUNT) { | ||
| 402 | unsigned long tid_bitmap = | ||
| 403 | mvm->queue_info[queue].tid_bitmap; | ||
| 404 | int ac = tid_to_mac80211_ac[tid]; | ||
| 405 | int i; | ||
| 406 | |||
| 407 | for_each_set_bit(i, &tid_bitmap, IWL_MAX_TID_COUNT) { | ||
| 408 | if (tid_to_mac80211_ac[i] == ac) | ||
| 409 | remove_mac_queue = false; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | if (remove_mac_queue) | ||
| 414 | mvm->hw_queue_to_mac80211[queue] &= | ||
| 415 | ~BIT(mac80211_queue); | ||
| 416 | |||
| 417 | cmd.action = mvm->queue_info[queue].tid_bitmap ? | ||
| 418 | SCD_CFG_ENABLE_QUEUE : SCD_CFG_DISABLE_QUEUE; | ||
| 419 | if (cmd.action == SCD_CFG_DISABLE_QUEUE) | ||
| 420 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE; | ||
| 421 | |||
| 422 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 423 | "Disabling TXQ #%d tids=0x%x (mac80211 map:0x%x)\n", | ||
| 424 | queue, | ||
| 425 | mvm->queue_info[queue].tid_bitmap, | ||
| 426 | mvm->hw_queue_to_mac80211[queue]); | ||
| 427 | |||
| 428 | /* If the queue is still enabled - nothing left to do in this func */ | ||
| 429 | if (cmd.action == SCD_CFG_ENABLE_QUEUE) { | ||
| 430 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 431 | return 0; | ||
| 432 | } | ||
| 433 | |||
| 434 | cmd.sta_id = mvm->queue_info[queue].ra_sta_id; | ||
| 435 | cmd.tid = mvm->queue_info[queue].txq_tid; | ||
| 436 | |||
| 437 | /* Make sure queue info is correct even though we overwrite it */ | ||
| 438 | WARN(mvm->queue_info[queue].tid_bitmap || | ||
| 439 | mvm->hw_queue_to_mac80211[queue], | ||
| 440 | "TXQ #%d info out-of-sync - mac map=0x%x, tids=0x%x\n", | ||
| 441 | queue, mvm->hw_queue_to_mac80211[queue], | ||
| 442 | mvm->queue_info[queue].tid_bitmap); | ||
| 443 | |||
| 444 | /* If we are here - the queue is freed and we can zero out these vals */ | ||
| 445 | mvm->queue_info[queue].tid_bitmap = 0; | ||
| 446 | mvm->hw_queue_to_mac80211[queue] = 0; | ||
| 447 | |||
| 448 | /* Regardless if this is a reserved TXQ for a STA - mark it as false */ | ||
| 449 | mvm->queue_info[queue].reserved = false; | ||
| 450 | |||
| 451 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 452 | |||
| 453 | iwl_trans_txq_disable(mvm->trans, queue, false); | ||
| 454 | ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags, | ||
| 455 | sizeof(struct iwl_scd_txq_cfg_cmd), &cmd); | ||
| 456 | |||
| 457 | if (ret) | ||
| 458 | IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n", | ||
| 459 | queue, ret); | ||
| 460 | return ret; | ||
| 461 | } | ||
| 462 | |||
| 361 | static int iwl_mvm_get_queue_agg_tids(struct iwl_mvm *mvm, int queue) | 463 | static int iwl_mvm_get_queue_agg_tids(struct iwl_mvm *mvm, int queue) |
| 362 | { | 464 | { |
| 363 | struct ieee80211_sta *sta; | 465 | struct ieee80211_sta *sta; |
| @@ -447,11 +549,12 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue) | |||
| 447 | } | 549 | } |
| 448 | 550 | ||
| 449 | static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, | 551 | static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, |
| 450 | bool same_sta) | 552 | u8 new_sta_id) |
| 451 | { | 553 | { |
| 452 | struct iwl_mvm_sta *mvmsta; | 554 | struct iwl_mvm_sta *mvmsta; |
| 453 | u8 txq_curr_ac, sta_id, tid; | 555 | u8 txq_curr_ac, sta_id, tid; |
| 454 | unsigned long disable_agg_tids = 0; | 556 | unsigned long disable_agg_tids = 0; |
| 557 | bool same_sta; | ||
| 455 | int ret; | 558 | int ret; |
| 456 | 559 | ||
| 457 | lockdep_assert_held(&mvm->mutex); | 560 | lockdep_assert_held(&mvm->mutex); |
| @@ -465,6 +568,8 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, | |||
| 465 | tid = mvm->queue_info[queue].txq_tid; | 568 | tid = mvm->queue_info[queue].txq_tid; |
| 466 | spin_unlock_bh(&mvm->queue_info_lock); | 569 | spin_unlock_bh(&mvm->queue_info_lock); |
| 467 | 570 | ||
| 571 | same_sta = sta_id == new_sta_id; | ||
| 572 | |||
| 468 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); | 573 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); |
| 469 | if (WARN_ON(!mvmsta)) | 574 | if (WARN_ON(!mvmsta)) |
| 470 | return -EINVAL; | 575 | return -EINVAL; |
| @@ -479,10 +584,6 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue, | |||
| 479 | mvmsta->vif->hw_queue[txq_curr_ac], | 584 | mvmsta->vif->hw_queue[txq_curr_ac], |
| 480 | tid, 0); | 585 | tid, 0); |
| 481 | if (ret) { | 586 | if (ret) { |
| 482 | /* Re-mark the inactive queue as inactive */ | ||
| 483 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 484 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_INACTIVE; | ||
| 485 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 486 | IWL_ERR(mvm, | 587 | IWL_ERR(mvm, |
| 487 | "Failed to free inactive queue %d (ret=%d)\n", | 588 | "Failed to free inactive queue %d (ret=%d)\n", |
| 488 | queue, ret); | 589 | queue, ret); |
| @@ -504,7 +605,13 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm, | |||
| 504 | u8 ac_to_queue[IEEE80211_NUM_ACS]; | 605 | u8 ac_to_queue[IEEE80211_NUM_ACS]; |
| 505 | int i; | 606 | int i; |
| 506 | 607 | ||
| 608 | /* | ||
| 609 | * This protects us against grabbing a queue that's being reconfigured | ||
| 610 | * by the inactivity checker. | ||
| 611 | */ | ||
| 612 | lockdep_assert_held(&mvm->mutex); | ||
| 507 | lockdep_assert_held(&mvm->queue_info_lock); | 613 | lockdep_assert_held(&mvm->queue_info_lock); |
| 614 | |||
| 508 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | 615 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) |
| 509 | return -EINVAL; | 616 | return -EINVAL; |
| 510 | 617 | ||
| @@ -517,11 +624,6 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm, | |||
| 517 | i != IWL_MVM_DQA_BSS_CLIENT_QUEUE) | 624 | i != IWL_MVM_DQA_BSS_CLIENT_QUEUE) |
| 518 | continue; | 625 | continue; |
| 519 | 626 | ||
| 520 | /* Don't try and take queues being reconfigured */ | ||
| 521 | if (mvm->queue_info[queue].status == | ||
| 522 | IWL_MVM_QUEUE_RECONFIGURING) | ||
| 523 | continue; | ||
| 524 | |||
| 525 | ac_to_queue[mvm->queue_info[i].mac80211_ac] = i; | 627 | ac_to_queue[mvm->queue_info[i].mac80211_ac] = i; |
| 526 | } | 628 | } |
| 527 | 629 | ||
| @@ -562,14 +664,6 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm, | |||
| 562 | return -ENOSPC; | 664 | return -ENOSPC; |
| 563 | } | 665 | } |
| 564 | 666 | ||
| 565 | /* Make sure the queue isn't in the middle of being reconfigured */ | ||
| 566 | if (mvm->queue_info[queue].status == IWL_MVM_QUEUE_RECONFIGURING) { | ||
| 567 | IWL_ERR(mvm, | ||
| 568 | "TXQ %d is in the middle of re-config - try again\n", | ||
| 569 | queue); | ||
| 570 | return -EBUSY; | ||
| 571 | } | ||
| 572 | |||
| 573 | return queue; | 667 | return queue; |
| 574 | } | 668 | } |
| 575 | 669 | ||
| @@ -579,9 +673,9 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm, | |||
| 579 | * in such a case, otherwise - if no redirection required - it does nothing, | 673 | * in such a case, otherwise - if no redirection required - it does nothing, |
| 580 | * unless the %force param is true. | 674 | * unless the %force param is true. |
| 581 | */ | 675 | */ |
| 582 | int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, | 676 | static int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, |
| 583 | int ac, int ssn, unsigned int wdg_timeout, | 677 | int ac, int ssn, unsigned int wdg_timeout, |
| 584 | bool force) | 678 | bool force) |
| 585 | { | 679 | { |
| 586 | struct iwl_scd_txq_cfg_cmd cmd = { | 680 | struct iwl_scd_txq_cfg_cmd cmd = { |
| 587 | .scd_queue = queue, | 681 | .scd_queue = queue, |
| @@ -616,7 +710,7 @@ int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, | |||
| 616 | cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[mvm->queue_info[queue].mac80211_ac]; | 710 | cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[mvm->queue_info[queue].mac80211_ac]; |
| 617 | cmd.tid = mvm->queue_info[queue].txq_tid; | 711 | cmd.tid = mvm->queue_info[queue].txq_tid; |
| 618 | mq = mvm->hw_queue_to_mac80211[queue]; | 712 | mq = mvm->hw_queue_to_mac80211[queue]; |
| 619 | shared_queue = (mvm->queue_info[queue].hw_queue_refcount > 1); | 713 | shared_queue = hweight16(mvm->queue_info[queue].tid_bitmap) > 1; |
| 620 | spin_unlock_bh(&mvm->queue_info_lock); | 714 | spin_unlock_bh(&mvm->queue_info_lock); |
| 621 | 715 | ||
| 622 | IWL_DEBUG_TX_QUEUES(mvm, "Redirecting TXQ #%d to FIFO #%d\n", | 716 | IWL_DEBUG_TX_QUEUES(mvm, "Redirecting TXQ #%d to FIFO #%d\n", |
| @@ -674,6 +768,57 @@ out: | |||
| 674 | return ret; | 768 | return ret; |
| 675 | } | 769 | } |
| 676 | 770 | ||
| 771 | static int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, | ||
| 772 | u8 minq, u8 maxq) | ||
| 773 | { | ||
| 774 | int i; | ||
| 775 | |||
| 776 | lockdep_assert_held(&mvm->queue_info_lock); | ||
| 777 | |||
| 778 | /* This should not be hit with new TX path */ | ||
| 779 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 780 | return -ENOSPC; | ||
| 781 | |||
| 782 | /* Start by looking for a free queue */ | ||
| 783 | for (i = minq; i <= maxq; i++) | ||
| 784 | if (mvm->queue_info[i].tid_bitmap == 0 && | ||
| 785 | mvm->queue_info[i].status == IWL_MVM_QUEUE_FREE) | ||
| 786 | return i; | ||
| 787 | |||
| 788 | return -ENOSPC; | ||
| 789 | } | ||
| 790 | |||
| 791 | static int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, | ||
| 792 | u8 sta_id, u8 tid, unsigned int timeout) | ||
| 793 | { | ||
| 794 | int queue, size = IWL_DEFAULT_QUEUE_SIZE; | ||
| 795 | |||
| 796 | if (tid == IWL_MAX_TID_COUNT) { | ||
| 797 | tid = IWL_MGMT_TID; | ||
| 798 | size = IWL_MGMT_QUEUE_SIZE; | ||
| 799 | } | ||
| 800 | queue = iwl_trans_txq_alloc(mvm->trans, | ||
| 801 | cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), | ||
| 802 | sta_id, tid, SCD_QUEUE_CFG, size, timeout); | ||
| 803 | |||
| 804 | if (queue < 0) { | ||
| 805 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 806 | "Failed allocating TXQ for sta %d tid %d, ret: %d\n", | ||
| 807 | sta_id, tid, queue); | ||
| 808 | return queue; | ||
| 809 | } | ||
| 810 | |||
| 811 | IWL_DEBUG_TX_QUEUES(mvm, "Enabling TXQ #%d for sta %d tid %d\n", | ||
| 812 | queue, sta_id, tid); | ||
| 813 | |||
| 814 | mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); | ||
| 815 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 816 | "Enabling TXQ #%d (mac80211 map:0x%x)\n", | ||
| 817 | queue, mvm->hw_queue_to_mac80211[queue]); | ||
| 818 | |||
| 819 | return queue; | ||
| 820 | } | ||
| 821 | |||
| 677 | static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm, | 822 | static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm, |
| 678 | struct ieee80211_sta *sta, u8 ac, | 823 | struct ieee80211_sta *sta, u8 ac, |
| 679 | int tid) | 824 | int tid) |
| @@ -698,12 +843,428 @@ static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm, | |||
| 698 | 843 | ||
| 699 | spin_lock_bh(&mvmsta->lock); | 844 | spin_lock_bh(&mvmsta->lock); |
| 700 | mvmsta->tid_data[tid].txq_id = queue; | 845 | mvmsta->tid_data[tid].txq_id = queue; |
| 701 | mvmsta->tid_data[tid].is_tid_active = true; | ||
| 702 | spin_unlock_bh(&mvmsta->lock); | 846 | spin_unlock_bh(&mvmsta->lock); |
| 703 | 847 | ||
| 704 | return 0; | 848 | return 0; |
| 705 | } | 849 | } |
| 706 | 850 | ||
| 851 | static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, | ||
| 852 | int mac80211_queue, u8 sta_id, u8 tid) | ||
| 853 | { | ||
| 854 | bool enable_queue = true; | ||
| 855 | |||
| 856 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 857 | |||
| 858 | /* Make sure this TID isn't already enabled */ | ||
| 859 | if (mvm->queue_info[queue].tid_bitmap & BIT(tid)) { | ||
| 860 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 861 | IWL_ERR(mvm, "Trying to enable TXQ %d with existing TID %d\n", | ||
| 862 | queue, tid); | ||
| 863 | return false; | ||
| 864 | } | ||
| 865 | |||
| 866 | /* Update mappings and refcounts */ | ||
| 867 | if (mvm->queue_info[queue].tid_bitmap) | ||
| 868 | enable_queue = false; | ||
| 869 | |||
| 870 | if (mac80211_queue != IEEE80211_INVAL_HW_QUEUE) { | ||
| 871 | WARN(mac80211_queue >= | ||
| 872 | BITS_PER_BYTE * sizeof(mvm->hw_queue_to_mac80211[0]), | ||
| 873 | "cannot track mac80211 queue %d (queue %d, sta %d, tid %d)\n", | ||
| 874 | mac80211_queue, queue, sta_id, tid); | ||
| 875 | mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); | ||
| 876 | } | ||
| 877 | |||
| 878 | mvm->queue_info[queue].tid_bitmap |= BIT(tid); | ||
| 879 | mvm->queue_info[queue].ra_sta_id = sta_id; | ||
| 880 | |||
| 881 | if (enable_queue) { | ||
| 882 | if (tid != IWL_MAX_TID_COUNT) | ||
| 883 | mvm->queue_info[queue].mac80211_ac = | ||
| 884 | tid_to_mac80211_ac[tid]; | ||
| 885 | else | ||
| 886 | mvm->queue_info[queue].mac80211_ac = IEEE80211_AC_VO; | ||
| 887 | |||
| 888 | mvm->queue_info[queue].txq_tid = tid; | ||
| 889 | } | ||
| 890 | |||
| 891 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 892 | "Enabling TXQ #%d tids=0x%x (mac80211 map:0x%x)\n", | ||
| 893 | queue, mvm->queue_info[queue].tid_bitmap, | ||
| 894 | mvm->hw_queue_to_mac80211[queue]); | ||
| 895 | |||
| 896 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 897 | |||
| 898 | return enable_queue; | ||
| 899 | } | ||
| 900 | |||
| 901 | static bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, | ||
| 902 | int mac80211_queue, u16 ssn, | ||
| 903 | const struct iwl_trans_txq_scd_cfg *cfg, | ||
| 904 | unsigned int wdg_timeout) | ||
| 905 | { | ||
| 906 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 907 | .scd_queue = queue, | ||
| 908 | .action = SCD_CFG_ENABLE_QUEUE, | ||
| 909 | .window = cfg->frame_limit, | ||
| 910 | .sta_id = cfg->sta_id, | ||
| 911 | .ssn = cpu_to_le16(ssn), | ||
| 912 | .tx_fifo = cfg->fifo, | ||
| 913 | .aggregate = cfg->aggregate, | ||
| 914 | .tid = cfg->tid, | ||
| 915 | }; | ||
| 916 | bool inc_ssn; | ||
| 917 | |||
| 918 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 919 | return false; | ||
| 920 | |||
| 921 | /* Send the enabling command if we need to */ | ||
| 922 | if (!iwl_mvm_update_txq_mapping(mvm, queue, mac80211_queue, | ||
| 923 | cfg->sta_id, cfg->tid)) | ||
| 924 | return false; | ||
| 925 | |||
| 926 | inc_ssn = iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, | ||
| 927 | NULL, wdg_timeout); | ||
| 928 | if (inc_ssn) | ||
| 929 | le16_add_cpu(&cmd.ssn, 1); | ||
| 930 | |||
| 931 | WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd), | ||
| 932 | "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo); | ||
| 933 | |||
| 934 | return inc_ssn; | ||
| 935 | } | ||
| 936 | |||
| 937 | static void iwl_mvm_change_queue_tid(struct iwl_mvm *mvm, int queue) | ||
| 938 | { | ||
| 939 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 940 | .scd_queue = queue, | ||
| 941 | .action = SCD_CFG_UPDATE_QUEUE_TID, | ||
| 942 | }; | ||
| 943 | int tid; | ||
| 944 | unsigned long tid_bitmap; | ||
| 945 | int ret; | ||
| 946 | |||
| 947 | lockdep_assert_held(&mvm->mutex); | ||
| 948 | |||
| 949 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 950 | return; | ||
| 951 | |||
| 952 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 953 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 954 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 955 | |||
| 956 | if (WARN(!tid_bitmap, "TXQ %d has no tids assigned to it\n", queue)) | ||
| 957 | return; | ||
| 958 | |||
| 959 | /* Find any TID for queue */ | ||
| 960 | tid = find_first_bit(&tid_bitmap, IWL_MAX_TID_COUNT + 1); | ||
| 961 | cmd.tid = tid; | ||
| 962 | cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]]; | ||
| 963 | |||
| 964 | ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd); | ||
| 965 | if (ret) { | ||
| 966 | IWL_ERR(mvm, "Failed to update owner of TXQ %d (ret=%d)\n", | ||
| 967 | queue, ret); | ||
| 968 | return; | ||
| 969 | } | ||
| 970 | |||
| 971 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 972 | mvm->queue_info[queue].txq_tid = tid; | ||
| 973 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 974 | IWL_DEBUG_TX_QUEUES(mvm, "Changed TXQ %d ownership to tid %d\n", | ||
| 975 | queue, tid); | ||
| 976 | } | ||
| 977 | |||
| 978 | static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, int queue) | ||
| 979 | { | ||
| 980 | struct ieee80211_sta *sta; | ||
| 981 | struct iwl_mvm_sta *mvmsta; | ||
| 982 | u8 sta_id; | ||
| 983 | int tid = -1; | ||
| 984 | unsigned long tid_bitmap; | ||
| 985 | unsigned int wdg_timeout; | ||
| 986 | int ssn; | ||
| 987 | int ret = true; | ||
| 988 | |||
| 989 | /* queue sharing is disabled on new TX path */ | ||
| 990 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 991 | return; | ||
| 992 | |||
| 993 | lockdep_assert_held(&mvm->mutex); | ||
| 994 | |||
| 995 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 996 | sta_id = mvm->queue_info[queue].ra_sta_id; | ||
| 997 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 998 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 999 | |||
| 1000 | /* Find TID for queue, and make sure it is the only one on the queue */ | ||
| 1001 | tid = find_first_bit(&tid_bitmap, IWL_MAX_TID_COUNT + 1); | ||
| 1002 | if (tid_bitmap != BIT(tid)) { | ||
| 1003 | IWL_ERR(mvm, "Failed to unshare q %d, active tids=0x%lx\n", | ||
| 1004 | queue, tid_bitmap); | ||
| 1005 | return; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | IWL_DEBUG_TX_QUEUES(mvm, "Unsharing TXQ %d, keeping tid %d\n", queue, | ||
| 1009 | tid); | ||
| 1010 | |||
| 1011 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
| 1012 | lockdep_is_held(&mvm->mutex)); | ||
| 1013 | |||
| 1014 | if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) | ||
| 1015 | return; | ||
| 1016 | |||
| 1017 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
| 1018 | wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); | ||
| 1019 | |||
| 1020 | ssn = IEEE80211_SEQ_TO_SN(mvmsta->tid_data[tid].seq_number); | ||
| 1021 | |||
| 1022 | ret = iwl_mvm_scd_queue_redirect(mvm, queue, tid, | ||
| 1023 | tid_to_mac80211_ac[tid], ssn, | ||
| 1024 | wdg_timeout, true); | ||
| 1025 | if (ret) { | ||
| 1026 | IWL_ERR(mvm, "Failed to redirect TXQ %d\n", queue); | ||
| 1027 | return; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | /* If aggs should be turned back on - do it */ | ||
| 1031 | if (mvmsta->tid_data[tid].state == IWL_AGG_ON) { | ||
| 1032 | struct iwl_mvm_add_sta_cmd cmd = {0}; | ||
| 1033 | |||
| 1034 | mvmsta->tid_disable_agg &= ~BIT(tid); | ||
| 1035 | |||
| 1036 | cmd.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color); | ||
| 1037 | cmd.sta_id = mvmsta->sta_id; | ||
| 1038 | cmd.add_modify = STA_MODE_MODIFY; | ||
| 1039 | cmd.modify_mask = STA_MODIFY_TID_DISABLE_TX; | ||
| 1040 | cmd.tfd_queue_msk = cpu_to_le32(mvmsta->tfd_queue_msk); | ||
| 1041 | cmd.tid_disable_tx = cpu_to_le16(mvmsta->tid_disable_agg); | ||
| 1042 | |||
| 1043 | ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, | ||
| 1044 | iwl_mvm_add_sta_cmd_size(mvm), &cmd); | ||
| 1045 | if (!ret) { | ||
| 1046 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1047 | "TXQ #%d is now aggregated again\n", | ||
| 1048 | queue); | ||
| 1049 | |||
| 1050 | /* Mark queue intenally as aggregating again */ | ||
| 1051 | iwl_trans_txq_set_shared_mode(mvm->trans, queue, false); | ||
| 1052 | } | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1056 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY; | ||
| 1057 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * Remove inactive TIDs of a given queue. | ||
| 1062 | * If all queue TIDs are inactive - mark the queue as inactive | ||
| 1063 | * If only some the queue TIDs are inactive - unmap them from the queue | ||
| 1064 | * | ||
| 1065 | * Returns %true if all TIDs were removed and the queue could be reused. | ||
| 1066 | */ | ||
| 1067 | static bool iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm, | ||
| 1068 | struct iwl_mvm_sta *mvmsta, int queue, | ||
| 1069 | unsigned long tid_bitmap, | ||
| 1070 | unsigned long *unshare_queues, | ||
| 1071 | unsigned long *changetid_queues) | ||
| 1072 | { | ||
| 1073 | int tid; | ||
| 1074 | |||
| 1075 | lockdep_assert_held(&mvmsta->lock); | ||
| 1076 | lockdep_assert_held(&mvm->queue_info_lock); | ||
| 1077 | |||
| 1078 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 1079 | return false; | ||
| 1080 | |||
| 1081 | /* Go over all non-active TIDs, incl. IWL_MAX_TID_COUNT (for mgmt) */ | ||
| 1082 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1083 | /* If some TFDs are still queued - don't mark TID as inactive */ | ||
| 1084 | if (iwl_mvm_tid_queued(mvm, &mvmsta->tid_data[tid])) | ||
| 1085 | tid_bitmap &= ~BIT(tid); | ||
| 1086 | |||
| 1087 | /* Don't mark as inactive any TID that has an active BA */ | ||
| 1088 | if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) | ||
| 1089 | tid_bitmap &= ~BIT(tid); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | /* If all TIDs in the queue are inactive - return it can be reused */ | ||
| 1093 | if (tid_bitmap == mvm->queue_info[queue].tid_bitmap) { | ||
| 1094 | IWL_DEBUG_TX_QUEUES(mvm, "Queue %d is inactive\n", queue); | ||
| 1095 | return true; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * If we are here, this is a shared queue and not all TIDs timed-out. | ||
| 1100 | * Remove the ones that did. | ||
| 1101 | */ | ||
| 1102 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1103 | int mac_queue = mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]]; | ||
| 1104 | u16 tid_bitmap; | ||
| 1105 | |||
| 1106 | mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE; | ||
| 1107 | mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac_queue); | ||
| 1108 | mvm->queue_info[queue].tid_bitmap &= ~BIT(tid); | ||
| 1109 | |||
| 1110 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 1111 | |||
| 1112 | /* | ||
| 1113 | * We need to take into account a situation in which a TXQ was | ||
| 1114 | * allocated to TID x, and then turned shared by adding TIDs y | ||
| 1115 | * and z. If TID x becomes inactive and is removed from the TXQ, | ||
| 1116 | * ownership must be given to one of the remaining TIDs. | ||
| 1117 | * This is mainly because if TID x continues - a new queue can't | ||
| 1118 | * be allocated for it as long as it is an owner of another TXQ. | ||
| 1119 | * | ||
| 1120 | * Mark this queue in the right bitmap, we'll send the command | ||
| 1121 | * to the firmware later. | ||
| 1122 | */ | ||
| 1123 | if (!(tid_bitmap & BIT(mvm->queue_info[queue].txq_tid))) | ||
| 1124 | set_bit(queue, changetid_queues); | ||
| 1125 | |||
| 1126 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1127 | "Removing inactive TID %d from shared Q:%d\n", | ||
| 1128 | tid, queue); | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1132 | "TXQ #%d left with tid bitmap 0x%x\n", queue, | ||
| 1133 | mvm->queue_info[queue].tid_bitmap); | ||
| 1134 | |||
| 1135 | /* | ||
| 1136 | * There may be different TIDs with the same mac queues, so make | ||
| 1137 | * sure all TIDs have existing corresponding mac queues enabled | ||
| 1138 | */ | ||
| 1139 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 1140 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1141 | mvm->hw_queue_to_mac80211[queue] |= | ||
| 1142 | BIT(mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]]); | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | /* If the queue is marked as shared - "unshare" it */ | ||
| 1146 | if (hweight16(mvm->queue_info[queue].tid_bitmap) == 1 && | ||
| 1147 | mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED) { | ||
| 1148 | IWL_DEBUG_TX_QUEUES(mvm, "Marking Q:%d for reconfig\n", | ||
| 1149 | queue); | ||
| 1150 | set_bit(queue, unshare_queues); | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | return false; | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | /* | ||
| 1157 | * Check for inactivity - this includes checking if any queue | ||
| 1158 | * can be unshared and finding one (and only one) that can be | ||
| 1159 | * reused. | ||
| 1160 | * This function is also invoked as a sort of clean-up task, | ||
| 1161 | * in which case @alloc_for_sta is IWL_MVM_INVALID_STA. | ||
| 1162 | * | ||
| 1163 | * Returns the queue number, or -ENOSPC. | ||
| 1164 | */ | ||
| 1165 | static int iwl_mvm_inactivity_check(struct iwl_mvm *mvm, u8 alloc_for_sta) | ||
| 1166 | { | ||
| 1167 | unsigned long now = jiffies; | ||
| 1168 | unsigned long unshare_queues = 0; | ||
| 1169 | unsigned long changetid_queues = 0; | ||
| 1170 | int i, ret, free_queue = -ENOSPC; | ||
| 1171 | |||
| 1172 | lockdep_assert_held(&mvm->mutex); | ||
| 1173 | |||
| 1174 | if (iwl_mvm_has_new_tx_api(mvm)) | ||
| 1175 | return -ENOSPC; | ||
| 1176 | |||
| 1177 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1178 | |||
| 1179 | rcu_read_lock(); | ||
| 1180 | |||
| 1181 | /* we skip the CMD queue below by starting at 1 */ | ||
| 1182 | BUILD_BUG_ON(IWL_MVM_DQA_CMD_QUEUE != 0); | ||
| 1183 | |||
| 1184 | for (i = 1; i < IWL_MAX_HW_QUEUES; i++) { | ||
| 1185 | struct ieee80211_sta *sta; | ||
| 1186 | struct iwl_mvm_sta *mvmsta; | ||
| 1187 | u8 sta_id; | ||
| 1188 | int tid; | ||
| 1189 | unsigned long inactive_tid_bitmap = 0; | ||
| 1190 | unsigned long queue_tid_bitmap; | ||
| 1191 | |||
| 1192 | queue_tid_bitmap = mvm->queue_info[i].tid_bitmap; | ||
| 1193 | if (!queue_tid_bitmap) | ||
| 1194 | continue; | ||
| 1195 | |||
| 1196 | /* If TXQ isn't in active use anyway - nothing to do here... */ | ||
| 1197 | if (mvm->queue_info[i].status != IWL_MVM_QUEUE_READY && | ||
| 1198 | mvm->queue_info[i].status != IWL_MVM_QUEUE_SHARED) | ||
| 1199 | continue; | ||
| 1200 | |||
| 1201 | /* Check to see if there are inactive TIDs on this queue */ | ||
| 1202 | for_each_set_bit(tid, &queue_tid_bitmap, | ||
| 1203 | IWL_MAX_TID_COUNT + 1) { | ||
| 1204 | if (time_after(mvm->queue_info[i].last_frame_time[tid] + | ||
| 1205 | IWL_MVM_DQA_QUEUE_TIMEOUT, now)) | ||
| 1206 | continue; | ||
| 1207 | |||
| 1208 | inactive_tid_bitmap |= BIT(tid); | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | /* If all TIDs are active - finish check on this queue */ | ||
| 1212 | if (!inactive_tid_bitmap) | ||
| 1213 | continue; | ||
| 1214 | |||
| 1215 | /* | ||
| 1216 | * If we are here - the queue hadn't been served recently and is | ||
| 1217 | * in use | ||
| 1218 | */ | ||
| 1219 | |||
| 1220 | sta_id = mvm->queue_info[i].ra_sta_id; | ||
| 1221 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
| 1222 | |||
| 1223 | /* | ||
| 1224 | * If the STA doesn't exist anymore, it isn't an error. It could | ||
| 1225 | * be that it was removed since getting the queues, and in this | ||
| 1226 | * case it should've inactivated its queues anyway. | ||
| 1227 | */ | ||
| 1228 | if (IS_ERR_OR_NULL(sta)) | ||
| 1229 | continue; | ||
| 1230 | |||
| 1231 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
| 1232 | |||
| 1233 | /* this isn't so nice, but works OK due to the way we loop */ | ||
| 1234 | spin_unlock(&mvm->queue_info_lock); | ||
| 1235 | |||
| 1236 | /* and we need this locking order */ | ||
| 1237 | spin_lock(&mvmsta->lock); | ||
| 1238 | spin_lock(&mvm->queue_info_lock); | ||
| 1239 | ret = iwl_mvm_remove_inactive_tids(mvm, mvmsta, i, | ||
| 1240 | inactive_tid_bitmap, | ||
| 1241 | &unshare_queues, | ||
| 1242 | &changetid_queues); | ||
| 1243 | if (ret >= 0 && free_queue < 0) | ||
| 1244 | free_queue = ret; | ||
| 1245 | /* only unlock sta lock - we still need the queue info lock */ | ||
| 1246 | spin_unlock(&mvmsta->lock); | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | rcu_read_unlock(); | ||
| 1250 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1251 | |||
| 1252 | /* Reconfigure queues requiring reconfiguation */ | ||
| 1253 | for_each_set_bit(i, &unshare_queues, IWL_MAX_HW_QUEUES) | ||
| 1254 | iwl_mvm_unshare_queue(mvm, i); | ||
| 1255 | for_each_set_bit(i, &changetid_queues, IWL_MAX_HW_QUEUES) | ||
| 1256 | iwl_mvm_change_queue_tid(mvm, i); | ||
| 1257 | |||
| 1258 | if (free_queue >= 0 && alloc_for_sta != IWL_MVM_INVALID_STA) { | ||
| 1259 | ret = iwl_mvm_free_inactive_queue(mvm, free_queue, | ||
| 1260 | alloc_for_sta); | ||
| 1261 | if (ret) | ||
| 1262 | return ret; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | return free_queue; | ||
| 1266 | } | ||
| 1267 | |||
| 707 | static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | 1268 | static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, |
| 708 | struct ieee80211_sta *sta, u8 ac, int tid, | 1269 | struct ieee80211_sta *sta, u8 ac, int tid, |
| 709 | struct ieee80211_hdr *hdr) | 1270 | struct ieee80211_hdr *hdr) |
| @@ -719,7 +1280,6 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 719 | iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); | 1280 | iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); |
| 720 | u8 mac_queue = mvmsta->vif->hw_queue[ac]; | 1281 | u8 mac_queue = mvmsta->vif->hw_queue[ac]; |
| 721 | int queue = -1; | 1282 | int queue = -1; |
| 722 | bool using_inactive_queue = false, same_sta = false; | ||
| 723 | unsigned long disable_agg_tids = 0; | 1283 | unsigned long disable_agg_tids = 0; |
| 724 | enum iwl_mvm_agg_state queue_state; | 1284 | enum iwl_mvm_agg_state queue_state; |
| 725 | bool shared_queue = false, inc_ssn; | 1285 | bool shared_queue = false, inc_ssn; |
| @@ -756,9 +1316,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 756 | 1316 | ||
| 757 | if ((queue < 0 && mvmsta->reserved_queue != IEEE80211_INVAL_HW_QUEUE) && | 1317 | if ((queue < 0 && mvmsta->reserved_queue != IEEE80211_INVAL_HW_QUEUE) && |
| 758 | (mvm->queue_info[mvmsta->reserved_queue].status == | 1318 | (mvm->queue_info[mvmsta->reserved_queue].status == |
| 759 | IWL_MVM_QUEUE_RESERVED || | 1319 | IWL_MVM_QUEUE_RESERVED)) { |
| 760 | mvm->queue_info[mvmsta->reserved_queue].status == | ||
| 761 | IWL_MVM_QUEUE_INACTIVE)) { | ||
| 762 | queue = mvmsta->reserved_queue; | 1320 | queue = mvmsta->reserved_queue; |
| 763 | mvm->queue_info[queue].reserved = true; | 1321 | mvm->queue_info[queue].reserved = true; |
| 764 | IWL_DEBUG_TX_QUEUES(mvm, "Using reserved queue #%d\n", queue); | 1322 | IWL_DEBUG_TX_QUEUES(mvm, "Using reserved queue #%d\n", queue); |
| @@ -768,21 +1326,13 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 768 | queue = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, | 1326 | queue = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id, |
| 769 | IWL_MVM_DQA_MIN_DATA_QUEUE, | 1327 | IWL_MVM_DQA_MIN_DATA_QUEUE, |
| 770 | IWL_MVM_DQA_MAX_DATA_QUEUE); | 1328 | IWL_MVM_DQA_MAX_DATA_QUEUE); |
| 1329 | if (queue < 0) { | ||
| 1330 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 771 | 1331 | ||
| 772 | /* | 1332 | /* try harder - perhaps kill an inactive queue */ |
| 773 | * Check if this queue is already allocated but inactive. | 1333 | queue = iwl_mvm_inactivity_check(mvm, mvmsta->sta_id); |
| 774 | * In such a case, we'll need to first free this queue before enabling | 1334 | |
| 775 | * it again, so we'll mark it as reserved to make sure no new traffic | 1335 | spin_lock_bh(&mvm->queue_info_lock); |
| 776 | * arrives on it | ||
| 777 | */ | ||
| 778 | if (queue > 0 && | ||
| 779 | mvm->queue_info[queue].status == IWL_MVM_QUEUE_INACTIVE) { | ||
| 780 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_RESERVED; | ||
| 781 | using_inactive_queue = true; | ||
| 782 | same_sta = mvm->queue_info[queue].ra_sta_id == mvmsta->sta_id; | ||
| 783 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 784 | "Re-assigning TXQ %d: sta_id=%d, tid=%d\n", | ||
| 785 | queue, mvmsta->sta_id, tid); | ||
| 786 | } | 1336 | } |
| 787 | 1337 | ||
| 788 | /* No free queue - we'll have to share */ | 1338 | /* No free queue - we'll have to share */ |
| @@ -800,7 +1350,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 800 | * This will allow avoiding re-acquiring the lock at the end of the | 1350 | * This will allow avoiding re-acquiring the lock at the end of the |
| 801 | * configuration. On error we'll mark it back as free. | 1351 | * configuration. On error we'll mark it back as free. |
| 802 | */ | 1352 | */ |
| 803 | if ((queue > 0) && !shared_queue) | 1353 | if (queue > 0 && !shared_queue) |
| 804 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY; | 1354 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY; |
| 805 | 1355 | ||
| 806 | spin_unlock_bh(&mvm->queue_info_lock); | 1356 | spin_unlock_bh(&mvm->queue_info_lock); |
| @@ -821,16 +1371,6 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 821 | cfg.aggregate = (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE || | 1371 | cfg.aggregate = (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE || |
| 822 | queue == IWL_MVM_DQA_BSS_CLIENT_QUEUE); | 1372 | queue == IWL_MVM_DQA_BSS_CLIENT_QUEUE); |
| 823 | 1373 | ||
| 824 | /* | ||
| 825 | * If this queue was previously inactive (idle) - we need to free it | ||
| 826 | * first | ||
| 827 | */ | ||
| 828 | if (using_inactive_queue) { | ||
| 829 | ret = iwl_mvm_free_inactive_queue(mvm, queue, same_sta); | ||
| 830 | if (ret) | ||
| 831 | return ret; | ||
| 832 | } | ||
| 833 | |||
| 834 | IWL_DEBUG_TX_QUEUES(mvm, | 1374 | IWL_DEBUG_TX_QUEUES(mvm, |
| 835 | "Allocating %squeue #%d to sta %d on tid %d\n", | 1375 | "Allocating %squeue #%d to sta %d on tid %d\n", |
| 836 | shared_queue ? "shared " : "", queue, | 1376 | shared_queue ? "shared " : "", queue, |
| @@ -874,7 +1414,6 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, | |||
| 874 | if (inc_ssn) | 1414 | if (inc_ssn) |
| 875 | mvmsta->tid_data[tid].seq_number += 0x10; | 1415 | mvmsta->tid_data[tid].seq_number += 0x10; |
| 876 | mvmsta->tid_data[tid].txq_id = queue; | 1416 | mvmsta->tid_data[tid].txq_id = queue; |
| 877 | mvmsta->tid_data[tid].is_tid_active = true; | ||
| 878 | mvmsta->tfd_queue_msk |= BIT(queue); | 1417 | mvmsta->tfd_queue_msk |= BIT(queue); |
| 879 | queue_state = mvmsta->tid_data[tid].state; | 1418 | queue_state = mvmsta->tid_data[tid].state; |
| 880 | 1419 | ||
| @@ -909,129 +1448,6 @@ out_err: | |||
| 909 | return ret; | 1448 | return ret; |
| 910 | } | 1449 | } |
| 911 | 1450 | ||
| 912 | static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue) | ||
| 913 | { | ||
| 914 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 915 | .scd_queue = queue, | ||
| 916 | .action = SCD_CFG_UPDATE_QUEUE_TID, | ||
| 917 | }; | ||
| 918 | int tid; | ||
| 919 | unsigned long tid_bitmap; | ||
| 920 | int ret; | ||
| 921 | |||
| 922 | lockdep_assert_held(&mvm->mutex); | ||
| 923 | |||
| 924 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 925 | return; | ||
| 926 | |||
| 927 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 928 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 929 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 930 | |||
| 931 | if (WARN(!tid_bitmap, "TXQ %d has no tids assigned to it\n", queue)) | ||
| 932 | return; | ||
| 933 | |||
| 934 | /* Find any TID for queue */ | ||
| 935 | tid = find_first_bit(&tid_bitmap, IWL_MAX_TID_COUNT + 1); | ||
| 936 | cmd.tid = tid; | ||
| 937 | cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]]; | ||
| 938 | |||
| 939 | ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd); | ||
| 940 | if (ret) { | ||
| 941 | IWL_ERR(mvm, "Failed to update owner of TXQ %d (ret=%d)\n", | ||
| 942 | queue, ret); | ||
| 943 | return; | ||
| 944 | } | ||
| 945 | |||
| 946 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 947 | mvm->queue_info[queue].txq_tid = tid; | ||
| 948 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 949 | IWL_DEBUG_TX_QUEUES(mvm, "Changed TXQ %d ownership to tid %d\n", | ||
| 950 | queue, tid); | ||
| 951 | } | ||
| 952 | |||
| 953 | static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, int queue) | ||
| 954 | { | ||
| 955 | struct ieee80211_sta *sta; | ||
| 956 | struct iwl_mvm_sta *mvmsta; | ||
| 957 | u8 sta_id; | ||
| 958 | int tid = -1; | ||
| 959 | unsigned long tid_bitmap; | ||
| 960 | unsigned int wdg_timeout; | ||
| 961 | int ssn; | ||
| 962 | int ret = true; | ||
| 963 | |||
| 964 | /* queue sharing is disabled on new TX path */ | ||
| 965 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 966 | return; | ||
| 967 | |||
| 968 | lockdep_assert_held(&mvm->mutex); | ||
| 969 | |||
| 970 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 971 | sta_id = mvm->queue_info[queue].ra_sta_id; | ||
| 972 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 973 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 974 | |||
| 975 | /* Find TID for queue, and make sure it is the only one on the queue */ | ||
| 976 | tid = find_first_bit(&tid_bitmap, IWL_MAX_TID_COUNT + 1); | ||
| 977 | if (tid_bitmap != BIT(tid)) { | ||
| 978 | IWL_ERR(mvm, "Failed to unshare q %d, active tids=0x%lx\n", | ||
| 979 | queue, tid_bitmap); | ||
| 980 | return; | ||
| 981 | } | ||
| 982 | |||
| 983 | IWL_DEBUG_TX_QUEUES(mvm, "Unsharing TXQ %d, keeping tid %d\n", queue, | ||
| 984 | tid); | ||
| 985 | |||
| 986 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
| 987 | lockdep_is_held(&mvm->mutex)); | ||
| 988 | |||
| 989 | if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) | ||
| 990 | return; | ||
| 991 | |||
| 992 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
| 993 | wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); | ||
| 994 | |||
| 995 | ssn = IEEE80211_SEQ_TO_SN(mvmsta->tid_data[tid].seq_number); | ||
| 996 | |||
| 997 | ret = iwl_mvm_scd_queue_redirect(mvm, queue, tid, | ||
| 998 | tid_to_mac80211_ac[tid], ssn, | ||
| 999 | wdg_timeout, true); | ||
| 1000 | if (ret) { | ||
| 1001 | IWL_ERR(mvm, "Failed to redirect TXQ %d\n", queue); | ||
| 1002 | return; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | /* If aggs should be turned back on - do it */ | ||
| 1006 | if (mvmsta->tid_data[tid].state == IWL_AGG_ON) { | ||
| 1007 | struct iwl_mvm_add_sta_cmd cmd = {0}; | ||
| 1008 | |||
| 1009 | mvmsta->tid_disable_agg &= ~BIT(tid); | ||
| 1010 | |||
| 1011 | cmd.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color); | ||
| 1012 | cmd.sta_id = mvmsta->sta_id; | ||
| 1013 | cmd.add_modify = STA_MODE_MODIFY; | ||
| 1014 | cmd.modify_mask = STA_MODIFY_TID_DISABLE_TX; | ||
| 1015 | cmd.tfd_queue_msk = cpu_to_le32(mvmsta->tfd_queue_msk); | ||
| 1016 | cmd.tid_disable_tx = cpu_to_le16(mvmsta->tid_disable_agg); | ||
| 1017 | |||
| 1018 | ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, | ||
| 1019 | iwl_mvm_add_sta_cmd_size(mvm), &cmd); | ||
| 1020 | if (!ret) { | ||
| 1021 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1022 | "TXQ #%d is now aggregated again\n", | ||
| 1023 | queue); | ||
| 1024 | |||
| 1025 | /* Mark queue intenally as aggregating again */ | ||
| 1026 | iwl_trans_txq_set_shared_mode(mvm->trans, queue, false); | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1031 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY; | ||
| 1032 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | static inline u8 iwl_mvm_tid_to_ac_queue(int tid) | 1451 | static inline u8 iwl_mvm_tid_to_ac_queue(int tid) |
| 1036 | { | 1452 | { |
| 1037 | if (tid == IWL_MAX_TID_COUNT) | 1453 | if (tid == IWL_MAX_TID_COUNT) |
| @@ -1100,47 +1516,12 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk) | |||
| 1100 | struct ieee80211_sta *sta; | 1516 | struct ieee80211_sta *sta; |
| 1101 | struct iwl_mvm_sta *mvmsta; | 1517 | struct iwl_mvm_sta *mvmsta; |
| 1102 | unsigned long deferred_tid_traffic; | 1518 | unsigned long deferred_tid_traffic; |
| 1103 | int queue, sta_id, tid; | 1519 | int sta_id, tid; |
| 1104 | |||
| 1105 | /* Check inactivity of queues */ | ||
| 1106 | iwl_mvm_inactivity_check(mvm); | ||
| 1107 | 1520 | ||
| 1108 | mutex_lock(&mvm->mutex); | 1521 | mutex_lock(&mvm->mutex); |
| 1109 | 1522 | ||
| 1110 | /* No queue reconfiguration in TVQM mode */ | 1523 | iwl_mvm_inactivity_check(mvm, IWL_MVM_INVALID_STA); |
| 1111 | if (iwl_mvm_has_new_tx_api(mvm)) | ||
| 1112 | goto alloc_queues; | ||
| 1113 | |||
| 1114 | /* Reconfigure queues requiring reconfiguation */ | ||
| 1115 | for (queue = 0; queue < ARRAY_SIZE(mvm->queue_info); queue++) { | ||
| 1116 | bool reconfig; | ||
| 1117 | bool change_owner; | ||
| 1118 | |||
| 1119 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1120 | reconfig = (mvm->queue_info[queue].status == | ||
| 1121 | IWL_MVM_QUEUE_RECONFIGURING); | ||
| 1122 | 1524 | ||
| 1123 | /* | ||
| 1124 | * We need to take into account a situation in which a TXQ was | ||
| 1125 | * allocated to TID x, and then turned shared by adding TIDs y | ||
| 1126 | * and z. If TID x becomes inactive and is removed from the TXQ, | ||
| 1127 | * ownership must be given to one of the remaining TIDs. | ||
| 1128 | * This is mainly because if TID x continues - a new queue can't | ||
| 1129 | * be allocated for it as long as it is an owner of another TXQ. | ||
| 1130 | */ | ||
| 1131 | change_owner = !(mvm->queue_info[queue].tid_bitmap & | ||
| 1132 | BIT(mvm->queue_info[queue].txq_tid)) && | ||
| 1133 | (mvm->queue_info[queue].status == | ||
| 1134 | IWL_MVM_QUEUE_SHARED); | ||
| 1135 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1136 | |||
| 1137 | if (reconfig) | ||
| 1138 | iwl_mvm_unshare_queue(mvm, queue); | ||
| 1139 | else if (change_owner) | ||
| 1140 | iwl_mvm_change_queue_owner(mvm, queue); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | alloc_queues: | ||
| 1144 | /* Go over all stations with deferred traffic */ | 1525 | /* Go over all stations with deferred traffic */ |
| 1145 | for_each_set_bit(sta_id, mvm->sta_deferred_frames, | 1526 | for_each_set_bit(sta_id, mvm->sta_deferred_frames, |
| 1146 | IWL_MVM_STATION_COUNT) { | 1527 | IWL_MVM_STATION_COUNT) { |
| @@ -1167,23 +1548,19 @@ static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm, | |||
| 1167 | { | 1548 | { |
| 1168 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 1549 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
| 1169 | int queue; | 1550 | int queue; |
| 1170 | bool using_inactive_queue = false, same_sta = false; | ||
| 1171 | 1551 | ||
| 1172 | /* queue reserving is disabled on new TX path */ | 1552 | /* queue reserving is disabled on new TX path */ |
| 1173 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | 1553 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) |
| 1174 | return 0; | 1554 | return 0; |
| 1175 | 1555 | ||
| 1176 | /* | 1556 | /* run the general cleanup/unsharing of queues */ |
| 1177 | * Check for inactive queues, so we don't reach a situation where we | 1557 | iwl_mvm_inactivity_check(mvm, IWL_MVM_INVALID_STA); |
| 1178 | * can't add a STA due to a shortage in queues that doesn't really exist | ||
| 1179 | */ | ||
| 1180 | iwl_mvm_inactivity_check(mvm); | ||
| 1181 | 1558 | ||
| 1182 | spin_lock_bh(&mvm->queue_info_lock); | 1559 | spin_lock_bh(&mvm->queue_info_lock); |
| 1183 | 1560 | ||
| 1184 | /* Make sure we have free resources for this STA */ | 1561 | /* Make sure we have free resources for this STA */ |
| 1185 | if (vif_type == NL80211_IFTYPE_STATION && !sta->tdls && | 1562 | if (vif_type == NL80211_IFTYPE_STATION && !sta->tdls && |
| 1186 | !mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].hw_queue_refcount && | 1563 | !mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].tid_bitmap && |
| 1187 | (mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].status == | 1564 | (mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].status == |
| 1188 | IWL_MVM_QUEUE_FREE)) | 1565 | IWL_MVM_QUEUE_FREE)) |
| 1189 | queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE; | 1566 | queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE; |
| @@ -1193,16 +1570,13 @@ static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm, | |||
| 1193 | IWL_MVM_DQA_MAX_DATA_QUEUE); | 1570 | IWL_MVM_DQA_MAX_DATA_QUEUE); |
| 1194 | if (queue < 0) { | 1571 | if (queue < 0) { |
| 1195 | spin_unlock_bh(&mvm->queue_info_lock); | 1572 | spin_unlock_bh(&mvm->queue_info_lock); |
| 1196 | IWL_ERR(mvm, "No available queues for new station\n"); | 1573 | /* try again - this time kick out a queue if needed */ |
| 1197 | return -ENOSPC; | 1574 | queue = iwl_mvm_inactivity_check(mvm, mvmsta->sta_id); |
| 1198 | } else if (mvm->queue_info[queue].status == IWL_MVM_QUEUE_INACTIVE) { | 1575 | if (queue < 0) { |
| 1199 | /* | 1576 | IWL_ERR(mvm, "No available queues for new station\n"); |
| 1200 | * If this queue is already allocated but inactive we'll need to | 1577 | return -ENOSPC; |
| 1201 | * first free this queue before enabling it again, we'll mark | 1578 | } |
| 1202 | * it as reserved to make sure no new traffic arrives on it | 1579 | spin_lock_bh(&mvm->queue_info_lock); |
| 1203 | */ | ||
| 1204 | using_inactive_queue = true; | ||
| 1205 | same_sta = mvm->queue_info[queue].ra_sta_id == mvmsta->sta_id; | ||
| 1206 | } | 1580 | } |
| 1207 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_RESERVED; | 1581 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_RESERVED; |
| 1208 | 1582 | ||
| @@ -1210,9 +1584,6 @@ static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm, | |||
| 1210 | 1584 | ||
| 1211 | mvmsta->reserved_queue = queue; | 1585 | mvmsta->reserved_queue = queue; |
| 1212 | 1586 | ||
| 1213 | if (using_inactive_queue) | ||
| 1214 | iwl_mvm_free_inactive_queue(mvm, queue, same_sta); | ||
| 1215 | |||
| 1216 | IWL_DEBUG_TX_QUEUES(mvm, "Reserving data queue #%d for sta_id %d\n", | 1587 | IWL_DEBUG_TX_QUEUES(mvm, "Reserving data queue #%d for sta_id %d\n", |
| 1217 | queue, mvmsta->sta_id); | 1588 | queue, mvmsta->sta_id); |
| 1218 | 1589 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index 0fc211108149..de1a0a2d8723 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h | |||
| @@ -312,9 +312,6 @@ enum iwl_mvm_agg_state { | |||
| 312 | * Basically when next_reclaimed reaches ssn, we can tell mac80211 that | 312 | * Basically when next_reclaimed reaches ssn, we can tell mac80211 that |
| 313 | * we are ready to finish the Tx AGG stop / start flow. | 313 | * we are ready to finish the Tx AGG stop / start flow. |
| 314 | * @tx_time: medium time consumed by this A-MPDU | 314 | * @tx_time: medium time consumed by this A-MPDU |
| 315 | * @is_tid_active: has this TID sent traffic in the last | ||
| 316 | * %IWL_MVM_DQA_QUEUE_TIMEOUT time period. If %txq_id is invalid, this | ||
| 317 | * field should be ignored. | ||
| 318 | * @tpt_meas_start: time of the throughput measurements start, is reset every HZ | 315 | * @tpt_meas_start: time of the throughput measurements start, is reset every HZ |
| 319 | * @tx_count_last: number of frames transmitted during the last second | 316 | * @tx_count_last: number of frames transmitted during the last second |
| 320 | * @tx_count: counts the number of frames transmitted since the last reset of | 317 | * @tx_count: counts the number of frames transmitted since the last reset of |
| @@ -332,7 +329,6 @@ struct iwl_mvm_tid_data { | |||
| 332 | u16 txq_id; | 329 | u16 txq_id; |
| 333 | u16 ssn; | 330 | u16 ssn; |
| 334 | u16 tx_time; | 331 | u16 tx_time; |
| 335 | bool is_tid_active; | ||
| 336 | unsigned long tpt_meas_start; | 332 | unsigned long tpt_meas_start; |
| 337 | u32 tx_count_last; | 333 | u32 tx_count_last; |
| 338 | u32 tx_count; | 334 | u32 tx_count; |
| @@ -572,8 +568,4 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm, | |||
| 572 | void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 568 | void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 573 | void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk); | 569 | void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk); |
| 574 | 570 | ||
| 575 | int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid, | ||
| 576 | int ac, int ssn, unsigned int wdg_timeout, | ||
| 577 | bool force); | ||
| 578 | |||
| 579 | #endif /* __sta_h__ */ | 571 | #endif /* __sta_h__ */ |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 99c64ea2619b..ec57682efe54 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
| @@ -1140,32 +1140,16 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 1140 | WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); | 1140 | WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); |
| 1141 | 1141 | ||
| 1142 | /* Check if TXQ needs to be allocated or re-activated */ | 1142 | /* Check if TXQ needs to be allocated or re-activated */ |
| 1143 | if (unlikely(txq_id == IWL_MVM_INVALID_QUEUE || | 1143 | if (unlikely(txq_id == IWL_MVM_INVALID_QUEUE)) { |
| 1144 | !mvmsta->tid_data[tid].is_tid_active)) { | 1144 | iwl_mvm_tx_add_stream(mvm, mvmsta, tid, skb); |
| 1145 | /* If TXQ needs to be allocated... */ | ||
| 1146 | if (txq_id == IWL_MVM_INVALID_QUEUE) { | ||
| 1147 | iwl_mvm_tx_add_stream(mvm, mvmsta, tid, skb); | ||
| 1148 | 1145 | ||
| 1149 | /* | 1146 | /* |
| 1150 | * The frame is now deferred, and the worker scheduled | 1147 | * The frame is now deferred, and the worker scheduled |
| 1151 | * will re-allocate it, so we can free it for now. | 1148 | * will re-allocate it, so we can free it for now. |
| 1152 | */ | 1149 | */ |
| 1153 | iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); | 1150 | iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); |
| 1154 | spin_unlock(&mvmsta->lock); | 1151 | spin_unlock(&mvmsta->lock); |
| 1155 | return 0; | 1152 | return 0; |
| 1156 | } | ||
| 1157 | |||
| 1158 | /* queue should always be active in new TX path */ | ||
| 1159 | WARN_ON(iwl_mvm_has_new_tx_api(mvm)); | ||
| 1160 | |||
| 1161 | /* If we are here - TXQ exists and needs to be re-activated */ | ||
| 1162 | spin_lock(&mvm->queue_info_lock); | ||
| 1163 | mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_READY; | ||
| 1164 | mvmsta->tid_data[tid].is_tid_active = true; | ||
| 1165 | spin_unlock(&mvm->queue_info_lock); | ||
| 1166 | |||
| 1167 | IWL_DEBUG_TX_QUEUES(mvm, "Re-activating queue %d for TX\n", | ||
| 1168 | txq_id); | ||
| 1169 | } | 1153 | } |
| 1170 | 1154 | ||
| 1171 | if (!iwl_mvm_has_new_tx_api(mvm)) { | 1155 | if (!iwl_mvm_has_new_tx_api(mvm)) { |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 6c14d3413bdc..818e1180bbdd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c | |||
| @@ -599,36 +599,6 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | |||
| 599 | iwl_mvm_dump_umac_error_log(mvm); | 599 | iwl_mvm_dump_umac_error_log(mvm); |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq) | ||
| 603 | { | ||
| 604 | int i; | ||
| 605 | |||
| 606 | lockdep_assert_held(&mvm->queue_info_lock); | ||
| 607 | |||
| 608 | /* This should not be hit with new TX path */ | ||
| 609 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 610 | return -ENOSPC; | ||
| 611 | |||
| 612 | /* Start by looking for a free queue */ | ||
| 613 | for (i = minq; i <= maxq; i++) | ||
| 614 | if (mvm->queue_info[i].hw_queue_refcount == 0 && | ||
| 615 | mvm->queue_info[i].status == IWL_MVM_QUEUE_FREE) | ||
| 616 | return i; | ||
| 617 | |||
| 618 | /* | ||
| 619 | * If no free queue found - settle for an inactive one to reconfigure | ||
| 620 | * Make sure that the inactive queue either already belongs to this STA, | ||
| 621 | * or that if it belongs to another one - it isn't the reserved queue | ||
| 622 | */ | ||
| 623 | for (i = minq; i <= maxq; i++) | ||
| 624 | if (mvm->queue_info[i].status == IWL_MVM_QUEUE_INACTIVE && | ||
| 625 | (sta_id == mvm->queue_info[i].ra_sta_id || | ||
| 626 | !mvm->queue_info[i].reserved)) | ||
| 627 | return i; | ||
| 628 | |||
| 629 | return -ENOSPC; | ||
| 630 | } | ||
| 631 | |||
| 632 | int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, | 602 | int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, |
| 633 | int tid, int frame_limit, u16 ssn) | 603 | int tid, int frame_limit, u16 ssn) |
| 634 | { | 604 | { |
| @@ -649,7 +619,7 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, | |||
| 649 | return -EINVAL; | 619 | return -EINVAL; |
| 650 | 620 | ||
| 651 | spin_lock_bh(&mvm->queue_info_lock); | 621 | spin_lock_bh(&mvm->queue_info_lock); |
| 652 | if (WARN(mvm->queue_info[queue].hw_queue_refcount == 0, | 622 | if (WARN(mvm->queue_info[queue].tid_bitmap == 0, |
| 653 | "Trying to reconfig unallocated queue %d\n", queue)) { | 623 | "Trying to reconfig unallocated queue %d\n", queue)) { |
| 654 | spin_unlock_bh(&mvm->queue_info_lock); | 624 | spin_unlock_bh(&mvm->queue_info_lock); |
| 655 | return -ENXIO; | 625 | return -ENXIO; |
| @@ -665,229 +635,6 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, | |||
| 665 | return ret; | 635 | return ret; |
| 666 | } | 636 | } |
| 667 | 637 | ||
| 668 | static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, | ||
| 669 | int mac80211_queue, u8 sta_id, u8 tid) | ||
| 670 | { | ||
| 671 | bool enable_queue = true; | ||
| 672 | |||
| 673 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 674 | |||
| 675 | /* Make sure this TID isn't already enabled */ | ||
| 676 | if (mvm->queue_info[queue].tid_bitmap & BIT(tid)) { | ||
| 677 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 678 | IWL_ERR(mvm, "Trying to enable TXQ %d with existing TID %d\n", | ||
| 679 | queue, tid); | ||
| 680 | return false; | ||
| 681 | } | ||
| 682 | |||
| 683 | /* Update mappings and refcounts */ | ||
| 684 | if (mvm->queue_info[queue].hw_queue_refcount > 0) | ||
| 685 | enable_queue = false; | ||
| 686 | |||
| 687 | if (mac80211_queue != IEEE80211_INVAL_HW_QUEUE) { | ||
| 688 | WARN(mac80211_queue >= | ||
| 689 | BITS_PER_BYTE * sizeof(mvm->hw_queue_to_mac80211[0]), | ||
| 690 | "cannot track mac80211 queue %d (queue %d, sta %d, tid %d)\n", | ||
| 691 | mac80211_queue, queue, sta_id, tid); | ||
| 692 | mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); | ||
| 693 | } | ||
| 694 | |||
| 695 | mvm->queue_info[queue].hw_queue_refcount++; | ||
| 696 | mvm->queue_info[queue].tid_bitmap |= BIT(tid); | ||
| 697 | mvm->queue_info[queue].ra_sta_id = sta_id; | ||
| 698 | |||
| 699 | if (enable_queue) { | ||
| 700 | if (tid != IWL_MAX_TID_COUNT) | ||
| 701 | mvm->queue_info[queue].mac80211_ac = | ||
| 702 | tid_to_mac80211_ac[tid]; | ||
| 703 | else | ||
| 704 | mvm->queue_info[queue].mac80211_ac = IEEE80211_AC_VO; | ||
| 705 | |||
| 706 | mvm->queue_info[queue].txq_tid = tid; | ||
| 707 | } | ||
| 708 | |||
| 709 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 710 | "Enabling TXQ #%d refcount=%d (mac80211 map:0x%x)\n", | ||
| 711 | queue, mvm->queue_info[queue].hw_queue_refcount, | ||
| 712 | mvm->hw_queue_to_mac80211[queue]); | ||
| 713 | |||
| 714 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 715 | |||
| 716 | return enable_queue; | ||
| 717 | } | ||
| 718 | |||
| 719 | int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, | ||
| 720 | u8 sta_id, u8 tid, unsigned int timeout) | ||
| 721 | { | ||
| 722 | int queue, size = IWL_DEFAULT_QUEUE_SIZE; | ||
| 723 | |||
| 724 | if (tid == IWL_MAX_TID_COUNT) { | ||
| 725 | tid = IWL_MGMT_TID; | ||
| 726 | size = IWL_MGMT_QUEUE_SIZE; | ||
| 727 | } | ||
| 728 | queue = iwl_trans_txq_alloc(mvm->trans, | ||
| 729 | cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), | ||
| 730 | sta_id, tid, SCD_QUEUE_CFG, size, timeout); | ||
| 731 | |||
| 732 | if (queue < 0) { | ||
| 733 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 734 | "Failed allocating TXQ for sta %d tid %d, ret: %d\n", | ||
| 735 | sta_id, tid, queue); | ||
| 736 | return queue; | ||
| 737 | } | ||
| 738 | |||
| 739 | IWL_DEBUG_TX_QUEUES(mvm, "Enabling TXQ #%d for sta %d tid %d\n", | ||
| 740 | queue, sta_id, tid); | ||
| 741 | |||
| 742 | mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); | ||
| 743 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 744 | "Enabling TXQ #%d (mac80211 map:0x%x)\n", | ||
| 745 | queue, mvm->hw_queue_to_mac80211[queue]); | ||
| 746 | |||
| 747 | return queue; | ||
| 748 | } | ||
| 749 | |||
| 750 | bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, | ||
| 751 | u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg, | ||
| 752 | unsigned int wdg_timeout) | ||
| 753 | { | ||
| 754 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 755 | .scd_queue = queue, | ||
| 756 | .action = SCD_CFG_ENABLE_QUEUE, | ||
| 757 | .window = cfg->frame_limit, | ||
| 758 | .sta_id = cfg->sta_id, | ||
| 759 | .ssn = cpu_to_le16(ssn), | ||
| 760 | .tx_fifo = cfg->fifo, | ||
| 761 | .aggregate = cfg->aggregate, | ||
| 762 | .tid = cfg->tid, | ||
| 763 | }; | ||
| 764 | bool inc_ssn; | ||
| 765 | |||
| 766 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 767 | return false; | ||
| 768 | |||
| 769 | /* Send the enabling command if we need to */ | ||
| 770 | if (!iwl_mvm_update_txq_mapping(mvm, queue, mac80211_queue, | ||
| 771 | cfg->sta_id, cfg->tid)) | ||
| 772 | return false; | ||
| 773 | |||
| 774 | inc_ssn = iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, | ||
| 775 | NULL, wdg_timeout); | ||
| 776 | if (inc_ssn) | ||
| 777 | le16_add_cpu(&cmd.ssn, 1); | ||
| 778 | |||
| 779 | WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd), | ||
| 780 | "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo); | ||
| 781 | |||
| 782 | return inc_ssn; | ||
| 783 | } | ||
| 784 | |||
| 785 | int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, | ||
| 786 | u8 tid, u8 flags) | ||
| 787 | { | ||
| 788 | struct iwl_scd_txq_cfg_cmd cmd = { | ||
| 789 | .scd_queue = queue, | ||
| 790 | .action = SCD_CFG_DISABLE_QUEUE, | ||
| 791 | }; | ||
| 792 | bool remove_mac_queue = mac80211_queue != IEEE80211_INVAL_HW_QUEUE; | ||
| 793 | int ret; | ||
| 794 | |||
| 795 | if (WARN_ON(remove_mac_queue && mac80211_queue >= IEEE80211_MAX_QUEUES)) | ||
| 796 | return -EINVAL; | ||
| 797 | |||
| 798 | if (iwl_mvm_has_new_tx_api(mvm)) { | ||
| 799 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 800 | |||
| 801 | if (remove_mac_queue) | ||
| 802 | mvm->hw_queue_to_mac80211[queue] &= | ||
| 803 | ~BIT(mac80211_queue); | ||
| 804 | |||
| 805 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 806 | |||
| 807 | iwl_trans_txq_free(mvm->trans, queue); | ||
| 808 | |||
| 809 | return 0; | ||
| 810 | } | ||
| 811 | |||
| 812 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 813 | |||
| 814 | if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) { | ||
| 815 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 816 | return 0; | ||
| 817 | } | ||
| 818 | |||
| 819 | mvm->queue_info[queue].tid_bitmap &= ~BIT(tid); | ||
| 820 | |||
| 821 | /* | ||
| 822 | * If there is another TID with the same AC - don't remove the MAC queue | ||
| 823 | * from the mapping | ||
| 824 | */ | ||
| 825 | if (tid < IWL_MAX_TID_COUNT) { | ||
| 826 | unsigned long tid_bitmap = | ||
| 827 | mvm->queue_info[queue].tid_bitmap; | ||
| 828 | int ac = tid_to_mac80211_ac[tid]; | ||
| 829 | int i; | ||
| 830 | |||
| 831 | for_each_set_bit(i, &tid_bitmap, IWL_MAX_TID_COUNT) { | ||
| 832 | if (tid_to_mac80211_ac[i] == ac) | ||
| 833 | remove_mac_queue = false; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | |||
| 837 | if (remove_mac_queue) | ||
| 838 | mvm->hw_queue_to_mac80211[queue] &= | ||
| 839 | ~BIT(mac80211_queue); | ||
| 840 | mvm->queue_info[queue].hw_queue_refcount--; | ||
| 841 | |||
| 842 | cmd.action = mvm->queue_info[queue].hw_queue_refcount ? | ||
| 843 | SCD_CFG_ENABLE_QUEUE : SCD_CFG_DISABLE_QUEUE; | ||
| 844 | if (cmd.action == SCD_CFG_DISABLE_QUEUE) | ||
| 845 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE; | ||
| 846 | |||
| 847 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 848 | "Disabling TXQ #%d refcount=%d (mac80211 map:0x%x)\n", | ||
| 849 | queue, | ||
| 850 | mvm->queue_info[queue].hw_queue_refcount, | ||
| 851 | mvm->hw_queue_to_mac80211[queue]); | ||
| 852 | |||
| 853 | /* If the queue is still enabled - nothing left to do in this func */ | ||
| 854 | if (cmd.action == SCD_CFG_ENABLE_QUEUE) { | ||
| 855 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 856 | return 0; | ||
| 857 | } | ||
| 858 | |||
| 859 | cmd.sta_id = mvm->queue_info[queue].ra_sta_id; | ||
| 860 | cmd.tid = mvm->queue_info[queue].txq_tid; | ||
| 861 | |||
| 862 | /* Make sure queue info is correct even though we overwrite it */ | ||
| 863 | WARN(mvm->queue_info[queue].hw_queue_refcount || | ||
| 864 | mvm->queue_info[queue].tid_bitmap || | ||
| 865 | mvm->hw_queue_to_mac80211[queue], | ||
| 866 | "TXQ #%d info out-of-sync - refcount=%d, mac map=0x%x, tid=0x%x\n", | ||
| 867 | queue, mvm->queue_info[queue].hw_queue_refcount, | ||
| 868 | mvm->hw_queue_to_mac80211[queue], | ||
| 869 | mvm->queue_info[queue].tid_bitmap); | ||
| 870 | |||
| 871 | /* If we are here - the queue is freed and we can zero out these vals */ | ||
| 872 | mvm->queue_info[queue].hw_queue_refcount = 0; | ||
| 873 | mvm->queue_info[queue].tid_bitmap = 0; | ||
| 874 | mvm->hw_queue_to_mac80211[queue] = 0; | ||
| 875 | |||
| 876 | /* Regardless if this is a reserved TXQ for a STA - mark it as false */ | ||
| 877 | mvm->queue_info[queue].reserved = false; | ||
| 878 | |||
| 879 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 880 | |||
| 881 | iwl_trans_txq_disable(mvm->trans, queue, false); | ||
| 882 | ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags, | ||
| 883 | sizeof(struct iwl_scd_txq_cfg_cmd), &cmd); | ||
| 884 | |||
| 885 | if (ret) | ||
| 886 | IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n", | ||
| 887 | queue, ret); | ||
| 888 | return ret; | ||
| 889 | } | ||
| 890 | |||
| 891 | /** | 638 | /** |
| 892 | * iwl_mvm_send_lq_cmd() - Send link quality command | 639 | * iwl_mvm_send_lq_cmd() - Send link quality command |
| 893 | * @sync: This command can be sent synchronously. | 640 | * @sync: This command can be sent synchronously. |
| @@ -1255,171 +1002,6 @@ out: | |||
| 1255 | ieee80211_connection_loss(vif); | 1002 | ieee80211_connection_loss(vif); |
| 1256 | } | 1003 | } |
| 1257 | 1004 | ||
| 1258 | /* | ||
| 1259 | * Remove inactive TIDs of a given queue. | ||
| 1260 | * If all queue TIDs are inactive - mark the queue as inactive | ||
| 1261 | * If only some the queue TIDs are inactive - unmap them from the queue | ||
| 1262 | */ | ||
| 1263 | static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm, | ||
| 1264 | struct iwl_mvm_sta *mvmsta, int queue, | ||
| 1265 | unsigned long tid_bitmap) | ||
| 1266 | { | ||
| 1267 | int tid; | ||
| 1268 | |||
| 1269 | lockdep_assert_held(&mvmsta->lock); | ||
| 1270 | lockdep_assert_held(&mvm->queue_info_lock); | ||
| 1271 | |||
| 1272 | if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) | ||
| 1273 | return; | ||
| 1274 | |||
| 1275 | /* Go over all non-active TIDs, incl. IWL_MAX_TID_COUNT (for mgmt) */ | ||
| 1276 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1277 | /* If some TFDs are still queued - don't mark TID as inactive */ | ||
| 1278 | if (iwl_mvm_tid_queued(mvm, &mvmsta->tid_data[tid])) | ||
| 1279 | tid_bitmap &= ~BIT(tid); | ||
| 1280 | |||
| 1281 | /* Don't mark as inactive any TID that has an active BA */ | ||
| 1282 | if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) | ||
| 1283 | tid_bitmap &= ~BIT(tid); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /* If all TIDs in the queue are inactive - mark queue as inactive. */ | ||
| 1287 | if (tid_bitmap == mvm->queue_info[queue].tid_bitmap) { | ||
| 1288 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_INACTIVE; | ||
| 1289 | |||
| 1290 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) | ||
| 1291 | mvmsta->tid_data[tid].is_tid_active = false; | ||
| 1292 | |||
| 1293 | IWL_DEBUG_TX_QUEUES(mvm, "Queue %d marked as inactive\n", | ||
| 1294 | queue); | ||
| 1295 | return; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | /* | ||
| 1299 | * If we are here, this is a shared queue and not all TIDs timed-out. | ||
| 1300 | * Remove the ones that did. | ||
| 1301 | */ | ||
| 1302 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1303 | int mac_queue = mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]]; | ||
| 1304 | |||
| 1305 | mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE; | ||
| 1306 | mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac_queue); | ||
| 1307 | mvm->queue_info[queue].hw_queue_refcount--; | ||
| 1308 | mvm->queue_info[queue].tid_bitmap &= ~BIT(tid); | ||
| 1309 | mvmsta->tid_data[tid].is_tid_active = false; | ||
| 1310 | |||
| 1311 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1312 | "Removing inactive TID %d from shared Q:%d\n", | ||
| 1313 | tid, queue); | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | IWL_DEBUG_TX_QUEUES(mvm, | ||
| 1317 | "TXQ #%d left with tid bitmap 0x%x\n", queue, | ||
| 1318 | mvm->queue_info[queue].tid_bitmap); | ||
| 1319 | |||
| 1320 | /* | ||
| 1321 | * There may be different TIDs with the same mac queues, so make | ||
| 1322 | * sure all TIDs have existing corresponding mac queues enabled | ||
| 1323 | */ | ||
| 1324 | tid_bitmap = mvm->queue_info[queue].tid_bitmap; | ||
| 1325 | for_each_set_bit(tid, &tid_bitmap, IWL_MAX_TID_COUNT + 1) { | ||
| 1326 | mvm->hw_queue_to_mac80211[queue] |= | ||
| 1327 | BIT(mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]]); | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | /* If the queue is marked as shared - "unshare" it */ | ||
| 1331 | if (mvm->queue_info[queue].hw_queue_refcount == 1 && | ||
| 1332 | mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED) { | ||
| 1333 | mvm->queue_info[queue].status = IWL_MVM_QUEUE_RECONFIGURING; | ||
| 1334 | IWL_DEBUG_TX_QUEUES(mvm, "Marking Q:%d for reconfig\n", | ||
| 1335 | queue); | ||
| 1336 | } | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | void iwl_mvm_inactivity_check(struct iwl_mvm *mvm) | ||
| 1340 | { | ||
| 1341 | unsigned long timeout_queues_map = 0; | ||
| 1342 | unsigned long now = jiffies; | ||
| 1343 | int i; | ||
| 1344 | |||
| 1345 | if (iwl_mvm_has_new_tx_api(mvm)) | ||
| 1346 | return; | ||
| 1347 | |||
| 1348 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1349 | for (i = 0; i < IWL_MAX_HW_QUEUES; i++) | ||
| 1350 | if (mvm->queue_info[i].hw_queue_refcount > 0) | ||
| 1351 | timeout_queues_map |= BIT(i); | ||
| 1352 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1353 | |||
| 1354 | rcu_read_lock(); | ||
| 1355 | |||
| 1356 | /* | ||
| 1357 | * If a queue time outs - mark it as INACTIVE (don't remove right away | ||
| 1358 | * if we don't have to.) This is an optimization in case traffic comes | ||
| 1359 | * later, and we don't HAVE to use a currently-inactive queue | ||
| 1360 | */ | ||
| 1361 | for_each_set_bit(i, &timeout_queues_map, IWL_MAX_HW_QUEUES) { | ||
| 1362 | struct ieee80211_sta *sta; | ||
| 1363 | struct iwl_mvm_sta *mvmsta; | ||
| 1364 | u8 sta_id; | ||
| 1365 | int tid; | ||
| 1366 | unsigned long inactive_tid_bitmap = 0; | ||
| 1367 | unsigned long queue_tid_bitmap; | ||
| 1368 | |||
| 1369 | spin_lock_bh(&mvm->queue_info_lock); | ||
| 1370 | queue_tid_bitmap = mvm->queue_info[i].tid_bitmap; | ||
| 1371 | |||
| 1372 | /* If TXQ isn't in active use anyway - nothing to do here... */ | ||
| 1373 | if (mvm->queue_info[i].status != IWL_MVM_QUEUE_READY && | ||
| 1374 | mvm->queue_info[i].status != IWL_MVM_QUEUE_SHARED) { | ||
| 1375 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1376 | continue; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | /* Check to see if there are inactive TIDs on this queue */ | ||
| 1380 | for_each_set_bit(tid, &queue_tid_bitmap, | ||
| 1381 | IWL_MAX_TID_COUNT + 1) { | ||
| 1382 | if (time_after(mvm->queue_info[i].last_frame_time[tid] + | ||
| 1383 | IWL_MVM_DQA_QUEUE_TIMEOUT, now)) | ||
| 1384 | continue; | ||
| 1385 | |||
| 1386 | inactive_tid_bitmap |= BIT(tid); | ||
| 1387 | } | ||
| 1388 | spin_unlock_bh(&mvm->queue_info_lock); | ||
| 1389 | |||
| 1390 | /* If all TIDs are active - finish check on this queue */ | ||
| 1391 | if (!inactive_tid_bitmap) | ||
| 1392 | continue; | ||
| 1393 | |||
| 1394 | /* | ||
| 1395 | * If we are here - the queue hadn't been served recently and is | ||
| 1396 | * in use | ||
| 1397 | */ | ||
| 1398 | |||
| 1399 | sta_id = mvm->queue_info[i].ra_sta_id; | ||
| 1400 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
| 1401 | |||
| 1402 | /* | ||
| 1403 | * If the STA doesn't exist anymore, it isn't an error. It could | ||
| 1404 | * be that it was removed since getting the queues, and in this | ||
| 1405 | * case it should've inactivated its queues anyway. | ||
| 1406 | */ | ||
| 1407 | if (IS_ERR_OR_NULL(sta)) | ||
| 1408 | continue; | ||
| 1409 | |||
| 1410 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
| 1411 | |||
| 1412 | spin_lock_bh(&mvmsta->lock); | ||
| 1413 | spin_lock(&mvm->queue_info_lock); | ||
| 1414 | iwl_mvm_remove_inactive_tids(mvm, mvmsta, i, | ||
| 1415 | inactive_tid_bitmap); | ||
| 1416 | spin_unlock(&mvm->queue_info_lock); | ||
| 1417 | spin_unlock_bh(&mvmsta->lock); | ||
| 1418 | } | ||
| 1419 | |||
| 1420 | rcu_read_unlock(); | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm, | 1005 | void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm, |
| 1424 | struct ieee80211_vif *vif, | 1006 | struct ieee80211_vif *vif, |
| 1425 | const struct ieee80211_sta *sta, | 1007 | const struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index b71cf55480fc..e880f69eac26 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | |||
| @@ -330,7 +330,7 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, | |||
| 330 | goto out_err; | 330 | goto out_err; |
| 331 | } | 331 | } |
| 332 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len); | 332 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len); |
| 333 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, tb_len); | 333 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, tb_len); |
| 334 | /* add this subframe's headers' length to the tx_cmd */ | 334 | /* add this subframe's headers' length to the tx_cmd */ |
| 335 | le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); | 335 | le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); |
| 336 | 336 | ||
| @@ -347,8 +347,8 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, | |||
| 347 | goto out_err; | 347 | goto out_err; |
| 348 | } | 348 | } |
| 349 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len); | 349 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len); |
| 350 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, tso.data, | 350 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data, |
| 351 | tb_len); | 351 | tb_len); |
| 352 | 352 | ||
| 353 | data_left -= tb_len; | 353 | data_left -= tb_len; |
| 354 | tso_build_data(skb, &tso, tb_len); | 354 | tso_build_data(skb, &tso, tb_len); |
| @@ -438,6 +438,9 @@ static int iwl_pcie_gen2_tx_add_frags(struct iwl_trans *trans, | |||
| 438 | return -ENOMEM; | 438 | return -ENOMEM; |
| 439 | tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, | 439 | tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, |
| 440 | skb_frag_size(frag)); | 440 | skb_frag_size(frag)); |
| 441 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, | ||
| 442 | skb_frag_address(frag), | ||
| 443 | skb_frag_size(frag)); | ||
| 441 | if (tb_idx < 0) | 444 | if (tb_idx < 0) |
| 442 | return tb_idx; | 445 | return tb_idx; |
| 443 | 446 | ||
| @@ -454,7 +457,8 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, | |||
| 454 | struct sk_buff *skb, | 457 | struct sk_buff *skb, |
| 455 | struct iwl_cmd_meta *out_meta, | 458 | struct iwl_cmd_meta *out_meta, |
| 456 | int hdr_len, | 459 | int hdr_len, |
| 457 | int tx_cmd_len) | 460 | int tx_cmd_len, |
| 461 | bool pad) | ||
| 458 | { | 462 | { |
| 459 | int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); | 463 | int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); |
| 460 | struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx); | 464 | struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx); |
| @@ -478,7 +482,10 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, | |||
| 478 | len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len - | 482 | len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len - |
| 479 | IWL_FIRST_TB_SIZE; | 483 | IWL_FIRST_TB_SIZE; |
| 480 | 484 | ||
| 481 | tb1_len = ALIGN(len, 4); | 485 | if (pad) |
| 486 | tb1_len = ALIGN(len, 4); | ||
| 487 | else | ||
| 488 | tb1_len = len; | ||
| 482 | 489 | ||
| 483 | /* map the data for TB1 */ | 490 | /* map the data for TB1 */ |
| 484 | tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE; | 491 | tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE; |
| @@ -486,6 +493,8 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, | |||
| 486 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) | 493 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) |
| 487 | goto out_err; | 494 | goto out_err; |
| 488 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb1_len); | 495 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb1_len); |
| 496 | trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr, | ||
| 497 | IWL_FIRST_TB_SIZE + tb1_len, hdr_len); | ||
| 489 | 498 | ||
| 490 | /* set up TFD's third entry to point to remainder of skb's head */ | 499 | /* set up TFD's third entry to point to remainder of skb's head */ |
| 491 | tb2_len = skb_headlen(skb) - hdr_len; | 500 | tb2_len = skb_headlen(skb) - hdr_len; |
| @@ -496,15 +505,14 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, | |||
| 496 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) | 505 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) |
| 497 | goto out_err; | 506 | goto out_err; |
| 498 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb2_len); | 507 | iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb2_len); |
| 508 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, | ||
| 509 | skb->data + hdr_len, | ||
| 510 | tb2_len); | ||
| 499 | } | 511 | } |
| 500 | 512 | ||
| 501 | if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) | 513 | if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) |
| 502 | goto out_err; | 514 | goto out_err; |
| 503 | 515 | ||
| 504 | trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr, | ||
| 505 | IWL_FIRST_TB_SIZE + tb1_len, hdr_len); | ||
| 506 | trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len); | ||
| 507 | |||
| 508 | return tfd; | 516 | return tfd; |
| 509 | 517 | ||
| 510 | out_err: | 518 | out_err: |
| @@ -551,7 +559,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, | |||
| 551 | out_meta, hdr_len, len); | 559 | out_meta, hdr_len, len); |
| 552 | 560 | ||
| 553 | return iwl_pcie_gen2_build_tx(trans, txq, dev_cmd, skb, out_meta, | 561 | return iwl_pcie_gen2_build_tx(trans, txq, dev_cmd, skb, out_meta, |
| 554 | hdr_len, len); | 562 | hdr_len, len, !amsdu); |
| 555 | } | 563 | } |
| 556 | 564 | ||
| 557 | int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, | 565 | int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index f227b91098c9..87b7225fe289 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c | |||
| @@ -1994,6 +1994,9 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 1994 | head_tb_len, DMA_TO_DEVICE); | 1994 | head_tb_len, DMA_TO_DEVICE); |
| 1995 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) | 1995 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) |
| 1996 | return -EINVAL; | 1996 | return -EINVAL; |
| 1997 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, | ||
| 1998 | skb->data + hdr_len, | ||
| 1999 | head_tb_len); | ||
| 1997 | iwl_pcie_txq_build_tfd(trans, txq, tb_phys, head_tb_len, false); | 2000 | iwl_pcie_txq_build_tfd(trans, txq, tb_phys, head_tb_len, false); |
| 1998 | } | 2001 | } |
| 1999 | 2002 | ||
| @@ -2011,6 +2014,9 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 2011 | 2014 | ||
| 2012 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) | 2015 | if (unlikely(dma_mapping_error(trans->dev, tb_phys))) |
| 2013 | return -EINVAL; | 2016 | return -EINVAL; |
| 2017 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, | ||
| 2018 | skb_frag_address(frag), | ||
| 2019 | skb_frag_size(frag)); | ||
| 2014 | tb_idx = iwl_pcie_txq_build_tfd(trans, txq, tb_phys, | 2020 | tb_idx = iwl_pcie_txq_build_tfd(trans, txq, tb_phys, |
| 2015 | skb_frag_size(frag), false); | 2021 | skb_frag_size(frag), false); |
| 2016 | if (tb_idx < 0) | 2022 | if (tb_idx < 0) |
| @@ -2190,8 +2196,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 2190 | } | 2196 | } |
| 2191 | iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys, | 2197 | iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys, |
| 2192 | hdr_tb_len, false); | 2198 | hdr_tb_len, false); |
| 2193 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, | 2199 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, |
| 2194 | hdr_tb_len); | 2200 | hdr_tb_len); |
| 2195 | /* add this subframe's headers' length to the tx_cmd */ | 2201 | /* add this subframe's headers' length to the tx_cmd */ |
| 2196 | le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); | 2202 | le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); |
| 2197 | 2203 | ||
| @@ -2216,8 +2222,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 2216 | 2222 | ||
| 2217 | iwl_pcie_txq_build_tfd(trans, txq, tb_phys, | 2223 | iwl_pcie_txq_build_tfd(trans, txq, tb_phys, |
| 2218 | size, false); | 2224 | size, false); |
| 2219 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, tso.data, | 2225 | trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data, |
| 2220 | size); | 2226 | size); |
| 2221 | 2227 | ||
| 2222 | data_left -= size; | 2228 | data_left -= size; |
| 2223 | tso_build_data(skb, &tso, size); | 2229 | tso_build_data(skb, &tso, size); |
| @@ -2398,6 +2404,13 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 2398 | goto out_err; | 2404 | goto out_err; |
| 2399 | iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false); | 2405 | iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false); |
| 2400 | 2406 | ||
| 2407 | trace_iwlwifi_dev_tx(trans->dev, skb, | ||
| 2408 | iwl_pcie_get_tfd(trans, txq, | ||
| 2409 | txq->write_ptr), | ||
| 2410 | trans_pcie->tfd_size, | ||
| 2411 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, | ||
| 2412 | hdr_len); | ||
| 2413 | |||
| 2401 | /* | 2414 | /* |
| 2402 | * If gso_size wasn't set, don't give the frame "amsdu treatment" | 2415 | * If gso_size wasn't set, don't give the frame "amsdu treatment" |
| 2403 | * (adding subframes, etc.). | 2416 | * (adding subframes, etc.). |
| @@ -2421,14 +2434,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
| 2421 | out_meta))) | 2434 | out_meta))) |
| 2422 | goto out_err; | 2435 | goto out_err; |
| 2423 | } | 2436 | } |
| 2424 | |||
| 2425 | trace_iwlwifi_dev_tx(trans->dev, skb, | ||
| 2426 | iwl_pcie_get_tfd(trans, txq, | ||
| 2427 | txq->write_ptr), | ||
| 2428 | trans_pcie->tfd_size, | ||
| 2429 | &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, | ||
| 2430 | hdr_len); | ||
| 2431 | trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len); | ||
| 2432 | } | 2437 | } |
| 2433 | 2438 | ||
| 2434 | /* building the A-MSDU might have changed this data, so memcpy it now */ | 2439 | /* building the A-MSDU might have changed this data, so memcpy it now */ |
diff --git a/drivers/net/wireless/marvell/libertas/if_cs.c b/drivers/net/wireless/marvell/libertas/if_cs.c index 7d88223f890b..cebf03c6a622 100644 --- a/drivers/net/wireless/marvell/libertas/if_cs.c +++ b/drivers/net/wireless/marvell/libertas/if_cs.c | |||
| @@ -900,8 +900,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
| 900 | 900 | ||
| 901 | /* Make this card known to the libertas driver */ | 901 | /* Make this card known to the libertas driver */ |
| 902 | priv = lbs_add_card(card, &p_dev->dev); | 902 | priv = lbs_add_card(card, &p_dev->dev); |
| 903 | if (!priv) { | 903 | if (IS_ERR(priv)) { |
| 904 | ret = -ENOMEM; | 904 | ret = PTR_ERR(priv); |
| 905 | goto out2; | 905 | goto out2; |
| 906 | } | 906 | } |
| 907 | 907 | ||
diff --git a/drivers/net/wireless/marvell/libertas/if_sdio.c b/drivers/net/wireless/marvell/libertas/if_sdio.c index 39bf85d0ade0..8d98e7fdd27c 100644 --- a/drivers/net/wireless/marvell/libertas/if_sdio.c +++ b/drivers/net/wireless/marvell/libertas/if_sdio.c | |||
| @@ -1206,8 +1206,8 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 1206 | 1206 | ||
| 1207 | 1207 | ||
| 1208 | priv = lbs_add_card(card, &func->dev); | 1208 | priv = lbs_add_card(card, &func->dev); |
| 1209 | if (!priv) { | 1209 | if (IS_ERR(priv)) { |
| 1210 | ret = -ENOMEM; | 1210 | ret = PTR_ERR(priv); |
| 1211 | goto free; | 1211 | goto free; |
| 1212 | } | 1212 | } |
| 1213 | 1213 | ||
diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c index e9aec6cb1105..504d6e096476 100644 --- a/drivers/net/wireless/marvell/libertas/if_spi.c +++ b/drivers/net/wireless/marvell/libertas/if_spi.c | |||
| @@ -1146,8 +1146,8 @@ static int if_spi_probe(struct spi_device *spi) | |||
| 1146 | * This will call alloc_etherdev. | 1146 | * This will call alloc_etherdev. |
| 1147 | */ | 1147 | */ |
| 1148 | priv = lbs_add_card(card, &spi->dev); | 1148 | priv = lbs_add_card(card, &spi->dev); |
| 1149 | if (!priv) { | 1149 | if (IS_ERR(priv)) { |
| 1150 | err = -ENOMEM; | 1150 | err = PTR_ERR(priv); |
| 1151 | goto free_card; | 1151 | goto free_card; |
| 1152 | } | 1152 | } |
| 1153 | card->priv = priv; | 1153 | card->priv = priv; |
diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index c67a8e7be310..220dcdee8d2b 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c | |||
| @@ -254,8 +254,11 @@ static int if_usb_probe(struct usb_interface *intf, | |||
| 254 | goto dealloc; | 254 | goto dealloc; |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | if (!(priv = lbs_add_card(cardp, &intf->dev))) | 257 | priv = lbs_add_card(cardp, &intf->dev); |
| 258 | if (IS_ERR(priv)) { | ||
| 259 | r = PTR_ERR(priv); | ||
| 258 | goto err_add_card; | 260 | goto err_add_card; |
| 261 | } | ||
| 259 | 262 | ||
| 260 | cardp->priv = priv; | 263 | cardp->priv = priv; |
| 261 | 264 | ||
| @@ -456,8 +459,6 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, | |||
| 456 | MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, | 459 | MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, |
| 457 | cardp); | 460 | cardp); |
| 458 | 461 | ||
| 459 | cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; | ||
| 460 | |||
| 461 | lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); | 462 | lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); |
| 462 | if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) { | 463 | if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) { |
| 463 | lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); | 464 | lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); |
diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index f22e1c220cba..f7db60bc7c7f 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c | |||
| @@ -907,25 +907,29 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
| 907 | struct net_device *dev; | 907 | struct net_device *dev; |
| 908 | struct wireless_dev *wdev; | 908 | struct wireless_dev *wdev; |
| 909 | struct lbs_private *priv = NULL; | 909 | struct lbs_private *priv = NULL; |
| 910 | int err; | ||
| 910 | 911 | ||
| 911 | /* Allocate an Ethernet device and register it */ | 912 | /* Allocate an Ethernet device and register it */ |
| 912 | wdev = lbs_cfg_alloc(dmdev); | 913 | wdev = lbs_cfg_alloc(dmdev); |
| 913 | if (IS_ERR(wdev)) { | 914 | if (IS_ERR(wdev)) { |
| 915 | err = PTR_ERR(wdev); | ||
| 914 | pr_err("cfg80211 init failed\n"); | 916 | pr_err("cfg80211 init failed\n"); |
| 915 | goto done; | 917 | goto err_cfg; |
| 916 | } | 918 | } |
| 917 | 919 | ||
| 918 | wdev->iftype = NL80211_IFTYPE_STATION; | 920 | wdev->iftype = NL80211_IFTYPE_STATION; |
| 919 | priv = wdev_priv(wdev); | 921 | priv = wdev_priv(wdev); |
| 920 | priv->wdev = wdev; | 922 | priv->wdev = wdev; |
| 921 | 923 | ||
| 922 | if (lbs_init_adapter(priv)) { | 924 | err = lbs_init_adapter(priv); |
| 925 | if (err) { | ||
| 923 | pr_err("failed to initialize adapter structure\n"); | 926 | pr_err("failed to initialize adapter structure\n"); |
| 924 | goto err_wdev; | 927 | goto err_wdev; |
| 925 | } | 928 | } |
| 926 | 929 | ||
| 927 | dev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup); | 930 | dev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup); |
| 928 | if (!dev) { | 931 | if (!dev) { |
| 932 | err = -ENOMEM; | ||
| 929 | dev_err(dmdev, "no memory for network device instance\n"); | 933 | dev_err(dmdev, "no memory for network device instance\n"); |
| 930 | goto err_adapter; | 934 | goto err_adapter; |
| 931 | } | 935 | } |
| @@ -949,6 +953,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
| 949 | init_waitqueue_head(&priv->waitq); | 953 | init_waitqueue_head(&priv->waitq); |
| 950 | priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main"); | 954 | priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main"); |
| 951 | if (IS_ERR(priv->main_thread)) { | 955 | if (IS_ERR(priv->main_thread)) { |
| 956 | err = PTR_ERR(priv->main_thread); | ||
| 952 | lbs_deb_thread("Error creating main thread.\n"); | 957 | lbs_deb_thread("Error creating main thread.\n"); |
| 953 | goto err_ndev; | 958 | goto err_ndev; |
| 954 | } | 959 | } |
| @@ -961,7 +966,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
| 961 | priv->wol_gap = 20; | 966 | priv->wol_gap = 20; |
| 962 | priv->ehs_remove_supported = true; | 967 | priv->ehs_remove_supported = true; |
| 963 | 968 | ||
| 964 | goto done; | 969 | return priv; |
| 965 | 970 | ||
| 966 | err_ndev: | 971 | err_ndev: |
| 967 | free_netdev(dev); | 972 | free_netdev(dev); |
| @@ -972,10 +977,8 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
| 972 | err_wdev: | 977 | err_wdev: |
| 973 | lbs_cfg_free(priv); | 978 | lbs_cfg_free(priv); |
| 974 | 979 | ||
| 975 | priv = NULL; | 980 | err_cfg: |
| 976 | 981 | return ERR_PTR(err); | |
| 977 | done: | ||
| 978 | return priv; | ||
| 979 | } | 982 | } |
| 980 | EXPORT_SYMBOL_GPL(lbs_add_card); | 983 | EXPORT_SYMBOL_GPL(lbs_add_card); |
| 981 | 984 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mmio.c b/drivers/net/wireless/mediatek/mt76/mmio.c index 30a5d928e655..1d6bbce76041 100644 --- a/drivers/net/wireless/mediatek/mt76/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mmio.c | |||
| @@ -79,6 +79,7 @@ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) | |||
| 79 | .copy = mt76_mmio_copy, | 79 | .copy = mt76_mmio_copy, |
| 80 | .wr_rp = mt76_mmio_wr_rp, | 80 | .wr_rp = mt76_mmio_wr_rp, |
| 81 | .rd_rp = mt76_mmio_rd_rp, | 81 | .rd_rp = mt76_mmio_rd_rp, |
| 82 | .type = MT76_BUS_MMIO, | ||
| 82 | }; | 83 | }; |
| 83 | 84 | ||
| 84 | dev->bus = &mt76_mmio_ops; | 85 | dev->bus = &mt76_mmio_ops; |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index f723a07cab29..3bfa7f5e3513 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h | |||
| @@ -38,6 +38,11 @@ struct mt76_reg_pair { | |||
| 38 | u32 value; | 38 | u32 value; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | enum mt76_bus_type { | ||
| 42 | MT76_BUS_MMIO, | ||
| 43 | MT76_BUS_USB, | ||
| 44 | }; | ||
| 45 | |||
| 41 | struct mt76_bus_ops { | 46 | struct mt76_bus_ops { |
| 42 | u32 (*rr)(struct mt76_dev *dev, u32 offset); | 47 | u32 (*rr)(struct mt76_dev *dev, u32 offset); |
| 43 | void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); | 48 | void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); |
| @@ -48,8 +53,12 @@ struct mt76_bus_ops { | |||
| 48 | const struct mt76_reg_pair *rp, int len); | 53 | const struct mt76_reg_pair *rp, int len); |
| 49 | int (*rd_rp)(struct mt76_dev *dev, u32 base, | 54 | int (*rd_rp)(struct mt76_dev *dev, u32 base, |
| 50 | struct mt76_reg_pair *rp, int len); | 55 | struct mt76_reg_pair *rp, int len); |
| 56 | enum mt76_bus_type type; | ||
| 51 | }; | 57 | }; |
| 52 | 58 | ||
| 59 | #define mt76_is_usb(dev) ((dev)->mt76.bus->type == MT76_BUS_USB) | ||
| 60 | #define mt76_is_mmio(dev) ((dev)->mt76.bus->type == MT76_BUS_MMIO) | ||
| 61 | |||
| 53 | enum mt76_txq_id { | 62 | enum mt76_txq_id { |
| 54 | MT_TXQ_VO = IEEE80211_AC_VO, | 63 | MT_TXQ_VO = IEEE80211_AC_VO, |
| 55 | MT_TXQ_VI = IEEE80211_AC_VI, | 64 | MT_TXQ_VI = IEEE80211_AC_VI, |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h deleted file mode 100644 index 891ce1c3461f..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h +++ /dev/null | |||
| @@ -1,126 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org> | ||
| 3 | * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 | ||
| 7 | * as published by the Free Software Foundation | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __MT76X0U_DMA_H | ||
| 16 | #define __MT76X0U_DMA_H | ||
| 17 | |||
| 18 | #include <asm/unaligned.h> | ||
| 19 | #include <linux/skbuff.h> | ||
| 20 | |||
| 21 | #define MT_DMA_HDR_LEN 4 | ||
| 22 | #define MT_RX_INFO_LEN 4 | ||
| 23 | #define MT_FCE_INFO_LEN 4 | ||
| 24 | #define MT_DMA_HDRS (MT_DMA_HDR_LEN + MT_RX_INFO_LEN) | ||
| 25 | |||
| 26 | /* Common Tx DMA descriptor fields */ | ||
| 27 | #define MT_TXD_INFO_LEN GENMASK(15, 0) | ||
| 28 | #define MT_TXD_INFO_D_PORT GENMASK(29, 27) | ||
| 29 | #define MT_TXD_INFO_TYPE GENMASK(31, 30) | ||
| 30 | |||
| 31 | /* Tx DMA MCU command specific flags */ | ||
| 32 | #define MT_TXD_CMD_SEQ GENMASK(19, 16) | ||
| 33 | #define MT_TXD_CMD_TYPE GENMASK(26, 20) | ||
| 34 | |||
| 35 | enum mt76_msg_port { | ||
| 36 | WLAN_PORT, | ||
| 37 | CPU_RX_PORT, | ||
| 38 | CPU_TX_PORT, | ||
| 39 | HOST_PORT, | ||
| 40 | VIRTUAL_CPU_RX_PORT, | ||
| 41 | VIRTUAL_CPU_TX_PORT, | ||
| 42 | DISCARD, | ||
| 43 | }; | ||
| 44 | |||
| 45 | enum mt76_info_type { | ||
| 46 | DMA_PACKET, | ||
| 47 | DMA_COMMAND, | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* Tx DMA packet specific flags */ | ||
| 51 | #define MT_TXD_PKT_INFO_NEXT_VLD BIT(16) | ||
| 52 | #define MT_TXD_PKT_INFO_TX_BURST BIT(17) | ||
| 53 | #define MT_TXD_PKT_INFO_80211 BIT(19) | ||
| 54 | #define MT_TXD_PKT_INFO_TSO BIT(20) | ||
| 55 | #define MT_TXD_PKT_INFO_CSO BIT(21) | ||
| 56 | #define MT_TXD_PKT_INFO_WIV BIT(24) | ||
| 57 | #define MT_TXD_PKT_INFO_QSEL GENMASK(26, 25) | ||
| 58 | |||
| 59 | enum mt76_qsel { | ||
| 60 | MT_QSEL_MGMT, | ||
| 61 | MT_QSEL_HCCA, | ||
| 62 | MT_QSEL_EDCA, | ||
| 63 | MT_QSEL_EDCA_2, | ||
| 64 | }; | ||
| 65 | |||
| 66 | |||
| 67 | static inline int mt76x0_dma_skb_wrap(struct sk_buff *skb, | ||
| 68 | enum mt76_msg_port d_port, | ||
| 69 | enum mt76_info_type type, u32 flags) | ||
| 70 | { | ||
| 71 | u32 info; | ||
| 72 | |||
| 73 | /* Buffer layout: | ||
| 74 | * | 4B | xfer len | pad | 4B | | ||
| 75 | * | TXINFO | pkt/cmd | zero pad to 4B | zero | | ||
| 76 | * | ||
| 77 | * length field of TXINFO should be set to 'xfer len'. | ||
| 78 | */ | ||
| 79 | |||
| 80 | info = flags | | ||
| 81 | FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) | | ||
| 82 | FIELD_PREP(MT_TXD_INFO_D_PORT, d_port) | | ||
| 83 | FIELD_PREP(MT_TXD_INFO_TYPE, type); | ||
| 84 | |||
| 85 | put_unaligned_le32(info, skb_push(skb, sizeof(info))); | ||
| 86 | return skb_put_padto(skb, round_up(skb->len, 4) + 4); | ||
| 87 | } | ||
| 88 | |||
| 89 | static inline int | ||
| 90 | mt76x0_dma_skb_wrap_pkt(struct sk_buff *skb, enum mt76_qsel qsel, u32 flags) | ||
| 91 | { | ||
| 92 | flags |= FIELD_PREP(MT_TXD_PKT_INFO_QSEL, qsel); | ||
| 93 | return mt76x0_dma_skb_wrap(skb, WLAN_PORT, DMA_PACKET, flags); | ||
| 94 | } | ||
| 95 | |||
| 96 | /* Common Rx DMA descriptor fields */ | ||
| 97 | #define MT_RXD_INFO_LEN GENMASK(13, 0) | ||
| 98 | #define MT_RXD_INFO_PCIE_INTR BIT(24) | ||
| 99 | #define MT_RXD_INFO_QSEL GENMASK(26, 25) | ||
| 100 | #define MT_RXD_INFO_PORT GENMASK(29, 27) | ||
| 101 | #define MT_RXD_INFO_TYPE GENMASK(31, 30) | ||
| 102 | |||
| 103 | /* Rx DMA packet specific flags */ | ||
| 104 | #define MT_RXD_PKT_INFO_UDP_ERR BIT(16) | ||
| 105 | #define MT_RXD_PKT_INFO_TCP_ERR BIT(17) | ||
| 106 | #define MT_RXD_PKT_INFO_IP_ERR BIT(18) | ||
| 107 | #define MT_RXD_PKT_INFO_PKT_80211 BIT(19) | ||
| 108 | #define MT_RXD_PKT_INFO_L3L4_DONE BIT(20) | ||
| 109 | #define MT_RXD_PKT_INFO_MAC_LEN GENMASK(23, 21) | ||
| 110 | |||
| 111 | /* Rx DMA MCU command specific flags */ | ||
| 112 | #define MT_RXD_CMD_INFO_SELF_GEN BIT(15) | ||
| 113 | #define MT_RXD_CMD_INFO_CMD_SEQ GENMASK(19, 16) | ||
| 114 | #define MT_RXD_CMD_INFO_EVT_TYPE GENMASK(23, 20) | ||
| 115 | |||
| 116 | enum mt76_evt_type { | ||
| 117 | CMD_DONE, | ||
| 118 | CMD_ERROR, | ||
| 119 | CMD_RETRY, | ||
| 120 | EVENT_PWR_RSP, | ||
| 121 | EVENT_WOW_RSP, | ||
| 122 | EVENT_CARRIER_DETECT_RSP, | ||
| 123 | EVENT_DFS_DETECT_RSP, | ||
| 124 | }; | ||
| 125 | |||
| 126 | #endif | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index 5735038c0e2d..ab4fd6e0f23a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | |||
| @@ -31,8 +31,8 @@ mt76x0_efuse_physical_size_check(struct mt76x02_dev *dev) | |||
| 31 | int ret, i; | 31 | int ret, i; |
| 32 | u32 start = 0, end = 0, cnt_free; | 32 | u32 start = 0, end = 0, cnt_free; |
| 33 | 33 | ||
| 34 | ret = mt76x02_get_efuse_data(&dev->mt76, MT_EE_USAGE_MAP_START, | 34 | ret = mt76x02_get_efuse_data(dev, MT_EE_USAGE_MAP_START, data, |
| 35 | data, sizeof(data), MT_EE_PHYSICAL_READ); | 35 | sizeof(data), MT_EE_PHYSICAL_READ); |
| 36 | if (ret) | 36 | if (ret) |
| 37 | return ret; | 37 | return ret; |
| 38 | 38 | ||
| @@ -55,10 +55,10 @@ mt76x0_efuse_physical_size_check(struct mt76x02_dev *dev) | |||
| 55 | 55 | ||
| 56 | static void mt76x0_set_chip_cap(struct mt76x02_dev *dev) | 56 | static void mt76x0_set_chip_cap(struct mt76x02_dev *dev) |
| 57 | { | 57 | { |
| 58 | u16 nic_conf0 = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_0); | 58 | u16 nic_conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); |
| 59 | u16 nic_conf1 = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_1); | 59 | u16 nic_conf1 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); |
| 60 | 60 | ||
| 61 | mt76x02_eeprom_parse_hw_cap(&dev->mt76); | 61 | mt76x02_eeprom_parse_hw_cap(dev); |
| 62 | dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n", | 62 | dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n", |
| 63 | dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz); | 63 | dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz); |
| 64 | 64 | ||
| @@ -86,7 +86,7 @@ static void mt76x0_set_temp_offset(struct mt76x02_dev *dev) | |||
| 86 | { | 86 | { |
| 87 | u8 val; | 87 | u8 val; |
| 88 | 88 | ||
| 89 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_2G_TARGET_POWER) >> 8; | 89 | val = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER) >> 8; |
| 90 | if (mt76x02_field_valid(val)) | 90 | if (mt76x02_field_valid(val)) |
| 91 | dev->cal.rx.temp_offset = mt76x02_sign_extend(val, 8); | 91 | dev->cal.rx.temp_offset = mt76x02_sign_extend(val, 8); |
| 92 | else | 92 | else |
| @@ -98,12 +98,12 @@ static void mt76x0_set_freq_offset(struct mt76x02_dev *dev) | |||
| 98 | struct mt76x02_rx_freq_cal *caldata = &dev->cal.rx; | 98 | struct mt76x02_rx_freq_cal *caldata = &dev->cal.rx; |
| 99 | u8 val; | 99 | u8 val; |
| 100 | 100 | ||
| 101 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_FREQ_OFFSET); | 101 | val = mt76x02_eeprom_get(dev, MT_EE_FREQ_OFFSET); |
| 102 | if (!mt76x02_field_valid(val)) | 102 | if (!mt76x02_field_valid(val)) |
| 103 | val = 0; | 103 | val = 0; |
| 104 | caldata->freq_offset = val; | 104 | caldata->freq_offset = val; |
| 105 | 105 | ||
| 106 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TSSI_BOUND4) >> 8; | 106 | val = mt76x02_eeprom_get(dev, MT_EE_TSSI_BOUND4) >> 8; |
| 107 | if (!mt76x02_field_valid(val)) | 107 | if (!mt76x02_field_valid(val)) |
| 108 | val = 0; | 108 | val = 0; |
| 109 | 109 | ||
| @@ -118,10 +118,8 @@ void mt76x0_read_rx_gain(struct mt76x02_dev *dev) | |||
| 118 | u16 rssi_offset; | 118 | u16 rssi_offset; |
| 119 | int i; | 119 | int i; |
| 120 | 120 | ||
| 121 | mt76x02_get_rx_gain(&dev->mt76, chan->band, &rssi_offset, | 121 | mt76x02_get_rx_gain(dev, chan->band, &rssi_offset, &lna_2g, lna_5g); |
| 122 | &lna_2g, lna_5g); | 122 | caldata->lna_gain = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); |
| 123 | caldata->lna_gain = mt76x02_get_lna_gain(&dev->mt76, &lna_2g, | ||
| 124 | lna_5g, chan); | ||
| 125 | 123 | ||
| 126 | for (i = 0; i < ARRAY_SIZE(caldata->rssi_offset); i++) { | 124 | for (i = 0; i < ARRAY_SIZE(caldata->rssi_offset); i++) { |
| 127 | val = rssi_offset >> (8 * i); | 125 | val = rssi_offset >> (8 * i); |
| @@ -132,12 +130,12 @@ void mt76x0_read_rx_gain(struct mt76x02_dev *dev) | |||
| 132 | } | 130 | } |
| 133 | } | 131 | } |
| 134 | 132 | ||
| 135 | static s8 mt76x0_get_delta(struct mt76_dev *dev) | 133 | static s8 mt76x0_get_delta(struct mt76x02_dev *dev) |
| 136 | { | 134 | { |
| 137 | struct cfg80211_chan_def *chandef = &dev->chandef; | 135 | struct cfg80211_chan_def *chandef = &dev->mt76.chandef; |
| 138 | u8 val; | 136 | u8 val; |
| 139 | 137 | ||
| 140 | if (mt76x02_tssi_enabled(dev)) | 138 | if (mt76x0_tssi_enabled(dev)) |
| 141 | return 0; | 139 | return 0; |
| 142 | 140 | ||
| 143 | if (chandef->width == NL80211_CHAN_WIDTH_80) { | 141 | if (chandef->width == NL80211_CHAN_WIDTH_80) { |
| @@ -162,54 +160,54 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev) | |||
| 162 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; | 160 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; |
| 163 | bool is_2ghz = chan->band == NL80211_BAND_2GHZ; | 161 | bool is_2ghz = chan->band == NL80211_BAND_2GHZ; |
| 164 | struct mt76_rate_power *t = &dev->mt76.rate_power; | 162 | struct mt76_rate_power *t = &dev->mt76.rate_power; |
| 165 | s8 delta = mt76x0_get_delta(&dev->mt76); | 163 | s8 delta = mt76x0_get_delta(dev); |
| 166 | u16 val, addr; | 164 | u16 val, addr; |
| 167 | 165 | ||
| 168 | memset(t, 0, sizeof(*t)); | 166 | memset(t, 0, sizeof(*t)); |
| 169 | 167 | ||
| 170 | /* cck 1M, 2M, 5.5M, 11M */ | 168 | /* cck 1M, 2M, 5.5M, 11M */ |
| 171 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_BYRATE_BASE); | 169 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_BYRATE_BASE); |
| 172 | t->cck[0] = t->cck[1] = s6_to_s8(val); | 170 | t->cck[0] = t->cck[1] = s6_to_s8(val); |
| 173 | t->cck[2] = t->cck[3] = s6_to_s8(val >> 8); | 171 | t->cck[2] = t->cck[3] = s6_to_s8(val >> 8); |
| 174 | 172 | ||
| 175 | /* ofdm 6M, 9M, 12M, 18M */ | 173 | /* ofdm 6M, 9M, 12M, 18M */ |
| 176 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 2 : 0x120; | 174 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 2 : 0x120; |
| 177 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 175 | val = mt76x02_eeprom_get(dev, addr); |
| 178 | t->ofdm[0] = t->ofdm[1] = s6_to_s8(val); | 176 | t->ofdm[0] = t->ofdm[1] = s6_to_s8(val); |
| 179 | t->ofdm[2] = t->ofdm[3] = s6_to_s8(val >> 8); | 177 | t->ofdm[2] = t->ofdm[3] = s6_to_s8(val >> 8); |
| 180 | 178 | ||
| 181 | /* ofdm 24M, 36M, 48M, 54M */ | 179 | /* ofdm 24M, 36M, 48M, 54M */ |
| 182 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 4 : 0x122; | 180 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 4 : 0x122; |
| 183 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 181 | val = mt76x02_eeprom_get(dev, addr); |
| 184 | t->ofdm[4] = t->ofdm[5] = s6_to_s8(val); | 182 | t->ofdm[4] = t->ofdm[5] = s6_to_s8(val); |
| 185 | t->ofdm[6] = t->ofdm[7] = s6_to_s8(val >> 8); | 183 | t->ofdm[6] = t->ofdm[7] = s6_to_s8(val >> 8); |
| 186 | 184 | ||
| 187 | /* ht-vht mcs 1ss 0, 1, 2, 3 */ | 185 | /* ht-vht mcs 1ss 0, 1, 2, 3 */ |
| 188 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 6 : 0x124; | 186 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 6 : 0x124; |
| 189 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 187 | val = mt76x02_eeprom_get(dev, addr); |
| 190 | t->ht[0] = t->ht[1] = t->vht[0] = t->vht[1] = s6_to_s8(val); | 188 | t->ht[0] = t->ht[1] = t->vht[0] = t->vht[1] = s6_to_s8(val); |
| 191 | t->ht[2] = t->ht[3] = t->vht[2] = t->vht[3] = s6_to_s8(val >> 8); | 189 | t->ht[2] = t->ht[3] = t->vht[2] = t->vht[3] = s6_to_s8(val >> 8); |
| 192 | 190 | ||
| 193 | /* ht-vht mcs 1ss 4, 5, 6 */ | 191 | /* ht-vht mcs 1ss 4, 5, 6 */ |
| 194 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 8 : 0x126; | 192 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 8 : 0x126; |
| 195 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 193 | val = mt76x02_eeprom_get(dev, addr); |
| 196 | t->ht[4] = t->ht[5] = t->vht[4] = t->vht[5] = s6_to_s8(val); | 194 | t->ht[4] = t->ht[5] = t->vht[4] = t->vht[5] = s6_to_s8(val); |
| 197 | t->ht[6] = t->vht[6] = s6_to_s8(val >> 8); | 195 | t->ht[6] = t->vht[6] = s6_to_s8(val >> 8); |
| 198 | 196 | ||
| 199 | /* ht-vht mcs 1ss 0, 1, 2, 3 stbc */ | 197 | /* ht-vht mcs 1ss 0, 1, 2, 3 stbc */ |
| 200 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 14 : 0xec; | 198 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 14 : 0xec; |
| 201 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 199 | val = mt76x02_eeprom_get(dev, addr); |
| 202 | t->stbc[0] = t->stbc[1] = s6_to_s8(val); | 200 | t->stbc[0] = t->stbc[1] = s6_to_s8(val); |
| 203 | t->stbc[2] = t->stbc[3] = s6_to_s8(val >> 8); | 201 | t->stbc[2] = t->stbc[3] = s6_to_s8(val >> 8); |
| 204 | 202 | ||
| 205 | /* ht-vht mcs 1ss 4, 5, 6 stbc */ | 203 | /* ht-vht mcs 1ss 4, 5, 6 stbc */ |
| 206 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 16 : 0xee; | 204 | addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 16 : 0xee; |
| 207 | val = mt76x02_eeprom_get(&dev->mt76, addr); | 205 | val = mt76x02_eeprom_get(dev, addr); |
| 208 | t->stbc[4] = t->stbc[5] = s6_to_s8(val); | 206 | t->stbc[4] = t->stbc[5] = s6_to_s8(val); |
| 209 | t->stbc[6] = t->stbc[7] = s6_to_s8(val >> 8); | 207 | t->stbc[6] = t->stbc[7] = s6_to_s8(val >> 8); |
| 210 | 208 | ||
| 211 | /* vht mcs 8, 9 5GHz */ | 209 | /* vht mcs 8, 9 5GHz */ |
| 212 | val = mt76x02_eeprom_get(&dev->mt76, 0x132); | 210 | val = mt76x02_eeprom_get(dev, 0x132); |
| 213 | t->vht[7] = s6_to_s8(val); | 211 | t->vht[7] = s6_to_s8(val); |
| 214 | t->vht[8] = s6_to_s8(val >> 8); | 212 | t->vht[8] = s6_to_s8(val >> 8); |
| 215 | 213 | ||
| @@ -266,7 +264,7 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev, u8 *info) | |||
| 266 | addr = MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE + 2 + offset; | 264 | addr = MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE + 2 + offset; |
| 267 | } | 265 | } |
| 268 | 266 | ||
| 269 | data = mt76x02_eeprom_get(&dev->mt76, addr); | 267 | data = mt76x02_eeprom_get(dev, addr); |
| 270 | 268 | ||
| 271 | info[0] = data; | 269 | info[0] = data; |
| 272 | if (!info[0] || info[0] > 0x3f) | 270 | if (!info[0] || info[0] > 0x3f) |
| @@ -312,7 +310,7 @@ static int mt76x0_load_eeprom(struct mt76x02_dev *dev) | |||
| 312 | if (found < 0) | 310 | if (found < 0) |
| 313 | return found; | 311 | return found; |
| 314 | 312 | ||
| 315 | return mt76x02_get_efuse_data(&dev->mt76, 0, dev->mt76.eeprom.data, | 313 | return mt76x02_get_efuse_data(dev, 0, dev->mt76.eeprom.data, |
| 316 | MT76X0_EEPROM_SIZE, MT_EE_READ); | 314 | MT76X0_EEPROM_SIZE, MT_EE_READ); |
| 317 | } | 315 | } |
| 318 | 316 | ||
| @@ -326,7 +324,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev) | |||
| 326 | if (err < 0) | 324 | if (err < 0) |
| 327 | return err; | 325 | return err; |
| 328 | 326 | ||
| 329 | data = mt76x02_eeprom_get(&dev->mt76, MT_EE_VERSION); | 327 | data = mt76x02_eeprom_get(dev, MT_EE_VERSION); |
| 330 | version = data >> 8; | 328 | version = data >> 8; |
| 331 | fae = data; | 329 | fae = data; |
| 332 | 330 | ||
| @@ -337,8 +335,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev) | |||
| 337 | dev_info(dev->mt76.dev, "EEPROM ver:%02hhx fae:%02hhx\n", | 335 | dev_info(dev->mt76.dev, "EEPROM ver:%02hhx fae:%02hhx\n", |
| 338 | version, fae); | 336 | version, fae); |
| 339 | 337 | ||
| 340 | mt76x02_mac_setaddr(&dev->mt76, | 338 | mt76x02_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR); |
| 341 | dev->mt76.eeprom.data + MT_EE_MAC_ADDR); | ||
| 342 | mt76x0_set_chip_cap(dev); | 339 | mt76x0_set_chip_cap(dev); |
| 343 | mt76x0_set_freq_offset(dev); | 340 | mt76x0_set_freq_offset(dev); |
| 344 | mt76x0_set_temp_offset(dev); | 341 | mt76x0_set_temp_offset(dev); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h index 40fd4e61769b..ee9ade9f3c8b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h | |||
| @@ -37,4 +37,10 @@ static inline s8 s6_to_s8(u32 val) | |||
| 37 | return ret; | 37 | return ret; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | static inline bool mt76x0_tssi_enabled(struct mt76x02_dev *dev) | ||
| 41 | { | ||
| 42 | return (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & | ||
| 43 | MT_EE_NIC_CONF_1_TX_ALC_EN); | ||
| 44 | } | ||
| 45 | |||
| 40 | #endif | 46 | #endif |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index ee2b8e885608..4a9408801260 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c | |||
| @@ -138,7 +138,7 @@ static void mt76x0_init_mac_registers(struct mt76x02_dev *dev) | |||
| 138 | 138 | ||
| 139 | RANDOM_WRITE(dev, common_mac_reg_table); | 139 | RANDOM_WRITE(dev, common_mac_reg_table); |
| 140 | 140 | ||
| 141 | mt76x02_set_beacon_offsets(&dev->mt76); | 141 | mt76x02_set_beacon_offsets(dev); |
| 142 | 142 | ||
| 143 | /* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */ | 143 | /* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */ |
| 144 | RANDOM_WRITE(dev, mt76x0_mac_reg_table); | 144 | RANDOM_WRITE(dev, mt76x0_mac_reg_table); |
| @@ -280,7 +280,7 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev) | |||
| 280 | return -ETIMEDOUT; | 280 | return -ETIMEDOUT; |
| 281 | 281 | ||
| 282 | mt76x0_reset_csr_bbp(dev); | 282 | mt76x0_reset_csr_bbp(dev); |
| 283 | ret = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); | 283 | ret = mt76x02_mcu_function_select(dev, Q_SELECT, 1, false); |
| 284 | if (ret) | 284 | if (ret) |
| 285 | return ret; | 285 | return ret; |
| 286 | 286 | ||
| @@ -368,7 +368,10 @@ int mt76x0_register_device(struct mt76x02_dev *dev) | |||
| 368 | hw->max_rates = 1; | 368 | hw->max_rates = 1; |
| 369 | hw->max_report_rates = 7; | 369 | hw->max_report_rates = 7; |
| 370 | hw->max_rate_tries = 1; | 370 | hw->max_rate_tries = 1; |
| 371 | hw->extra_tx_headroom = sizeof(struct mt76x02_txwi) + 4 + 2; | 371 | hw->extra_tx_headroom = 2; |
| 372 | if (mt76_is_usb(dev)) | ||
| 373 | hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) + | ||
| 374 | MT_DMA_HDR_LEN; | ||
| 372 | 375 | ||
| 373 | hw->sta_data_size = sizeof(struct mt76x02_sta); | 376 | hw->sta_data_size = sizeof(struct mt76x02_sta); |
| 374 | hw->vif_data_size = sizeof(struct mt76x02_vif); | 377 | hw->vif_data_size = sizeof(struct mt76x02_vif); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index c9cd0254a979..9273d2d2764a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c | |||
| @@ -16,6 +16,20 @@ | |||
| 16 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
| 17 | #include "mt76x0.h" | 17 | #include "mt76x0.h" |
| 18 | 18 | ||
| 19 | static int | ||
| 20 | mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef) | ||
| 21 | { | ||
| 22 | int ret; | ||
| 23 | |||
| 24 | cancel_delayed_work_sync(&dev->cal_work); | ||
| 25 | |||
| 26 | mt76_set_channel(&dev->mt76); | ||
| 27 | ret = mt76x0_phy_set_channel(dev, chandef); | ||
| 28 | mt76_txq_schedule_all(&dev->mt76); | ||
| 29 | |||
| 30 | return ret; | ||
| 31 | } | ||
| 32 | |||
| 19 | int mt76x0_config(struct ieee80211_hw *hw, u32 changed) | 33 | int mt76x0_config(struct ieee80211_hw *hw, u32 changed) |
| 20 | { | 34 | { |
| 21 | struct mt76x02_dev *dev = hw->priv; | 35 | struct mt76x02_dev *dev = hw->priv; |
| @@ -25,7 +39,7 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed) | |||
| 25 | 39 | ||
| 26 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 40 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 27 | ieee80211_stop_queues(hw); | 41 | ieee80211_stop_queues(hw); |
| 28 | ret = mt76x0_phy_set_channel(dev, &hw->conf.chandef); | 42 | ret = mt76x0_set_channel(dev, &hw->conf.chandef); |
| 29 | ieee80211_wake_queues(hw); | 43 | ieee80211_wake_queues(hw); |
| 30 | } | 44 | } |
| 31 | 45 | ||
| @@ -114,8 +128,6 @@ void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 114 | { | 128 | { |
| 115 | struct mt76x02_dev *dev = hw->priv; | 129 | struct mt76x02_dev *dev = hw->priv; |
| 116 | 130 | ||
| 117 | cancel_delayed_work_sync(&dev->cal_work); | ||
| 118 | mt76x0_agc_save(dev); | ||
| 119 | set_bit(MT76_SCANNING, &dev->mt76.state); | 131 | set_bit(MT76_SCANNING, &dev->mt76.state); |
| 120 | } | 132 | } |
| 121 | EXPORT_SYMBOL_GPL(mt76x0_sw_scan); | 133 | EXPORT_SYMBOL_GPL(mt76x0_sw_scan); |
| @@ -125,11 +137,7 @@ void mt76x0_sw_scan_complete(struct ieee80211_hw *hw, | |||
| 125 | { | 137 | { |
| 126 | struct mt76x02_dev *dev = hw->priv; | 138 | struct mt76x02_dev *dev = hw->priv; |
| 127 | 139 | ||
| 128 | mt76x0_agc_restore(dev); | ||
| 129 | clear_bit(MT76_SCANNING, &dev->mt76.state); | 140 | clear_bit(MT76_SCANNING, &dev->mt76.state); |
| 130 | |||
| 131 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, | ||
| 132 | MT_CALIBRATE_INTERVAL); | ||
| 133 | } | 141 | } |
| 134 | EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete); | 142 | EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete); |
| 135 | 143 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index b66e70f6cd89..3b34e1d2769f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h | |||
| @@ -39,6 +39,9 @@ enum mcu_calibrate { | |||
| 39 | MCU_CAL_TXDCOC, | 39 | MCU_CAL_TXDCOC, |
| 40 | MCU_CAL_RX_GROUP_DELAY, | 40 | MCU_CAL_RX_GROUP_DELAY, |
| 41 | MCU_CAL_TX_GROUP_DELAY, | 41 | MCU_CAL_TX_GROUP_DELAY, |
| 42 | MCU_CAL_VCO, | ||
| 43 | MCU_CAL_NO_SIGNAL = 0xfe, | ||
| 44 | MCU_CAL_FULL = 0xff, | ||
| 42 | }; | 45 | }; |
| 43 | 46 | ||
| 44 | int mt76x0e_mcu_init(struct mt76x02_dev *dev); | 47 | int mt76x0e_mcu_init(struct mt76x02_dev *dev); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 1bff2be45a13..2187bafaf2e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | |||
| @@ -66,12 +66,11 @@ int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value); | |||
| 66 | /* PHY */ | 66 | /* PHY */ |
| 67 | void mt76x0_phy_init(struct mt76x02_dev *dev); | 67 | void mt76x0_phy_init(struct mt76x02_dev *dev); |
| 68 | int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev); | 68 | int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev); |
| 69 | void mt76x0_agc_save(struct mt76x02_dev *dev); | ||
| 70 | void mt76x0_agc_restore(struct mt76x02_dev *dev); | ||
| 71 | int mt76x0_phy_set_channel(struct mt76x02_dev *dev, | 69 | int mt76x0_phy_set_channel(struct mt76x02_dev *dev, |
| 72 | struct cfg80211_chan_def *chandef); | 70 | struct cfg80211_chan_def *chandef); |
| 73 | void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev); | 71 | void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev); |
| 74 | void mt76x0_phy_set_txpower(struct mt76x02_dev *dev); | 72 | void mt76x0_phy_set_txpower(struct mt76x02_dev *dev); |
| 73 | void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on); | ||
| 75 | 74 | ||
| 76 | /* MAC */ | 75 | /* MAC */ |
| 77 | void mt76x0_mac_work(struct work_struct *work); | 76 | void mt76x0_mac_work(struct work_struct *work); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c index 87997cddf0d6..522c86059bcb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | |||
| @@ -28,6 +28,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw) | |||
| 28 | mutex_lock(&dev->mt76.mutex); | 28 | mutex_lock(&dev->mt76.mutex); |
| 29 | 29 | ||
| 30 | mt76x02_mac_start(dev); | 30 | mt76x02_mac_start(dev); |
| 31 | mt76x0_phy_calibrate(dev, true); | ||
| 31 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, | 32 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, |
| 32 | MT_CALIBRATE_INTERVAL); | 33 | MT_CALIBRATE_INTERVAL); |
| 33 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, | 34 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, |
| @@ -71,10 +72,19 @@ static const struct ieee80211_ops mt76x0e_ops = { | |||
| 71 | .tx = mt76x02_tx, | 72 | .tx = mt76x02_tx, |
| 72 | .start = mt76x0e_start, | 73 | .start = mt76x0e_start, |
| 73 | .stop = mt76x0e_stop, | 74 | .stop = mt76x0e_stop, |
| 74 | .config = mt76x0_config, | ||
| 75 | .add_interface = mt76x02_add_interface, | 75 | .add_interface = mt76x02_add_interface, |
| 76 | .remove_interface = mt76x02_remove_interface, | 76 | .remove_interface = mt76x02_remove_interface, |
| 77 | .config = mt76x0_config, | ||
| 77 | .configure_filter = mt76x02_configure_filter, | 78 | .configure_filter = mt76x02_configure_filter, |
| 79 | .sta_add = mt76x02_sta_add, | ||
| 80 | .sta_remove = mt76x02_sta_remove, | ||
| 81 | .set_key = mt76x02_set_key, | ||
| 82 | .conf_tx = mt76x02_conf_tx, | ||
| 83 | .sw_scan_start = mt76x0_sw_scan, | ||
| 84 | .sw_scan_complete = mt76x0_sw_scan_complete, | ||
| 85 | .ampdu_action = mt76x02_ampdu_action, | ||
| 86 | .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, | ||
| 87 | .wake_tx_queue = mt76_wake_tx_queue, | ||
| 78 | }; | 88 | }; |
| 79 | 89 | ||
| 80 | static int mt76x0e_register_device(struct mt76x02_dev *dev) | 90 | static int mt76x0e_register_device(struct mt76x02_dev *dev) |
| @@ -102,28 +112,34 @@ static int mt76x0e_register_device(struct mt76x02_dev *dev) | |||
| 102 | u16 val; | 112 | u16 val; |
| 103 | 113 | ||
| 104 | mt76_clear(dev, MT_COEXCFG0, BIT(0)); | 114 | mt76_clear(dev, MT_COEXCFG0, BIT(0)); |
| 105 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_0); | 115 | |
| 106 | if (val & MT_EE_NIC_CONF_0_PA_IO_CURRENT) { | 116 | val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); |
| 107 | u32 data; | 117 | if (!(val & MT_EE_NIC_CONF_0_PA_IO_CURRENT)) |
| 108 | 118 | mt76_set(dev, MT_XO_CTRL7, 0xc03); | |
| 109 | /* set external external PA I/O | ||
| 110 | * current to 16mA | ||
| 111 | */ | ||
| 112 | data = mt76_rr(dev, 0x11c); | ||
| 113 | val |= 0xc03; | ||
| 114 | mt76_wr(dev, 0x11c, val); | ||
| 115 | } | ||
| 116 | } | 119 | } |
| 117 | 120 | ||
| 118 | mt76_clear(dev, 0x110, BIT(9)); | 121 | mt76_clear(dev, 0x110, BIT(9)); |
| 119 | mt76_set(dev, MT_MAX_LEN_CFG, BIT(13)); | 122 | mt76_set(dev, MT_MAX_LEN_CFG, BIT(13)); |
| 120 | 123 | ||
| 124 | err = mt76x0_register_device(dev); | ||
| 125 | if (err < 0) | ||
| 126 | return err; | ||
| 127 | |||
| 128 | set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); | ||
| 129 | |||
| 121 | return 0; | 130 | return 0; |
| 122 | } | 131 | } |
| 123 | 132 | ||
| 124 | static int | 133 | static int |
| 125 | mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 134 | mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| 126 | { | 135 | { |
| 136 | static const struct mt76_driver_ops drv_ops = { | ||
| 137 | .txwi_size = sizeof(struct mt76x02_txwi), | ||
| 138 | .tx_prepare_skb = mt76x02_tx_prepare_skb, | ||
| 139 | .tx_complete_skb = mt76x02_tx_complete_skb, | ||
| 140 | .rx_skb = mt76x02_queue_rx_skb, | ||
| 141 | .rx_poll_complete = mt76x02_rx_poll_complete, | ||
| 142 | }; | ||
| 127 | struct mt76x02_dev *dev; | 143 | struct mt76x02_dev *dev; |
| 128 | int ret; | 144 | int ret; |
| 129 | 145 | ||
| @@ -141,7 +157,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 141 | if (ret) | 157 | if (ret) |
| 142 | return ret; | 158 | return ret; |
| 143 | 159 | ||
| 144 | dev = mt76x0_alloc_device(&pdev->dev, NULL, &mt76x0e_ops); | 160 | dev = mt76x0_alloc_device(&pdev->dev, &drv_ops, &mt76x0e_ops); |
| 145 | if (!dev) | 161 | if (!dev) |
| 146 | return -ENOMEM; | 162 | return -ENOMEM; |
| 147 | 163 | ||
| @@ -150,6 +166,11 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 150 | dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); | 166 | dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); |
| 151 | dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); | 167 | dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); |
| 152 | 168 | ||
| 169 | ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x02_irq_handler, | ||
| 170 | IRQF_SHARED, KBUILD_MODNAME, dev); | ||
| 171 | if (ret) | ||
| 172 | goto error; | ||
| 173 | |||
| 153 | ret = mt76x0e_register_device(dev); | 174 | ret = mt76x0e_register_device(dev); |
| 154 | if (ret < 0) | 175 | if (ret < 0) |
| 155 | goto error; | 176 | goto error; |
| @@ -167,7 +188,7 @@ static void mt76x0e_cleanup(struct mt76x02_dev *dev) | |||
| 167 | mt76x0_chip_onoff(dev, false, false); | 188 | mt76x0_chip_onoff(dev, false, false); |
| 168 | mt76x0e_stop_hw(dev); | 189 | mt76x0e_stop_hw(dev); |
| 169 | mt76x02_dma_cleanup(dev); | 190 | mt76x02_dma_cleanup(dev); |
| 170 | mt76x02_mcu_cleanup(&dev->mt76); | 191 | mt76x02_mcu_cleanup(dev); |
| 171 | } | 192 | } |
| 172 | 193 | ||
| 173 | static void | 194 | static void |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c index 6c66656c21f4..569861289aa5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c | |||
| @@ -116,6 +116,7 @@ static int mt76x0e_load_firmware(struct mt76x02_dev *dev) | |||
| 116 | goto out; | 116 | goto out; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | mt76x02_set_ethtool_fwver(dev, hdr); | ||
| 119 | dev_dbg(dev->mt76.dev, "Firmware running!\n"); | 120 | dev_dbg(dev->mt76.dev, "Firmware running!\n"); |
| 120 | 121 | ||
| 121 | out: | 122 | out: |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 4850a2db18d7..cf024950e0ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/etherdevice.h> | ||
| 19 | |||
| 17 | #include "mt76x0.h" | 20 | #include "mt76x0.h" |
| 18 | #include "mcu.h" | 21 | #include "mcu.h" |
| 19 | #include "eeprom.h" | 22 | #include "eeprom.h" |
| @@ -23,8 +26,6 @@ | |||
| 23 | #include "initvals_phy.h" | 26 | #include "initvals_phy.h" |
| 24 | #include "../mt76x02_phy.h" | 27 | #include "../mt76x02_phy.h" |
| 25 | 28 | ||
| 26 | #include <linux/etherdevice.h> | ||
| 27 | |||
| 28 | static int | 29 | static int |
| 29 | mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value) | 30 | mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value) |
| 30 | { | 31 | { |
| @@ -37,7 +38,7 @@ mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value) | |||
| 37 | bank = MT_RF_BANK(offset); | 38 | bank = MT_RF_BANK(offset); |
| 38 | reg = MT_RF_REG(offset); | 39 | reg = MT_RF_REG(offset); |
| 39 | 40 | ||
| 40 | if (WARN_ON_ONCE(reg > 64) || WARN_ON_ONCE(bank) > 8) | 41 | if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8)) |
| 41 | return -EINVAL; | 42 | return -EINVAL; |
| 42 | 43 | ||
| 43 | mutex_lock(&dev->phy_mutex); | 44 | mutex_lock(&dev->phy_mutex); |
| @@ -76,7 +77,7 @@ static int mt76x0_rf_csr_rr(struct mt76x02_dev *dev, u32 offset) | |||
| 76 | bank = MT_RF_BANK(offset); | 77 | bank = MT_RF_BANK(offset); |
| 77 | reg = MT_RF_REG(offset); | 78 | reg = MT_RF_REG(offset); |
| 78 | 79 | ||
| 79 | if (WARN_ON_ONCE(reg > 64) || WARN_ON_ONCE(bank) > 8) | 80 | if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8)) |
| 80 | return -EINVAL; | 81 | return -EINVAL; |
| 81 | 82 | ||
| 82 | mutex_lock(&dev->phy_mutex); | 83 | mutex_lock(&dev->phy_mutex); |
| @@ -111,15 +112,16 @@ out: | |||
| 111 | static int | 112 | static int |
| 112 | rf_wr(struct mt76x02_dev *dev, u32 offset, u8 val) | 113 | rf_wr(struct mt76x02_dev *dev, u32 offset, u8 val) |
| 113 | { | 114 | { |
| 114 | if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state)) { | 115 | if (mt76_is_usb(dev)) { |
| 115 | struct mt76_reg_pair pair = { | 116 | struct mt76_reg_pair pair = { |
| 116 | .reg = offset, | 117 | .reg = offset, |
| 117 | .value = val, | 118 | .value = val, |
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 121 | WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING, | ||
| 122 | &dev->mt76.state)); | ||
| 120 | return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); | 123 | return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); |
| 121 | } else { | 124 | } else { |
| 122 | WARN_ON_ONCE(1); | ||
| 123 | return mt76x0_rf_csr_wr(dev, offset, val); | 125 | return mt76x0_rf_csr_wr(dev, offset, val); |
| 124 | } | 126 | } |
| 125 | } | 127 | } |
| @@ -130,15 +132,16 @@ rf_rr(struct mt76x02_dev *dev, u32 offset) | |||
| 130 | int ret; | 132 | int ret; |
| 131 | u32 val; | 133 | u32 val; |
| 132 | 134 | ||
| 133 | if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state)) { | 135 | if (mt76_is_usb(dev)) { |
| 134 | struct mt76_reg_pair pair = { | 136 | struct mt76_reg_pair pair = { |
| 135 | .reg = offset, | 137 | .reg = offset, |
| 136 | }; | 138 | }; |
| 137 | 139 | ||
| 140 | WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING, | ||
| 141 | &dev->mt76.state)); | ||
| 138 | ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); | 142 | ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); |
| 139 | val = pair.value; | 143 | val = pair.value; |
| 140 | } else { | 144 | } else { |
| 141 | WARN_ON_ONCE(1); | ||
| 142 | ret = val = mt76x0_rf_csr_rr(dev, offset); | 145 | ret = val = mt76x0_rf_csr_rr(dev, offset); |
| 143 | } | 146 | } |
| 144 | 147 | ||
| @@ -175,9 +178,22 @@ rf_clear(struct mt76x02_dev *dev, u32 offset, u8 mask) | |||
| 175 | } | 178 | } |
| 176 | #endif | 179 | #endif |
| 177 | 180 | ||
| 178 | #define RF_RANDOM_WRITE(dev, tab) \ | 181 | static void |
| 179 | mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, \ | 182 | mt76x0_rf_csr_wr_rp(struct mt76x02_dev *dev, const struct mt76_reg_pair *data, |
| 180 | tab, ARRAY_SIZE(tab)) | 183 | int n) |
| 184 | { | ||
| 185 | while (n-- > 0) { | ||
| 186 | mt76x0_rf_csr_wr(dev, data->reg, data->value); | ||
| 187 | data++; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | #define RF_RANDOM_WRITE(dev, tab) do { \ | ||
| 192 | if (mt76_is_mmio(dev)) \ | ||
| 193 | mt76x0_rf_csr_wr_rp(dev, tab, ARRAY_SIZE(tab)); \ | ||
| 194 | else \ | ||
| 195 | mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, tab, ARRAY_SIZE(tab));\ | ||
| 196 | } while (0) | ||
| 181 | 197 | ||
| 182 | int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) | 198 | int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) |
| 183 | { | 199 | { |
| @@ -186,7 +202,6 @@ int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) | |||
| 186 | 202 | ||
| 187 | do { | 203 | do { |
| 188 | val = mt76_rr(dev, MT_BBP(CORE, 0)); | 204 | val = mt76_rr(dev, MT_BBP(CORE, 0)); |
| 189 | printk("BBP version %08x\n", val); | ||
| 190 | if (val && ~val) | 205 | if (val && ~val) |
| 191 | break; | 206 | break; |
| 192 | } while (--i); | 207 | } while (--i); |
| @@ -196,36 +211,10 @@ int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) | |||
| 196 | return -EIO; | 211 | return -EIO; |
| 197 | } | 212 | } |
| 198 | 213 | ||
| 214 | dev_dbg(dev->mt76.dev, "BBP version %08x\n", val); | ||
| 199 | return 0; | 215 | return 0; |
| 200 | } | 216 | } |
| 201 | 217 | ||
| 202 | static void | ||
| 203 | mt76x0_bbp_set_ctrlch(struct mt76x02_dev *dev, enum nl80211_chan_width width, | ||
| 204 | u8 ctrl) | ||
| 205 | { | ||
| 206 | int core_val, agc_val; | ||
| 207 | |||
| 208 | switch (width) { | ||
| 209 | case NL80211_CHAN_WIDTH_80: | ||
| 210 | core_val = 3; | ||
| 211 | agc_val = 7; | ||
| 212 | break; | ||
| 213 | case NL80211_CHAN_WIDTH_40: | ||
| 214 | core_val = 2; | ||
| 215 | agc_val = 3; | ||
| 216 | break; | ||
| 217 | default: | ||
| 218 | core_val = 0; | ||
| 219 | agc_val = 1; | ||
| 220 | break; | ||
| 221 | } | ||
| 222 | |||
| 223 | mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val); | ||
| 224 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val); | ||
| 225 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl); | ||
| 226 | mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); | ||
| 227 | } | ||
| 228 | |||
| 229 | static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel) | 218 | static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel) |
| 230 | { | 219 | { |
| 231 | u8 val; | 220 | u8 val; |
| @@ -283,13 +272,6 @@ static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel) | |||
| 283 | } | 272 | } |
| 284 | 273 | ||
| 285 | static void | 274 | static void |
| 286 | mt76x0_mac_set_ctrlch(struct mt76x02_dev *dev, bool primary_upper) | ||
| 287 | { | ||
| 288 | mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M, | ||
| 289 | primary_upper); | ||
| 290 | } | ||
| 291 | |||
| 292 | static void | ||
| 293 | mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) | 275 | mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) |
| 294 | { | 276 | { |
| 295 | switch (band) { | 277 | switch (band) { |
| @@ -299,9 +281,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) | |||
| 299 | rf_wr(dev, MT_RF(5, 0), 0x45); | 281 | rf_wr(dev, MT_RF(5, 0), 0x45); |
| 300 | rf_wr(dev, MT_RF(6, 0), 0x44); | 282 | rf_wr(dev, MT_RF(6, 0), 0x44); |
| 301 | 283 | ||
| 302 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 303 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 304 | |||
| 305 | mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007); | 284 | mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007); |
| 306 | mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002); | 285 | mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002); |
| 307 | break; | 286 | break; |
| @@ -311,9 +290,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) | |||
| 311 | rf_wr(dev, MT_RF(5, 0), 0x44); | 290 | rf_wr(dev, MT_RF(5, 0), 0x44); |
| 312 | rf_wr(dev, MT_RF(6, 0), 0x45); | 291 | rf_wr(dev, MT_RF(6, 0), 0x45); |
| 313 | 292 | ||
| 314 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 315 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 316 | |||
| 317 | mt76_wr(dev, MT_TX_ALC_VGA3, 0x00000005); | 293 | mt76_wr(dev, MT_TX_ALC_VGA3, 0x00000005); |
| 318 | mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102); | 294 | mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102); |
| 319 | break; | 295 | break; |
| @@ -475,7 +451,7 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban | |||
| 475 | mt76_wr(dev, MT_RF_MISC, mac_reg); | 451 | mt76_wr(dev, MT_RF_MISC, mac_reg); |
| 476 | 452 | ||
| 477 | band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; | 453 | band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; |
| 478 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { | 454 | if (mt76x02_ext_pa_enabled(dev, band)) { |
| 479 | /* | 455 | /* |
| 480 | MT_RF_MISC (offset: 0x0518) | 456 | MT_RF_MISC (offset: 0x0518) |
| 481 | [2]1'b1: enable external A band PA, 1'b0: disable external A band PA | 457 | [2]1'b1: enable external A band PA, 1'b0: disable external A band PA |
| @@ -514,7 +490,7 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban | |||
| 514 | } | 490 | } |
| 515 | 491 | ||
| 516 | static void | 492 | static void |
| 517 | mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_band) | 493 | mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u16 rf_bw_band) |
| 518 | { | 494 | { |
| 519 | int i; | 495 | int i; |
| 520 | 496 | ||
| @@ -587,7 +563,7 @@ mt76x0_bbp_set_bw(struct mt76x02_dev *dev, enum nl80211_chan_width width) | |||
| 587 | return ; | 563 | return ; |
| 588 | } | 564 | } |
| 589 | 565 | ||
| 590 | mt76x02_mcu_function_select(&dev->mt76, BW_SETTING, bw, false); | 566 | mt76x02_mcu_function_select(dev, BW_SETTING, bw, false); |
| 591 | } | 567 | } |
| 592 | 568 | ||
| 593 | void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) | 569 | void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) |
| @@ -603,8 +579,50 @@ void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) | |||
| 603 | dev->mt76.txpower_cur = mt76x02_get_max_rate_power(t); | 579 | dev->mt76.txpower_cur = mt76x02_get_max_rate_power(t); |
| 604 | mt76x02_add_rate_power_offset(t, -info[0]); | 580 | mt76x02_add_rate_power_offset(t, -info[0]); |
| 605 | 581 | ||
| 606 | mt76x02_phy_set_txpower(&dev->mt76, info[0], info[1]); | 582 | mt76x02_phy_set_txpower(dev, info[0], info[1]); |
| 583 | } | ||
| 584 | |||
| 585 | void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on) | ||
| 586 | { | ||
| 587 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; | ||
| 588 | u32 val, tx_alc, reg_val; | ||
| 589 | |||
| 590 | if (power_on) { | ||
| 591 | mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false); | ||
| 592 | mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value, | ||
| 593 | false); | ||
| 594 | usleep_range(10, 20); | ||
| 595 | /* XXX: tssi */ | ||
| 596 | } | ||
| 597 | |||
| 598 | tx_alc = mt76_rr(dev, MT_TX_ALC_CFG_0); | ||
| 599 | mt76_wr(dev, MT_TX_ALC_CFG_0, 0); | ||
| 600 | usleep_range(500, 700); | ||
| 601 | |||
| 602 | reg_val = mt76_rr(dev, MT_BBP(IBI, 9)); | ||
| 603 | mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e); | ||
| 604 | |||
| 605 | if (chan->band == NL80211_BAND_5GHZ) { | ||
| 606 | if (chan->hw_value < 100) | ||
| 607 | val = 0x701; | ||
| 608 | else if (chan->hw_value < 140) | ||
| 609 | val = 0x801; | ||
| 610 | else | ||
| 611 | val = 0x901; | ||
| 612 | } else { | ||
| 613 | val = 0x600; | ||
| 614 | } | ||
| 615 | |||
| 616 | mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val, false); | ||
| 617 | msleep(350); | ||
| 618 | mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 1, false); | ||
| 619 | usleep_range(15000, 20000); | ||
| 620 | |||
| 621 | mt76_wr(dev, MT_BBP(IBI, 9), reg_val); | ||
| 622 | mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); | ||
| 623 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false); | ||
| 607 | } | 624 | } |
| 625 | EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate); | ||
| 608 | 626 | ||
| 609 | int mt76x0_phy_set_channel(struct mt76x02_dev *dev, | 627 | int mt76x0_phy_set_channel(struct mt76x02_dev *dev, |
| 610 | struct cfg80211_chan_def *chandef) | 628 | struct cfg80211_chan_def *chandef) |
| @@ -665,9 +683,19 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, | |||
| 665 | break; | 683 | break; |
| 666 | } | 684 | } |
| 667 | 685 | ||
| 668 | mt76x0_bbp_set_bw(dev, chandef->width); | 686 | if (mt76_is_usb(dev)) { |
| 669 | mt76x0_bbp_set_ctrlch(dev, chandef->width, ch_group_index); | 687 | mt76x0_bbp_set_bw(dev, chandef->width); |
| 670 | mt76x0_mac_set_ctrlch(dev, ch_group_index & 1); | 688 | } else { |
| 689 | if (chandef->width == NL80211_CHAN_WIDTH_80 || | ||
| 690 | chandef->width == NL80211_CHAN_WIDTH_40) | ||
| 691 | val = 0x201; | ||
| 692 | else | ||
| 693 | val = 0x601; | ||
| 694 | mt76_wr(dev, MT_TX_SW_CFG0, val); | ||
| 695 | } | ||
| 696 | mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); | ||
| 697 | mt76x02_phy_set_band(dev, chandef->chan->band, | ||
| 698 | ch_group_index & 1); | ||
| 671 | mt76x0_ant_select(dev); | 699 | mt76x0_ant_select(dev); |
| 672 | 700 | ||
| 673 | mt76_rmw(dev, MT_EXT_CCA_CFG, | 701 | mt76_rmw(dev, MT_EXT_CCA_CFG, |
| @@ -680,7 +708,6 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, | |||
| 680 | 708 | ||
| 681 | mt76x0_phy_set_band(dev, chandef->chan->band); | 709 | mt76x0_phy_set_band(dev, chandef->chan->band); |
| 682 | mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band); | 710 | mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band); |
| 683 | mt76x0_read_rx_gain(dev); | ||
| 684 | 711 | ||
| 685 | /* set Japan Tx filter at channel 14 */ | 712 | /* set Japan Tx filter at channel 14 */ |
| 686 | val = mt76_rr(dev, MT_BBP(CORE, 1)); | 713 | val = mt76_rr(dev, MT_BBP(CORE, 1)); |
| @@ -690,17 +717,27 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, | |||
| 690 | val &= ~0x20; | 717 | val &= ~0x20; |
| 691 | mt76_wr(dev, MT_BBP(CORE, 1), val); | 718 | mt76_wr(dev, MT_BBP(CORE, 1), val); |
| 692 | 719 | ||
| 693 | mt76x0_phy_set_chan_bbp_params(dev, channel, rf_bw_band); | 720 | mt76x0_read_rx_gain(dev); |
| 721 | mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band); | ||
| 722 | mt76x02_init_agc_gain(dev); | ||
| 694 | 723 | ||
| 695 | /* Vendor driver don't do it */ | 724 | if (mt76_is_usb(dev)) { |
| 696 | /* mt76x0_phy_set_tx_power(dev, channel, rf_bw_band); */ | 725 | mt76x0_vco_cal(dev, channel); |
| 726 | } else { | ||
| 727 | /* enable vco */ | ||
| 728 | rf_set(dev, MT_RF(0, 4), BIT(7)); | ||
| 729 | } | ||
| 697 | 730 | ||
| 698 | mt76x0_vco_cal(dev, channel); | ||
| 699 | if (scan) | 731 | if (scan) |
| 700 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); | 732 | return 0; |
| 701 | 733 | ||
| 734 | if (mt76_is_mmio(dev)) | ||
| 735 | mt76x0_phy_calibrate(dev, false); | ||
| 702 | mt76x0_phy_set_txpower(dev); | 736 | mt76x0_phy_set_txpower(dev); |
| 703 | 737 | ||
| 738 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, | ||
| 739 | MT_CALIBRATE_INTERVAL); | ||
| 740 | |||
| 704 | return 0; | 741 | return 0; |
| 705 | } | 742 | } |
| 706 | 743 | ||
| @@ -710,7 +747,7 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev) | |||
| 710 | u8 channel = dev->mt76.chandef.chan->hw_value; | 747 | u8 channel = dev->mt76.chandef.chan->hw_value; |
| 711 | int is_5ghz = (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) ? 1 : 0; | 748 | int is_5ghz = (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) ? 1 : 0; |
| 712 | 749 | ||
| 713 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, false); | 750 | mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false); |
| 714 | 751 | ||
| 715 | mt76x0_vco_cal(dev, channel); | 752 | mt76x0_vco_cal(dev, channel); |
| 716 | 753 | ||
| @@ -718,109 +755,113 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev) | |||
| 718 | mt76_wr(dev, MT_TX_ALC_CFG_0, 0); | 755 | mt76_wr(dev, MT_TX_ALC_CFG_0, 0); |
| 719 | usleep_range(500, 700); | 756 | usleep_range(500, 700); |
| 720 | 757 | ||
| 721 | reg_val = mt76_rr(dev, 0x2124); | 758 | reg_val = mt76_rr(dev, MT_BBP(IBI, 9)); |
| 722 | reg_val &= 0xffffff7e; | 759 | mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e); |
| 723 | mt76_wr(dev, 0x2124, reg_val); | ||
| 724 | 760 | ||
| 725 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 0, false); | 761 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 0, false); |
| 726 | 762 | ||
| 727 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, is_5ghz, false); | 763 | mt76x02_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz, false); |
| 728 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LOFT, is_5ghz, false); | 764 | mt76x02_mcu_calibrate(dev, MCU_CAL_LOFT, is_5ghz, false); |
| 729 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false); | 765 | mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, false); |
| 730 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_GROUP_DELAY, | 766 | mt76x02_mcu_calibrate(dev, MCU_CAL_TX_GROUP_DELAY, is_5ghz, false); |
| 731 | is_5ghz, false); | 767 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQ, is_5ghz, false); |
| 732 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQ, is_5ghz, false); | 768 | mt76x02_mcu_calibrate(dev, MCU_CAL_RX_GROUP_DELAY, is_5ghz, false); |
| 733 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RX_GROUP_DELAY, | ||
| 734 | is_5ghz, false); | ||
| 735 | 769 | ||
| 736 | mt76_wr(dev, 0x2124, reg_val); | 770 | mt76_wr(dev, MT_BBP(IBI, 9), reg_val); |
| 737 | mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); | 771 | mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); |
| 738 | msleep(100); | 772 | msleep(100); |
| 739 | 773 | ||
| 740 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); | 774 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false); |
| 741 | } | ||
| 742 | |||
| 743 | void mt76x0_agc_save(struct mt76x02_dev *dev) | ||
| 744 | { | ||
| 745 | /* Only one RX path */ | ||
| 746 | dev->agc_save = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, 8))); | ||
| 747 | } | ||
| 748 | |||
| 749 | void mt76x0_agc_restore(struct mt76x02_dev *dev) | ||
| 750 | { | ||
| 751 | mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, dev->agc_save); | ||
| 752 | } | 775 | } |
| 753 | 776 | ||
| 754 | static void mt76x0_temp_sensor(struct mt76x02_dev *dev) | 777 | static void mt76x0_temp_sensor(struct mt76x02_dev *dev) |
| 755 | { | 778 | { |
| 756 | u8 rf_b7_73, rf_b0_66, rf_b0_67; | 779 | u8 rf_b7_73, rf_b0_66, rf_b0_67; |
| 757 | int cycle, temp; | 780 | s8 val; |
| 758 | u32 val; | ||
| 759 | s32 sval; | ||
| 760 | 781 | ||
| 761 | rf_b7_73 = rf_rr(dev, MT_RF(7, 73)); | 782 | rf_b7_73 = rf_rr(dev, MT_RF(7, 73)); |
| 762 | rf_b0_66 = rf_rr(dev, MT_RF(0, 66)); | 783 | rf_b0_66 = rf_rr(dev, MT_RF(0, 66)); |
| 763 | rf_b0_67 = rf_rr(dev, MT_RF(0, 73)); | 784 | rf_b0_67 = rf_rr(dev, MT_RF(0, 67)); |
| 764 | 785 | ||
| 765 | rf_wr(dev, MT_RF(7, 73), 0x02); | 786 | rf_wr(dev, MT_RF(7, 73), 0x02); |
| 766 | rf_wr(dev, MT_RF(0, 66), 0x23); | 787 | rf_wr(dev, MT_RF(0, 66), 0x23); |
| 767 | rf_wr(dev, MT_RF(0, 73), 0x01); | 788 | rf_wr(dev, MT_RF(0, 67), 0x01); |
| 768 | 789 | ||
| 769 | mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055); | 790 | mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055); |
| 770 | 791 | ||
| 771 | for (cycle = 0; cycle < 2000; cycle++) { | 792 | if (!mt76_poll(dev, MT_BBP(CORE, 34), BIT(4), 0, 2000)) { |
| 772 | val = mt76_rr(dev, MT_BBP(CORE, 34)); | 793 | mt76_clear(dev, MT_BBP(CORE, 34), BIT(4)); |
| 773 | if (!(val & 0x10)) | ||
| 774 | break; | ||
| 775 | udelay(3); | ||
| 776 | } | ||
| 777 | |||
| 778 | if (cycle >= 2000) { | ||
| 779 | val &= 0x10; | ||
| 780 | mt76_wr(dev, MT_BBP(CORE, 34), val); | ||
| 781 | goto done; | 794 | goto done; |
| 782 | } | 795 | } |
| 783 | 796 | ||
| 784 | sval = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff; | 797 | val = mt76_rr(dev, MT_BBP(CORE, 35)); |
| 785 | if (!(sval & 0x80)) | 798 | val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25; |
| 786 | sval &= 0x7f; /* Positive */ | ||
| 787 | else | ||
| 788 | sval |= 0xffffff00; /* Negative */ | ||
| 789 | 799 | ||
| 790 | temp = (35 * (sval - dev->cal.rx.temp_offset)) / 10 + 25; | 800 | if (abs(val - dev->cal.temp_vco) > 20) { |
| 801 | mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, | ||
| 802 | dev->mt76.chandef.chan->hw_value, | ||
| 803 | false); | ||
| 804 | dev->cal.temp_vco = val; | ||
| 805 | } | ||
| 806 | if (abs(val - dev->cal.temp) > 30) { | ||
| 807 | mt76x0_phy_calibrate(dev, false); | ||
| 808 | dev->cal.temp = val; | ||
| 809 | } | ||
| 791 | 810 | ||
| 792 | done: | 811 | done: |
| 793 | rf_wr(dev, MT_RF(7, 73), rf_b7_73); | 812 | rf_wr(dev, MT_RF(7, 73), rf_b7_73); |
| 794 | rf_wr(dev, MT_RF(0, 66), rf_b0_66); | 813 | rf_wr(dev, MT_RF(0, 66), rf_b0_66); |
| 795 | rf_wr(dev, MT_RF(0, 73), rf_b0_67); | 814 | rf_wr(dev, MT_RF(0, 67), rf_b0_67); |
| 796 | } | 815 | } |
| 797 | 816 | ||
| 798 | static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev *dev) | 817 | static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev) |
| 799 | { | 818 | { |
| 800 | struct cfg80211_chan_def *chandef = &dev->mt76.chandef; | 819 | u8 gain = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust; |
| 801 | u32 val, init_vga; | 820 | u32 val = 0x122c << 16 | 0xf2; |
| 802 | int avg_rssi; | 821 | |
| 803 | 822 | mt76_wr(dev, MT_BBP(AGC, 8), | |
| 804 | init_vga = chandef->chan->band == NL80211_BAND_5GHZ ? 0x54 : 0x4E; | 823 | val | FIELD_PREP(MT_BBP_AGC_GAIN, gain)); |
| 805 | avg_rssi = mt76x02_phy_get_min_avg_rssi(&dev->mt76); | 824 | } |
| 806 | if (avg_rssi > -60) | 825 | |
| 807 | init_vga -= 0x20; | 826 | static void |
| 808 | else if (avg_rssi > -70) | 827 | mt76x0_phy_update_channel_gain(struct mt76x02_dev *dev) |
| 809 | init_vga -= 0x10; | 828 | { |
| 810 | 829 | bool gain_change; | |
| 811 | val = mt76_rr(dev, MT_BBP(AGC, 8)); | 830 | u8 gain_delta; |
| 812 | val &= 0xFFFF80FF; | 831 | int low_gain; |
| 813 | val |= init_vga << 8; | 832 | |
| 814 | mt76_wr(dev, MT_BBP(AGC,8), val); | 833 | dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev); |
| 834 | |||
| 835 | low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) + | ||
| 836 | (dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev)); | ||
| 837 | |||
| 838 | gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2); | ||
| 839 | dev->cal.low_gain = low_gain; | ||
| 840 | |||
| 841 | if (!gain_change) { | ||
| 842 | if (mt76x02_phy_adjust_vga_gain(dev)) | ||
| 843 | mt76x0_phy_set_gain_val(dev); | ||
| 844 | return; | ||
| 845 | } | ||
| 846 | |||
| 847 | dev->cal.agc_gain_adjust = (low_gain == 2) ? 0 : 10; | ||
| 848 | gain_delta = (low_gain == 2) ? 10 : 0; | ||
| 849 | |||
| 850 | dev->cal.agc_gain_cur[0] = dev->cal.agc_gain_init[0] - gain_delta; | ||
| 851 | mt76x0_phy_set_gain_val(dev); | ||
| 852 | |||
| 853 | /* clear false CCA counters */ | ||
| 854 | mt76_rr(dev, MT_RX_STAT_1); | ||
| 815 | } | 855 | } |
| 816 | 856 | ||
| 817 | static void mt76x0_phy_calibrate(struct work_struct *work) | 857 | static void mt76x0_phy_calibration_work(struct work_struct *work) |
| 818 | { | 858 | { |
| 819 | struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev, | 859 | struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev, |
| 820 | cal_work.work); | 860 | cal_work.work); |
| 821 | 861 | ||
| 822 | mt76x0_dynamic_vga_tuning(dev); | 862 | mt76x0_phy_update_channel_gain(dev); |
| 823 | mt76x0_temp_sensor(dev); | 863 | if (!mt76x0_tssi_enabled(dev)) |
| 864 | mt76x0_temp_sensor(dev); | ||
| 824 | 865 | ||
| 825 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, | 866 | ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, |
| 826 | MT_CALIBRATE_INTERVAL); | 867 | MT_CALIBRATE_INTERVAL); |
| @@ -881,9 +922,9 @@ static void mt76x0_rf_init(struct mt76x02_dev *dev) | |||
| 881 | 922 | ||
| 882 | void mt76x0_phy_init(struct mt76x02_dev *dev) | 923 | void mt76x0_phy_init(struct mt76x02_dev *dev) |
| 883 | { | 924 | { |
| 884 | INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibrate); | 925 | INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibration_work); |
| 885 | 926 | ||
| 886 | mt76x0_rf_init(dev); | 927 | mt76x0_rf_init(dev); |
| 887 | mt76x02_phy_set_rxpath(&dev->mt76); | 928 | mt76x02_phy_set_rxpath(dev); |
| 888 | mt76x02_phy_set_txdac(&dev->mt76); | 929 | mt76x02_phy_set_txdac(dev); |
| 889 | } | 930 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c index fb6fa1fa5548..a9f14d5149d1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c | |||
| @@ -40,8 +40,7 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev, | |||
| 40 | ilm_len = le32_to_cpu(hdr->ilm_len) - MT_MCU_IVB_SIZE; | 40 | ilm_len = le32_to_cpu(hdr->ilm_len) - MT_MCU_IVB_SIZE; |
| 41 | dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %u\n", | 41 | dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %u\n", |
| 42 | ilm_len, MT_MCU_IVB_SIZE); | 42 | ilm_len, MT_MCU_IVB_SIZE); |
| 43 | err = mt76x02u_mcu_fw_send_data(&dev->mt76, | 43 | err = mt76x02u_mcu_fw_send_data(dev, fw_payload + MT_MCU_IVB_SIZE, |
| 44 | fw_payload + MT_MCU_IVB_SIZE, | ||
| 45 | ilm_len, MCU_FW_URB_MAX_PAYLOAD, | 44 | ilm_len, MCU_FW_URB_MAX_PAYLOAD, |
| 46 | MT_MCU_IVB_SIZE); | 45 | MT_MCU_IVB_SIZE); |
| 47 | if (err) | 46 | if (err) |
| @@ -49,7 +48,7 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev, | |||
| 49 | 48 | ||
| 50 | dlm_len = le32_to_cpu(hdr->dlm_len); | 49 | dlm_len = le32_to_cpu(hdr->dlm_len); |
| 51 | dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); | 50 | dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); |
| 52 | err = mt76x02u_mcu_fw_send_data(&dev->mt76, | 51 | err = mt76x02u_mcu_fw_send_data(dev, |
| 53 | fw_payload + le32_to_cpu(hdr->ilm_len), | 52 | fw_payload + le32_to_cpu(hdr->ilm_len), |
| 54 | dlm_len, MCU_FW_URB_MAX_PAYLOAD, | 53 | dlm_len, MCU_FW_URB_MAX_PAYLOAD, |
| 55 | MT_MCU_DLM_OFFSET); | 54 | MT_MCU_DLM_OFFSET); |
| @@ -121,7 +120,7 @@ static int mt76x0u_load_firmware(struct mt76x02_dev *dev) | |||
| 121 | mt76_set(dev, MT_USB_DMA_CFG, | 120 | mt76_set(dev, MT_USB_DMA_CFG, |
| 122 | (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) | | 121 | (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) | |
| 123 | FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); | 122 | FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); |
| 124 | mt76x02u_mcu_fw_reset(&dev->mt76); | 123 | mt76x02u_mcu_fw_reset(dev); |
| 125 | usleep_range(5000, 6000); | 124 | usleep_range(5000, 6000); |
| 126 | /* | 125 | /* |
| 127 | mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | | 126 | mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h index 65174817ebc4..47c42c607964 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h | |||
| @@ -55,7 +55,8 @@ struct mt76x02_calibration { | |||
| 55 | s8 agc_gain_adjust; | 55 | s8 agc_gain_adjust; |
| 56 | s8 low_gain; | 56 | s8 low_gain; |
| 57 | 57 | ||
| 58 | u8 temp; | 58 | s8 temp_vco; |
| 59 | s8 temp; | ||
| 59 | 60 | ||
| 60 | bool init_cal_done; | 61 | bool init_cal_done; |
| 61 | bool tssi_cal_done; | 62 | bool tssi_cal_done; |
| @@ -101,8 +102,6 @@ struct mt76x02_dev { | |||
| 101 | 102 | ||
| 102 | bool no_2ghz; | 103 | bool no_2ghz; |
| 103 | 104 | ||
| 104 | u8 agc_save; | ||
| 105 | |||
| 106 | u8 coverage_class; | 105 | u8 coverage_class; |
| 107 | u8 slottime; | 106 | u8 slottime; |
| 108 | 107 | ||
| @@ -119,8 +118,8 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 119 | int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 118 | int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 120 | struct ieee80211_sta *sta); | 119 | struct ieee80211_sta *sta); |
| 121 | 120 | ||
| 122 | void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, | 121 | void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, |
| 123 | unsigned int idx); | 122 | unsigned int idx); |
| 124 | int mt76x02_add_interface(struct ieee80211_hw *hw, | 123 | int mt76x02_add_interface(struct ieee80211_hw *hw, |
| 125 | struct ieee80211_vif *vif); | 124 | struct ieee80211_vif *vif); |
| 126 | void mt76x02_remove_interface(struct ieee80211_hw *hw, | 125 | void mt76x02_remove_interface(struct ieee80211_hw *hw, |
| @@ -136,14 +135,15 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 136 | void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, | 135 | void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, |
| 137 | struct ieee80211_vif *vif, | 136 | struct ieee80211_vif *vif, |
| 138 | struct ieee80211_sta *sta); | 137 | struct ieee80211_sta *sta); |
| 139 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev, | 138 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, |
| 140 | const struct ieee80211_tx_rate *rate); | 139 | const struct ieee80211_tx_rate *rate); |
| 141 | s8 mt76x02_tx_get_txpwr_adj(struct mt76_dev *mdev, s8 txpwr, s8 max_txpwr_adj); | 140 | s8 mt76x02_tx_get_txpwr_adj(struct mt76x02_dev *dev, s8 txpwr, |
| 141 | s8 max_txpwr_adj); | ||
| 142 | void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr); | 142 | void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr); |
| 143 | int mt76x02_insert_hdr_pad(struct sk_buff *skb); | 143 | int mt76x02_insert_hdr_pad(struct sk_buff *skb); |
| 144 | void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); | 144 | void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); |
| 145 | void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); | 145 | void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb); |
| 146 | bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update); | 146 | bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update); |
| 147 | void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, | 147 | void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, |
| 148 | struct sk_buff *skb); | 148 | struct sk_buff *skb); |
| 149 | void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); | 149 | void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); |
| @@ -156,10 +156,17 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, | |||
| 156 | u32 *tx_info); | 156 | u32 *tx_info); |
| 157 | 157 | ||
| 158 | extern const u16 mt76x02_beacon_offsets[16]; | 158 | extern const u16 mt76x02_beacon_offsets[16]; |
| 159 | void mt76x02_set_beacon_offsets(struct mt76_dev *dev); | 159 | void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev); |
| 160 | void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set); | 160 | void mt76x02_set_irq_mask(struct mt76x02_dev *dev, u32 clear, u32 set); |
| 161 | void mt76x02_mac_start(struct mt76x02_dev *dev); | 161 | void mt76x02_mac_start(struct mt76x02_dev *dev); |
| 162 | 162 | ||
| 163 | static inline bool is_mt76x2(struct mt76x02_dev *dev) | ||
| 164 | { | ||
| 165 | return mt76_chip(&dev->mt76) == 0x7612 || | ||
| 166 | mt76_chip(&dev->mt76) == 0x7662 || | ||
| 167 | mt76_chip(&dev->mt76) == 0x7602; | ||
| 168 | } | ||
| 169 | |||
| 163 | static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask) | 170 | static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask) |
| 164 | { | 171 | { |
| 165 | mt76x02_set_irq_mask(dev, 0, mask); | 172 | mt76x02_set_irq_mask(dev, 0, mask); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c index d3efeb8a72b7..9390de2a323e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c | |||
| @@ -17,46 +17,43 @@ | |||
| 17 | 17 | ||
| 18 | #include <asm/unaligned.h> | 18 | #include <asm/unaligned.h> |
| 19 | 19 | ||
| 20 | #include "mt76.h" | ||
| 21 | #include "mt76x02_eeprom.h" | 20 | #include "mt76x02_eeprom.h" |
| 22 | #include "mt76x02_regs.h" | ||
| 23 | 21 | ||
| 24 | static int | 22 | static int |
| 25 | mt76x02_efuse_read(struct mt76_dev *dev, u16 addr, u8 *data, | 23 | mt76x02_efuse_read(struct mt76x02_dev *dev, u16 addr, u8 *data, |
| 26 | enum mt76x02_eeprom_modes mode) | 24 | enum mt76x02_eeprom_modes mode) |
| 27 | { | 25 | { |
| 28 | u32 val; | 26 | u32 val; |
| 29 | int i; | 27 | int i; |
| 30 | 28 | ||
| 31 | val = __mt76_rr(dev, MT_EFUSE_CTRL); | 29 | val = mt76_rr(dev, MT_EFUSE_CTRL); |
| 32 | val &= ~(MT_EFUSE_CTRL_AIN | | 30 | val &= ~(MT_EFUSE_CTRL_AIN | |
| 33 | MT_EFUSE_CTRL_MODE); | 31 | MT_EFUSE_CTRL_MODE); |
| 34 | val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf); | 32 | val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf); |
| 35 | val |= FIELD_PREP(MT_EFUSE_CTRL_MODE, mode); | 33 | val |= FIELD_PREP(MT_EFUSE_CTRL_MODE, mode); |
| 36 | val |= MT_EFUSE_CTRL_KICK; | 34 | val |= MT_EFUSE_CTRL_KICK; |
| 37 | __mt76_wr(dev, MT_EFUSE_CTRL, val); | 35 | mt76_wr(dev, MT_EFUSE_CTRL, val); |
| 38 | 36 | ||
| 39 | if (!__mt76_poll_msec(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, | 37 | if (!mt76_poll_msec(dev, MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000)) |
| 40 | 0, 1000)) | ||
| 41 | return -ETIMEDOUT; | 38 | return -ETIMEDOUT; |
| 42 | 39 | ||
| 43 | udelay(2); | 40 | udelay(2); |
| 44 | 41 | ||
| 45 | val = __mt76_rr(dev, MT_EFUSE_CTRL); | 42 | val = mt76_rr(dev, MT_EFUSE_CTRL); |
| 46 | if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) { | 43 | if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT) { |
| 47 | memset(data, 0xff, 16); | 44 | memset(data, 0xff, 16); |
| 48 | return 0; | 45 | return 0; |
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | for (i = 0; i < 4; i++) { | 48 | for (i = 0; i < 4; i++) { |
| 52 | val = __mt76_rr(dev, MT_EFUSE_DATA(i)); | 49 | val = mt76_rr(dev, MT_EFUSE_DATA(i)); |
| 53 | put_unaligned_le32(val, data + 4 * i); | 50 | put_unaligned_le32(val, data + 4 * i); |
| 54 | } | 51 | } |
| 55 | 52 | ||
| 56 | return 0; | 53 | return 0; |
| 57 | } | 54 | } |
| 58 | 55 | ||
| 59 | int mt76x02_get_efuse_data(struct mt76_dev *dev, u16 base, void *buf, | 56 | int mt76x02_get_efuse_data(struct mt76x02_dev *dev, u16 base, void *buf, |
| 60 | int len, enum mt76x02_eeprom_modes mode) | 57 | int len, enum mt76x02_eeprom_modes mode) |
| 61 | { | 58 | { |
| 62 | int ret, i; | 59 | int ret, i; |
| @@ -71,26 +68,26 @@ int mt76x02_get_efuse_data(struct mt76_dev *dev, u16 base, void *buf, | |||
| 71 | } | 68 | } |
| 72 | EXPORT_SYMBOL_GPL(mt76x02_get_efuse_data); | 69 | EXPORT_SYMBOL_GPL(mt76x02_get_efuse_data); |
| 73 | 70 | ||
| 74 | void mt76x02_eeprom_parse_hw_cap(struct mt76_dev *dev) | 71 | void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev) |
| 75 | { | 72 | { |
| 76 | u16 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); | 73 | u16 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); |
| 77 | 74 | ||
| 78 | switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) { | 75 | switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) { |
| 79 | case BOARD_TYPE_5GHZ: | 76 | case BOARD_TYPE_5GHZ: |
| 80 | dev->cap.has_5ghz = true; | 77 | dev->mt76.cap.has_5ghz = true; |
| 81 | break; | 78 | break; |
| 82 | case BOARD_TYPE_2GHZ: | 79 | case BOARD_TYPE_2GHZ: |
| 83 | dev->cap.has_2ghz = true; | 80 | dev->mt76.cap.has_2ghz = true; |
| 84 | break; | 81 | break; |
| 85 | default: | 82 | default: |
| 86 | dev->cap.has_2ghz = true; | 83 | dev->mt76.cap.has_2ghz = true; |
| 87 | dev->cap.has_5ghz = true; | 84 | dev->mt76.cap.has_5ghz = true; |
| 88 | break; | 85 | break; |
| 89 | } | 86 | } |
| 90 | } | 87 | } |
| 91 | EXPORT_SYMBOL_GPL(mt76x02_eeprom_parse_hw_cap); | 88 | EXPORT_SYMBOL_GPL(mt76x02_eeprom_parse_hw_cap); |
| 92 | 89 | ||
| 93 | bool mt76x02_ext_pa_enabled(struct mt76_dev *dev, enum nl80211_band band) | 90 | bool mt76x02_ext_pa_enabled(struct mt76x02_dev *dev, enum nl80211_band band) |
| 94 | { | 91 | { |
| 95 | u16 conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); | 92 | u16 conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); |
| 96 | 93 | ||
| @@ -101,7 +98,7 @@ bool mt76x02_ext_pa_enabled(struct mt76_dev *dev, enum nl80211_band band) | |||
| 101 | } | 98 | } |
| 102 | EXPORT_SYMBOL_GPL(mt76x02_ext_pa_enabled); | 99 | EXPORT_SYMBOL_GPL(mt76x02_ext_pa_enabled); |
| 103 | 100 | ||
| 104 | void mt76x02_get_rx_gain(struct mt76_dev *dev, enum nl80211_band band, | 101 | void mt76x02_get_rx_gain(struct mt76x02_dev *dev, enum nl80211_band band, |
| 105 | u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g) | 102 | u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g) |
| 106 | { | 103 | { |
| 107 | u16 val; | 104 | u16 val; |
| @@ -129,7 +126,7 @@ void mt76x02_get_rx_gain(struct mt76_dev *dev, enum nl80211_band band, | |||
| 129 | } | 126 | } |
| 130 | EXPORT_SYMBOL_GPL(mt76x02_get_rx_gain); | 127 | EXPORT_SYMBOL_GPL(mt76x02_get_rx_gain); |
| 131 | 128 | ||
| 132 | u8 mt76x02_get_lna_gain(struct mt76_dev *dev, | 129 | u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev, |
| 133 | s8 *lna_2g, s8 *lna_5g, | 130 | s8 *lna_2g, s8 *lna_5g, |
| 134 | struct ieee80211_channel *chan) | 131 | struct ieee80211_channel *chan) |
| 135 | { | 132 | { |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h index bcd05f7c5f45..b3ec74835d10 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #ifndef __MT76x02_EEPROM_H | 18 | #ifndef __MT76x02_EEPROM_H |
| 19 | #define __MT76x02_EEPROM_H | 19 | #define __MT76x02_EEPROM_H |
| 20 | 20 | ||
| 21 | #include "mt76x02.h" | ||
| 22 | |||
| 21 | enum mt76x02_eeprom_field { | 23 | enum mt76x02_eeprom_field { |
| 22 | MT_EE_CHIP_ID = 0x000, | 24 | MT_EE_CHIP_ID = 0x000, |
| 23 | MT_EE_VERSION = 0x002, | 25 | MT_EE_VERSION = 0x002, |
| @@ -168,44 +170,23 @@ static inline s8 mt76x02_rate_power_val(u8 val) | |||
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | static inline int | 172 | static inline int |
| 171 | mt76x02_eeprom_get(struct mt76_dev *dev, | 173 | mt76x02_eeprom_get(struct mt76x02_dev *dev, |
| 172 | enum mt76x02_eeprom_field field) | 174 | enum mt76x02_eeprom_field field) |
| 173 | { | 175 | { |
| 174 | if ((field & 1) || field >= __MT_EE_MAX) | 176 | if ((field & 1) || field >= __MT_EE_MAX) |
| 175 | return -1; | 177 | return -1; |
| 176 | 178 | ||
| 177 | return get_unaligned_le16(dev->eeprom.data + field); | 179 | return get_unaligned_le16(dev->mt76.eeprom.data + field); |
| 178 | } | ||
| 179 | |||
| 180 | static inline bool | ||
| 181 | mt76x02_temp_tx_alc_enabled(struct mt76_dev *dev) | ||
| 182 | { | ||
| 183 | u16 val; | ||
| 184 | |||
| 185 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G); | ||
| 186 | if (!(val & BIT(15))) | ||
| 187 | return false; | ||
| 188 | |||
| 189 | return mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & | ||
| 190 | MT_EE_NIC_CONF_1_TEMP_TX_ALC; | ||
| 191 | } | ||
| 192 | |||
| 193 | static inline bool | ||
| 194 | mt76x02_tssi_enabled(struct mt76_dev *dev) | ||
| 195 | { | ||
| 196 | return !mt76x02_temp_tx_alc_enabled(dev) && | ||
| 197 | (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & | ||
| 198 | MT_EE_NIC_CONF_1_TX_ALC_EN); | ||
| 199 | } | 180 | } |
| 200 | 181 | ||
| 201 | bool mt76x02_ext_pa_enabled(struct mt76_dev *dev, enum nl80211_band band); | 182 | bool mt76x02_ext_pa_enabled(struct mt76x02_dev *dev, enum nl80211_band band); |
| 202 | int mt76x02_get_efuse_data(struct mt76_dev *dev, u16 base, void *buf, | 183 | int mt76x02_get_efuse_data(struct mt76x02_dev *dev, u16 base, void *buf, |
| 203 | int len, enum mt76x02_eeprom_modes mode); | 184 | int len, enum mt76x02_eeprom_modes mode); |
| 204 | void mt76x02_get_rx_gain(struct mt76_dev *dev, enum nl80211_band band, | 185 | void mt76x02_get_rx_gain(struct mt76x02_dev *dev, enum nl80211_band band, |
| 205 | u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g); | 186 | u16 *rssi_offset, s8 *lna_2g, s8 *lna_5g); |
| 206 | u8 mt76x02_get_lna_gain(struct mt76_dev *dev, | 187 | u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev, |
| 207 | s8 *lna_2g, s8 *lna_5g, | 188 | s8 *lna_2g, s8 *lna_5g, |
| 208 | struct ieee80211_channel *chan); | 189 | struct ieee80211_channel *chan); |
| 209 | void mt76x02_eeprom_parse_hw_cap(struct mt76_dev *dev); | 190 | void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev); |
| 210 | 191 | ||
| 211 | #endif /* __MT76x02_EEPROM_H */ | 192 | #endif /* __MT76x02_EEPROM_H */ |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 244245418ebb..10578e4cb269 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | |||
| @@ -45,8 +45,8 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) | |||
| 45 | } | 45 | } |
| 46 | EXPORT_SYMBOL_GPL(mt76x02_mac_get_key_info); | 46 | EXPORT_SYMBOL_GPL(mt76x02_mac_get_key_info); |
| 47 | 47 | ||
| 48 | int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, | 48 | int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx, |
| 49 | struct ieee80211_key_conf *key) | 49 | u8 key_idx, struct ieee80211_key_conf *key) |
| 50 | { | 50 | { |
| 51 | enum mt76x02_cipher_type cipher; | 51 | enum mt76x02_cipher_type cipher; |
| 52 | u8 key_data[32]; | 52 | u8 key_data[32]; |
| @@ -56,20 +56,20 @@ int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, | |||
| 56 | if (cipher == MT_CIPHER_NONE && key) | 56 | if (cipher == MT_CIPHER_NONE && key) |
| 57 | return -EOPNOTSUPP; | 57 | return -EOPNOTSUPP; |
| 58 | 58 | ||
| 59 | val = __mt76_rr(dev, MT_SKEY_MODE(vif_idx)); | 59 | val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); |
| 60 | val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); | 60 | val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx)); |
| 61 | val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); | 61 | val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx); |
| 62 | __mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); | 62 | mt76_wr(dev, MT_SKEY_MODE(vif_idx), val); |
| 63 | 63 | ||
| 64 | __mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data, | 64 | mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data, |
| 65 | sizeof(key_data)); | 65 | sizeof(key_data)); |
| 66 | 66 | ||
| 67 | return 0; | 67 | return 0; |
| 68 | } | 68 | } |
| 69 | EXPORT_SYMBOL_GPL(mt76x02_mac_shared_key_setup); | 69 | EXPORT_SYMBOL_GPL(mt76x02_mac_shared_key_setup); |
| 70 | 70 | ||
| 71 | int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, | 71 | int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx, |
| 72 | struct ieee80211_key_conf *key) | 72 | struct ieee80211_key_conf *key) |
| 73 | { | 73 | { |
| 74 | enum mt76x02_cipher_type cipher; | 74 | enum mt76x02_cipher_type cipher; |
| 75 | u8 key_data[32]; | 75 | u8 key_data[32]; |
| @@ -79,25 +79,26 @@ int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, | |||
| 79 | if (cipher == MT_CIPHER_NONE && key) | 79 | if (cipher == MT_CIPHER_NONE && key) |
| 80 | return -EOPNOTSUPP; | 80 | return -EOPNOTSUPP; |
| 81 | 81 | ||
| 82 | __mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); | 82 | mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); |
| 83 | __mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher); | 83 | mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher); |
| 84 | 84 | ||
| 85 | memset(iv_data, 0, sizeof(iv_data)); | 85 | memset(iv_data, 0, sizeof(iv_data)); |
| 86 | if (key) { | 86 | if (key) { |
| 87 | __mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE, | 87 | mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE, |
| 88 | !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); | 88 | !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); |
| 89 | iv_data[3] = key->keyidx << 6; | 89 | iv_data[3] = key->keyidx << 6; |
| 90 | if (cipher >= MT_CIPHER_TKIP) | 90 | if (cipher >= MT_CIPHER_TKIP) |
| 91 | iv_data[3] |= 0x20; | 91 | iv_data[3] |= 0x20; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | __mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); | 94 | mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data)); |
| 95 | 95 | ||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_key); | 98 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_key); |
| 99 | 99 | ||
| 100 | void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac) | 100 | void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx, |
| 101 | u8 vif_idx, u8 *mac) | ||
| 101 | { | 102 | { |
| 102 | struct mt76_wcid_addr addr = {}; | 103 | struct mt76_wcid_addr addr = {}; |
| 103 | u32 attr; | 104 | u32 attr; |
| @@ -105,10 +106,10 @@ void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac) | |||
| 105 | attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | | 106 | attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) | |
| 106 | FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); | 107 | FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8)); |
| 107 | 108 | ||
| 108 | __mt76_wr(dev, MT_WCID_ATTR(idx), attr); | 109 | mt76_wr(dev, MT_WCID_ATTR(idx), attr); |
| 109 | 110 | ||
| 110 | __mt76_wr(dev, MT_WCID_TX_RATE(idx), 0); | 111 | mt76_wr(dev, MT_WCID_TX_RATE(idx), 0); |
| 111 | __mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0); | 112 | mt76_wr(dev, MT_WCID_TX_RATE(idx) + 4, 0); |
| 112 | 113 | ||
| 113 | if (idx >= 128) | 114 | if (idx >= 128) |
| 114 | return; | 115 | return; |
| @@ -116,22 +117,22 @@ void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac) | |||
| 116 | if (mac) | 117 | if (mac) |
| 117 | memcpy(addr.macaddr, mac, ETH_ALEN); | 118 | memcpy(addr.macaddr, mac, ETH_ALEN); |
| 118 | 119 | ||
| 119 | __mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); | 120 | mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr)); |
| 120 | } | 121 | } |
| 121 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup); | 122 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup); |
| 122 | 123 | ||
| 123 | void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop) | 124 | void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop) |
| 124 | { | 125 | { |
| 125 | u32 val = __mt76_rr(dev, MT_WCID_DROP(idx)); | 126 | u32 val = mt76_rr(dev, MT_WCID_DROP(idx)); |
| 126 | u32 bit = MT_WCID_DROP_MASK(idx); | 127 | u32 bit = MT_WCID_DROP_MASK(idx); |
| 127 | 128 | ||
| 128 | /* prevent unnecessary writes */ | 129 | /* prevent unnecessary writes */ |
| 129 | if ((val & bit) != (bit * drop)) | 130 | if ((val & bit) != (bit * drop)) |
| 130 | __mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); | 131 | mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); |
| 131 | } | 132 | } |
| 132 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop); | 133 | EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_set_drop); |
| 133 | 134 | ||
| 134 | void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) | 135 | void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq) |
| 135 | { | 136 | { |
| 136 | struct mt76_txq *mtxq; | 137 | struct mt76_txq *mtxq; |
| 137 | 138 | ||
| @@ -151,55 +152,13 @@ void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq) | |||
| 151 | mtxq->wcid = &mvif->group_wcid; | 152 | mtxq->wcid = &mvif->group_wcid; |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | mt76_txq_init(dev, txq); | 155 | mt76_txq_init(&dev->mt76, txq); |
| 155 | } | 156 | } |
| 156 | EXPORT_SYMBOL_GPL(mt76x02_txq_init); | 157 | EXPORT_SYMBOL_GPL(mt76x02_txq_init); |
| 157 | 158 | ||
| 158 | static void | ||
| 159 | mt76x02_mac_fill_txwi(struct mt76x02_txwi *txwi, struct sk_buff *skb, | ||
| 160 | struct ieee80211_sta *sta, int len, u8 nss) | ||
| 161 | { | ||
| 162 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 163 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 164 | u16 txwi_flags = 0; | ||
| 165 | |||
| 166 | if (info->flags & IEEE80211_TX_CTL_LDPC) | ||
| 167 | txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); | ||
| 168 | if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) | ||
| 169 | txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); | ||
| 170 | if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) | ||
| 171 | txwi_flags |= MT_TXWI_FLAGS_MMPS; | ||
| 172 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | ||
| 173 | txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; | ||
| 174 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | ||
| 175 | txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; | ||
| 176 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) | ||
| 177 | txwi->pktid |= MT_TXWI_PKTID_PROBE; | ||
| 178 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { | ||
| 179 | u8 ba_size = IEEE80211_MIN_AMPDU_BUF; | ||
| 180 | |||
| 181 | ba_size <<= sta->ht_cap.ampdu_factor; | ||
| 182 | ba_size = min_t(int, 63, ba_size - 1); | ||
| 183 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) | ||
| 184 | ba_size = 0; | ||
| 185 | txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); | ||
| 186 | |||
| 187 | txwi_flags |= MT_TXWI_FLAGS_AMPDU | | ||
| 188 | FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, | ||
| 189 | sta->ht_cap.ampdu_density); | ||
| 190 | } | ||
| 191 | |||
| 192 | if (ieee80211_is_probe_resp(hdr->frame_control) || | ||
| 193 | ieee80211_is_beacon(hdr->frame_control)) | ||
| 194 | txwi_flags |= MT_TXWI_FLAGS_TS; | ||
| 195 | |||
| 196 | txwi->flags |= cpu_to_le16(txwi_flags); | ||
| 197 | txwi->len_ctl = cpu_to_le16(len); | ||
| 198 | } | ||
| 199 | |||
| 200 | static __le16 | 159 | static __le16 |
| 201 | mt76x02_mac_tx_rate_val(struct mt76_dev *dev, | 160 | mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev, |
| 202 | const struct ieee80211_tx_rate *rate, u8 *nss_val) | 161 | const struct ieee80211_tx_rate *rate, u8 *nss_val) |
| 203 | { | 162 | { |
| 204 | u16 rateval; | 163 | u16 rateval; |
| 205 | u8 phy, rate_idx; | 164 | u8 phy, rate_idx; |
| @@ -224,10 +183,10 @@ mt76x02_mac_tx_rate_val(struct mt76_dev *dev, | |||
| 224 | bw = 1; | 183 | bw = 1; |
| 225 | } else { | 184 | } else { |
| 226 | const struct ieee80211_rate *r; | 185 | const struct ieee80211_rate *r; |
| 227 | int band = dev->chandef.chan->band; | 186 | int band = dev->mt76.chandef.chan->band; |
| 228 | u16 val; | 187 | u16 val; |
| 229 | 188 | ||
| 230 | r = &dev->hw->wiphy->bands[band]->bitrates[rate->idx]; | 189 | r = &dev->mt76.hw->wiphy->bands[band]->bitrates[rate->idx]; |
| 231 | if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 190 | if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
| 232 | val = r->hw_value_short; | 191 | val = r->hw_value_short; |
| 233 | else | 192 | else |
| @@ -248,22 +207,22 @@ mt76x02_mac_tx_rate_val(struct mt76_dev *dev, | |||
| 248 | return cpu_to_le16(rateval); | 207 | return cpu_to_le16(rateval); |
| 249 | } | 208 | } |
| 250 | 209 | ||
| 251 | void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, | 210 | void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid, |
| 252 | const struct ieee80211_tx_rate *rate) | 211 | const struct ieee80211_tx_rate *rate) |
| 253 | { | 212 | { |
| 254 | spin_lock_bh(&dev->lock); | 213 | spin_lock_bh(&dev->mt76.lock); |
| 255 | wcid->tx_rate = mt76x02_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); | 214 | wcid->tx_rate = mt76x02_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss); |
| 256 | wcid->tx_rate_set = true; | 215 | wcid->tx_rate_set = true; |
| 257 | spin_unlock_bh(&dev->lock); | 216 | spin_unlock_bh(&dev->mt76.lock); |
| 258 | } | 217 | } |
| 259 | 218 | ||
| 260 | bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, | 219 | bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev, |
| 261 | struct mt76x02_tx_status *stat) | 220 | struct mt76x02_tx_status *stat) |
| 262 | { | 221 | { |
| 263 | u32 stat1, stat2; | 222 | u32 stat1, stat2; |
| 264 | 223 | ||
| 265 | stat2 = __mt76_rr(dev, MT_TX_STAT_FIFO_EXT); | 224 | stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT); |
| 266 | stat1 = __mt76_rr(dev, MT_TX_STAT_FIFO); | 225 | stat1 = mt76_rr(dev, MT_TX_STAT_FIFO); |
| 267 | 226 | ||
| 268 | stat->valid = !!(stat1 & MT_TX_STAT_FIFO_VALID); | 227 | stat->valid = !!(stat1 & MT_TX_STAT_FIFO_VALID); |
| 269 | if (!stat->valid) | 228 | if (!stat->valid) |
| @@ -339,17 +298,19 @@ mt76x02_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate, | |||
| 339 | return 0; | 298 | return 0; |
| 340 | } | 299 | } |
| 341 | 300 | ||
| 342 | void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct mt76x02_txwi *txwi, | 301 | void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi, |
| 343 | struct sk_buff *skb, struct mt76_wcid *wcid, | 302 | struct sk_buff *skb, struct mt76_wcid *wcid, |
| 344 | struct ieee80211_sta *sta, int len) | 303 | struct ieee80211_sta *sta, int len) |
| 345 | { | 304 | { |
| 305 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
| 346 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 306 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 347 | struct ieee80211_tx_rate *rate = &info->control.rates[0]; | 307 | struct ieee80211_tx_rate *rate = &info->control.rates[0]; |
| 348 | struct ieee80211_key_conf *key = info->control.hw_key; | 308 | struct ieee80211_key_conf *key = info->control.hw_key; |
| 349 | u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); | 309 | u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); |
| 310 | u16 txwi_flags = 0; | ||
| 350 | u8 nss; | 311 | u8 nss; |
| 351 | s8 txpwr_adj, max_txpwr_adj; | 312 | s8 txpwr_adj, max_txpwr_adj; |
| 352 | u8 ccmp_pn[8], nstreams = dev->chainmask & 0xf; | 313 | u8 ccmp_pn[8], nstreams = dev->mt76.chainmask & 0xf; |
| 353 | 314 | ||
| 354 | memset(txwi, 0, sizeof(*txwi)); | 315 | memset(txwi, 0, sizeof(*txwi)); |
| 355 | 316 | ||
| @@ -374,7 +335,7 @@ void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct mt76x02_txwi *txwi, | |||
| 374 | txwi->eiv = *((__le32 *)&ccmp_pn[1]); | 335 | txwi->eiv = *((__le32 *)&ccmp_pn[1]); |
| 375 | } | 336 | } |
| 376 | 337 | ||
| 377 | spin_lock_bh(&dev->lock); | 338 | spin_lock_bh(&dev->mt76.lock); |
| 378 | if (wcid && (rate->idx < 0 || !rate->count)) { | 339 | if (wcid && (rate->idx < 0 || !rate->count)) { |
| 379 | txwi->rate = wcid->tx_rate; | 340 | txwi->rate = wcid->tx_rate; |
| 380 | max_txpwr_adj = wcid->max_txpwr_adj; | 341 | max_txpwr_adj = wcid->max_txpwr_adj; |
| @@ -383,26 +344,57 @@ void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct mt76x02_txwi *txwi, | |||
| 383 | txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss); | 344 | txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss); |
| 384 | max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); | 345 | max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); |
| 385 | } | 346 | } |
| 386 | spin_unlock_bh(&dev->lock); | 347 | spin_unlock_bh(&dev->mt76.lock); |
| 387 | 348 | ||
| 388 | txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->txpower_conf, | 349 | txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf, |
| 389 | max_txpwr_adj); | 350 | max_txpwr_adj); |
| 390 | txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj); | 351 | txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj); |
| 391 | 352 | ||
| 392 | if (nstreams > 1 && mt76_rev(dev) >= MT76XX_REV_E4) | 353 | if (nstreams > 1 && mt76_rev(&dev->mt76) >= MT76XX_REV_E4) |
| 393 | txwi->txstream = 0x13; | 354 | txwi->txstream = 0x13; |
| 394 | else if (nstreams > 1 && mt76_rev(dev) >= MT76XX_REV_E3 && | 355 | else if (nstreams > 1 && mt76_rev(&dev->mt76) >= MT76XX_REV_E3 && |
| 395 | !(txwi->rate & cpu_to_le16(rate_ht_mask))) | 356 | !(txwi->rate & cpu_to_le16(rate_ht_mask))) |
| 396 | txwi->txstream = 0x93; | 357 | txwi->txstream = 0x93; |
| 397 | 358 | ||
| 398 | mt76x02_mac_fill_txwi(txwi, skb, sta, len, nss); | 359 | if (is_mt76x2(dev) && (info->flags & IEEE80211_TX_CTL_LDPC)) |
| 360 | txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC); | ||
| 361 | if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1) | ||
| 362 | txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC); | ||
| 363 | if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC) | ||
| 364 | txwi_flags |= MT_TXWI_FLAGS_MMPS; | ||
| 365 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | ||
| 366 | txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ; | ||
| 367 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | ||
| 368 | txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ; | ||
| 369 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) | ||
| 370 | txwi->pktid |= MT_TXWI_PKTID_PROBE; | ||
| 371 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) { | ||
| 372 | u8 ba_size = IEEE80211_MIN_AMPDU_BUF; | ||
| 373 | |||
| 374 | ba_size <<= sta->ht_cap.ampdu_factor; | ||
| 375 | ba_size = min_t(int, 63, ba_size - 1); | ||
| 376 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) | ||
| 377 | ba_size = 0; | ||
| 378 | txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size); | ||
| 379 | |||
| 380 | txwi_flags |= MT_TXWI_FLAGS_AMPDU | | ||
| 381 | FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY, | ||
| 382 | sta->ht_cap.ampdu_density); | ||
| 383 | } | ||
| 384 | |||
| 385 | if (ieee80211_is_probe_resp(hdr->frame_control) || | ||
| 386 | ieee80211_is_beacon(hdr->frame_control)) | ||
| 387 | txwi_flags |= MT_TXWI_FLAGS_TS; | ||
| 388 | |||
| 389 | txwi->flags |= cpu_to_le16(txwi_flags); | ||
| 390 | txwi->len_ctl = cpu_to_le16(len); | ||
| 399 | } | 391 | } |
| 400 | EXPORT_SYMBOL_GPL(mt76x02_mac_write_txwi); | 392 | EXPORT_SYMBOL_GPL(mt76x02_mac_write_txwi); |
| 401 | 393 | ||
| 402 | static void | 394 | static void |
| 403 | mt76x02_mac_fill_tx_status(struct mt76_dev *dev, | 395 | mt76x02_mac_fill_tx_status(struct mt76x02_dev *dev, |
| 404 | struct ieee80211_tx_info *info, | 396 | struct ieee80211_tx_info *info, |
| 405 | struct mt76x02_tx_status *st, int n_frames) | 397 | struct mt76x02_tx_status *st, int n_frames) |
| 406 | { | 398 | { |
| 407 | struct ieee80211_tx_rate *rate = info->status.rates; | 399 | struct ieee80211_tx_rate *rate = info->status.rates; |
| 408 | int cur_idx, last_rate; | 400 | int cur_idx, last_rate; |
| @@ -413,7 +405,7 @@ mt76x02_mac_fill_tx_status(struct mt76_dev *dev, | |||
| 413 | 405 | ||
| 414 | last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); | 406 | last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1); |
| 415 | mt76x02_mac_process_tx_rate(&rate[last_rate], st->rate, | 407 | mt76x02_mac_process_tx_rate(&rate[last_rate], st->rate, |
| 416 | dev->chandef.chan->band); | 408 | dev->mt76.chandef.chan->band); |
| 417 | if (last_rate < IEEE80211_TX_MAX_RATES - 1) | 409 | if (last_rate < IEEE80211_TX_MAX_RATES - 1) |
| 418 | rate[last_rate + 1].idx = -1; | 410 | rate[last_rate + 1].idx = -1; |
| 419 | 411 | ||
| @@ -441,8 +433,8 @@ mt76x02_mac_fill_tx_status(struct mt76_dev *dev, | |||
| 441 | info->flags |= IEEE80211_TX_STAT_ACK; | 433 | info->flags |= IEEE80211_TX_STAT_ACK; |
| 442 | } | 434 | } |
| 443 | 435 | ||
| 444 | void mt76x02_send_tx_status(struct mt76_dev *dev, | 436 | void mt76x02_send_tx_status(struct mt76x02_dev *dev, |
| 445 | struct mt76x02_tx_status *stat, u8 *update) | 437 | struct mt76x02_tx_status *stat, u8 *update) |
| 446 | { | 438 | { |
| 447 | struct ieee80211_tx_info info = {}; | 439 | struct ieee80211_tx_info info = {}; |
| 448 | struct ieee80211_sta *sta = NULL; | 440 | struct ieee80211_sta *sta = NULL; |
| @@ -450,8 +442,8 @@ void mt76x02_send_tx_status(struct mt76_dev *dev, | |||
| 450 | struct mt76x02_sta *msta = NULL; | 442 | struct mt76x02_sta *msta = NULL; |
| 451 | 443 | ||
| 452 | rcu_read_lock(); | 444 | rcu_read_lock(); |
| 453 | if (stat->wcid < ARRAY_SIZE(dev->wcid)) | 445 | if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid)) |
| 454 | wcid = rcu_dereference(dev->wcid[stat->wcid]); | 446 | wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]); |
| 455 | 447 | ||
| 456 | if (wcid) { | 448 | if (wcid) { |
| 457 | void *priv; | 449 | void *priv; |
| @@ -476,7 +468,7 @@ void mt76x02_send_tx_status(struct mt76_dev *dev, | |||
| 476 | } | 468 | } |
| 477 | 469 | ||
| 478 | mt76x02_mac_fill_tx_status(dev, &info, &msta->status, | 470 | mt76x02_mac_fill_tx_status(dev, &info, &msta->status, |
| 479 | msta->n_frames); | 471 | msta->n_frames); |
| 480 | 472 | ||
| 481 | msta->status = *stat; | 473 | msta->status = *stat; |
| 482 | msta->n_frames = 1; | 474 | msta->n_frames = 1; |
| @@ -486,7 +478,7 @@ void mt76x02_send_tx_status(struct mt76_dev *dev, | |||
| 486 | *update = 1; | 478 | *update = 1; |
| 487 | } | 479 | } |
| 488 | 480 | ||
| 489 | ieee80211_tx_status_noskb(dev->hw, sta, &info); | 481 | ieee80211_tx_status_noskb(dev->mt76.hw, sta, &info); |
| 490 | 482 | ||
| 491 | out: | 483 | out: |
| 492 | rcu_read_unlock(); | 484 | rcu_read_unlock(); |
| @@ -561,21 +553,21 @@ mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate) | |||
| 561 | } | 553 | } |
| 562 | EXPORT_SYMBOL_GPL(mt76x02_mac_process_rate); | 554 | EXPORT_SYMBOL_GPL(mt76x02_mac_process_rate); |
| 563 | 555 | ||
| 564 | void mt76x02_mac_setaddr(struct mt76_dev *dev, u8 *addr) | 556 | void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr) |
| 565 | { | 557 | { |
| 566 | ether_addr_copy(dev->macaddr, addr); | 558 | ether_addr_copy(dev->mt76.macaddr, addr); |
| 567 | 559 | ||
| 568 | if (!is_valid_ether_addr(dev->macaddr)) { | 560 | if (!is_valid_ether_addr(dev->mt76.macaddr)) { |
| 569 | eth_random_addr(dev->macaddr); | 561 | eth_random_addr(dev->mt76.macaddr); |
| 570 | dev_info(dev->dev, | 562 | dev_info(dev->mt76.dev, |
| 571 | "Invalid MAC address, using random address %pM\n", | 563 | "Invalid MAC address, using random address %pM\n", |
| 572 | dev->macaddr); | 564 | dev->mt76.macaddr); |
| 573 | } | 565 | } |
| 574 | 566 | ||
| 575 | __mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dev->macaddr)); | 567 | mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dev->mt76.macaddr)); |
| 576 | __mt76_wr(dev, MT_MAC_ADDR_DW1, | 568 | mt76_wr(dev, MT_MAC_ADDR_DW1, |
| 577 | get_unaligned_le16(dev->macaddr + 4) | | 569 | get_unaligned_le16(dev->mt76.macaddr + 4) | |
| 578 | FIELD_PREP(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff)); | 570 | FIELD_PREP(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff)); |
| 579 | } | 571 | } |
| 580 | EXPORT_SYMBOL_GPL(mt76x02_mac_setaddr); | 572 | EXPORT_SYMBOL_GPL(mt76x02_mac_setaddr); |
| 581 | 573 | ||
| @@ -697,7 +689,7 @@ void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq) | |||
| 697 | 689 | ||
| 698 | while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) { | 690 | while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) { |
| 699 | spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags); | 691 | spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags); |
| 700 | ret = mt76x02_mac_load_tx_status(&dev->mt76, &stat); | 692 | ret = mt76x02_mac_load_tx_status(dev, &stat); |
| 701 | spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags); | 693 | spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags); |
| 702 | 694 | ||
| 703 | if (!ret) | 695 | if (!ret) |
| @@ -706,7 +698,7 @@ void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq) | |||
| 706 | trace_mac_txstat_fetch(dev, &stat); | 698 | trace_mac_txstat_fetch(dev, &stat); |
| 707 | 699 | ||
| 708 | if (!irq) { | 700 | if (!irq) { |
| 709 | mt76x02_send_tx_status(&dev->mt76, &stat, &update); | 701 | mt76x02_send_tx_status(dev, &stat, &update); |
| 710 | continue; | 702 | continue; |
| 711 | } | 703 | } |
| 712 | 704 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h index 4f7ee4620ab5..d99c18743969 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | |||
| @@ -198,28 +198,29 @@ mt76x02_skb_tx_info(struct sk_buff *skb) | |||
| 198 | return (void *)info->status.status_driver_data; | 198 | return (void *)info->status.status_driver_data; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq); | 201 | void mt76x02_txq_init(struct mt76x02_dev *dev, struct ieee80211_txq *txq); |
| 202 | enum mt76x02_cipher_type | 202 | enum mt76x02_cipher_type |
| 203 | mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); | 203 | mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data); |
| 204 | 204 | ||
| 205 | int mt76x02_mac_shared_key_setup(struct mt76_dev *dev, u8 vif_idx, u8 key_idx, | 205 | int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx, |
| 206 | struct ieee80211_key_conf *key); | 206 | u8 key_idx, struct ieee80211_key_conf *key); |
| 207 | int mt76x02_mac_wcid_set_key(struct mt76_dev *dev, u8 idx, | 207 | int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx, |
| 208 | struct ieee80211_key_conf *key); | 208 | struct ieee80211_key_conf *key); |
| 209 | void mt76x02_mac_wcid_setup(struct mt76_dev *dev, u8 idx, u8 vif_idx, u8 *mac); | 209 | void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx, u8 vif_idx, |
| 210 | void mt76x02_mac_wcid_set_drop(struct mt76_dev *dev, u8 idx, bool drop); | 210 | u8 *mac); |
| 211 | void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid, | 211 | void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop); |
| 212 | const struct ieee80211_tx_rate *rate); | 212 | void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid, |
| 213 | bool mt76x02_mac_load_tx_status(struct mt76_dev *dev, | 213 | const struct ieee80211_tx_rate *rate); |
| 214 | struct mt76x02_tx_status *stat); | 214 | bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev, |
| 215 | void mt76x02_send_tx_status(struct mt76_dev *dev, | 215 | struct mt76x02_tx_status *stat); |
| 216 | struct mt76x02_tx_status *stat, u8 *update); | 216 | void mt76x02_send_tx_status(struct mt76x02_dev *dev, |
| 217 | struct mt76x02_tx_status *stat, u8 *update); | ||
| 217 | int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb, | 218 | int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb, |
| 218 | void *rxi); | 219 | void *rxi); |
| 219 | int | 220 | int |
| 220 | mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate); | 221 | mt76x02_mac_process_rate(struct mt76_rx_status *status, u16 rate); |
| 221 | void mt76x02_mac_setaddr(struct mt76_dev *dev, u8 *addr); | 222 | void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr); |
| 222 | void mt76x02_mac_write_txwi(struct mt76_dev *dev, struct mt76x02_txwi *txwi, | 223 | void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi, |
| 223 | struct sk_buff *skb, struct mt76_wcid *wcid, | 224 | struct sk_buff *skb, struct mt76_wcid *wcid, |
| 224 | struct ieee80211_sta *sta, int len); | 225 | struct ieee80211_sta *sta, int len); |
| 225 | void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq); | 226 | void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c index 6d565133b7af..1b853bb723fb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c | |||
| @@ -19,9 +19,7 @@ | |||
| 19 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | 21 | ||
| 22 | #include "mt76.h" | ||
| 23 | #include "mt76x02_mcu.h" | 22 | #include "mt76x02_mcu.h" |
| 24 | #include "mt76x02_dma.h" | ||
| 25 | 23 | ||
| 26 | struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len) | 24 | struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len) |
| 27 | { | 25 | { |
| @@ -37,7 +35,7 @@ struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len) | |||
| 37 | EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_alloc); | 35 | EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_alloc); |
| 38 | 36 | ||
| 39 | static struct sk_buff * | 37 | static struct sk_buff * |
| 40 | mt76x02_mcu_get_response(struct mt76_dev *dev, unsigned long expires) | 38 | mt76x02_mcu_get_response(struct mt76x02_dev *dev, unsigned long expires) |
| 41 | { | 39 | { |
| 42 | unsigned long timeout; | 40 | unsigned long timeout; |
| 43 | 41 | ||
| @@ -45,17 +43,17 @@ mt76x02_mcu_get_response(struct mt76_dev *dev, unsigned long expires) | |||
| 45 | return NULL; | 43 | return NULL; |
| 46 | 44 | ||
| 47 | timeout = expires - jiffies; | 45 | timeout = expires - jiffies; |
| 48 | wait_event_timeout(dev->mmio.mcu.wait, | 46 | wait_event_timeout(dev->mt76.mmio.mcu.wait, |
| 49 | !skb_queue_empty(&dev->mmio.mcu.res_q), | 47 | !skb_queue_empty(&dev->mt76.mmio.mcu.res_q), |
| 50 | timeout); | 48 | timeout); |
| 51 | return skb_dequeue(&dev->mmio.mcu.res_q); | 49 | return skb_dequeue(&dev->mt76.mmio.mcu.res_q); |
| 52 | } | 50 | } |
| 53 | 51 | ||
| 54 | static int | 52 | static int |
| 55 | mt76x02_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, | 53 | mt76x02_tx_queue_mcu(struct mt76x02_dev *dev, enum mt76_txq_id qid, |
| 56 | struct sk_buff *skb, int cmd, int seq) | 54 | struct sk_buff *skb, int cmd, int seq) |
| 57 | { | 55 | { |
| 58 | struct mt76_queue *q = &dev->q_tx[qid]; | 56 | struct mt76_queue *q = &dev->mt76.q_tx[qid]; |
| 59 | struct mt76_queue_buf buf; | 57 | struct mt76_queue_buf buf; |
| 60 | dma_addr_t addr; | 58 | dma_addr_t addr; |
| 61 | u32 tx_info; | 59 | u32 tx_info; |
| @@ -66,24 +64,26 @@ mt76x02_tx_queue_mcu(struct mt76_dev *dev, enum mt76_txq_id qid, | |||
| 66 | FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | | 64 | FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) | |
| 67 | FIELD_PREP(MT_MCU_MSG_LEN, skb->len); | 65 | FIELD_PREP(MT_MCU_MSG_LEN, skb->len); |
| 68 | 66 | ||
| 69 | addr = dma_map_single(dev->dev, skb->data, skb->len, | 67 | addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, |
| 70 | DMA_TO_DEVICE); | 68 | DMA_TO_DEVICE); |
| 71 | if (dma_mapping_error(dev->dev, addr)) | 69 | if (dma_mapping_error(dev->mt76.dev, addr)) |
| 72 | return -ENOMEM; | 70 | return -ENOMEM; |
| 73 | 71 | ||
| 74 | buf.addr = addr; | 72 | buf.addr = addr; |
| 75 | buf.len = skb->len; | 73 | buf.len = skb->len; |
| 74 | |||
| 76 | spin_lock_bh(&q->lock); | 75 | spin_lock_bh(&q->lock); |
| 77 | dev->queue_ops->add_buf(dev, q, &buf, 1, tx_info, skb, NULL); | 76 | mt76_queue_add_buf(dev, q, &buf, 1, tx_info, skb, NULL); |
| 78 | dev->queue_ops->kick(dev, q); | 77 | mt76_queue_kick(dev, q); |
| 79 | spin_unlock_bh(&q->lock); | 78 | spin_unlock_bh(&q->lock); |
| 80 | 79 | ||
| 81 | return 0; | 80 | return 0; |
| 82 | } | 81 | } |
| 83 | 82 | ||
| 84 | int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, | 83 | int mt76x02_mcu_msg_send(struct mt76_dev *mdev, struct sk_buff *skb, |
| 85 | int cmd, bool wait_resp) | 84 | int cmd, bool wait_resp) |
| 86 | { | 85 | { |
| 86 | struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); | ||
| 87 | unsigned long expires = jiffies + HZ; | 87 | unsigned long expires = jiffies + HZ; |
| 88 | int ret; | 88 | int ret; |
| 89 | u8 seq; | 89 | u8 seq; |
| @@ -91,11 +91,11 @@ int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, | |||
| 91 | if (!skb) | 91 | if (!skb) |
| 92 | return -EINVAL; | 92 | return -EINVAL; |
| 93 | 93 | ||
| 94 | mutex_lock(&dev->mmio.mcu.mutex); | 94 | mutex_lock(&mdev->mmio.mcu.mutex); |
| 95 | 95 | ||
| 96 | seq = ++dev->mmio.mcu.msg_seq & 0xf; | 96 | seq = ++mdev->mmio.mcu.msg_seq & 0xf; |
| 97 | if (!seq) | 97 | if (!seq) |
| 98 | seq = ++dev->mmio.mcu.msg_seq & 0xf; | 98 | seq = ++mdev->mmio.mcu.msg_seq & 0xf; |
| 99 | 99 | ||
| 100 | ret = mt76x02_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); | 100 | ret = mt76x02_tx_queue_mcu(dev, MT_TXQ_MCU, skb, cmd, seq); |
| 101 | if (ret) | 101 | if (ret) |
| @@ -107,7 +107,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, | |||
| 107 | 107 | ||
| 108 | skb = mt76x02_mcu_get_response(dev, expires); | 108 | skb = mt76x02_mcu_get_response(dev, expires); |
| 109 | if (!skb) { | 109 | if (!skb) { |
| 110 | dev_err(dev->dev, | 110 | dev_err(mdev->dev, |
| 111 | "MCU message %d (seq %d) timed out\n", cmd, | 111 | "MCU message %d (seq %d) timed out\n", cmd, |
| 112 | seq); | 112 | seq); |
| 113 | ret = -ETIMEDOUT; | 113 | ret = -ETIMEDOUT; |
| @@ -125,13 +125,13 @@ int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | out: | 127 | out: |
| 128 | mutex_unlock(&dev->mmio.mcu.mutex); | 128 | mutex_unlock(&mdev->mmio.mcu.mutex); |
| 129 | 129 | ||
| 130 | return ret; | 130 | return ret; |
| 131 | } | 131 | } |
| 132 | EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_send); | 132 | EXPORT_SYMBOL_GPL(mt76x02_mcu_msg_send); |
| 133 | 133 | ||
| 134 | int mt76x02_mcu_function_select(struct mt76_dev *dev, | 134 | int mt76x02_mcu_function_select(struct mt76x02_dev *dev, |
| 135 | enum mcu_function func, | 135 | enum mcu_function func, |
| 136 | u32 val, bool wait_resp) | 136 | u32 val, bool wait_resp) |
| 137 | { | 137 | { |
| @@ -144,13 +144,12 @@ int mt76x02_mcu_function_select(struct mt76_dev *dev, | |||
| 144 | .value = cpu_to_le32(val), | 144 | .value = cpu_to_le32(val), |
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); | 147 | skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); |
| 148 | return dev->mcu_ops->mcu_send_msg(dev, skb, CMD_FUN_SET_OP, | 148 | return mt76_mcu_send_msg(dev, skb, CMD_FUN_SET_OP, wait_resp); |
| 149 | wait_resp); | ||
| 150 | } | 149 | } |
| 151 | EXPORT_SYMBOL_GPL(mt76x02_mcu_function_select); | 150 | EXPORT_SYMBOL_GPL(mt76x02_mcu_function_select); |
| 152 | 151 | ||
| 153 | int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, | 152 | int mt76x02_mcu_set_radio_state(struct mt76x02_dev *dev, bool on, |
| 154 | bool wait_resp) | 153 | bool wait_resp) |
| 155 | { | 154 | { |
| 156 | struct sk_buff *skb; | 155 | struct sk_buff *skb; |
| @@ -162,13 +161,12 @@ int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, | |||
| 162 | .level = cpu_to_le32(0), | 161 | .level = cpu_to_le32(0), |
| 163 | }; | 162 | }; |
| 164 | 163 | ||
| 165 | skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); | 164 | skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); |
| 166 | return dev->mcu_ops->mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, | 165 | return mt76_mcu_send_msg(dev, skb, CMD_POWER_SAVING_OP, wait_resp); |
| 167 | wait_resp); | ||
| 168 | } | 166 | } |
| 169 | EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state); | 167 | EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state); |
| 170 | 168 | ||
| 171 | int mt76x02_mcu_calibrate(struct mt76_dev *dev, int type, | 169 | int mt76x02_mcu_calibrate(struct mt76x02_dev *dev, int type, |
| 172 | u32 param, bool wait) | 170 | u32 param, bool wait) |
| 173 | { | 171 | { |
| 174 | struct sk_buff *skb; | 172 | struct sk_buff *skb; |
| @@ -182,44 +180,44 @@ int mt76x02_mcu_calibrate(struct mt76_dev *dev, int type, | |||
| 182 | int ret; | 180 | int ret; |
| 183 | 181 | ||
| 184 | if (wait) | 182 | if (wait) |
| 185 | dev->bus->rmw(dev, MT_MCU_COM_REG0, BIT(31), 0); | 183 | mt76_rmw(dev, MT_MCU_COM_REG0, BIT(31), 0); |
| 186 | 184 | ||
| 187 | skb = dev->mcu_ops->mcu_msg_alloc(&msg, sizeof(msg)); | 185 | skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); |
| 188 | ret = dev->mcu_ops->mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); | 186 | ret = mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true); |
| 189 | if (ret) | 187 | if (ret) |
| 190 | return ret; | 188 | return ret; |
| 191 | 189 | ||
| 192 | if (wait && | 190 | if (wait && |
| 193 | WARN_ON(!__mt76_poll_msec(dev, MT_MCU_COM_REG0, | 191 | WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0, |
| 194 | BIT(31), BIT(31), 100))) | 192 | BIT(31), BIT(31), 100))) |
| 195 | return -ETIMEDOUT; | 193 | return -ETIMEDOUT; |
| 196 | 194 | ||
| 197 | return 0; | 195 | return 0; |
| 198 | } | 196 | } |
| 199 | EXPORT_SYMBOL_GPL(mt76x02_mcu_calibrate); | 197 | EXPORT_SYMBOL_GPL(mt76x02_mcu_calibrate); |
| 200 | 198 | ||
| 201 | int mt76x02_mcu_cleanup(struct mt76_dev *dev) | 199 | int mt76x02_mcu_cleanup(struct mt76x02_dev *dev) |
| 202 | { | 200 | { |
| 203 | struct sk_buff *skb; | 201 | struct sk_buff *skb; |
| 204 | 202 | ||
| 205 | dev->bus->wr(dev, MT_MCU_INT_LEVEL, 1); | 203 | mt76_wr(dev, MT_MCU_INT_LEVEL, 1); |
| 206 | usleep_range(20000, 30000); | 204 | usleep_range(20000, 30000); |
| 207 | 205 | ||
| 208 | while ((skb = skb_dequeue(&dev->mmio.mcu.res_q)) != NULL) | 206 | while ((skb = skb_dequeue(&dev->mt76.mmio.mcu.res_q)) != NULL) |
| 209 | dev_kfree_skb(skb); | 207 | dev_kfree_skb(skb); |
| 210 | 208 | ||
| 211 | return 0; | 209 | return 0; |
| 212 | } | 210 | } |
| 213 | EXPORT_SYMBOL_GPL(mt76x02_mcu_cleanup); | 211 | EXPORT_SYMBOL_GPL(mt76x02_mcu_cleanup); |
| 214 | 212 | ||
| 215 | void mt76x02_set_ethtool_fwver(struct mt76_dev *dev, | 213 | void mt76x02_set_ethtool_fwver(struct mt76x02_dev *dev, |
| 216 | const struct mt76x02_fw_header *h) | 214 | const struct mt76x02_fw_header *h) |
| 217 | { | 215 | { |
| 218 | u16 bld = le16_to_cpu(h->build_ver); | 216 | u16 bld = le16_to_cpu(h->build_ver); |
| 219 | u16 ver = le16_to_cpu(h->fw_ver); | 217 | u16 ver = le16_to_cpu(h->fw_ver); |
| 220 | 218 | ||
| 221 | snprintf(dev->hw->wiphy->fw_version, | 219 | snprintf(dev->mt76.hw->wiphy->fw_version, |
| 222 | sizeof(dev->hw->wiphy->fw_version), | 220 | sizeof(dev->mt76.hw->wiphy->fw_version), |
| 223 | "%d.%d.%02d-b%x", | 221 | "%d.%d.%02d-b%x", |
| 224 | (ver >> 12) & 0xf, (ver >> 8) & 0xf, ver & 0xf, bld); | 222 | (ver >> 12) & 0xf, (ver >> 8) & 0xf, ver & 0xf, bld); |
| 225 | } | 223 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h index ce664f8b1c94..2d8fd2514570 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #ifndef __MT76x02_MCU_H | 17 | #ifndef __MT76x02_MCU_H |
| 18 | #define __MT76x02_MCU_H | 18 | #define __MT76x02_MCU_H |
| 19 | 19 | ||
| 20 | #include "mt76x02.h" | ||
| 21 | |||
| 20 | #define MT_MCU_RESET_CTL 0x070C | 22 | #define MT_MCU_RESET_CTL 0x070C |
| 21 | #define MT_MCU_INT_LEVEL 0x0718 | 23 | #define MT_MCU_INT_LEVEL 0x0718 |
| 22 | #define MT_MCU_COM_REG0 0x0730 | 24 | #define MT_MCU_COM_REG0 0x0730 |
| @@ -94,18 +96,18 @@ struct mt76x02_patch_header { | |||
| 94 | u8 pad[2]; | 96 | u8 pad[2]; |
| 95 | }; | 97 | }; |
| 96 | 98 | ||
| 97 | int mt76x02_mcu_cleanup(struct mt76_dev *dev); | 99 | int mt76x02_mcu_cleanup(struct mt76x02_dev *dev); |
| 98 | int mt76x02_mcu_calibrate(struct mt76_dev *dev, int type, | 100 | int mt76x02_mcu_calibrate(struct mt76x02_dev *dev, int type, |
| 99 | u32 param, bool wait); | 101 | u32 param, bool wait); |
| 100 | struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len); | 102 | struct sk_buff *mt76x02_mcu_msg_alloc(const void *data, int len); |
| 101 | int mt76x02_mcu_msg_send(struct mt76_dev *dev, struct sk_buff *skb, | 103 | int mt76x02_mcu_msg_send(struct mt76_dev *mdev, struct sk_buff *skb, |
| 102 | int cmd, bool wait_resp); | 104 | int cmd, bool wait_resp); |
| 103 | int mt76x02_mcu_function_select(struct mt76_dev *dev, | 105 | int mt76x02_mcu_function_select(struct mt76x02_dev *dev, |
| 104 | enum mcu_function func, | 106 | enum mcu_function func, |
| 105 | u32 val, bool wait_resp); | 107 | u32 val, bool wait_resp); |
| 106 | int mt76x02_mcu_set_radio_state(struct mt76_dev *dev, bool on, | 108 | int mt76x02_mcu_set_radio_state(struct mt76x02_dev *dev, bool on, |
| 107 | bool wait_resp); | 109 | bool wait_resp); |
| 108 | void mt76x02_set_ethtool_fwver(struct mt76_dev *dev, | 110 | void mt76x02_set_ethtool_fwver(struct mt76x02_dev *dev, |
| 109 | const struct mt76x02_fw_header *h); | 111 | const struct mt76x02_fw_header *h); |
| 110 | 112 | ||
| 111 | #endif /* __MT76x02_MCU_H */ | 113 | #endif /* __MT76x02_MCU_H */ |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c index 1b945079c802..39f092034240 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | |||
| @@ -65,7 +65,7 @@ static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev) | |||
| 65 | u8 update = 1; | 65 | u8 update = 1; |
| 66 | 66 | ||
| 67 | while (kfifo_get(&dev->txstatus_fifo, &stat)) | 67 | while (kfifo_get(&dev->txstatus_fifo, &stat)) |
| 68 | mt76x02_send_tx_status(&dev->mt76, &stat, &update); | 68 | mt76x02_send_tx_status(dev, &stat, &update); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static void mt76x02_tx_tasklet(unsigned long data) | 71 | static void mt76x02_tx_tasklet(unsigned long data) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c index d31ce1d7b689..0f1d7b5c9f68 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c | |||
| @@ -17,18 +17,17 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | 19 | ||
| 20 | #include "mt76.h" | 20 | #include "mt76x02.h" |
| 21 | #include "mt76x02_phy.h" | 21 | #include "mt76x02_phy.h" |
| 22 | #include "mt76x02_mac.h" | ||
| 23 | 22 | ||
| 24 | void mt76x02_phy_set_rxpath(struct mt76_dev *dev) | 23 | void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev) |
| 25 | { | 24 | { |
| 26 | u32 val; | 25 | u32 val; |
| 27 | 26 | ||
| 28 | val = __mt76_rr(dev, MT_BBP(AGC, 0)); | 27 | val = mt76_rr(dev, MT_BBP(AGC, 0)); |
| 29 | val &= ~BIT(4); | 28 | val &= ~BIT(4); |
| 30 | 29 | ||
| 31 | switch (dev->chainmask & 0xf) { | 30 | switch (dev->mt76.chainmask & 0xf) { |
| 32 | case 2: | 31 | case 2: |
| 33 | val |= BIT(3); | 32 | val |= BIT(3); |
| 34 | break; | 33 | break; |
| @@ -37,23 +36,23 @@ void mt76x02_phy_set_rxpath(struct mt76_dev *dev) | |||
| 37 | break; | 36 | break; |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | __mt76_wr(dev, MT_BBP(AGC, 0), val); | 39 | mt76_wr(dev, MT_BBP(AGC, 0), val); |
| 41 | mb(); | 40 | mb(); |
| 42 | val = __mt76_rr(dev, MT_BBP(AGC, 0)); | 41 | val = mt76_rr(dev, MT_BBP(AGC, 0)); |
| 43 | } | 42 | } |
| 44 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_rxpath); | 43 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_rxpath); |
| 45 | 44 | ||
| 46 | void mt76x02_phy_set_txdac(struct mt76_dev *dev) | 45 | void mt76x02_phy_set_txdac(struct mt76x02_dev *dev) |
| 47 | { | 46 | { |
| 48 | int txpath; | 47 | int txpath; |
| 49 | 48 | ||
| 50 | txpath = (dev->chainmask >> 8) & 0xf; | 49 | txpath = (dev->mt76.chainmask >> 8) & 0xf; |
| 51 | switch (txpath) { | 50 | switch (txpath) { |
| 52 | case 2: | 51 | case 2: |
| 53 | __mt76_set(dev, MT_BBP(TXBE, 5), 0x3); | 52 | mt76_set(dev, MT_BBP(TXBE, 5), 0x3); |
| 54 | break; | 53 | break; |
| 55 | default: | 54 | default: |
| 56 | __mt76_clear(dev, MT_BBP(TXBE, 5), 0x3); | 55 | mt76_clear(dev, MT_BBP(TXBE, 5), 0x3); |
| 57 | break; | 56 | break; |
| 58 | } | 57 | } |
| 59 | } | 58 | } |
| @@ -102,40 +101,38 @@ void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset) | |||
| 102 | } | 101 | } |
| 103 | EXPORT_SYMBOL_GPL(mt76x02_add_rate_power_offset); | 102 | EXPORT_SYMBOL_GPL(mt76x02_add_rate_power_offset); |
| 104 | 103 | ||
| 105 | void mt76x02_phy_set_txpower(struct mt76_dev *dev, int txp_0, int txp_1) | 104 | void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_1) |
| 106 | { | 105 | { |
| 107 | struct mt76_rate_power *t = &dev->rate_power; | 106 | struct mt76_rate_power *t = &dev->mt76.rate_power; |
| 108 | 107 | ||
| 109 | __mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, | 108 | mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, txp_0); |
| 110 | txp_0); | 109 | mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, txp_1); |
| 111 | __mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, | 110 | |
| 112 | txp_1); | 111 | mt76_wr(dev, MT_TX_PWR_CFG_0, |
| 113 | 112 | mt76x02_tx_power_mask(t->cck[0], t->cck[2], t->ofdm[0], | |
| 114 | __mt76_wr(dev, MT_TX_PWR_CFG_0, | 113 | t->ofdm[2])); |
| 115 | mt76x02_tx_power_mask(t->cck[0], t->cck[2], t->ofdm[0], | 114 | mt76_wr(dev, MT_TX_PWR_CFG_1, |
| 116 | t->ofdm[2])); | 115 | mt76x02_tx_power_mask(t->ofdm[4], t->ofdm[6], t->ht[0], |
| 117 | __mt76_wr(dev, MT_TX_PWR_CFG_1, | 116 | t->ht[2])); |
| 118 | mt76x02_tx_power_mask(t->ofdm[4], t->ofdm[6], t->ht[0], | 117 | mt76_wr(dev, MT_TX_PWR_CFG_2, |
| 119 | t->ht[2])); | 118 | mt76x02_tx_power_mask(t->ht[4], t->ht[6], t->ht[8], |
| 120 | __mt76_wr(dev, MT_TX_PWR_CFG_2, | 119 | t->ht[10])); |
| 121 | mt76x02_tx_power_mask(t->ht[4], t->ht[6], t->ht[8], | 120 | mt76_wr(dev, MT_TX_PWR_CFG_3, |
| 122 | t->ht[10])); | 121 | mt76x02_tx_power_mask(t->ht[12], t->ht[14], t->stbc[0], |
| 123 | __mt76_wr(dev, MT_TX_PWR_CFG_3, | 122 | t->stbc[2])); |
| 124 | mt76x02_tx_power_mask(t->ht[12], t->ht[14], t->stbc[0], | 123 | mt76_wr(dev, MT_TX_PWR_CFG_4, |
| 125 | t->stbc[2])); | 124 | mt76x02_tx_power_mask(t->stbc[4], t->stbc[6], 0, 0)); |
| 126 | __mt76_wr(dev, MT_TX_PWR_CFG_4, | 125 | mt76_wr(dev, MT_TX_PWR_CFG_7, |
| 127 | mt76x02_tx_power_mask(t->stbc[4], t->stbc[6], 0, 0)); | 126 | mt76x02_tx_power_mask(t->ofdm[7], t->vht[8], t->ht[7], |
| 128 | __mt76_wr(dev, MT_TX_PWR_CFG_7, | 127 | t->vht[9])); |
| 129 | mt76x02_tx_power_mask(t->ofdm[7], t->vht[8], t->ht[7], | 128 | mt76_wr(dev, MT_TX_PWR_CFG_8, |
| 130 | t->vht[9])); | 129 | mt76x02_tx_power_mask(t->ht[14], 0, t->vht[8], t->vht[9])); |
| 131 | __mt76_wr(dev, MT_TX_PWR_CFG_8, | 130 | mt76_wr(dev, MT_TX_PWR_CFG_9, |
| 132 | mt76x02_tx_power_mask(t->ht[14], 0, t->vht[8], t->vht[9])); | 131 | mt76x02_tx_power_mask(t->ht[7], 0, t->stbc[8], t->stbc[9])); |
| 133 | __mt76_wr(dev, MT_TX_PWR_CFG_9, | ||
| 134 | mt76x02_tx_power_mask(t->ht[7], 0, t->stbc[8], t->stbc[9])); | ||
| 135 | } | 132 | } |
| 136 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_txpower); | 133 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_txpower); |
| 137 | 134 | ||
| 138 | int mt76x02_phy_get_min_avg_rssi(struct mt76_dev *dev) | 135 | int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev) |
| 139 | { | 136 | { |
| 140 | struct mt76x02_sta *sta; | 137 | struct mt76x02_sta *sta; |
| 141 | struct mt76_wcid *wcid; | 138 | struct mt76_wcid *wcid; |
| @@ -145,8 +142,8 @@ int mt76x02_phy_get_min_avg_rssi(struct mt76_dev *dev) | |||
| 145 | local_bh_disable(); | 142 | local_bh_disable(); |
| 146 | rcu_read_lock(); | 143 | rcu_read_lock(); |
| 147 | 144 | ||
| 148 | for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) { | 145 | for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) { |
| 149 | unsigned long mask = dev->wcid_mask[i]; | 146 | unsigned long mask = dev->mt76.wcid_mask[i]; |
| 150 | 147 | ||
| 151 | if (!mask) | 148 | if (!mask) |
| 152 | continue; | 149 | continue; |
| @@ -155,17 +152,17 @@ int mt76x02_phy_get_min_avg_rssi(struct mt76_dev *dev) | |||
| 155 | if (!(mask & 1)) | 152 | if (!(mask & 1)) |
| 156 | continue; | 153 | continue; |
| 157 | 154 | ||
| 158 | wcid = rcu_dereference(dev->wcid[j]); | 155 | wcid = rcu_dereference(dev->mt76.wcid[j]); |
| 159 | if (!wcid) | 156 | if (!wcid) |
| 160 | continue; | 157 | continue; |
| 161 | 158 | ||
| 162 | sta = container_of(wcid, struct mt76x02_sta, wcid); | 159 | sta = container_of(wcid, struct mt76x02_sta, wcid); |
| 163 | spin_lock(&dev->rx_lock); | 160 | spin_lock(&dev->mt76.rx_lock); |
| 164 | if (sta->inactive_count++ < 5) | 161 | if (sta->inactive_count++ < 5) |
| 165 | cur_rssi = ewma_signal_read(&sta->rssi); | 162 | cur_rssi = ewma_signal_read(&sta->rssi); |
| 166 | else | 163 | else |
| 167 | cur_rssi = 0; | 164 | cur_rssi = 0; |
| 168 | spin_unlock(&dev->rx_lock); | 165 | spin_unlock(&dev->mt76.rx_lock); |
| 169 | 166 | ||
| 170 | if (cur_rssi < min_rssi) | 167 | if (cur_rssi < min_rssi) |
| 171 | min_rssi = cur_rssi; | 168 | min_rssi = cur_rssi; |
| @@ -181,3 +178,81 @@ int mt76x02_phy_get_min_avg_rssi(struct mt76_dev *dev) | |||
| 181 | return min_rssi; | 178 | return min_rssi; |
| 182 | } | 179 | } |
| 183 | EXPORT_SYMBOL_GPL(mt76x02_phy_get_min_avg_rssi); | 180 | EXPORT_SYMBOL_GPL(mt76x02_phy_get_min_avg_rssi); |
| 181 | |||
| 182 | void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl) | ||
| 183 | { | ||
| 184 | int core_val, agc_val; | ||
| 185 | |||
| 186 | switch (width) { | ||
| 187 | case NL80211_CHAN_WIDTH_80: | ||
| 188 | core_val = 3; | ||
| 189 | agc_val = 7; | ||
| 190 | break; | ||
| 191 | case NL80211_CHAN_WIDTH_40: | ||
| 192 | core_val = 2; | ||
| 193 | agc_val = 3; | ||
| 194 | break; | ||
| 195 | default: | ||
| 196 | core_val = 0; | ||
| 197 | agc_val = 1; | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | |||
| 201 | mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val); | ||
| 202 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val); | ||
| 203 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl); | ||
| 204 | mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); | ||
| 205 | } | ||
| 206 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_bw); | ||
| 207 | |||
| 208 | void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band, | ||
| 209 | bool primary_upper) | ||
| 210 | { | ||
| 211 | switch (band) { | ||
| 212 | case NL80211_BAND_2GHZ: | ||
| 213 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 214 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 215 | break; | ||
| 216 | case NL80211_BAND_5GHZ: | ||
| 217 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 218 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M, | ||
| 223 | primary_upper); | ||
| 224 | } | ||
| 225 | EXPORT_SYMBOL_GPL(mt76x02_phy_set_band); | ||
| 226 | |||
| 227 | bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev) | ||
| 228 | { | ||
| 229 | u8 limit = dev->cal.low_gain > 0 ? 16 : 4; | ||
| 230 | bool ret = false; | ||
| 231 | u32 false_cca; | ||
| 232 | |||
| 233 | false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1)); | ||
| 234 | dev->cal.false_cca = false_cca; | ||
| 235 | if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) { | ||
| 236 | dev->cal.agc_gain_adjust += 2; | ||
| 237 | ret = true; | ||
| 238 | } else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) || | ||
| 239 | (dev->cal.agc_gain_adjust >= limit && false_cca < 500)) { | ||
| 240 | dev->cal.agc_gain_adjust -= 2; | ||
| 241 | ret = true; | ||
| 242 | } | ||
| 243 | |||
| 244 | return ret; | ||
| 245 | } | ||
| 246 | EXPORT_SYMBOL_GPL(mt76x02_phy_adjust_vga_gain); | ||
| 247 | |||
| 248 | void mt76x02_init_agc_gain(struct mt76x02_dev *dev) | ||
| 249 | { | ||
| 250 | dev->cal.agc_gain_init[0] = mt76_get_field(dev, MT_BBP(AGC, 8), | ||
| 251 | MT_BBP_AGC_GAIN); | ||
| 252 | dev->cal.agc_gain_init[1] = mt76_get_field(dev, MT_BBP(AGC, 9), | ||
| 253 | MT_BBP_AGC_GAIN); | ||
| 254 | memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init, | ||
| 255 | sizeof(dev->cal.agc_gain_cur)); | ||
| 256 | dev->cal.low_gain = -1; | ||
| 257 | } | ||
| 258 | EXPORT_SYMBOL_GPL(mt76x02_init_agc_gain); | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h index e70ea6eeb077..2b316cf7c70c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.h | |||
| @@ -19,12 +19,43 @@ | |||
| 19 | 19 | ||
| 20 | #include "mt76x02_regs.h" | 20 | #include "mt76x02_regs.h" |
| 21 | 21 | ||
| 22 | static inline int | ||
| 23 | mt76x02_get_rssi_gain_thresh(struct mt76x02_dev *dev) | ||
| 24 | { | ||
| 25 | switch (dev->mt76.chandef.width) { | ||
| 26 | case NL80211_CHAN_WIDTH_80: | ||
| 27 | return -62; | ||
| 28 | case NL80211_CHAN_WIDTH_40: | ||
| 29 | return -65; | ||
| 30 | default: | ||
| 31 | return -68; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline int | ||
| 36 | mt76x02_get_low_rssi_gain_thresh(struct mt76x02_dev *dev) | ||
| 37 | { | ||
| 38 | switch (dev->mt76.chandef.width) { | ||
| 39 | case NL80211_CHAN_WIDTH_80: | ||
| 40 | return -76; | ||
| 41 | case NL80211_CHAN_WIDTH_40: | ||
| 42 | return -79; | ||
| 43 | default: | ||
| 44 | return -82; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 22 | void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset); | 48 | void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset); |
| 23 | void mt76x02_phy_set_txpower(struct mt76_dev *dev, int txp_0, int txp_2); | 49 | void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_2); |
| 24 | void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit); | 50 | void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit); |
| 25 | int mt76x02_get_max_rate_power(struct mt76_rate_power *r); | 51 | int mt76x02_get_max_rate_power(struct mt76_rate_power *r); |
| 26 | void mt76x02_phy_set_rxpath(struct mt76_dev *dev); | 52 | void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev); |
| 27 | void mt76x02_phy_set_txdac(struct mt76_dev *dev); | 53 | void mt76x02_phy_set_txdac(struct mt76x02_dev *dev); |
| 28 | int mt76x02_phy_get_min_avg_rssi(struct mt76_dev *dev); | 54 | int mt76x02_phy_get_min_avg_rssi(struct mt76x02_dev *dev); |
| 55 | void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl); | ||
| 56 | void mt76x02_phy_set_band(struct mt76x02_dev *dev, int band, | ||
| 57 | bool primary_upper); | ||
| 58 | bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev); | ||
| 59 | void mt76x02_init_agc_gain(struct mt76x02_dev *dev); | ||
| 29 | 60 | ||
| 30 | #endif /* __MT76x02_PHY_H */ | 61 | #endif /* __MT76x02_PHY_H */ |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h index 24d1e6d747dd..f7de77d09d28 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h | |||
| @@ -205,8 +205,8 @@ | |||
| 205 | #define MT_TXQ_STA 0x0434 | 205 | #define MT_TXQ_STA 0x0434 |
| 206 | #define MT_RF_CSR_CFG 0x0500 | 206 | #define MT_RF_CSR_CFG 0x0500 |
| 207 | #define MT_RF_CSR_CFG_DATA GENMASK(7, 0) | 207 | #define MT_RF_CSR_CFG_DATA GENMASK(7, 0) |
| 208 | #define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8) | 208 | #define MT_RF_CSR_CFG_REG_ID GENMASK(14, 8) |
| 209 | #define MT_RF_CSR_CFG_REG_BANK GENMASK(17, 14) | 209 | #define MT_RF_CSR_CFG_REG_BANK GENMASK(17, 15) |
| 210 | #define MT_RF_CSR_CFG_WR BIT(30) | 210 | #define MT_RF_CSR_CFG_WR BIT(30) |
| 211 | #define MT_RF_CSR_CFG_KICK BIT(31) | 211 | #define MT_RF_CSR_CFG_KICK BIT(31) |
| 212 | 212 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c index 830377221739..d3de08872d6e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | |||
| @@ -71,7 +71,7 @@ void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, | |||
| 71 | } | 71 | } |
| 72 | EXPORT_SYMBOL_GPL(mt76x02_queue_rx_skb); | 72 | EXPORT_SYMBOL_GPL(mt76x02_queue_rx_skb); |
| 73 | 73 | ||
| 74 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev, | 74 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, |
| 75 | const struct ieee80211_tx_rate *rate) | 75 | const struct ieee80211_tx_rate *rate) |
| 76 | { | 76 | { |
| 77 | s8 max_txpwr; | 77 | s8 max_txpwr; |
| @@ -80,23 +80,23 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev, | |||
| 80 | u8 mcs = ieee80211_rate_get_vht_mcs(rate); | 80 | u8 mcs = ieee80211_rate_get_vht_mcs(rate); |
| 81 | 81 | ||
| 82 | if (mcs == 8 || mcs == 9) { | 82 | if (mcs == 8 || mcs == 9) { |
| 83 | max_txpwr = dev->rate_power.vht[8]; | 83 | max_txpwr = dev->mt76.rate_power.vht[8]; |
| 84 | } else { | 84 | } else { |
| 85 | u8 nss, idx; | 85 | u8 nss, idx; |
| 86 | 86 | ||
| 87 | nss = ieee80211_rate_get_vht_nss(rate); | 87 | nss = ieee80211_rate_get_vht_nss(rate); |
| 88 | idx = ((nss - 1) << 3) + mcs; | 88 | idx = ((nss - 1) << 3) + mcs; |
| 89 | max_txpwr = dev->rate_power.ht[idx & 0xf]; | 89 | max_txpwr = dev->mt76.rate_power.ht[idx & 0xf]; |
| 90 | } | 90 | } |
| 91 | } else if (rate->flags & IEEE80211_TX_RC_MCS) { | 91 | } else if (rate->flags & IEEE80211_TX_RC_MCS) { |
| 92 | max_txpwr = dev->rate_power.ht[rate->idx & 0xf]; | 92 | max_txpwr = dev->mt76.rate_power.ht[rate->idx & 0xf]; |
| 93 | } else { | 93 | } else { |
| 94 | enum nl80211_band band = dev->chandef.chan->band; | 94 | enum nl80211_band band = dev->mt76.chandef.chan->band; |
| 95 | 95 | ||
| 96 | if (band == NL80211_BAND_2GHZ) { | 96 | if (band == NL80211_BAND_2GHZ) { |
| 97 | const struct ieee80211_rate *r; | 97 | const struct ieee80211_rate *r; |
| 98 | struct wiphy *wiphy = dev->hw->wiphy; | 98 | struct wiphy *wiphy = dev->mt76.hw->wiphy; |
| 99 | struct mt76_rate_power *rp = &dev->rate_power; | 99 | struct mt76_rate_power *rp = &dev->mt76.rate_power; |
| 100 | 100 | ||
| 101 | r = &wiphy->bands[band]->bitrates[rate->idx]; | 101 | r = &wiphy->bands[band]->bitrates[rate->idx]; |
| 102 | if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 102 | if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE) |
| @@ -104,7 +104,7 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev, | |||
| 104 | else | 104 | else |
| 105 | max_txpwr = rp->ofdm[r->hw_value & 0x7]; | 105 | max_txpwr = rp->ofdm[r->hw_value & 0x7]; |
| 106 | } else { | 106 | } else { |
| 107 | max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7]; | 107 | max_txpwr = dev->mt76.rate_power.ofdm[rate->idx & 0x7]; |
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | 110 | ||
| @@ -112,10 +112,8 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev, | |||
| 112 | } | 112 | } |
| 113 | EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj); | 113 | EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj); |
| 114 | 114 | ||
| 115 | s8 mt76x02_tx_get_txpwr_adj(struct mt76_dev *mdev, s8 txpwr, s8 max_txpwr_adj) | 115 | s8 mt76x02_tx_get_txpwr_adj(struct mt76x02_dev *dev, s8 txpwr, s8 max_txpwr_adj) |
| 116 | { | 116 | { |
| 117 | struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); | ||
| 118 | |||
| 119 | txpwr = min_t(s8, txpwr, dev->mt76.txpower_conf); | 117 | txpwr = min_t(s8, txpwr, dev->mt76.txpower_conf); |
| 120 | txpwr -= (dev->target_power + dev->target_power_delta[0]); | 118 | txpwr -= (dev->target_power + dev->target_power_delta[0]); |
| 121 | txpwr = min_t(s8, txpwr, max_txpwr_adj); | 119 | txpwr = min_t(s8, txpwr, max_txpwr_adj); |
| @@ -133,7 +131,7 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr) | |||
| 133 | { | 131 | { |
| 134 | s8 txpwr_adj; | 132 | s8 txpwr_adj; |
| 135 | 133 | ||
| 136 | txpwr_adj = mt76x02_tx_get_txpwr_adj(&dev->mt76, txpwr, | 134 | txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, txpwr, |
| 137 | dev->mt76.rate_power.ofdm[4]); | 135 | dev->mt76.rate_power.ofdm[4]); |
| 138 | mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, | 136 | mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, |
| 139 | MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj); | 137 | MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj); |
| @@ -157,8 +155,9 @@ void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb) | |||
| 157 | } | 155 | } |
| 158 | EXPORT_SYMBOL_GPL(mt76x02_tx_complete); | 156 | EXPORT_SYMBOL_GPL(mt76x02_tx_complete); |
| 159 | 157 | ||
| 160 | bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update) | 158 | bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update) |
| 161 | { | 159 | { |
| 160 | struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); | ||
| 162 | struct mt76x02_tx_status stat; | 161 | struct mt76x02_tx_status stat; |
| 163 | 162 | ||
| 164 | if (!mt76x02_mac_load_tx_status(dev, &stat)) | 163 | if (!mt76x02_mac_load_tx_status(dev, &stat)) |
| @@ -181,9 +180,9 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, | |||
| 181 | int ret; | 180 | int ret; |
| 182 | 181 | ||
| 183 | if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128) | 182 | if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128) |
| 184 | mt76x02_mac_wcid_set_drop(&dev->mt76, wcid->idx, false); | 183 | mt76x02_mac_wcid_set_drop(dev, wcid->idx, false); |
| 185 | 184 | ||
| 186 | mt76x02_mac_write_txwi(mdev, txwi, skb, wcid, sta, skb->len); | 185 | mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len); |
| 187 | 186 | ||
| 188 | ret = mt76x02_insert_hdr_pad(skb); | 187 | ret = mt76x02_insert_hdr_pad(skb); |
| 189 | if (ret < 0) | 188 | if (ret < 0) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h index 6b2138328eb2..0126e51d77ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h | |||
| @@ -17,15 +17,15 @@ | |||
| 17 | #ifndef __MT76x02_USB_H | 17 | #ifndef __MT76x02_USB_H |
| 18 | #define __MT76x02_USB_H | 18 | #define __MT76x02_USB_H |
| 19 | 19 | ||
| 20 | #include "mt76.h" | 20 | #include "mt76x02.h" |
| 21 | 21 | ||
| 22 | void mt76x02u_init_mcu(struct mt76_dev *dev); | 22 | void mt76x02u_init_mcu(struct mt76_dev *dev); |
| 23 | void mt76x02u_mcu_fw_reset(struct mt76_dev *dev); | 23 | void mt76x02u_mcu_fw_reset(struct mt76x02_dev *dev); |
| 24 | int mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, | 24 | int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data, |
| 25 | int data_len, u32 max_payload, u32 offset); | 25 | int data_len, u32 max_payload, u32 offset); |
| 26 | 26 | ||
| 27 | int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); | 27 | int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags); |
| 28 | int mt76x02u_tx_prepare_skb(struct mt76_dev *dev, void *data, | 28 | int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data, |
| 29 | struct sk_buff *skb, struct mt76_queue *q, | 29 | struct sk_buff *skb, struct mt76_queue *q, |
| 30 | struct mt76_wcid *wcid, struct ieee80211_sta *sta, | 30 | struct mt76_wcid *wcid, struct ieee80211_sta *sta, |
| 31 | u32 *tx_info); | 31 | u32 *tx_info); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c index 7c6c973af386..dc2226c722dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | |||
| @@ -34,17 +34,6 @@ void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q, | |||
| 34 | } | 34 | } |
| 35 | EXPORT_SYMBOL_GPL(mt76x02u_tx_complete_skb); | 35 | EXPORT_SYMBOL_GPL(mt76x02u_tx_complete_skb); |
| 36 | 36 | ||
| 37 | static int mt76x02u_check_skb_rooms(struct sk_buff *skb) | ||
| 38 | { | ||
| 39 | int hdr_len = ieee80211_get_hdrlen_from_skb(skb); | ||
| 40 | u32 need_head; | ||
| 41 | |||
| 42 | need_head = sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN; | ||
| 43 | if (hdr_len % 4) | ||
| 44 | need_head += 2; | ||
| 45 | return skb_cow(skb, need_head); | ||
| 46 | } | ||
| 47 | |||
| 48 | int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags) | 37 | int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags) |
| 49 | { | 38 | { |
| 50 | struct sk_buff *iter, *last = skb; | 39 | struct sk_buff *iter, *last = skb; |
| @@ -99,17 +88,14 @@ mt76x02u_set_txinfo(struct sk_buff *skb, struct mt76_wcid *wcid, u8 ep) | |||
| 99 | return mt76x02u_skb_dma_info(skb, WLAN_PORT, flags); | 88 | return mt76x02u_skb_dma_info(skb, WLAN_PORT, flags); |
| 100 | } | 89 | } |
| 101 | 90 | ||
| 102 | int mt76x02u_tx_prepare_skb(struct mt76_dev *dev, void *data, | 91 | int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data, |
| 103 | struct sk_buff *skb, struct mt76_queue *q, | 92 | struct sk_buff *skb, struct mt76_queue *q, |
| 104 | struct mt76_wcid *wcid, struct ieee80211_sta *sta, | 93 | struct mt76_wcid *wcid, struct ieee80211_sta *sta, |
| 105 | u32 *tx_info) | 94 | u32 *tx_info) |
| 106 | { | 95 | { |
| 96 | struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); | ||
| 107 | struct mt76x02_txwi *txwi; | 97 | struct mt76x02_txwi *txwi; |
| 108 | int err, len = skb->len; | 98 | int len = skb->len; |
| 109 | |||
| 110 | err = mt76x02u_check_skb_rooms(skb); | ||
| 111 | if (err < 0) | ||
| 112 | return -ENOMEM; | ||
| 113 | 99 | ||
| 114 | mt76x02_insert_hdr_pad(skb); | 100 | mt76x02_insert_hdr_pad(skb); |
| 115 | 101 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c index cb5f073f08af..da299b8a1334 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | |||
| @@ -17,8 +17,7 @@ | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/firmware.h> | 18 | #include <linux/firmware.h> |
| 19 | 19 | ||
| 20 | #include "mt76.h" | 20 | #include "mt76x02.h" |
| 21 | #include "mt76x02_dma.h" | ||
| 22 | #include "mt76x02_mcu.h" | 21 | #include "mt76x02_mcu.h" |
| 23 | #include "mt76x02_usb.h" | 22 | #include "mt76x02_usb.h" |
| 24 | 23 | ||
| @@ -255,16 +254,16 @@ mt76x02u_mcu_rd_rp(struct mt76_dev *dev, u32 base, | |||
| 255 | return ret; | 254 | return ret; |
| 256 | } | 255 | } |
| 257 | 256 | ||
| 258 | void mt76x02u_mcu_fw_reset(struct mt76_dev *dev) | 257 | void mt76x02u_mcu_fw_reset(struct mt76x02_dev *dev) |
| 259 | { | 258 | { |
| 260 | mt76u_vendor_request(dev, MT_VEND_DEV_MODE, | 259 | mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE, |
| 261 | USB_DIR_OUT | USB_TYPE_VENDOR, | 260 | USB_DIR_OUT | USB_TYPE_VENDOR, |
| 262 | 0x1, 0, NULL, 0); | 261 | 0x1, 0, NULL, 0); |
| 263 | } | 262 | } |
| 264 | EXPORT_SYMBOL_GPL(mt76x02u_mcu_fw_reset); | 263 | EXPORT_SYMBOL_GPL(mt76x02u_mcu_fw_reset); |
| 265 | 264 | ||
| 266 | static int | 265 | static int |
| 267 | __mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, struct mt76u_buf *buf, | 266 | __mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, struct mt76u_buf *buf, |
| 268 | const void *fw_data, int len, u32 dst_addr) | 267 | const void *fw_data, int len, u32 dst_addr) |
| 269 | { | 268 | { |
| 270 | u8 *data = sg_virt(&buf->urb->sg[0]); | 269 | u8 *data = sg_virt(&buf->urb->sg[0]); |
| @@ -281,14 +280,14 @@ __mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, struct mt76u_buf *buf, | |||
| 281 | memcpy(data + sizeof(info), fw_data, len); | 280 | memcpy(data + sizeof(info), fw_data, len); |
| 282 | memset(data + sizeof(info) + len, 0, 4); | 281 | memset(data + sizeof(info) + len, 0, 4); |
| 283 | 282 | ||
| 284 | mt76u_single_wr(dev, MT_VEND_WRITE_FCE, | 283 | mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, |
| 285 | MT_FCE_DMA_ADDR, dst_addr); | 284 | MT_FCE_DMA_ADDR, dst_addr); |
| 286 | len = roundup(len, 4); | 285 | len = roundup(len, 4); |
| 287 | mt76u_single_wr(dev, MT_VEND_WRITE_FCE, | 286 | mt76u_single_wr(&dev->mt76, MT_VEND_WRITE_FCE, |
| 288 | MT_FCE_DMA_LEN, len << 16); | 287 | MT_FCE_DMA_LEN, len << 16); |
| 289 | 288 | ||
| 290 | buf->len = MT_CMD_HDR_LEN + len + sizeof(info); | 289 | buf->len = MT_CMD_HDR_LEN + len + sizeof(info); |
| 291 | err = mt76u_submit_buf(dev, USB_DIR_OUT, | 290 | err = mt76u_submit_buf(&dev->mt76, USB_DIR_OUT, |
| 292 | MT_EP_OUT_INBAND_CMD, | 291 | MT_EP_OUT_INBAND_CMD, |
| 293 | buf, GFP_KERNEL, | 292 | buf, GFP_KERNEL, |
| 294 | mt76u_mcu_complete_urb, &cmpl); | 293 | mt76u_mcu_complete_urb, &cmpl); |
| @@ -297,31 +296,31 @@ __mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, struct mt76u_buf *buf, | |||
| 297 | 296 | ||
| 298 | if (!wait_for_completion_timeout(&cmpl, | 297 | if (!wait_for_completion_timeout(&cmpl, |
| 299 | msecs_to_jiffies(1000))) { | 298 | msecs_to_jiffies(1000))) { |
| 300 | dev_err(dev->dev, "firmware upload timed out\n"); | 299 | dev_err(dev->mt76.dev, "firmware upload timed out\n"); |
| 301 | usb_kill_urb(buf->urb); | 300 | usb_kill_urb(buf->urb); |
| 302 | return -ETIMEDOUT; | 301 | return -ETIMEDOUT; |
| 303 | } | 302 | } |
| 304 | 303 | ||
| 305 | if (mt76u_urb_error(buf->urb)) { | 304 | if (mt76u_urb_error(buf->urb)) { |
| 306 | dev_err(dev->dev, "firmware upload failed: %d\n", | 305 | dev_err(dev->mt76.dev, "firmware upload failed: %d\n", |
| 307 | buf->urb->status); | 306 | buf->urb->status); |
| 308 | return buf->urb->status; | 307 | return buf->urb->status; |
| 309 | } | 308 | } |
| 310 | 309 | ||
| 311 | val = mt76u_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); | 310 | val = mt76_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); |
| 312 | val++; | 311 | val++; |
| 313 | mt76u_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); | 312 | mt76_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); |
| 314 | 313 | ||
| 315 | return 0; | 314 | return 0; |
| 316 | } | 315 | } |
| 317 | 316 | ||
| 318 | int mt76x02u_mcu_fw_send_data(struct mt76_dev *dev, const void *data, | 317 | int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data, |
| 319 | int data_len, u32 max_payload, u32 offset) | 318 | int data_len, u32 max_payload, u32 offset) |
| 320 | { | 319 | { |
| 321 | int err, len, pos = 0, max_len = max_payload - 8; | 320 | int err, len, pos = 0, max_len = max_payload - 8; |
| 322 | struct mt76u_buf buf; | 321 | struct mt76u_buf buf; |
| 323 | 322 | ||
| 324 | err = mt76u_buf_alloc(dev, &buf, 1, max_payload, max_payload, | 323 | err = mt76u_buf_alloc(&dev->mt76, &buf, 1, max_payload, max_payload, |
| 325 | GFP_KERNEL); | 324 | GFP_KERNEL); |
| 326 | if (err < 0) | 325 | if (err < 0) |
| 327 | return err; | 326 | return err; |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 5851ab6b7e26..ca05332f81fc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c | |||
| @@ -48,21 +48,21 @@ struct ieee80211_rate mt76x02_rates[] = { | |||
| 48 | EXPORT_SYMBOL_GPL(mt76x02_rates); | 48 | EXPORT_SYMBOL_GPL(mt76x02_rates); |
| 49 | 49 | ||
| 50 | void mt76x02_configure_filter(struct ieee80211_hw *hw, | 50 | void mt76x02_configure_filter(struct ieee80211_hw *hw, |
| 51 | unsigned int changed_flags, | 51 | unsigned int changed_flags, |
| 52 | unsigned int *total_flags, u64 multicast) | 52 | unsigned int *total_flags, u64 multicast) |
| 53 | { | 53 | { |
| 54 | struct mt76_dev *dev = hw->priv; | 54 | struct mt76x02_dev *dev = hw->priv; |
| 55 | u32 flags = 0; | 55 | u32 flags = 0; |
| 56 | 56 | ||
| 57 | #define MT76_FILTER(_flag, _hw) do { \ | 57 | #define MT76_FILTER(_flag, _hw) do { \ |
| 58 | flags |= *total_flags & FIF_##_flag; \ | 58 | flags |= *total_flags & FIF_##_flag; \ |
| 59 | dev->rxfilter &= ~(_hw); \ | 59 | dev->mt76.rxfilter &= ~(_hw); \ |
| 60 | dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \ | 60 | dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw); \ |
| 61 | } while (0) | 61 | } while (0) |
| 62 | 62 | ||
| 63 | mutex_lock(&dev->mutex); | 63 | mutex_lock(&dev->mt76.mutex); |
| 64 | 64 | ||
| 65 | dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; | 65 | dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; |
| 66 | 66 | ||
| 67 | MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); | 67 | MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); |
| 68 | MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); | 68 | MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); |
| @@ -75,25 +75,25 @@ void mt76x02_configure_filter(struct ieee80211_hw *hw, | |||
| 75 | MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); | 75 | MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); |
| 76 | 76 | ||
| 77 | *total_flags = flags; | 77 | *total_flags = flags; |
| 78 | dev->bus->wr(dev, MT_RX_FILTR_CFG, dev->rxfilter); | 78 | mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); |
| 79 | 79 | ||
| 80 | mutex_unlock(&dev->mutex); | 80 | mutex_unlock(&dev->mt76.mutex); |
| 81 | } | 81 | } |
| 82 | EXPORT_SYMBOL_GPL(mt76x02_configure_filter); | 82 | EXPORT_SYMBOL_GPL(mt76x02_configure_filter); |
| 83 | 83 | ||
| 84 | int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 84 | int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 85 | struct ieee80211_sta *sta) | 85 | struct ieee80211_sta *sta) |
| 86 | { | 86 | { |
| 87 | struct mt76_dev *dev = hw->priv; | 87 | struct mt76x02_dev *dev = hw->priv; |
| 88 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; | 88 | struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv; |
| 89 | struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; | 89 | struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; |
| 90 | int ret = 0; | 90 | int ret = 0; |
| 91 | int idx = 0; | 91 | int idx = 0; |
| 92 | int i; | 92 | int i; |
| 93 | 93 | ||
| 94 | mutex_lock(&dev->mutex); | 94 | mutex_lock(&dev->mt76.mutex); |
| 95 | 95 | ||
| 96 | idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid)); | 96 | idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); |
| 97 | if (idx < 0) { | 97 | if (idx < 0) { |
| 98 | ret = -ENOSPC; | 98 | ret = -ENOSPC; |
| 99 | goto out; | 99 | goto out; |
| @@ -113,40 +113,40 @@ int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 113 | 113 | ||
| 114 | ewma_signal_init(&msta->rssi); | 114 | ewma_signal_init(&msta->rssi); |
| 115 | 115 | ||
| 116 | rcu_assign_pointer(dev->wcid[idx], &msta->wcid); | 116 | rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid); |
| 117 | 117 | ||
| 118 | out: | 118 | out: |
| 119 | mutex_unlock(&dev->mutex); | 119 | mutex_unlock(&dev->mt76.mutex); |
| 120 | 120 | ||
| 121 | return ret; | 121 | return ret; |
| 122 | } | 122 | } |
| 123 | EXPORT_SYMBOL_GPL(mt76x02_sta_add); | 123 | EXPORT_SYMBOL_GPL(mt76x02_sta_add); |
| 124 | 124 | ||
| 125 | int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 125 | int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 126 | struct ieee80211_sta *sta) | 126 | struct ieee80211_sta *sta) |
| 127 | { | 127 | { |
| 128 | struct mt76_dev *dev = hw->priv; | 128 | struct mt76x02_dev *dev = hw->priv; |
| 129 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; | 129 | struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv; |
| 130 | int idx = msta->wcid.idx; | 130 | int idx = msta->wcid.idx; |
| 131 | int i; | 131 | int i; |
| 132 | 132 | ||
| 133 | mutex_lock(&dev->mutex); | 133 | mutex_lock(&dev->mt76.mutex); |
| 134 | rcu_assign_pointer(dev->wcid[idx], NULL); | 134 | rcu_assign_pointer(dev->mt76.wcid[idx], NULL); |
| 135 | for (i = 0; i < ARRAY_SIZE(sta->txq); i++) | 135 | for (i = 0; i < ARRAY_SIZE(sta->txq); i++) |
| 136 | mt76_txq_remove(dev, sta->txq[i]); | 136 | mt76_txq_remove(&dev->mt76, sta->txq[i]); |
| 137 | mt76x02_mac_wcid_set_drop(dev, idx, true); | 137 | mt76x02_mac_wcid_set_drop(dev, idx, true); |
| 138 | mt76_wcid_free(dev->wcid_mask, idx); | 138 | mt76_wcid_free(dev->mt76.wcid_mask, idx); |
| 139 | mt76x02_mac_wcid_setup(dev, idx, 0, NULL); | 139 | mt76x02_mac_wcid_setup(dev, idx, 0, NULL); |
| 140 | mutex_unlock(&dev->mutex); | 140 | mutex_unlock(&dev->mt76.mutex); |
| 141 | 141 | ||
| 142 | return 0; | 142 | return 0; |
| 143 | } | 143 | } |
| 144 | EXPORT_SYMBOL_GPL(mt76x02_sta_remove); | 144 | EXPORT_SYMBOL_GPL(mt76x02_sta_remove); |
| 145 | 145 | ||
| 146 | void mt76x02_vif_init(struct mt76_dev *dev, struct ieee80211_vif *vif, | 146 | void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, |
| 147 | unsigned int idx) | 147 | unsigned int idx) |
| 148 | { | 148 | { |
| 149 | struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; | 149 | struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; |
| 150 | 150 | ||
| 151 | mvif->idx = idx; | 151 | mvif->idx = idx; |
| 152 | mvif->group_wcid.idx = MT_VIF_WCID(idx); | 152 | mvif->group_wcid.idx = MT_VIF_WCID(idx); |
| @@ -158,11 +158,11 @@ EXPORT_SYMBOL_GPL(mt76x02_vif_init); | |||
| 158 | int | 158 | int |
| 159 | mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 159 | mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
| 160 | { | 160 | { |
| 161 | struct mt76_dev *dev = hw->priv; | 161 | struct mt76x02_dev *dev = hw->priv; |
| 162 | unsigned int idx = 0; | 162 | unsigned int idx = 0; |
| 163 | 163 | ||
| 164 | if (vif->addr[0] & BIT(1)) | 164 | if (vif->addr[0] & BIT(1)) |
| 165 | idx = 1 + (((dev->macaddr[0] ^ vif->addr[0]) >> 2) & 7); | 165 | idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); |
| 166 | 166 | ||
| 167 | /* | 167 | /* |
| 168 | * Client mode typically only has one configurable BSSID register, | 168 | * Client mode typically only has one configurable BSSID register, |
| @@ -186,20 +186,20 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 186 | EXPORT_SYMBOL_GPL(mt76x02_add_interface); | 186 | EXPORT_SYMBOL_GPL(mt76x02_add_interface); |
| 187 | 187 | ||
| 188 | void mt76x02_remove_interface(struct ieee80211_hw *hw, | 188 | void mt76x02_remove_interface(struct ieee80211_hw *hw, |
| 189 | struct ieee80211_vif *vif) | 189 | struct ieee80211_vif *vif) |
| 190 | { | 190 | { |
| 191 | struct mt76_dev *dev = hw->priv; | 191 | struct mt76x02_dev *dev = hw->priv; |
| 192 | 192 | ||
| 193 | mt76_txq_remove(dev, vif->txq); | 193 | mt76_txq_remove(&dev->mt76, vif->txq); |
| 194 | } | 194 | } |
| 195 | EXPORT_SYMBOL_GPL(mt76x02_remove_interface); | 195 | EXPORT_SYMBOL_GPL(mt76x02_remove_interface); |
| 196 | 196 | ||
| 197 | int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 197 | int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 198 | struct ieee80211_ampdu_params *params) | 198 | struct ieee80211_ampdu_params *params) |
| 199 | { | 199 | { |
| 200 | enum ieee80211_ampdu_mlme_action action = params->action; | 200 | enum ieee80211_ampdu_mlme_action action = params->action; |
| 201 | struct ieee80211_sta *sta = params->sta; | 201 | struct ieee80211_sta *sta = params->sta; |
| 202 | struct mt76_dev *dev = hw->priv; | 202 | struct mt76x02_dev *dev = hw->priv; |
| 203 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; | 203 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; |
| 204 | struct ieee80211_txq *txq = sta->txq[params->tid]; | 204 | struct ieee80211_txq *txq = sta->txq[params->tid]; |
| 205 | u16 tid = params->tid; | 205 | u16 tid = params->tid; |
| @@ -213,12 +213,14 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 213 | 213 | ||
| 214 | switch (action) { | 214 | switch (action) { |
| 215 | case IEEE80211_AMPDU_RX_START: | 215 | case IEEE80211_AMPDU_RX_START: |
| 216 | mt76_rx_aggr_start(dev, &msta->wcid, tid, *ssn, params->buf_size); | 216 | mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, |
| 217 | __mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); | 217 | *ssn, params->buf_size); |
| 218 | mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); | ||
| 218 | break; | 219 | break; |
| 219 | case IEEE80211_AMPDU_RX_STOP: | 220 | case IEEE80211_AMPDU_RX_STOP: |
| 220 | mt76_rx_aggr_stop(dev, &msta->wcid, tid); | 221 | mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid); |
| 221 | __mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); | 222 | mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, |
| 223 | BIT(16 + tid)); | ||
| 222 | break; | 224 | break; |
| 223 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 225 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
| 224 | mtxq->aggr = true; | 226 | mtxq->aggr = true; |
| @@ -245,11 +247,11 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 245 | EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); | 247 | EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); |
| 246 | 248 | ||
| 247 | int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 249 | int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| 248 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, | 250 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
| 249 | struct ieee80211_key_conf *key) | 251 | struct ieee80211_key_conf *key) |
| 250 | { | 252 | { |
| 251 | struct mt76_dev *dev = hw->priv; | 253 | struct mt76x02_dev *dev = hw->priv; |
| 252 | struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv; | 254 | struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; |
| 253 | struct mt76x02_sta *msta; | 255 | struct mt76x02_sta *msta; |
| 254 | struct mt76_wcid *wcid; | 256 | struct mt76_wcid *wcid; |
| 255 | int idx = key->keyidx; | 257 | int idx = key->keyidx; |
| @@ -295,7 +297,7 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 295 | 297 | ||
| 296 | key = NULL; | 298 | key = NULL; |
| 297 | } | 299 | } |
| 298 | mt76_wcid_key_setup(dev, wcid, key); | 300 | mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 299 | 301 | ||
| 300 | if (!msta) { | 302 | if (!msta) { |
| 301 | if (key || wcid->hw_key_idx == idx) { | 303 | if (key || wcid->hw_key_idx == idx) { |
| @@ -312,13 +314,13 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 312 | EXPORT_SYMBOL_GPL(mt76x02_set_key); | 314 | EXPORT_SYMBOL_GPL(mt76x02_set_key); |
| 313 | 315 | ||
| 314 | int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 316 | int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 315 | u16 queue, const struct ieee80211_tx_queue_params *params) | 317 | u16 queue, const struct ieee80211_tx_queue_params *params) |
| 316 | { | 318 | { |
| 317 | struct mt76_dev *dev = hw->priv; | 319 | struct mt76x02_dev *dev = hw->priv; |
| 318 | u8 cw_min = 5, cw_max = 10, qid; | 320 | u8 cw_min = 5, cw_max = 10, qid; |
| 319 | u32 val; | 321 | u32 val; |
| 320 | 322 | ||
| 321 | qid = dev->q_tx[queue].hw_idx; | 323 | qid = dev->mt76.q_tx[queue].hw_idx; |
| 322 | 324 | ||
| 323 | if (params->cw_min) | 325 | if (params->cw_min) |
| 324 | cw_min = fls(params->cw_min); | 326 | cw_min = fls(params->cw_min); |
| @@ -329,27 +331,27 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 329 | FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | | 331 | FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | |
| 330 | FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | | 332 | FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | |
| 331 | FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); | 333 | FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); |
| 332 | __mt76_wr(dev, MT_EDCA_CFG_AC(qid), val); | 334 | mt76_wr(dev, MT_EDCA_CFG_AC(qid), val); |
| 333 | 335 | ||
| 334 | val = __mt76_rr(dev, MT_WMM_TXOP(qid)); | 336 | val = mt76_rr(dev, MT_WMM_TXOP(qid)); |
| 335 | val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid)); | 337 | val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid)); |
| 336 | val |= params->txop << MT_WMM_TXOP_SHIFT(qid); | 338 | val |= params->txop << MT_WMM_TXOP_SHIFT(qid); |
| 337 | __mt76_wr(dev, MT_WMM_TXOP(qid), val); | 339 | mt76_wr(dev, MT_WMM_TXOP(qid), val); |
| 338 | 340 | ||
| 339 | val = __mt76_rr(dev, MT_WMM_AIFSN); | 341 | val = mt76_rr(dev, MT_WMM_AIFSN); |
| 340 | val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid)); | 342 | val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid)); |
| 341 | val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid); | 343 | val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid); |
| 342 | __mt76_wr(dev, MT_WMM_AIFSN, val); | 344 | mt76_wr(dev, MT_WMM_AIFSN, val); |
| 343 | 345 | ||
| 344 | val = __mt76_rr(dev, MT_WMM_CWMIN); | 346 | val = mt76_rr(dev, MT_WMM_CWMIN); |
| 345 | val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid)); | 347 | val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid)); |
| 346 | val |= cw_min << MT_WMM_CWMIN_SHIFT(qid); | 348 | val |= cw_min << MT_WMM_CWMIN_SHIFT(qid); |
| 347 | __mt76_wr(dev, MT_WMM_CWMIN, val); | 349 | mt76_wr(dev, MT_WMM_CWMIN, val); |
| 348 | 350 | ||
| 349 | val = __mt76_rr(dev, MT_WMM_CWMAX); | 351 | val = mt76_rr(dev, MT_WMM_CWMAX); |
| 350 | val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid)); | 352 | val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid)); |
| 351 | val |= cw_max << MT_WMM_CWMAX_SHIFT(qid); | 353 | val |= cw_max << MT_WMM_CWMAX_SHIFT(qid); |
| 352 | __mt76_wr(dev, MT_WMM_CWMAX, val); | 354 | mt76_wr(dev, MT_WMM_CWMAX, val); |
| 353 | 355 | ||
| 354 | return 0; | 356 | return 0; |
| 355 | } | 357 | } |
| @@ -359,7 +361,7 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, | |||
| 359 | struct ieee80211_vif *vif, | 361 | struct ieee80211_vif *vif, |
| 360 | struct ieee80211_sta *sta) | 362 | struct ieee80211_sta *sta) |
| 361 | { | 363 | { |
| 362 | struct mt76_dev *dev = hw->priv; | 364 | struct mt76x02_dev *dev = hw->priv; |
| 363 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; | 365 | struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; |
| 364 | struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); | 366 | struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); |
| 365 | struct ieee80211_tx_rate rate = {}; | 367 | struct ieee80211_tx_rate rate = {}; |
| @@ -425,7 +427,7 @@ const u16 mt76x02_beacon_offsets[16] = { | |||
| 425 | }; | 427 | }; |
| 426 | EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets); | 428 | EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets); |
| 427 | 429 | ||
| 428 | void mt76x02_set_beacon_offsets(struct mt76_dev *dev) | 430 | void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev) |
| 429 | { | 431 | { |
| 430 | u16 val, base = MT_BEACON_BASE; | 432 | u16 val, base = MT_BEACON_BASE; |
| 431 | u32 regs[4] = {}; | 433 | u32 regs[4] = {}; |
| @@ -437,7 +439,7 @@ void mt76x02_set_beacon_offsets(struct mt76_dev *dev) | |||
| 437 | } | 439 | } |
| 438 | 440 | ||
| 439 | for (i = 0; i < 4; i++) | 441 | for (i = 0; i < 4; i++) |
| 440 | __mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]); | 442 | mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]); |
| 441 | } | 443 | } |
| 442 | EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets); | 444 | EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets); |
| 443 | 445 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c index bbab021b5f1a..f39b622d03f4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c | |||
| @@ -177,8 +177,8 @@ mt76x2_eeprom_load(struct mt76x02_dev *dev) | |||
| 177 | 177 | ||
| 178 | efuse = dev->mt76.otp.data; | 178 | efuse = dev->mt76.otp.data; |
| 179 | 179 | ||
| 180 | if (mt76x02_get_efuse_data(&dev->mt76, 0, efuse, | 180 | if (mt76x02_get_efuse_data(dev, 0, efuse, MT7662_EEPROM_SIZE, |
| 181 | MT7662_EEPROM_SIZE, MT_EE_READ)) | 181 | MT_EE_READ)) |
| 182 | goto out; | 182 | goto out; |
| 183 | 183 | ||
| 184 | if (found) { | 184 | if (found) { |
| @@ -248,22 +248,22 @@ mt76x2_get_5g_rx_gain(struct mt76x02_dev *dev, u8 channel) | |||
| 248 | group = mt76x2_get_cal_channel_group(channel); | 248 | group = mt76x2_get_cal_channel_group(channel); |
| 249 | switch (group) { | 249 | switch (group) { |
| 250 | case MT_CH_5G_JAPAN: | 250 | case MT_CH_5G_JAPAN: |
| 251 | return mt76x02_eeprom_get(&dev->mt76, | 251 | return mt76x02_eeprom_get(dev, |
| 252 | MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN); | 252 | MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN); |
| 253 | case MT_CH_5G_UNII_1: | 253 | case MT_CH_5G_UNII_1: |
| 254 | return mt76x02_eeprom_get(&dev->mt76, | 254 | return mt76x02_eeprom_get(dev, |
| 255 | MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8; | 255 | MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8; |
| 256 | case MT_CH_5G_UNII_2: | 256 | case MT_CH_5G_UNII_2: |
| 257 | return mt76x02_eeprom_get(&dev->mt76, | 257 | return mt76x02_eeprom_get(dev, |
| 258 | MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN); | 258 | MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN); |
| 259 | case MT_CH_5G_UNII_2E_1: | 259 | case MT_CH_5G_UNII_2E_1: |
| 260 | return mt76x02_eeprom_get(&dev->mt76, | 260 | return mt76x02_eeprom_get(dev, |
| 261 | MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8; | 261 | MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8; |
| 262 | case MT_CH_5G_UNII_2E_2: | 262 | case MT_CH_5G_UNII_2E_2: |
| 263 | return mt76x02_eeprom_get(&dev->mt76, | 263 | return mt76x02_eeprom_get(dev, |
| 264 | MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN); | 264 | MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN); |
| 265 | default: | 265 | default: |
| 266 | return mt76x02_eeprom_get(&dev->mt76, | 266 | return mt76x02_eeprom_get(dev, |
| 267 | MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8; | 267 | MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8; |
| 268 | } | 268 | } |
| 269 | } | 269 | } |
| @@ -277,14 +277,13 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) | |||
| 277 | u16 val; | 277 | u16 val; |
| 278 | 278 | ||
| 279 | if (chan->band == NL80211_BAND_2GHZ) | 279 | if (chan->band == NL80211_BAND_2GHZ) |
| 280 | val = mt76x02_eeprom_get(&dev->mt76, | 280 | val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN) >> 8; |
| 281 | MT_EE_RF_2G_RX_HIGH_GAIN) >> 8; | ||
| 282 | else | 281 | else |
| 283 | val = mt76x2_get_5g_rx_gain(dev, channel); | 282 | val = mt76x2_get_5g_rx_gain(dev, channel); |
| 284 | 283 | ||
| 285 | mt76x2_set_rx_gain_group(dev, val); | 284 | mt76x2_set_rx_gain_group(dev, val); |
| 286 | 285 | ||
| 287 | mt76x02_get_rx_gain(&dev->mt76, chan->band, &val, &lna_2g, lna_5g); | 286 | mt76x02_get_rx_gain(dev, chan->band, &val, &lna_2g, lna_5g); |
| 288 | mt76x2_set_rssi_offset(dev, 0, val); | 287 | mt76x2_set_rssi_offset(dev, 0, val); |
| 289 | mt76x2_set_rssi_offset(dev, 1, val >> 8); | 288 | mt76x2_set_rssi_offset(dev, 1, val >> 8); |
| 290 | 289 | ||
| @@ -293,7 +292,7 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) | |||
| 293 | dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; | 292 | dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; |
| 294 | dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; | 293 | dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; |
| 295 | 294 | ||
| 296 | lna = mt76x02_get_lna_gain(&dev->mt76, &lna_2g, lna_5g, chan); | 295 | lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); |
| 297 | dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); | 296 | dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); |
| 298 | } | 297 | } |
| 299 | EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); | 298 | EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); |
| @@ -308,53 +307,49 @@ void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t, | |||
| 308 | 307 | ||
| 309 | memset(t, 0, sizeof(*t)); | 308 | memset(t, 0, sizeof(*t)); |
| 310 | 309 | ||
| 311 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_CCK); | 310 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_CCK); |
| 312 | t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val); | 311 | t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val); |
| 313 | t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8); | 312 | t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8); |
| 314 | 313 | ||
| 315 | if (is_5ghz) | 314 | if (is_5ghz) |
| 316 | val = mt76x02_eeprom_get(&dev->mt76, | 315 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_6M); |
| 317 | MT_EE_TX_POWER_OFDM_5G_6M); | ||
| 318 | else | 316 | else |
| 319 | val = mt76x02_eeprom_get(&dev->mt76, | 317 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_6M); |
| 320 | MT_EE_TX_POWER_OFDM_2G_6M); | ||
| 321 | t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val); | 318 | t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val); |
| 322 | t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8); | 319 | t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8); |
| 323 | 320 | ||
| 324 | if (is_5ghz) | 321 | if (is_5ghz) |
| 325 | val = mt76x02_eeprom_get(&dev->mt76, | 322 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_24M); |
| 326 | MT_EE_TX_POWER_OFDM_5G_24M); | ||
| 327 | else | 323 | else |
| 328 | val = mt76x02_eeprom_get(&dev->mt76, | 324 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_24M); |
| 329 | MT_EE_TX_POWER_OFDM_2G_24M); | ||
| 330 | t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val); | 325 | t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val); |
| 331 | t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8); | 326 | t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8); |
| 332 | 327 | ||
| 333 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS0); | 328 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS0); |
| 334 | t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val); | 329 | t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val); |
| 335 | t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8); | 330 | t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8); |
| 336 | 331 | ||
| 337 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS4); | 332 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS4); |
| 338 | t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val); | 333 | t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val); |
| 339 | t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8); | 334 | t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8); |
| 340 | 335 | ||
| 341 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS8); | 336 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS8); |
| 342 | t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val); | 337 | t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val); |
| 343 | t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8); | 338 | t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8); |
| 344 | 339 | ||
| 345 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS12); | 340 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS12); |
| 346 | t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val); | 341 | t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val); |
| 347 | t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8); | 342 | t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8); |
| 348 | 343 | ||
| 349 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS0); | 344 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0); |
| 350 | t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val); | 345 | t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val); |
| 351 | t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8); | 346 | t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8); |
| 352 | 347 | ||
| 353 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS4); | 348 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4); |
| 354 | t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val); | 349 | t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val); |
| 355 | t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8); | 350 | t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8); |
| 356 | 351 | ||
| 357 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS8); | 352 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8); |
| 358 | if (!is_5ghz) | 353 | if (!is_5ghz) |
| 359 | val >>= 8; | 354 | val >>= 8; |
| 360 | t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8); | 355 | t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8); |
| @@ -390,7 +385,7 @@ mt76x2_get_power_info_2g(struct mt76x02_dev *dev, | |||
| 390 | t->chain[chain].target_power = data[2]; | 385 | t->chain[chain].target_power = data[2]; |
| 391 | t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); | 386 | t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); |
| 392 | 387 | ||
| 393 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_TSSI_OFF_TXPOWER); | 388 | val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER); |
| 394 | t->target_power = val >> 8; | 389 | t->target_power = val >> 8; |
| 395 | } | 390 | } |
| 396 | 391 | ||
| @@ -441,7 +436,7 @@ mt76x2_get_power_info_5g(struct mt76x02_dev *dev, | |||
| 441 | t->chain[chain].target_power = data[2]; | 436 | t->chain[chain].target_power = data[2]; |
| 442 | t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); | 437 | t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); |
| 443 | 438 | ||
| 444 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_RX_HIGH_GAIN); | 439 | val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN); |
| 445 | t->target_power = val & 0xff; | 440 | t->target_power = val & 0xff; |
| 446 | } | 441 | } |
| 447 | 442 | ||
| @@ -453,8 +448,8 @@ void mt76x2_get_power_info(struct mt76x02_dev *dev, | |||
| 453 | 448 | ||
| 454 | memset(t, 0, sizeof(*t)); | 449 | memset(t, 0, sizeof(*t)); |
| 455 | 450 | ||
| 456 | bw40 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW40); | 451 | bw40 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40); |
| 457 | bw80 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW80); | 452 | bw80 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80); |
| 458 | 453 | ||
| 459 | if (chan->band == NL80211_BAND_5GHZ) { | 454 | if (chan->band == NL80211_BAND_5GHZ) { |
| 460 | bw40 >>= 8; | 455 | bw40 >>= 8; |
| @@ -469,7 +464,7 @@ void mt76x2_get_power_info(struct mt76x02_dev *dev, | |||
| 469 | MT_EE_TX_POWER_1_START_2G); | 464 | MT_EE_TX_POWER_1_START_2G); |
| 470 | } | 465 | } |
| 471 | 466 | ||
| 472 | if (mt76x02_tssi_enabled(&dev->mt76) || | 467 | if (mt76x2_tssi_enabled(dev) || |
| 473 | !mt76x02_field_valid(t->target_power)) | 468 | !mt76x02_field_valid(t->target_power)) |
| 474 | t->target_power = t->chain[0].target_power; | 469 | t->target_power = t->chain[0].target_power; |
| 475 | 470 | ||
| @@ -486,23 +481,20 @@ int mt76x2_get_temp_comp(struct mt76x02_dev *dev, struct mt76x2_temp_comp *t) | |||
| 486 | 481 | ||
| 487 | memset(t, 0, sizeof(*t)); | 482 | memset(t, 0, sizeof(*t)); |
| 488 | 483 | ||
| 489 | if (!mt76x02_temp_tx_alc_enabled(&dev->mt76)) | 484 | if (!mt76x2_temp_tx_alc_enabled(dev)) |
| 490 | return -EINVAL; | 485 | return -EINVAL; |
| 491 | 486 | ||
| 492 | if (!mt76x02_ext_pa_enabled(&dev->mt76, band)) | 487 | if (!mt76x02_ext_pa_enabled(dev, band)) |
| 493 | return -EINVAL; | 488 | return -EINVAL; |
| 494 | 489 | ||
| 495 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_EXT_PA_5G) >> 8; | 490 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G) >> 8; |
| 496 | t->temp_25_ref = val & 0x7f; | 491 | t->temp_25_ref = val & 0x7f; |
| 497 | if (band == NL80211_BAND_5GHZ) { | 492 | if (band == NL80211_BAND_5GHZ) { |
| 498 | slope = mt76x02_eeprom_get(&dev->mt76, | 493 | slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_5G); |
| 499 | MT_EE_RF_TEMP_COMP_SLOPE_5G); | 494 | bounds = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G); |
| 500 | bounds = mt76x02_eeprom_get(&dev->mt76, | ||
| 501 | MT_EE_TX_POWER_EXT_PA_5G); | ||
| 502 | } else { | 495 | } else { |
| 503 | slope = mt76x02_eeprom_get(&dev->mt76, | 496 | slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_2G); |
| 504 | MT_EE_RF_TEMP_COMP_SLOPE_2G); | 497 | bounds = mt76x02_eeprom_get(dev, |
| 505 | bounds = mt76x02_eeprom_get(&dev->mt76, | ||
| 506 | MT_EE_TX_POWER_DELTA_BW80) >> 8; | 498 | MT_EE_TX_POWER_DELTA_BW80) >> 8; |
| 507 | } | 499 | } |
| 508 | 500 | ||
| @@ -523,7 +515,7 @@ int mt76x2_eeprom_init(struct mt76x02_dev *dev) | |||
| 523 | if (ret) | 515 | if (ret) |
| 524 | return ret; | 516 | return ret; |
| 525 | 517 | ||
| 526 | mt76x02_eeprom_parse_hw_cap(&dev->mt76); | 518 | mt76x02_eeprom_parse_hw_cap(dev); |
| 527 | mt76x2_eeprom_get_macaddr(dev); | 519 | mt76x2_eeprom_get_macaddr(dev); |
| 528 | mt76_eeprom_override(&dev->mt76); | 520 | mt76_eeprom_override(&dev->mt76); |
| 529 | dev->mt76.macaddr[0] &= ~BIT(1); | 521 | dev->mt76.macaddr[0] &= ~BIT(1); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h index c97b31c77d83..9e735524d367 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h | |||
| @@ -62,7 +62,7 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev); | |||
| 62 | static inline bool | 62 | static inline bool |
| 63 | mt76x2_has_ext_lna(struct mt76x02_dev *dev) | 63 | mt76x2_has_ext_lna(struct mt76x02_dev *dev) |
| 64 | { | 64 | { |
| 65 | u32 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_1); | 65 | u32 val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); |
| 66 | 66 | ||
| 67 | if (dev->mt76.chandef.chan->band == NL80211_BAND_2GHZ) | 67 | if (dev->mt76.chandef.chan->band == NL80211_BAND_2GHZ) |
| 68 | return val & MT_EE_NIC_CONF_1_LNA_EXT_2G; | 68 | return val & MT_EE_NIC_CONF_1_LNA_EXT_2G; |
| @@ -70,4 +70,25 @@ mt76x2_has_ext_lna(struct mt76x02_dev *dev) | |||
| 70 | return val & MT_EE_NIC_CONF_1_LNA_EXT_5G; | 70 | return val & MT_EE_NIC_CONF_1_LNA_EXT_5G; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static inline bool | ||
| 74 | mt76x2_temp_tx_alc_enabled(struct mt76x02_dev *dev) | ||
| 75 | { | ||
| 76 | u16 val; | ||
| 77 | |||
| 78 | val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G); | ||
| 79 | if (!(val & BIT(15))) | ||
| 80 | return false; | ||
| 81 | |||
| 82 | return mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & | ||
| 83 | MT_EE_NIC_CONF_1_TEMP_TX_ALC; | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline bool | ||
| 87 | mt76x2_tssi_enabled(struct mt76x02_dev *dev) | ||
| 88 | { | ||
| 89 | return !mt76x2_temp_tx_alc_enabled(dev) && | ||
| 90 | (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & | ||
| 91 | MT_EE_NIC_CONF_1_TX_ALC_EN); | ||
| 92 | } | ||
| 93 | |||
| 73 | #endif | 94 | #endif |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c index ccd9bc9d3e1e..3c73fdeaf30f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c | |||
| @@ -167,6 +167,9 @@ void mt76x2_init_device(struct mt76x02_dev *dev) | |||
| 167 | hw->max_report_rates = 7; | 167 | hw->max_report_rates = 7; |
| 168 | hw->max_rate_tries = 1; | 168 | hw->max_rate_tries = 1; |
| 169 | hw->extra_tx_headroom = 2; | 169 | hw->extra_tx_headroom = 2; |
| 170 | if (mt76_is_usb(dev)) | ||
| 171 | hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) + | ||
| 172 | MT_DMA_HDR_LEN; | ||
| 170 | 173 | ||
| 171 | hw->sta_data_size = sizeof(struct mt76x02_sta); | 174 | hw->sta_data_size = sizeof(struct mt76x02_sta); |
| 172 | hw->vif_data_size = sizeof(struct mt76x02_vif); | 175 | hw->vif_data_size = sizeof(struct mt76x02_vif); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c index 134037a227d7..88bd62cfbdf9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c | |||
| @@ -59,7 +59,6 @@ EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel); | |||
| 59 | int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level, | 59 | int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level, |
| 60 | u8 channel) | 60 | u8 channel) |
| 61 | { | 61 | { |
| 62 | struct mt76_dev *mdev = &dev->mt76; | ||
| 63 | struct sk_buff *skb; | 62 | struct sk_buff *skb; |
| 64 | struct { | 63 | struct { |
| 65 | u8 cr_mode; | 64 | u8 cr_mode; |
| @@ -76,8 +75,8 @@ int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level, | |||
| 76 | u32 val; | 75 | u32 val; |
| 77 | 76 | ||
| 78 | val = BIT(31); | 77 | val = BIT(31); |
| 79 | val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; | 78 | val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; |
| 80 | val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_1) << 8) & 0xff00; | 79 | val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; |
| 81 | msg.cfg = cpu_to_le32(val); | 80 | msg.cfg = cpu_to_le32(val); |
| 82 | 81 | ||
| 83 | /* first set the channel without the extension channel info */ | 82 | /* first set the channel without the extension channel info */ |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h index cbec8c6f1b2d..ab93125f46de 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h | |||
| @@ -100,8 +100,6 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, | |||
| 100 | enum nl80211_band band); | 100 | enum nl80211_band band); |
| 101 | void mt76x2_configure_tx_delay(struct mt76x02_dev *dev, | 101 | void mt76x2_configure_tx_delay(struct mt76x02_dev *dev, |
| 102 | enum nl80211_band band, u8 bw); | 102 | enum nl80211_band band, u8 bw); |
| 103 | void mt76x2_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl); | ||
| 104 | void mt76x2_phy_set_band(struct mt76x02_dev *dev, int band, bool primary_upper); | ||
| 105 | void mt76x2_apply_gain_adj(struct mt76x02_dev *dev); | 103 | void mt76x2_apply_gain_adj(struct mt76x02_dev *dev); |
| 106 | 104 | ||
| 107 | #endif | 105 | #endif |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c index f229c6eb65dc..3824290b219d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | |||
| @@ -43,7 +43,7 @@ mt76x2_fixup_xtal(struct mt76x02_dev *dev) | |||
| 43 | u16 eep_val; | 43 | u16 eep_val; |
| 44 | s8 offset = 0; | 44 | s8 offset = 0; |
| 45 | 45 | ||
| 46 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2); | 46 | eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_2); |
| 47 | 47 | ||
| 48 | offset = eep_val & 0x7f; | 48 | offset = eep_val & 0x7f; |
| 49 | if ((eep_val & 0xff) == 0xff) | 49 | if ((eep_val & 0xff) == 0xff) |
| @@ -53,7 +53,7 @@ mt76x2_fixup_xtal(struct mt76x02_dev *dev) | |||
| 53 | 53 | ||
| 54 | eep_val >>= 8; | 54 | eep_val >>= 8; |
| 55 | if (eep_val == 0x00 || eep_val == 0xff) { | 55 | if (eep_val == 0x00 || eep_val == 0xff) { |
| 56 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1); | 56 | eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_1); |
| 57 | eep_val &= 0xff; | 57 | eep_val &= 0xff; |
| 58 | 58 | ||
| 59 | if (eep_val == 0x00 || eep_val == 0xff) | 59 | if (eep_val == 0x00 || eep_val == 0xff) |
| @@ -64,7 +64,7 @@ mt76x2_fixup_xtal(struct mt76x02_dev *dev) | |||
| 64 | mt76_rmw_field(dev, MT_XO_CTRL5, MT_XO_CTRL5_C2_VAL, eep_val + offset); | 64 | mt76_rmw_field(dev, MT_XO_CTRL5, MT_XO_CTRL5_C2_VAL, eep_val + offset); |
| 65 | mt76_set(dev, MT_XO_CTRL6, MT_XO_CTRL6_C2_CTRL); | 65 | mt76_set(dev, MT_XO_CTRL6, MT_XO_CTRL6_C2_CTRL); |
| 66 | 66 | ||
| 67 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2); | 67 | eep_val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); |
| 68 | switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) { | 68 | switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) { |
| 69 | case 0: | 69 | case 0: |
| 70 | mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80); | 70 | mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80); |
| @@ -143,14 +143,14 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool hard) | |||
| 143 | mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0); | 143 | mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0); |
| 144 | 144 | ||
| 145 | for (i = 0; i < 256; i++) | 145 | for (i = 0; i < 256; i++) |
| 146 | mt76x02_mac_wcid_setup(&dev->mt76, i, 0, NULL); | 146 | mt76x02_mac_wcid_setup(dev, i, 0, NULL); |
| 147 | 147 | ||
| 148 | for (i = 0; i < MT_MAX_VIFS; i++) | 148 | for (i = 0; i < MT_MAX_VIFS; i++) |
| 149 | mt76x02_mac_wcid_setup(&dev->mt76, MT_VIF_WCID(i), i, NULL); | 149 | mt76x02_mac_wcid_setup(dev, MT_VIF_WCID(i), i, NULL); |
| 150 | 150 | ||
| 151 | for (i = 0; i < 16; i++) | 151 | for (i = 0; i < 16; i++) |
| 152 | for (k = 0; k < 4; k++) | 152 | for (k = 0; k < 4; k++) |
| 153 | mt76x02_mac_shared_key_setup(&dev->mt76, i, k, NULL); | 153 | mt76x02_mac_shared_key_setup(dev, i, k, NULL); |
| 154 | 154 | ||
| 155 | for (i = 0; i < 8; i++) { | 155 | for (i = 0; i < 8; i++) { |
| 156 | mt76x2_mac_set_bssid(dev, i, null_addr); | 156 | mt76x2_mac_set_bssid(dev, i, null_addr); |
| @@ -168,7 +168,7 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool hard) | |||
| 168 | MT_CH_TIME_CFG_EIFS_AS_BUSY | | 168 | MT_CH_TIME_CFG_EIFS_AS_BUSY | |
| 169 | FIELD_PREP(MT_CH_TIME_CFG_CH_TIMER_CLR, 1)); | 169 | FIELD_PREP(MT_CH_TIME_CFG_CH_TIMER_CLR, 1)); |
| 170 | 170 | ||
| 171 | mt76x02_set_beacon_offsets(&dev->mt76); | 171 | mt76x02_set_beacon_offsets(dev); |
| 172 | 172 | ||
| 173 | mt76x2_set_tx_ackto(dev); | 173 | mt76x2_set_tx_ackto(dev); |
| 174 | 174 | ||
| @@ -337,7 +337,7 @@ void mt76x2_stop_hardware(struct mt76x02_dev *dev) | |||
| 337 | { | 337 | { |
| 338 | cancel_delayed_work_sync(&dev->cal_work); | 338 | cancel_delayed_work_sync(&dev->cal_work); |
| 339 | cancel_delayed_work_sync(&dev->mac_work); | 339 | cancel_delayed_work_sync(&dev->mac_work); |
| 340 | mt76x02_mcu_set_radio_state(&dev->mt76, false, true); | 340 | mt76x02_mcu_set_radio_state(dev, false, true); |
| 341 | mt76x2_mac_stop(dev, false); | 341 | mt76x2_mac_stop(dev, false); |
| 342 | } | 342 | } |
| 343 | 343 | ||
| @@ -347,7 +347,7 @@ void mt76x2_cleanup(struct mt76x02_dev *dev) | |||
| 347 | tasklet_disable(&dev->pre_tbtt_tasklet); | 347 | tasklet_disable(&dev->pre_tbtt_tasklet); |
| 348 | mt76x2_stop_hardware(dev); | 348 | mt76x2_stop_hardware(dev); |
| 349 | mt76x02_dma_cleanup(dev); | 349 | mt76x02_dma_cleanup(dev); |
| 350 | mt76x02_mcu_cleanup(&dev->mt76); | 350 | mt76x02_mcu_cleanup(dev); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | struct mt76x02_dev *mt76x2_alloc_device(struct device *pdev) | 353 | struct mt76x02_dev *mt76x2_alloc_device(struct device *pdev) |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c index 08366c5988ea..4b331ed14bb2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c | |||
| @@ -36,7 +36,7 @@ mt76_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb) | |||
| 36 | if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi))) | 36 | if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi))) |
| 37 | return -ENOSPC; | 37 | return -ENOSPC; |
| 38 | 38 | ||
| 39 | mt76x02_mac_write_txwi(&dev->mt76, &txwi, skb, NULL, NULL, skb->len); | 39 | mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len); |
| 40 | 40 | ||
| 41 | mt76_wr_copy(dev, offset, &txwi, sizeof(txwi)); | 41 | mt76_wr_copy(dev, offset, &txwi, sizeof(txwi)); |
| 42 | offset += sizeof(txwi); | 42 | offset += sizeof(txwi); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c index 65fef082e7cc..034a06295668 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | |||
| @@ -172,7 +172,7 @@ mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) | |||
| 172 | int idx = msta->wcid.idx; | 172 | int idx = msta->wcid.idx; |
| 173 | 173 | ||
| 174 | mt76_stop_tx_queues(&dev->mt76, sta, true); | 174 | mt76_stop_tx_queues(&dev->mt76, sta, true); |
| 175 | mt76x02_mac_wcid_set_drop(&dev->mt76, idx, ps); | 175 | mt76x02_mac_wcid_set_drop(dev, idx, ps); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static void | 178 | static void |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c index 898aa229671c..d8fa9ba56437 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c | |||
| @@ -140,7 +140,7 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) | |||
| 140 | 140 | ||
| 141 | mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); | 141 | mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0); |
| 142 | 142 | ||
| 143 | val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2); | 143 | val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); |
| 144 | if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1) | 144 | if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1) |
| 145 | mt76_set(dev, MT_MCU_COM_REG0, BIT(30)); | 145 | mt76_set(dev, MT_MCU_COM_REG0, BIT(30)); |
| 146 | 146 | ||
| @@ -152,8 +152,8 @@ mt76pci_load_firmware(struct mt76x02_dev *dev) | |||
| 152 | return -ETIMEDOUT; | 152 | return -ETIMEDOUT; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | mt76x02_set_ethtool_fwver(dev, hdr); | ||
| 155 | dev_info(dev->mt76.dev, "Firmware running!\n"); | 156 | dev_info(dev->mt76.dev, "Firmware running!\n"); |
| 156 | mt76x02_set_ethtool_fwver(&dev->mt76, hdr); | ||
| 157 | 157 | ||
| 158 | release_firmware(fw); | 158 | release_firmware(fw); |
| 159 | 159 | ||
| @@ -183,6 +183,6 @@ int mt76x2_mcu_init(struct mt76x02_dev *dev) | |||
| 183 | if (ret) | 183 | if (ret) |
| 184 | return ret; | 184 | return ret; |
| 185 | 185 | ||
| 186 | mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, true); | 186 | mt76x02_mcu_function_select(dev, Q_SELECT, 1, true); |
| 187 | return 0; | 187 | return 0; |
| 188 | } | 188 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c index 40ea5f7480fb..5bda44540225 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c | |||
| @@ -26,7 +26,7 @@ mt76x2_phy_tssi_init_cal(struct mt76x02_dev *dev) | |||
| 26 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; | 26 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; |
| 27 | u32 flag = 0; | 27 | u32 flag = 0; |
| 28 | 28 | ||
| 29 | if (!mt76x02_tssi_enabled(&dev->mt76)) | 29 | if (!mt76x2_tssi_enabled(dev)) |
| 30 | return false; | 30 | return false; |
| 31 | 31 | ||
| 32 | if (mt76x2_channel_silent(dev)) | 32 | if (mt76x2_channel_silent(dev)) |
| @@ -35,10 +35,10 @@ mt76x2_phy_tssi_init_cal(struct mt76x02_dev *dev) | |||
| 35 | if (chan->band == NL80211_BAND_5GHZ) | 35 | if (chan->band == NL80211_BAND_5GHZ) |
| 36 | flag |= BIT(0); | 36 | flag |= BIT(0); |
| 37 | 37 | ||
| 38 | if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band)) | 38 | if (mt76x02_ext_pa_enabled(dev, chan->band)) |
| 39 | flag |= BIT(8); | 39 | flag |= BIT(8); |
| 40 | 40 | ||
| 41 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, flag, true); | 41 | mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag, true); |
| 42 | dev->cal.tssi_cal_done = true; | 42 | dev->cal.tssi_cal_done = true; |
| 43 | return true; | 43 | return true; |
| 44 | } | 44 | } |
| @@ -62,13 +62,13 @@ mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped) | |||
| 62 | mt76x2_mac_stop(dev, false); | 62 | mt76x2_mac_stop(dev, false); |
| 63 | 63 | ||
| 64 | if (is_5ghz) | 64 | if (is_5ghz) |
| 65 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, true); | 65 | mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0, true); |
| 66 | 66 | ||
| 67 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, true); | 67 | mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz, true); |
| 68 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, true); | 68 | mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, true); |
| 69 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, true); | 69 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz, true); |
| 70 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, true); | 70 | mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, true); |
| 71 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_SHAPING, 0, true); | 71 | mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0, true); |
| 72 | 72 | ||
| 73 | if (!mac_stopped) | 73 | if (!mac_stopped) |
| 74 | mt76x2_mac_resume(dev); | 74 | mt76x2_mac_resume(dev); |
| @@ -125,39 +125,6 @@ void mt76x2_phy_set_antenna(struct mt76x02_dev *dev) | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static void | 127 | static void |
| 128 | mt76x2_get_agc_gain(struct mt76x02_dev *dev, u8 *dest) | ||
| 129 | { | ||
| 130 | dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN); | ||
| 131 | dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN); | ||
| 132 | } | ||
| 133 | |||
| 134 | static int | ||
| 135 | mt76x2_get_rssi_gain_thresh(struct mt76x02_dev *dev) | ||
| 136 | { | ||
| 137 | switch (dev->mt76.chandef.width) { | ||
| 138 | case NL80211_CHAN_WIDTH_80: | ||
| 139 | return -62; | ||
| 140 | case NL80211_CHAN_WIDTH_40: | ||
| 141 | return -65; | ||
| 142 | default: | ||
| 143 | return -68; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static int | ||
| 148 | mt76x2_get_low_rssi_gain_thresh(struct mt76x02_dev *dev) | ||
| 149 | { | ||
| 150 | switch (dev->mt76.chandef.width) { | ||
| 151 | case NL80211_CHAN_WIDTH_80: | ||
| 152 | return -76; | ||
| 153 | case NL80211_CHAN_WIDTH_40: | ||
| 154 | return -79; | ||
| 155 | default: | ||
| 156 | return -82; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | static void | ||
| 161 | mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) | 128 | mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) |
| 162 | { | 129 | { |
| 163 | u32 val; | 130 | u32 val; |
| @@ -183,25 +150,6 @@ mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) | |||
| 183 | } | 150 | } |
| 184 | 151 | ||
| 185 | static void | 152 | static void |
| 186 | mt76x2_phy_adjust_vga_gain(struct mt76x02_dev *dev) | ||
| 187 | { | ||
| 188 | u32 false_cca; | ||
| 189 | u8 limit = dev->cal.low_gain > 0 ? 16 : 4; | ||
| 190 | |||
| 191 | false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1)); | ||
| 192 | dev->cal.false_cca = false_cca; | ||
| 193 | if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) | ||
| 194 | dev->cal.agc_gain_adjust += 2; | ||
| 195 | else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) || | ||
| 196 | (dev->cal.agc_gain_adjust >= limit && false_cca < 500)) | ||
| 197 | dev->cal.agc_gain_adjust -= 2; | ||
| 198 | else | ||
| 199 | return; | ||
| 200 | |||
| 201 | mt76x2_phy_set_gain_val(dev); | ||
| 202 | } | ||
| 203 | |||
| 204 | static void | ||
| 205 | mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) | 153 | mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) |
| 206 | { | 154 | { |
| 207 | u8 *gain = dev->cal.agc_gain_init; | 155 | u8 *gain = dev->cal.agc_gain_init; |
| @@ -210,16 +158,17 @@ mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) | |||
| 210 | int low_gain; | 158 | int low_gain; |
| 211 | u32 val; | 159 | u32 val; |
| 212 | 160 | ||
| 213 | dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(&dev->mt76); | 161 | dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev); |
| 214 | 162 | ||
| 215 | low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) + | 163 | low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) + |
| 216 | (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev)); | 164 | (dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev)); |
| 217 | 165 | ||
| 218 | gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2); | 166 | gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2); |
| 219 | dev->cal.low_gain = low_gain; | 167 | dev->cal.low_gain = low_gain; |
| 220 | 168 | ||
| 221 | if (!gain_change) { | 169 | if (!gain_change) { |
| 222 | mt76x2_phy_adjust_vga_gain(dev); | 170 | if (mt76x02_phy_adjust_vga_gain(dev)) |
| 171 | mt76x2_phy_set_gain_val(dev); | ||
| 223 | return; | 172 | return; |
| 224 | } | 173 | } |
| 225 | 174 | ||
| @@ -337,8 +286,8 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev, | |||
| 337 | mt76x2_configure_tx_delay(dev, band, bw); | 286 | mt76x2_configure_tx_delay(dev, band, bw); |
| 338 | mt76x2_phy_set_txpower(dev); | 287 | mt76x2_phy_set_txpower(dev); |
| 339 | 288 | ||
| 340 | mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1); | 289 | mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); |
| 341 | mt76x2_phy_set_bw(dev, chandef->width, ch_group_index); | 290 | mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); |
| 342 | 291 | ||
| 343 | mt76_rmw(dev, MT_EXT_CCA_CFG, | 292 | mt76_rmw(dev, MT_EXT_CCA_CFG, |
| 344 | (MT_EXT_CCA_CFG_CCA0 | | 293 | (MT_EXT_CCA_CFG_CCA0 | |
| @@ -361,17 +310,17 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev, | |||
| 361 | mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); | 310 | mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); |
| 362 | 311 | ||
| 363 | if (!dev->cal.init_cal_done) { | 312 | if (!dev->cal.init_cal_done) { |
| 364 | u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT); | 313 | u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); |
| 365 | 314 | ||
| 366 | if (val != 0xff) | 315 | if (val != 0xff) |
| 367 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, true); | 316 | mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, true); |
| 368 | } | 317 | } |
| 369 | 318 | ||
| 370 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, true); | 319 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel, true); |
| 371 | 320 | ||
| 372 | /* Rx LPF calibration */ | 321 | /* Rx LPF calibration */ |
| 373 | if (!dev->cal.init_cal_done) | 322 | if (!dev->cal.init_cal_done) |
| 374 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, true); | 323 | mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0, true); |
| 375 | 324 | ||
| 376 | dev->cal.init_cal_done = true; | 325 | dev->cal.init_cal_done = true; |
| 377 | 326 | ||
| @@ -384,14 +333,11 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev, | |||
| 384 | if (scan) | 333 | if (scan) |
| 385 | return 0; | 334 | return 0; |
| 386 | 335 | ||
| 387 | dev->cal.low_gain = -1; | ||
| 388 | mt76x2_phy_channel_calibrate(dev, true); | 336 | mt76x2_phy_channel_calibrate(dev, true); |
| 389 | mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init); | 337 | mt76x02_init_agc_gain(dev); |
| 390 | memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init, | ||
| 391 | sizeof(dev->cal.agc_gain_cur)); | ||
| 392 | 338 | ||
| 393 | /* init default values for temp compensation */ | 339 | /* init default values for temp compensation */ |
| 394 | if (mt76x02_tssi_enabled(&dev->mt76)) { | 340 | if (mt76x2_tssi_enabled(dev)) { |
| 395 | mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, | 341 | mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, |
| 396 | 0x38); | 342 | 0x38); |
| 397 | mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, | 343 | mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, |
| @@ -449,7 +395,7 @@ int mt76x2_phy_start(struct mt76x02_dev *dev) | |||
| 449 | { | 395 | { |
| 450 | int ret; | 396 | int ret; |
| 451 | 397 | ||
| 452 | ret = mt76x02_mcu_set_radio_state(&dev->mt76, true, true); | 398 | ret = mt76x02_mcu_set_radio_state(dev, true, true); |
| 453 | if (ret) | 399 | if (ret) |
| 454 | return ret; | 400 | return ret; |
| 455 | 401 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c index f00aed915ee8..e9fff5b7f125 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c | |||
| @@ -65,7 +65,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, | |||
| 65 | mt76_wr(dev, MT_TX_ALC_CFG_2, 0x35160a00); | 65 | mt76_wr(dev, MT_TX_ALC_CFG_2, 0x35160a00); |
| 66 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x35160a06); | 66 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x35160a06); |
| 67 | 67 | ||
| 68 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { | 68 | if (mt76x02_ext_pa_enabled(dev, band)) { |
| 69 | mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0x0000ec00); | 69 | mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0x0000ec00); |
| 70 | mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0x0000ec00); | 70 | mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0x0000ec00); |
| 71 | } else { | 71 | } else { |
| @@ -76,7 +76,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, | |||
| 76 | pa_mode[0] = 0x0000ffff; | 76 | pa_mode[0] = 0x0000ffff; |
| 77 | pa_mode[1] = 0x00ff00ff; | 77 | pa_mode[1] = 0x00ff00ff; |
| 78 | 78 | ||
| 79 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { | 79 | if (mt76x02_ext_pa_enabled(dev, band)) { |
| 80 | mt76_wr(dev, MT_TX_ALC_CFG_2, 0x2f0f0400); | 80 | mt76_wr(dev, MT_TX_ALC_CFG_2, 0x2f0f0400); |
| 81 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x2f0f0476); | 81 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x2f0f0476); |
| 82 | } else { | 82 | } else { |
| @@ -84,7 +84,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, | |||
| 84 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x1b0f0476); | 84 | mt76_wr(dev, MT_TX_ALC_CFG_3, 0x1b0f0476); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) | 87 | if (mt76x02_ext_pa_enabled(dev, band)) |
| 88 | pa_mode_adj = 0x04000000; | 88 | pa_mode_adj = 0x04000000; |
| 89 | else | 89 | else |
| 90 | pa_mode_adj = 0; | 90 | pa_mode_adj = 0; |
| @@ -98,7 +98,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, | |||
| 98 | mt76_wr(dev, MT_RF_PA_MODE_CFG0, pa_mode[0]); | 98 | mt76_wr(dev, MT_RF_PA_MODE_CFG0, pa_mode[0]); |
| 99 | mt76_wr(dev, MT_RF_PA_MODE_CFG1, pa_mode[1]); | 99 | mt76_wr(dev, MT_RF_PA_MODE_CFG1, pa_mode[1]); |
| 100 | 100 | ||
| 101 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { | 101 | if (mt76x02_ext_pa_enabled(dev, band)) { |
| 102 | u32 val; | 102 | u32 val; |
| 103 | 103 | ||
| 104 | if (band == NL80211_BAND_2GHZ) | 104 | if (band == NL80211_BAND_2GHZ) |
| @@ -187,7 +187,7 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) | |||
| 187 | dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power; | 187 | dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power; |
| 188 | dev->mt76.rate_power = t; | 188 | dev->mt76.rate_power = t; |
| 189 | 189 | ||
| 190 | mt76x02_phy_set_txpower(&dev->mt76, txp_0, txp_1); | 190 | mt76x02_phy_set_txpower(dev, txp_0, txp_1); |
| 191 | } | 191 | } |
| 192 | EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower); | 192 | EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower); |
| 193 | 193 | ||
| @@ -196,7 +196,7 @@ void mt76x2_configure_tx_delay(struct mt76x02_dev *dev, | |||
| 196 | { | 196 | { |
| 197 | u32 cfg0, cfg1; | 197 | u32 cfg0, cfg1; |
| 198 | 198 | ||
| 199 | if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { | 199 | if (mt76x02_ext_pa_enabled(dev, band)) { |
| 200 | cfg0 = bw ? 0x000b0c01 : 0x00101101; | 200 | cfg0 = bw ? 0x000b0c01 : 0x00101101; |
| 201 | cfg1 = 0x00011414; | 201 | cfg1 = 0x00011414; |
| 202 | } else { | 202 | } else { |
| @@ -210,50 +210,6 @@ void mt76x2_configure_tx_delay(struct mt76x02_dev *dev, | |||
| 210 | } | 210 | } |
| 211 | EXPORT_SYMBOL_GPL(mt76x2_configure_tx_delay); | 211 | EXPORT_SYMBOL_GPL(mt76x2_configure_tx_delay); |
| 212 | 212 | ||
| 213 | void mt76x2_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl) | ||
| 214 | { | ||
| 215 | int core_val, agc_val; | ||
| 216 | |||
| 217 | switch (width) { | ||
| 218 | case NL80211_CHAN_WIDTH_80: | ||
| 219 | core_val = 3; | ||
| 220 | agc_val = 7; | ||
| 221 | break; | ||
| 222 | case NL80211_CHAN_WIDTH_40: | ||
| 223 | core_val = 2; | ||
| 224 | agc_val = 3; | ||
| 225 | break; | ||
| 226 | default: | ||
| 227 | core_val = 0; | ||
| 228 | agc_val = 1; | ||
| 229 | break; | ||
| 230 | } | ||
| 231 | |||
| 232 | mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val); | ||
| 233 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val); | ||
| 234 | mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl); | ||
| 235 | mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); | ||
| 236 | } | ||
| 237 | EXPORT_SYMBOL_GPL(mt76x2_phy_set_bw); | ||
| 238 | |||
| 239 | void mt76x2_phy_set_band(struct mt76x02_dev *dev, int band, bool primary_upper) | ||
| 240 | { | ||
| 241 | switch (band) { | ||
| 242 | case NL80211_BAND_2GHZ: | ||
| 243 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 244 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 245 | break; | ||
| 246 | case NL80211_BAND_5GHZ: | ||
| 247 | mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); | ||
| 248 | mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M, | ||
| 253 | primary_upper); | ||
| 254 | } | ||
| 255 | EXPORT_SYMBOL_GPL(mt76x2_phy_set_band); | ||
| 256 | |||
| 257 | void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait) | 213 | void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait) |
| 258 | { | 214 | { |
| 259 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; | 215 | struct ieee80211_channel *chan = dev->mt76.chandef.chan; |
| @@ -275,7 +231,7 @@ void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait) | |||
| 275 | dev->cal.tssi_comp_pending = false; | 231 | dev->cal.tssi_comp_pending = false; |
| 276 | mt76x2_get_power_info(dev, &txp, chan); | 232 | mt76x2_get_power_info(dev, &txp, chan); |
| 277 | 233 | ||
| 278 | if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band)) | 234 | if (mt76x02_ext_pa_enabled(dev, chan->band)) |
| 279 | t.pa_mode = 1; | 235 | t.pa_mode = 1; |
| 280 | 236 | ||
| 281 | t.cal_mode = BIT(1); | 237 | t.cal_mode = BIT(1); |
| @@ -289,8 +245,7 @@ void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait) | |||
| 289 | return; | 245 | return; |
| 290 | 246 | ||
| 291 | usleep_range(10000, 20000); | 247 | usleep_range(10000, 20000); |
| 292 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD, | 248 | mt76x02_mcu_calibrate(dev, MCU_CAL_DPD, chan->hw_value, wait); |
| 293 | chan->hw_value, wait); | ||
| 294 | dev->cal.dpd_cal_done = true; | 249 | dev->cal.dpd_cal_done = true; |
| 295 | } | 250 | } |
| 296 | } | 251 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c index c82f16efa327..13cce2937573 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c | |||
| @@ -130,7 +130,7 @@ static int mt76x2u_init_eeprom(struct mt76x02_dev *dev) | |||
| 130 | put_unaligned_le32(val, dev->mt76.eeprom.data + i); | 130 | put_unaligned_le32(val, dev->mt76.eeprom.data + i); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | mt76x02_eeprom_parse_hw_cap(&dev->mt76); | 133 | mt76x02_eeprom_parse_hw_cap(dev); |
| 134 | return 0; | 134 | return 0; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| @@ -204,8 +204,7 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev) | |||
| 204 | if (err < 0) | 204 | if (err < 0) |
| 205 | return err; | 205 | return err; |
| 206 | 206 | ||
| 207 | mt76x02_mac_setaddr(&dev->mt76, | 207 | mt76x02_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR); |
| 208 | dev->mt76.eeprom.data + MT_EE_MAC_ADDR); | ||
| 209 | dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); | 208 | dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG); |
| 210 | 209 | ||
| 211 | mt76x2u_init_beacon_offsets(dev); | 210 | mt76x2u_init_beacon_offsets(dev); |
| @@ -237,8 +236,8 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev) | |||
| 237 | if (err < 0) | 236 | if (err < 0) |
| 238 | return err; | 237 | return err; |
| 239 | 238 | ||
| 240 | mt76x02_phy_set_rxpath(&dev->mt76); | 239 | mt76x02_phy_set_rxpath(dev); |
| 241 | mt76x02_phy_set_txdac(&dev->mt76); | 240 | mt76x02_phy_set_txdac(dev); |
| 242 | 241 | ||
| 243 | return mt76x2u_mac_stop(dev); | 242 | return mt76x2u_mac_stop(dev); |
| 244 | } | 243 | } |
| @@ -303,7 +302,7 @@ void mt76x2u_stop_hw(struct mt76x02_dev *dev) | |||
| 303 | 302 | ||
| 304 | void mt76x2u_cleanup(struct mt76x02_dev *dev) | 303 | void mt76x2u_cleanup(struct mt76x02_dev *dev) |
| 305 | { | 304 | { |
| 306 | mt76x02_mcu_set_radio_state(&dev->mt76, false, false); | 305 | mt76x02_mcu_set_radio_state(dev, false, false); |
| 307 | mt76x2u_stop_hw(dev); | 306 | mt76x2u_stop_hw(dev); |
| 308 | mt76u_queues_deinit(&dev->mt76); | 307 | mt76u_queues_deinit(&dev->mt76); |
| 309 | mt76u_mcu_deinit(&dev->mt76); | 308 | mt76u_mcu_deinit(&dev->mt76); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c index dbd635aa763b..db2194a92e67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c | |||
| @@ -32,7 +32,7 @@ static void mt76x2u_mac_fixup_xtal(struct mt76x02_dev *dev) | |||
| 32 | s8 offset = 0; | 32 | s8 offset = 0; |
| 33 | u16 eep_val; | 33 | u16 eep_val; |
| 34 | 34 | ||
| 35 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2); | 35 | eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_2); |
| 36 | 36 | ||
| 37 | offset = eep_val & 0x7f; | 37 | offset = eep_val & 0x7f; |
| 38 | if ((eep_val & 0xff) == 0xff) | 38 | if ((eep_val & 0xff) == 0xff) |
| @@ -42,7 +42,7 @@ static void mt76x2u_mac_fixup_xtal(struct mt76x02_dev *dev) | |||
| 42 | 42 | ||
| 43 | eep_val >>= 8; | 43 | eep_val >>= 8; |
| 44 | if (eep_val == 0x00 || eep_val == 0xff) { | 44 | if (eep_val == 0x00 || eep_val == 0xff) { |
| 45 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1); | 45 | eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_1); |
| 46 | eep_val &= 0xff; | 46 | eep_val &= 0xff; |
| 47 | 47 | ||
| 48 | if (eep_val == 0x00 || eep_val == 0xff) | 48 | if (eep_val == 0x00 || eep_val == 0xff) |
| @@ -67,7 +67,7 @@ static void mt76x2u_mac_fixup_xtal(struct mt76x02_dev *dev) | |||
| 67 | /* init fce */ | 67 | /* init fce */ |
| 68 | mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN); | 68 | mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN); |
| 69 | 69 | ||
| 70 | eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2); | 70 | eep_val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); |
| 71 | switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) { | 71 | switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) { |
| 72 | case 0: | 72 | case 0: |
| 73 | mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80); | 73 | mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c index 224609d6915f..1971a1b00038 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | |||
| @@ -50,9 +50,9 @@ static int mt76x2u_add_interface(struct ieee80211_hw *hw, | |||
| 50 | struct mt76x02_dev *dev = hw->priv; | 50 | struct mt76x02_dev *dev = hw->priv; |
| 51 | 51 | ||
| 52 | if (!ether_addr_equal(dev->mt76.macaddr, vif->addr)) | 52 | if (!ether_addr_equal(dev->mt76.macaddr, vif->addr)) |
| 53 | mt76x02_mac_setaddr(&dev->mt76, vif->addr); | 53 | mt76x02_mac_setaddr(dev, vif->addr); |
| 54 | 54 | ||
| 55 | mt76x02_vif_init(&dev->mt76, vif, 0); | 55 | mt76x02_vif_init(dev, vif, 0); |
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c index 259ceae2a3a9..3f1e558e5e6d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c | |||
| @@ -137,7 +137,7 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x02_dev *dev) | |||
| 137 | mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val); | 137 | mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val); |
| 138 | 138 | ||
| 139 | /* vendor reset */ | 139 | /* vendor reset */ |
| 140 | mt76x02u_mcu_fw_reset(&dev->mt76); | 140 | mt76x02u_mcu_fw_reset(dev); |
| 141 | usleep_range(5000, 10000); | 141 | usleep_range(5000, 10000); |
| 142 | 142 | ||
| 143 | /* enable FCE to send in-band cmd */ | 143 | /* enable FCE to send in-band cmd */ |
| @@ -151,7 +151,7 @@ static int mt76x2u_mcu_load_rom_patch(struct mt76x02_dev *dev) | |||
| 151 | /* FCE skip_fs_en */ | 151 | /* FCE skip_fs_en */ |
| 152 | mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); | 152 | mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); |
| 153 | 153 | ||
| 154 | err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), | 154 | err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr), |
| 155 | fw->size - sizeof(*hdr), | 155 | fw->size - sizeof(*hdr), |
| 156 | MCU_ROM_PATCH_MAX_PAYLOAD, | 156 | MCU_ROM_PATCH_MAX_PAYLOAD, |
| 157 | MT76U_MCU_ROM_PATCH_OFFSET); | 157 | MT76U_MCU_ROM_PATCH_OFFSET); |
| @@ -210,7 +210,7 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) | |||
| 210 | dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); | 210 | dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time); |
| 211 | 211 | ||
| 212 | /* vendor reset */ | 212 | /* vendor reset */ |
| 213 | mt76x02u_mcu_fw_reset(&dev->mt76); | 213 | mt76x02u_mcu_fw_reset(dev); |
| 214 | usleep_range(5000, 10000); | 214 | usleep_range(5000, 10000); |
| 215 | 215 | ||
| 216 | /* enable USB_DMA_CFG */ | 216 | /* enable USB_DMA_CFG */ |
| @@ -230,7 +230,7 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) | |||
| 230 | mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); | 230 | mt76_wr(dev, MT_FCE_SKIP_FS, 0x3); |
| 231 | 231 | ||
| 232 | /* load ILM */ | 232 | /* load ILM */ |
| 233 | err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr), | 233 | err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr), |
| 234 | ilm_len, MCU_FW_URB_MAX_PAYLOAD, | 234 | ilm_len, MCU_FW_URB_MAX_PAYLOAD, |
| 235 | MT76U_MCU_ILM_OFFSET); | 235 | MT76U_MCU_ILM_OFFSET); |
| 236 | if (err < 0) { | 236 | if (err < 0) { |
| @@ -241,8 +241,7 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) | |||
| 241 | /* load DLM */ | 241 | /* load DLM */ |
| 242 | if (mt76xx_rev(dev) >= MT76XX_REV_E3) | 242 | if (mt76xx_rev(dev) >= MT76XX_REV_E3) |
| 243 | dlm_offset += 0x800; | 243 | dlm_offset += 0x800; |
| 244 | err = mt76x02u_mcu_fw_send_data(&dev->mt76, | 244 | err = mt76x02u_mcu_fw_send_data(dev, fw->data + sizeof(*hdr) + ilm_len, |
| 245 | fw->data + sizeof(*hdr) + ilm_len, | ||
| 246 | dlm_len, MCU_FW_URB_MAX_PAYLOAD, | 245 | dlm_len, MCU_FW_URB_MAX_PAYLOAD, |
| 247 | dlm_offset); | 246 | dlm_offset); |
| 248 | if (err < 0) { | 247 | if (err < 0) { |
| @@ -260,8 +259,8 @@ static int mt76x2u_mcu_load_firmware(struct mt76x02_dev *dev) | |||
| 260 | mt76_set(dev, MT_MCU_COM_REG0, BIT(1)); | 259 | mt76_set(dev, MT_MCU_COM_REG0, BIT(1)); |
| 261 | /* enable FCE to send in-band cmd */ | 260 | /* enable FCE to send in-band cmd */ |
| 262 | mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1); | 261 | mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1); |
| 262 | mt76x02_set_ethtool_fwver(dev, hdr); | ||
| 263 | dev_dbg(dev->mt76.dev, "firmware running\n"); | 263 | dev_dbg(dev->mt76.dev, "firmware running\n"); |
| 264 | mt76x02_set_ethtool_fwver(&dev->mt76, hdr); | ||
| 265 | 264 | ||
| 266 | out: | 265 | out: |
| 267 | release_firmware(fw); | 266 | release_firmware(fw); |
| @@ -283,10 +282,9 @@ int mt76x2u_mcu_init(struct mt76x02_dev *dev) | |||
| 283 | { | 282 | { |
| 284 | int err; | 283 | int err; |
| 285 | 284 | ||
| 286 | err = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, | 285 | err = mt76x02_mcu_function_select(dev, Q_SELECT, 1, false); |
| 287 | 1, false); | ||
| 288 | if (err < 0) | 286 | if (err < 0) |
| 289 | return err; | 287 | return err; |
| 290 | 288 | ||
| 291 | return mt76x02_mcu_set_radio_state(&dev->mt76, true, false); | 289 | return mt76x02_mcu_set_radio_state(dev, true, false); |
| 292 | } | 290 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c index b11f8a6a6254..ca96ba60510e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c | |||
| @@ -29,12 +29,12 @@ void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev) | |||
| 29 | mt76x2u_mac_stop(dev); | 29 | mt76x2u_mac_stop(dev); |
| 30 | 30 | ||
| 31 | if (is_5ghz) | 31 | if (is_5ghz) |
| 32 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, false); | 32 | mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0, false); |
| 33 | 33 | ||
| 34 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, false); | 34 | mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz, false); |
| 35 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false); | 35 | mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, false); |
| 36 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, false); | 36 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz, false); |
| 37 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, false); | 37 | mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, false); |
| 38 | 38 | ||
| 39 | mt76x2u_mac_resume(dev); | 39 | mt76x2u_mac_resume(dev); |
| 40 | } | 40 | } |
| @@ -69,7 +69,7 @@ mt76x2u_phy_update_channel_gain(struct mt76x02_dev *dev) | |||
| 69 | break; | 69 | break; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(&dev->mt76); | 72 | dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev); |
| 73 | false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, | 73 | false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, |
| 74 | mt76_rr(dev, MT_RX_STAT_1)); | 74 | mt76_rr(dev, MT_RX_STAT_1)); |
| 75 | 75 | ||
| @@ -155,8 +155,8 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev, | |||
| 155 | mt76x2_configure_tx_delay(dev, chan->band, bw); | 155 | mt76x2_configure_tx_delay(dev, chan->band, bw); |
| 156 | mt76x2_phy_set_txpower(dev); | 156 | mt76x2_phy_set_txpower(dev); |
| 157 | 157 | ||
| 158 | mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1); | 158 | mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); |
| 159 | mt76x2_phy_set_bw(dev, chandef->width, ch_group_index); | 159 | mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); |
| 160 | 160 | ||
| 161 | mt76_rmw(dev, MT_EXT_CCA_CFG, | 161 | mt76_rmw(dev, MT_EXT_CCA_CFG, |
| 162 | (MT_EXT_CCA_CFG_CCA0 | | 162 | (MT_EXT_CCA_CFG_CCA0 | |
| @@ -177,18 +177,17 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev, | |||
| 177 | mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); | 177 | mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); |
| 178 | 178 | ||
| 179 | if (!dev->cal.init_cal_done) { | 179 | if (!dev->cal.init_cal_done) { |
| 180 | u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT); | 180 | u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); |
| 181 | 181 | ||
| 182 | if (val != 0xff) | 182 | if (val != 0xff) |
| 183 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, | 183 | mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false); |
| 184 | 0, false); | ||
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, false); | 186 | mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel, false); |
| 188 | 187 | ||
| 189 | /* Rx LPF calibration */ | 188 | /* Rx LPF calibration */ |
| 190 | if (!dev->cal.init_cal_done) | 189 | if (!dev->cal.init_cal_done) |
| 191 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, false); | 190 | mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0, false); |
| 192 | dev->cal.init_cal_done = true; | 191 | dev->cal.init_cal_done = true; |
| 193 | 192 | ||
| 194 | mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2); | 193 | mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2); |
| @@ -203,7 +202,7 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev, | |||
| 203 | if (scan) | 202 | if (scan) |
| 204 | return 0; | 203 | return 0; |
| 205 | 204 | ||
| 206 | if (mt76x02_tssi_enabled(&dev->mt76)) { | 205 | if (mt76x2_tssi_enabled(dev)) { |
| 207 | /* init default values for temp compensation */ | 206 | /* init default values for temp compensation */ |
| 208 | mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, | 207 | mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, |
| 209 | 0x38); | 208 | 0x38); |
| @@ -218,10 +217,9 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev, | |||
| 218 | chan = dev->mt76.chandef.chan; | 217 | chan = dev->mt76.chandef.chan; |
| 219 | if (chan->band == NL80211_BAND_5GHZ) | 218 | if (chan->band == NL80211_BAND_5GHZ) |
| 220 | flag |= BIT(0); | 219 | flag |= BIT(0); |
| 221 | if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band)) | 220 | if (mt76x02_ext_pa_enabled(dev, chan->band)) |
| 222 | flag |= BIT(8); | 221 | flag |= BIT(8); |
| 223 | mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, | 222 | mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag, false); |
| 224 | flag, false); | ||
| 225 | dev->cal.tssi_cal_done = true; | 223 | dev->cal.tssi_cal_done = true; |
| 226 | } | 224 | } |
| 227 | } | 225 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index bf0e9e666bc4..7cbce03aa65b 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c | |||
| @@ -96,7 +96,8 @@ mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb) | |||
| 96 | { | 96 | { |
| 97 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 97 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 98 | 98 | ||
| 99 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 99 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
| 100 | !ieee80211_is_data_present(hdr->frame_control)) | ||
| 100 | return; | 101 | return; |
| 101 | 102 | ||
| 102 | mtxq->agg_ssn = le16_to_cpu(hdr->seq_ctrl) + 0x10; | 103 | mtxq->agg_ssn = le16_to_cpu(hdr->seq_ctrl) + 0x10; |
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 6a255643c1f0..5f0faf07c346 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c | |||
| @@ -862,6 +862,7 @@ int mt76u_init(struct mt76_dev *dev, | |||
| 862 | .copy = mt76u_copy, | 862 | .copy = mt76u_copy, |
| 863 | .wr_rp = mt76u_wr_rp, | 863 | .wr_rp = mt76u_wr_rp, |
| 864 | .rd_rp = mt76u_rd_rp, | 864 | .rd_rp = mt76u_rd_rp, |
| 865 | .type = MT76_BUS_USB, | ||
| 865 | }; | 866 | }; |
| 866 | struct mt76_usb *usb = &dev->usb; | 867 | struct mt76_usb *usb = &dev->usb; |
| 867 | 868 | ||
diff --git a/drivers/net/wireless/quantenna/Kconfig b/drivers/net/wireless/quantenna/Kconfig index de84ce125c26..7628d9c1ea6a 100644 --- a/drivers/net/wireless/quantenna/Kconfig +++ b/drivers/net/wireless/quantenna/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config WLAN_VENDOR_QUANTENNA | 1 | config WLAN_VENDOR_QUANTENNA |
| 2 | bool "Quantenna wireless cards support" | 2 | bool "Quantenna wireless cards support" |
| 3 | default y | 3 | default y |
| 4 | ---help--- | 4 | help |
| 5 | If you have a wireless card belonging to this class, say Y. | 5 | If you have a wireless card belonging to this class, say Y. |
| 6 | 6 | ||
| 7 | Note that the answer to this question doesn't directly affect the | 7 | Note that the answer to this question doesn't directly affect the |
diff --git a/drivers/net/wireless/quantenna/qtnfmac/Kconfig b/drivers/net/wireless/quantenna/qtnfmac/Kconfig index 8d1492a90bd1..b8c12a5f16b4 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/Kconfig +++ b/drivers/net/wireless/quantenna/qtnfmac/Kconfig | |||
| @@ -11,7 +11,7 @@ config QTNFMAC_PEARL_PCIE | |||
| 11 | select QTNFMAC | 11 | select QTNFMAC |
| 12 | select FW_LOADER | 12 | select FW_LOADER |
| 13 | select CRC32 | 13 | select CRC32 |
| 14 | ---help--- | 14 | help |
| 15 | This option adds support for wireless adapters based on Quantenna | 15 | This option adds support for wireless adapters based on Quantenna |
| 16 | 802.11ac QSR10g (aka Pearl) FullMAC chipset running over PCIe. | 16 | 802.11ac QSR10g (aka Pearl) FullMAC chipset running over PCIe. |
| 17 | 17 | ||
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c index 5aca12a51fe3..95c7b95c6f8a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c | |||
| @@ -1,18 +1,5 @@ | |||
| 1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | * Copyright (c) 2015-2016 Quantenna Communications, Inc. | 2 | /* Copyright (c) 2018 Quantenna Communications */ |
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | 3 | ||
| 17 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
| 18 | #include <linux/module.h> | 5 | #include <linux/module.h> |
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h index f21e97ede090..634480fe6a64 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_ipc.h | |||
| @@ -1,18 +1,5 @@ | |||
| 1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | * Copyright (c) 2015-2016 Quantenna Communications, Inc. | 2 | /* Copyright (c) 2015-2016 Quantenna Communications */ |
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | 3 | ||
| 17 | #ifndef _QTN_FMAC_PCIE_IPC_H_ | 4 | #ifndef _QTN_FMAC_PCIE_IPC_H_ |
| 18 | #define _QTN_FMAC_PCIE_IPC_H_ | 5 | #define _QTN_FMAC_PCIE_IPC_H_ |
| @@ -85,11 +72,6 @@ | |||
| 85 | 72 | ||
| 86 | #define QTN_EP_LHOST_TQE_PORT 4 | 73 | #define QTN_EP_LHOST_TQE_PORT 4 |
| 87 | 74 | ||
| 88 | enum qtnf_pcie_bda_ipc_flags { | ||
| 89 | QTN_PCIE_IPC_FLAG_HBM_MAGIC = BIT(0), | ||
| 90 | QTN_PCIE_IPC_FLAG_SHM_PIO = BIT(1), | ||
| 91 | }; | ||
| 92 | |||
| 93 | enum qtnf_fw_loadtype { | 75 | enum qtnf_fw_loadtype { |
| 94 | QTN_FW_DBEGIN, | 76 | QTN_FW_DBEGIN, |
| 95 | QTN_FW_DSUB, | 77 | QTN_FW_DSUB, |
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h index 0bfe285b6b48..6e9a5c61d46f 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie_regs.h | |||
| @@ -1,28 +1,10 @@ | |||
| 1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | * Copyright (c) 2015 Quantenna Communications, Inc. | 2 | /* Copyright (c) 2015 Quantenna Communications */ |
| 3 | * All rights reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | 3 | ||
| 17 | #ifndef __PEARL_PCIE_H | 4 | #ifndef __PEARL_PCIE_H |
| 18 | #define __PEARL_PCIE_H | 5 | #define __PEARL_PCIE_H |
| 19 | 6 | ||
| 20 | #define PCIE_GEN2_BASE (0xe9000000) | 7 | /* Pearl PCIe HDP registers */ |
| 21 | #define PCIE_GEN3_BASE (0xe7000000) | ||
| 22 | |||
| 23 | #define PEARL_CUR_PCIE_BASE (PCIE_GEN2_BASE) | ||
| 24 | #define PCIE_HDP_OFFSET (0x2000) | ||
| 25 | |||
| 26 | #define PCIE_HDP_CTRL(base) ((base) + 0x2c00) | 8 | #define PCIE_HDP_CTRL(base) ((base) + 0x2c00) |
| 27 | #define PCIE_HDP_AXI_CTRL(base) ((base) + 0x2c04) | 9 | #define PCIE_HDP_AXI_CTRL(base) ((base) + 0x2c04) |
| 28 | #define PCIE_HDP_HOST_WR_DESC0(base) ((base) + 0x2c10) | 10 | #define PCIE_HDP_HOST_WR_DESC0(base) ((base) + 0x2c10) |
| @@ -86,7 +68,7 @@ | |||
| 86 | #define PCIE_HDP_TX_HOST_Q_RD_PTR(base) ((base) + 0x2d3c) | 68 | #define PCIE_HDP_TX_HOST_Q_RD_PTR(base) ((base) + 0x2d3c) |
| 87 | #define PCIE_HDP_TX_HOST_Q_STS(base) ((base) + 0x2d40) | 69 | #define PCIE_HDP_TX_HOST_Q_STS(base) ((base) + 0x2d40) |
| 88 | 70 | ||
| 89 | /* Host HBM pool registers */ | 71 | /* Pearl PCIe HBM pool registers */ |
| 90 | #define PCIE_HHBM_CSR_REG(base) ((base) + 0x2e00) | 72 | #define PCIE_HHBM_CSR_REG(base) ((base) + 0x2e00) |
| 91 | #define PCIE_HHBM_Q_BASE_REG(base) ((base) + 0x2e04) | 73 | #define PCIE_HHBM_Q_BASE_REG(base) ((base) + 0x2e04) |
| 92 | #define PCIE_HHBM_Q_LIMIT_REG(base) ((base) + 0x2e08) | 74 | #define PCIE_HHBM_Q_LIMIT_REG(base) ((base) + 0x2e08) |
| @@ -104,230 +86,13 @@ | |||
| 104 | #define HBM_INT_STATUS(base) ((base) + 0x2f9c) | 86 | #define HBM_INT_STATUS(base) ((base) + 0x2f9c) |
| 105 | #define PCIE_HHBM_POOL_CNFIG(base) ((base) + 0x2f9c) | 87 | #define PCIE_HHBM_POOL_CNFIG(base) ((base) + 0x2f9c) |
| 106 | 88 | ||
| 107 | /* host HBM bit field definition */ | 89 | /* Pearl PCIe HBM bit field definitions */ |
| 108 | #define HHBM_CONFIG_SOFT_RESET (BIT(8)) | 90 | #define HHBM_CONFIG_SOFT_RESET (BIT(8)) |
| 109 | #define HHBM_WR_REQ (BIT(0)) | 91 | #define HHBM_WR_REQ (BIT(0)) |
| 110 | #define HHBM_RD_REQ (BIT(1)) | 92 | #define HHBM_RD_REQ (BIT(1)) |
| 111 | #define HHBM_DONE (BIT(31)) | 93 | #define HHBM_DONE (BIT(31)) |
| 112 | #define HHBM_64BIT (BIT(10)) | 94 | #define HHBM_64BIT (BIT(10)) |
| 113 | 95 | ||
| 114 | /* offsets for dual PCIE */ | ||
| 115 | #define PCIE_PORT_LINK_CTL(base) ((base) + 0x0710) | ||
| 116 | #define PCIE_GEN2_CTL(base) ((base) + 0x080C) | ||
| 117 | #define PCIE_GEN3_OFF(base) ((base) + 0x0890) | ||
| 118 | #define PCIE_ATU_CTRL1(base) ((base) + 0x0904) | ||
| 119 | #define PCIE_ATU_CTRL2(base) ((base) + 0x0908) | ||
| 120 | #define PCIE_ATU_BASE_LOW(base) ((base) + 0x090C) | ||
| 121 | #define PCIE_ATU_BASE_HIGH(base) ((base) + 0x0910) | ||
| 122 | #define PCIE_ATU_BASE_LIMIT(base) ((base) + 0x0914) | ||
| 123 | #define PCIE_ATU_TGT_LOW(base) ((base) + 0x0918) | ||
| 124 | #define PCIE_ATU_TGT_HIGH(base) ((base) + 0x091C) | ||
| 125 | #define PCIE_DMA_WR_ENABLE(base) ((base) + 0x097C) | ||
| 126 | #define PCIE_DMA_WR_CHWTLOW(base) ((base) + 0x0988) | ||
| 127 | #define PCIE_DMA_WR_CHWTHIG(base) ((base) + 0x098C) | ||
| 128 | #define PCIE_DMA_WR_INTSTS(base) ((base) + 0x09BC) | ||
| 129 | #define PCIE_DMA_WR_INTMASK(base) ((base) + 0x09C4) | ||
| 130 | #define PCIE_DMA_WR_INTCLER(base) ((base) + 0x09C8) | ||
| 131 | #define PCIE_DMA_WR_DONE_IMWR_ADDR_L(base) ((base) + 0x09D0) | ||
| 132 | #define PCIE_DMA_WR_DONE_IMWR_ADDR_H(base) ((base) + 0x09D4) | ||
| 133 | #define PCIE_DMA_WR_ABORT_IMWR_ADDR_L(base) ((base) + 0x09D8) | ||
| 134 | #define PCIE_DMA_WR_ABORT_IMWR_ADDR_H(base) ((base) + 0x09DC) | ||
| 135 | #define PCIE_DMA_WR_IMWR_DATA(base) ((base) + 0x09E0) | ||
| 136 | #define PCIE_DMA_WR_LL_ERR_EN(base) ((base) + 0x0A00) | ||
| 137 | #define PCIE_DMA_WR_DOORBELL(base) ((base) + 0x0980) | ||
| 138 | #define PCIE_DMA_RD_ENABLE(base) ((base) + 0x099C) | ||
| 139 | #define PCIE_DMA_RD_DOORBELL(base) ((base) + 0x09A0) | ||
| 140 | #define PCIE_DMA_RD_CHWTLOW(base) ((base) + 0x09A8) | ||
| 141 | #define PCIE_DMA_RD_CHWTHIG(base) ((base) + 0x09AC) | ||
| 142 | #define PCIE_DMA_RD_INTSTS(base) ((base) + 0x0A10) | ||
| 143 | #define PCIE_DMA_RD_INTMASK(base) ((base) + 0x0A18) | ||
| 144 | #define PCIE_DMA_RD_INTCLER(base) ((base) + 0x0A1C) | ||
| 145 | #define PCIE_DMA_RD_ERR_STS_L(base) ((base) + 0x0A24) | ||
| 146 | #define PCIE_DMA_RD_ERR_STS_H(base) ((base) + 0x0A28) | ||
| 147 | #define PCIE_DMA_RD_LL_ERR_EN(base) ((base) + 0x0A34) | ||
| 148 | #define PCIE_DMA_RD_DONE_IMWR_ADDR_L(base) ((base) + 0x0A3C) | ||
| 149 | #define PCIE_DMA_RD_DONE_IMWR_ADDR_H(base) ((base) + 0x0A40) | ||
| 150 | #define PCIE_DMA_RD_ABORT_IMWR_ADDR_L(base) ((base) + 0x0A44) | ||
| 151 | #define PCIE_DMA_RD_ABORT_IMWR_ADDR_H(base) ((base) + 0x0A48) | ||
| 152 | #define PCIE_DMA_RD_IMWR_DATA(base) ((base) + 0x0A4C) | ||
| 153 | #define PCIE_DMA_CHNL_CONTEXT(base) ((base) + 0x0A6C) | ||
| 154 | #define PCIE_DMA_CHNL_CNTRL(base) ((base) + 0x0A70) | ||
| 155 | #define PCIE_DMA_XFR_SIZE(base) ((base) + 0x0A78) | ||
| 156 | #define PCIE_DMA_SAR_LOW(base) ((base) + 0x0A7C) | ||
| 157 | #define PCIE_DMA_SAR_HIGH(base) ((base) + 0x0A80) | ||
| 158 | #define PCIE_DMA_DAR_LOW(base) ((base) + 0x0A84) | ||
| 159 | #define PCIE_DMA_DAR_HIGH(base) ((base) + 0x0A88) | ||
| 160 | #define PCIE_DMA_LLPTR_LOW(base) ((base) + 0x0A8C) | ||
| 161 | #define PCIE_DMA_LLPTR_HIGH(base) ((base) + 0x0A90) | ||
| 162 | #define PCIE_DMA_WRLL_ERR_ENB(base) ((base) + 0x0A00) | ||
| 163 | #define PCIE_DMA_RDLL_ERR_ENB(base) ((base) + 0x0A34) | ||
| 164 | #define PCIE_DMABD_CHNL_CNTRL(base) ((base) + 0x8000) | ||
| 165 | #define PCIE_DMABD_XFR_SIZE(base) ((base) + 0x8004) | ||
| 166 | #define PCIE_DMABD_SAR_LOW(base) ((base) + 0x8008) | ||
| 167 | #define PCIE_DMABD_SAR_HIGH(base) ((base) + 0x800c) | ||
| 168 | #define PCIE_DMABD_DAR_LOW(base) ((base) + 0x8010) | ||
| 169 | #define PCIE_DMABD_DAR_HIGH(base) ((base) + 0x8014) | ||
| 170 | #define PCIE_DMABD_LLPTR_LOW(base) ((base) + 0x8018) | ||
| 171 | #define PCIE_DMABD_LLPTR_HIGH(base) ((base) + 0x801c) | ||
| 172 | #define PCIE_WRDMA0_CHNL_CNTRL(base) ((base) + 0x8000) | ||
| 173 | #define PCIE_WRDMA0_XFR_SIZE(base) ((base) + 0x8004) | ||
| 174 | #define PCIE_WRDMA0_SAR_LOW(base) ((base) + 0x8008) | ||
| 175 | #define PCIE_WRDMA0_SAR_HIGH(base) ((base) + 0x800c) | ||
| 176 | #define PCIE_WRDMA0_DAR_LOW(base) ((base) + 0x8010) | ||
| 177 | #define PCIE_WRDMA0_DAR_HIGH(base) ((base) + 0x8014) | ||
| 178 | #define PCIE_WRDMA0_LLPTR_LOW(base) ((base) + 0x8018) | ||
| 179 | #define PCIE_WRDMA0_LLPTR_HIGH(base) ((base) + 0x801c) | ||
| 180 | #define PCIE_WRDMA1_CHNL_CNTRL(base) ((base) + 0x8020) | ||
| 181 | #define PCIE_WRDMA1_XFR_SIZE(base) ((base) + 0x8024) | ||
| 182 | #define PCIE_WRDMA1_SAR_LOW(base) ((base) + 0x8028) | ||
| 183 | #define PCIE_WRDMA1_SAR_HIGH(base) ((base) + 0x802c) | ||
| 184 | #define PCIE_WRDMA1_DAR_LOW(base) ((base) + 0x8030) | ||
| 185 | #define PCIE_WRDMA1_DAR_HIGH(base) ((base) + 0x8034) | ||
| 186 | #define PCIE_WRDMA1_LLPTR_LOW(base) ((base) + 0x8038) | ||
| 187 | #define PCIE_WRDMA1_LLPTR_HIGH(base) ((base) + 0x803c) | ||
| 188 | #define PCIE_RDDMA0_CHNL_CNTRL(base) ((base) + 0x8040) | ||
| 189 | #define PCIE_RDDMA0_XFR_SIZE(base) ((base) + 0x8044) | ||
| 190 | #define PCIE_RDDMA0_SAR_LOW(base) ((base) + 0x8048) | ||
| 191 | #define PCIE_RDDMA0_SAR_HIGH(base) ((base) + 0x804c) | ||
| 192 | #define PCIE_RDDMA0_DAR_LOW(base) ((base) + 0x8050) | ||
| 193 | #define PCIE_RDDMA0_DAR_HIGH(base) ((base) + 0x8054) | ||
| 194 | #define PCIE_RDDMA0_LLPTR_LOW(base) ((base) + 0x8058) | ||
| 195 | #define PCIE_RDDMA0_LLPTR_HIGH(base) ((base) + 0x805c) | ||
| 196 | #define PCIE_RDDMA1_CHNL_CNTRL(base) ((base) + 0x8060) | ||
| 197 | #define PCIE_RDDMA1_XFR_SIZE(base) ((base) + 0x8064) | ||
| 198 | #define PCIE_RDDMA1_SAR_LOW(base) ((base) + 0x8068) | ||
| 199 | #define PCIE_RDDMA1_SAR_HIGH(base) ((base) + 0x806c) | ||
| 200 | #define PCIE_RDDMA1_DAR_LOW(base) ((base) + 0x8070) | ||
| 201 | #define PCIE_RDDMA1_DAR_HIGH(base) ((base) + 0x8074) | ||
| 202 | #define PCIE_RDDMA1_LLPTR_LOW(base) ((base) + 0x8078) | ||
| 203 | #define PCIE_RDDMA1_LLPTR_HIGH(base) ((base) + 0x807c) | ||
| 204 | |||
| 205 | #define PCIE_ID(base) ((base) + 0x0000) | ||
| 206 | #define PCIE_CMD(base) ((base) + 0x0004) | ||
| 207 | #define PCIE_BAR(base, n) ((base) + 0x0010 + ((n) << 2)) | ||
| 208 | #define PCIE_CAP_PTR(base) ((base) + 0x0034) | ||
| 209 | #define PCIE_MSI_LBAR(base) ((base) + 0x0054) | ||
| 210 | #define PCIE_MSI_CTRL(base) ((base) + 0x0050) | ||
| 211 | #define PCIE_MSI_ADDR_L(base) ((base) + 0x0054) | ||
| 212 | #define PCIE_MSI_ADDR_H(base) ((base) + 0x0058) | ||
| 213 | #define PCIE_MSI_DATA(base) ((base) + 0x005C) | ||
| 214 | #define PCIE_MSI_MASK_BIT(base) ((base) + 0x0060) | ||
| 215 | #define PCIE_MSI_PEND_BIT(base) ((base) + 0x0064) | ||
| 216 | #define PCIE_DEVCAP(base) ((base) + 0x0074) | ||
| 217 | #define PCIE_DEVCTLSTS(base) ((base) + 0x0078) | ||
| 218 | |||
| 219 | #define PCIE_CMDSTS(base) ((base) + 0x0004) | ||
| 220 | #define PCIE_LINK_STAT(base) ((base) + 0x80) | ||
| 221 | #define PCIE_LINK_CTL2(base) ((base) + 0xa0) | ||
| 222 | #define PCIE_ASPM_L1_CTRL(base) ((base) + 0x70c) | ||
| 223 | #define PCIE_ASPM_LINK_CTRL(base) (PCIE_LINK_STAT) | ||
| 224 | #define PCIE_ASPM_L1_SUBSTATE_TIMING(base) ((base) + 0xB44) | ||
| 225 | #define PCIE_L1SUB_CTRL1(base) ((base) + 0x150) | ||
| 226 | #define PCIE_PMCSR(base) ((base) + 0x44) | ||
| 227 | #define PCIE_CFG_SPACE_LIMIT(base) ((base) + 0x100) | ||
| 228 | |||
| 229 | /* PCIe link defines */ | ||
| 230 | #define PEARL_PCIE_LINKUP (0x7) | ||
| 231 | #define PEARL_PCIE_DATA_LINK (BIT(0)) | ||
| 232 | #define PEARL_PCIE_PHY_LINK (BIT(1)) | ||
| 233 | #define PEARL_PCIE_LINK_RST (BIT(3)) | ||
| 234 | #define PEARL_PCIE_FATAL_ERR (BIT(5)) | ||
| 235 | #define PEARL_PCIE_NONFATAL_ERR (BIT(6)) | ||
| 236 | |||
| 237 | /* PCIe Lane defines */ | ||
| 238 | #define PCIE_G2_LANE_X1 ((BIT(0)) << 16) | ||
| 239 | #define PCIE_G2_LANE_X2 ((BIT(0) | BIT(1)) << 16) | ||
| 240 | |||
| 241 | /* PCIe DLL link enable */ | ||
| 242 | #define PCIE_DLL_LINK_EN ((BIT(0)) << 5) | ||
| 243 | |||
| 244 | #define PCIE_LINK_GEN1 (BIT(0)) | ||
| 245 | #define PCIE_LINK_GEN2 (BIT(1)) | ||
| 246 | #define PCIE_LINK_GEN3 (BIT(2)) | ||
| 247 | #define PCIE_LINK_MODE(x) (((x) >> 16) & 0x7) | ||
| 248 | |||
| 249 | #define MSI_EN (BIT(0)) | ||
| 250 | #define MSI_64_EN (BIT(7)) | ||
| 251 | #define PCIE_MSI_ADDR_OFFSET(a) ((a) & 0xFFFF) | ||
| 252 | #define PCIE_MSI_ADDR_ALIGN(a) ((a) & (~0xFFFF)) | ||
| 253 | |||
| 254 | #define PCIE_BAR_MASK(base, n) ((base) + 0x1010 + ((n) << 2)) | ||
| 255 | #define PCIE_MAX_BAR (6) | ||
| 256 | |||
| 257 | #define PCIE_ATU_VIEW(base) ((base) + 0x0900) | ||
| 258 | #define PCIE_ATU_CTL1(base) ((base) + 0x0904) | ||
| 259 | #define PCIE_ATU_CTL2(base) ((base) + 0x0908) | ||
| 260 | #define PCIE_ATU_LBAR(base) ((base) + 0x090c) | ||
| 261 | #define PCIE_ATU_UBAR(base) ((base) + 0x0910) | ||
| 262 | #define PCIE_ATU_LAR(base) ((base) + 0x0914) | ||
| 263 | #define PCIE_ATU_LTAR(base) ((base) + 0x0918) | ||
| 264 | #define PCIE_ATU_UTAR(base) ((base) + 0x091c) | ||
| 265 | |||
| 266 | #define PCIE_MSI_ADDR_LOWER(base) ((base) + 0x0820) | ||
| 267 | #define PCIE_MSI_ADDR_UPPER(base) ((base) + 0x0824) | ||
| 268 | #define PCIE_MSI_ENABLE(base) ((base) + 0x0828) | ||
| 269 | #define PCIE_MSI_MASK_RC(base) ((base) + 0x082c) | ||
| 270 | #define PCIE_MSI_STATUS(base) ((base) + 0x0830) | ||
| 271 | #define PEARL_PCIE_MSI_REGION (0xce000000) | ||
| 272 | #define PEARL_PCIE_MSI_DATA (0) | ||
| 273 | #define PCIE_MSI_GPIO(base) ((base) + 0x0888) | ||
| 274 | |||
| 275 | #define PCIE_HDP_HOST_QUEUE_FULL (BIT(17)) | ||
| 276 | #define USE_BAR_MATCH_MODE | ||
| 277 | #define PCIE_ATU_OB_REGION (BIT(0)) | ||
| 278 | #define PCIE_ATU_EN_REGION (BIT(31)) | ||
| 279 | #define PCIE_ATU_EN_MATCH (BIT(30)) | ||
| 280 | #define PCIE_BASE_REGION (0xb0000000) | ||
| 281 | #define PCIE_MEM_MAP_SIZE (512 * 1024) | ||
| 282 | |||
| 283 | #define PCIE_OB_REG_REGION (0xcf000000) | ||
| 284 | #define PCIE_CONFIG_REGION (0xcf000000) | ||
| 285 | #define PCIE_CONFIG_SIZE (4096) | ||
| 286 | #define PCIE_CONFIG_CH (1) | ||
| 287 | |||
| 288 | /* inbound mapping */ | ||
| 289 | #define PCIE_IB_BAR0 (0x00000000) /* ddr */ | ||
| 290 | #define PCIE_IB_BAR0_CH (0) | ||
| 291 | #define PCIE_IB_BAR3 (0xe0000000) /* sys_reg */ | ||
| 292 | #define PCIE_IB_BAR3_CH (1) | ||
| 293 | |||
| 294 | /* outbound mapping */ | ||
| 295 | #define PCIE_MEM_CH (0) | ||
| 296 | #define PCIE_REG_CH (1) | ||
| 297 | #define PCIE_MEM_REGION (0xc0000000) | ||
| 298 | #define PCIE_MEM_SIZE (0x000fffff) | ||
| 299 | #define PCIE_MEM_TAR (0x80000000) | ||
| 300 | |||
| 301 | #define PCIE_MSI_REGION (0xce000000) | ||
| 302 | #define PCIE_MSI_SIZE (KBYTE(4) - 1) | ||
| 303 | #define PCIE_MSI_CH (1) | ||
| 304 | |||
| 305 | /* size of config region */ | ||
| 306 | #define PCIE_CFG_SIZE (0x0000ffff) | ||
| 307 | |||
| 308 | #define PCIE_ATU_DIR_IB (BIT(31)) | ||
| 309 | #define PCIE_ATU_DIR_OB (0) | ||
| 310 | #define PCIE_ATU_DIR_CFG (2) | ||
| 311 | #define PCIE_ATU_DIR_MATCH_IB (BIT(31) | BIT(30)) | ||
| 312 | |||
| 313 | #define PCIE_DMA_WR_0 (0) | ||
| 314 | #define PCIE_DMA_WR_1 (1) | ||
| 315 | #define PCIE_DMA_RD_0 (2) | ||
| 316 | #define PCIE_DMA_RD_1 (3) | ||
| 317 | |||
| 318 | #define PCIE_DMA_CHNL_CNTRL_CB (BIT(0)) | ||
| 319 | #define PCIE_DMA_CHNL_CNTRL_TCB (BIT(1)) | ||
| 320 | #define PCIE_DMA_CHNL_CNTRL_LLP (BIT(2)) | ||
| 321 | #define PCIE_DMA_CHNL_CNTRL_LIE (BIT(3)) | ||
| 322 | #define PCIE_DMA_CHNL_CNTRL_RIE (BIT(4)) | ||
| 323 | #define PCIE_DMA_CHNL_CNTRL_CSS (BIT(8)) | ||
| 324 | #define PCIE_DMA_CHNL_CNTRL_LLE (BIT(9)) | ||
| 325 | #define PCIE_DMA_CHNL_CNTRL_TLP (BIT(26)) | ||
| 326 | |||
| 327 | #define PCIE_DMA_CHNL_CONTEXT_RD (BIT(31)) | ||
| 328 | #define PCIE_DMA_CHNL_CONTEXT_WR (0) | ||
| 329 | #define PCIE_MAX_BAR (6) | ||
| 330 | |||
| 331 | /* PCIe HDP interrupt status definition */ | 96 | /* PCIe HDP interrupt status definition */ |
| 332 | #define PCIE_HDP_INT_EP_RXDMA (BIT(0)) | 97 | #define PCIE_HDP_INT_EP_RXDMA (BIT(0)) |
| 333 | #define PCIE_HDP_INT_HBM_UF (BIT(1)) | 98 | #define PCIE_HDP_INT_HBM_UF (BIT(1)) |
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 73f6fc0d4a01..56040b181cf5 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | |||
| @@ -4918,11 +4918,10 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, | |||
| 4918 | struct device *dev = &priv->udev->dev; | 4918 | struct device *dev = &priv->udev->dev; |
| 4919 | u32 queue, rts_rate; | 4919 | u32 queue, rts_rate; |
| 4920 | u16 pktlen = skb->len; | 4920 | u16 pktlen = skb->len; |
| 4921 | u16 seq_number; | ||
| 4922 | u16 rate_flag = tx_info->control.rates[0].flags; | 4921 | u16 rate_flag = tx_info->control.rates[0].flags; |
| 4923 | int tx_desc_size = priv->fops->tx_desc_size; | 4922 | int tx_desc_size = priv->fops->tx_desc_size; |
| 4924 | int ret; | 4923 | int ret; |
| 4925 | bool usedesc40, ampdu_enable, sgi = false, short_preamble = false; | 4924 | bool ampdu_enable, sgi = false, short_preamble = false; |
| 4926 | 4925 | ||
| 4927 | if (skb_headroom(skb) < tx_desc_size) { | 4926 | if (skb_headroom(skb) < tx_desc_size) { |
| 4928 | dev_warn(dev, | 4927 | dev_warn(dev, |
| @@ -4946,7 +4945,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, | |||
| 4946 | if (ieee80211_is_action(hdr->frame_control)) | 4945 | if (ieee80211_is_action(hdr->frame_control)) |
| 4947 | rtl8xxxu_dump_action(dev, hdr); | 4946 | rtl8xxxu_dump_action(dev, hdr); |
| 4948 | 4947 | ||
| 4949 | usedesc40 = (tx_desc_size == 40); | ||
| 4950 | tx_info->rate_driver_data[0] = hw; | 4948 | tx_info->rate_driver_data[0] = hw; |
| 4951 | 4949 | ||
| 4952 | if (control && control->sta) | 4950 | if (control && control->sta) |
| @@ -5013,7 +5011,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, | |||
| 5013 | else | 5011 | else |
| 5014 | rts_rate = 0; | 5012 | rts_rate = 0; |
| 5015 | 5013 | ||
| 5016 | seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); | ||
| 5017 | 5014 | ||
| 5018 | priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble, | 5015 | priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble, |
| 5019 | ampdu_enable, rts_rate); | 5016 | ampdu_enable, rts_rate); |
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 317c1b3101da..ba258318ee9f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | |||
| @@ -3404,75 +3404,6 @@ static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw, | |||
| 3404 | "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); | 3404 | "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); |
| 3405 | } | 3405 | } |
| 3406 | 3406 | ||
| 3407 | static u8 _rtl8821ae_mrate_idx_to_arfr_id( | ||
| 3408 | struct ieee80211_hw *hw, u8 rate_index, | ||
| 3409 | enum wireless_mode wirelessmode) | ||
| 3410 | { | ||
| 3411 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
| 3412 | struct rtl_phy *rtlphy = &rtlpriv->phy; | ||
| 3413 | u8 ret = 0; | ||
| 3414 | switch (rate_index) { | ||
| 3415 | case RATR_INX_WIRELESS_NGB: | ||
| 3416 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3417 | ret = 1; | ||
| 3418 | else | ||
| 3419 | ret = 0; | ||
| 3420 | ; break; | ||
| 3421 | case RATR_INX_WIRELESS_N: | ||
| 3422 | case RATR_INX_WIRELESS_NG: | ||
| 3423 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3424 | ret = 5; | ||
| 3425 | else | ||
| 3426 | ret = 4; | ||
| 3427 | ; break; | ||
| 3428 | case RATR_INX_WIRELESS_NB: | ||
| 3429 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3430 | ret = 3; | ||
| 3431 | else | ||
| 3432 | ret = 2; | ||
| 3433 | ; break; | ||
| 3434 | case RATR_INX_WIRELESS_GB: | ||
| 3435 | ret = 6; | ||
| 3436 | break; | ||
| 3437 | case RATR_INX_WIRELESS_G: | ||
| 3438 | ret = 7; | ||
| 3439 | break; | ||
| 3440 | case RATR_INX_WIRELESS_B: | ||
| 3441 | ret = 8; | ||
| 3442 | break; | ||
| 3443 | case RATR_INX_WIRELESS_MC: | ||
| 3444 | if ((wirelessmode == WIRELESS_MODE_B) | ||
| 3445 | || (wirelessmode == WIRELESS_MODE_G) | ||
| 3446 | || (wirelessmode == WIRELESS_MODE_N_24G) | ||
| 3447 | || (wirelessmode == WIRELESS_MODE_AC_24G)) | ||
| 3448 | ret = 6; | ||
| 3449 | else | ||
| 3450 | ret = 7; | ||
| 3451 | case RATR_INX_WIRELESS_AC_5N: | ||
| 3452 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3453 | ret = 10; | ||
| 3454 | else | ||
| 3455 | ret = 9; | ||
| 3456 | break; | ||
| 3457 | case RATR_INX_WIRELESS_AC_24N: | ||
| 3458 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { | ||
| 3459 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3460 | ret = 10; | ||
| 3461 | else | ||
| 3462 | ret = 9; | ||
| 3463 | } else { | ||
| 3464 | if (rtlphy->rf_type == RF_1T1R) | ||
| 3465 | ret = 11; | ||
| 3466 | else | ||
| 3467 | ret = 12; | ||
| 3468 | } | ||
| 3469 | break; | ||
| 3470 | default: | ||
| 3471 | ret = 0; break; | ||
| 3472 | } | ||
| 3473 | return ret; | ||
| 3474 | } | ||
| 3475 | |||
| 3476 | static u32 _rtl8821ae_rate_to_bitmap_2ssvht(__le16 vht_rate) | 3407 | static u32 _rtl8821ae_rate_to_bitmap_2ssvht(__le16 vht_rate) |
| 3477 | { | 3408 | { |
| 3478 | u8 i, j, tmp_rate; | 3409 | u8 i, j, tmp_rate; |
| @@ -3761,7 +3692,7 @@ static void rtl8821ae_update_hal_rate_mask(struct ieee80211_hw *hw, | |||
| 3761 | break; | 3692 | break; |
| 3762 | } | 3693 | } |
| 3763 | 3694 | ||
| 3764 | ratr_index = _rtl8821ae_mrate_idx_to_arfr_id(hw, ratr_index, wirelessmode); | 3695 | ratr_index = rtl_mrate_idx_to_arfr_id(hw, ratr_index, wirelessmode); |
| 3765 | sta_entry->ratr_index = ratr_index; | 3696 | sta_entry->ratr_index = ratr_index; |
| 3766 | ratr_bitmap = _rtl8821ae_set_ra_vht_ratr_bitmap(hw, wirelessmode, | 3697 | ratr_bitmap = _rtl8821ae_set_ra_vht_ratr_bitmap(hw, wirelessmode, |
| 3767 | ratr_bitmap); | 3698 | ratr_bitmap); |
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 5d65521260b3..06996ad4f2bc 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. | 1 | /* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights reserved. |
| 2 | * Copyright (C) 2015 Linaro Ltd. | 2 | * Copyright (C) 2015 Linaro Ltd. |
| 3 | * | 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
| @@ -33,6 +33,8 @@ struct qcom_scm_vmperm { | |||
| 33 | 33 | ||
| 34 | #define QCOM_SCM_VMID_HLOS 0x3 | 34 | #define QCOM_SCM_VMID_HLOS 0x3 |
| 35 | #define QCOM_SCM_VMID_MSS_MSA 0xF | 35 | #define QCOM_SCM_VMID_MSS_MSA 0xF |
| 36 | #define QCOM_SCM_VMID_WLAN 0x18 | ||
| 37 | #define QCOM_SCM_VMID_WLAN_CE 0x19 | ||
| 36 | #define QCOM_SCM_PERM_READ 0x4 | 38 | #define QCOM_SCM_PERM_READ 0x4 |
| 37 | #define QCOM_SCM_PERM_WRITE 0x2 | 39 | #define QCOM_SCM_PERM_WRITE 0x2 |
| 38 | #define QCOM_SCM_PERM_EXEC 0x1 | 40 | #define QCOM_SCM_PERM_EXEC 0x1 |
