wireless-next patches for v6.5

The second pull request for v6.5. We have support for three new
 Realtek chipsets, all from different generations. Shows how active
 Realtek development is right now, even older generations are being
 worked on.
 
 Note: We merged wireless into wireless-next to avoid complex conflicts
 between the trees.
 
 Major changes:
 
 rtl8xxxu
 
 * RTL8192FU support
 
 rtw89
 
 * RTL8851BE support
 
 rtw88
 
 * RTL8723DS support
 
 ath11k
 
 * Multiple Basic Service Set Identifier (MBSSID) and Enhanced MBSSID
   Advertisement (EMA) support in AP mode
 
 iwlwifi
 
 * support for segmented PNVM images and power tables
 
 * new vendor entries for PPAG (platform antenna gain) feature
 
 cfg80211/mac80211
 
 * more Multi-Link Operation (MLO) support such as hardware restart
 
 * fixes for a potential work/mutex deadlock and with it beginnings of
   the previously discussed locking simplifications
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmSDHDERHGt2YWxvQGtl
 cm5lbC5vcmcACgkQbhckVSbrbZsMDgf/YWmT/b6W4pYRltHRPYksxKfxASGf6mvZ
 UXo5vEehCF4eY2vo4MXTknVJOjrvfbqK5uvWnUfqIYBMgCThBAlG1dz+4Ziiwtw5
 QrSKG2rTQxRlI8ecbfe1Kd1TXr9bSvBAtoNAmElgxcRqG1GbiSqUBvcUox63AYuB
 yozONCvdAOsrPJTcCX+ThP+ABayAonEZf7YeISIRU6q3QMkbVksHAGAe3TnIAPJq
 8l5fQQmHwC0CxActOT2fH8WcJ3dyl5OTqjziRfjrh9T8QUJRp9Yl7zJhpYiBT116
 aCVg/NRxAFT+RkKWdQ6jRHMVOAtzL2fe6fuVW0sk7e1/s5uzyyBxJw==
 =hq6p
 -----END PGP SIGNATURE-----

Merge tag 'wireless-next-2023-06-09' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Kalle Valo says:

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

The second pull request for v6.5. We have support for three new
Realtek chipsets, all from different generations. Shows how active
Realtek development is right now, even older generations are being
worked on.

Note: We merged wireless into wireless-next to avoid complex conflicts
between the trees.

Major changes:

rtl8xxxu
 - RTL8192FU support

rtw89
 - RTL8851BE support

rtw88
 - RTL8723DS support

ath11k
 - Multiple Basic Service Set Identifier (MBSSID) and Enhanced MBSSID
   Advertisement (EMA) support in AP mode

iwlwifi
 - support for segmented PNVM images and power tables
 - new vendor entries for PPAG (platform antenna gain) feature

cfg80211/mac80211
 - more Multi-Link Operation (MLO) support such as hardware restart
 - fixes for a potential work/mutex deadlock and with it beginnings of
   the previously discussed locking simplifications

* tag 'wireless-next-2023-06-09' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (162 commits)
  wifi: rtlwifi: remove misused flag from HAL data
  wifi: rtlwifi: remove unused dualmac control leftovers
  wifi: rtlwifi: remove unused timer and related code
  wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
  wifi: rsi: Do not configure WoWlan in shutdown hook if not enabled
  wifi: brcmfmac: Detect corner error case earlier with log
  wifi: rtw89: 8852c: update RF radio A/B parameters to R63
  wifi: rtw89: 8852c: update TX power tables to R63 with 6 GHz power type (3 of 3)
  wifi: rtw89: 8852c: update TX power tables to R63 with 6 GHz power type (2 of 3)
  wifi: rtw89: 8852c: update TX power tables to R63 with 6 GHz power type (1 of 3)
  wifi: rtw89: process regulatory for 6 GHz power type
  wifi: rtw89: regd: update regulatory map to R64-R40
  wifi: rtw89: regd: judge 6 GHz according to chip and BIOS
  wifi: rtw89: refine clearing supported bands to check 2/5 GHz first
  wifi: rtw89: 8851b: configure CRASH_TRIGGER feature for 8851B
  wifi: rtw89: set TX power without precondition during setting channel
  wifi: rtw89: debug: txpwr table access only valid page according to chip
  wifi: rtw89: 8851b: enable hw_scan support
  wifi: cfg80211: move scan done work to wiphy work
  wifi: cfg80211: move sched scan stop to wiphy work
  ...
====================

Link: https://lore.kernel.org/r/87bkhohkbg.fsf@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2023-06-09 23:26:55 -07:00
commit cde11936cf
173 changed files with 33442 additions and 6229 deletions

View File

@ -3643,6 +3643,9 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
mutex_init(&ar->dump_mutex);
spin_lock_init(&ar->data_lock);
for (int ac = 0; ac < IEEE80211_NUM_ACS; ac++)
spin_lock_init(&ar->queue_lock[ac]);
INIT_LIST_HEAD(&ar->peers);
init_waitqueue_head(&ar->peer_mapping_wq);
init_waitqueue_head(&ar->htt.empty_tx_wq);

View File

@ -1170,6 +1170,9 @@ struct ath10k {
/* protects shared structure data */
spinlock_t data_lock;
/* serialize wake_tx_queue calls per ac */
spinlock_t queue_lock[IEEE80211_NUM_ACS];
struct list_head arvifs;
struct list_head peers;
struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS];

View File

@ -293,8 +293,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
goto free;
}
num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
num_peers = list_count_nodes(&ar->debug.fw_stats.peers);
num_vdevs = list_count_nodes(&ar->debug.fw_stats.vdevs);
is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
!list_empty(&stats.pdevs));
is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&

View File

@ -4732,13 +4732,14 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
{
struct ath10k *ar = hw->priv;
int ret;
u8 ac;
u8 ac = txq->ac;
ath10k_htt_tx_txq_update(hw, txq);
if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
return;
ac = txq->ac;
spin_lock_bh(&ar->queue_lock[ac]);
ieee80211_txq_schedule_start(hw, ac);
txq = ieee80211_next_txq(hw, ac);
if (!txq)
@ -4753,6 +4754,7 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
ath10k_htt_tx_txq_update(hw, txq);
out:
ieee80211_txq_schedule_end(hw, ac);
spin_unlock_bh(&ar->queue_lock[ac]);
}
/* Must not be called with conf_mutex held as workers can use that also. */

View File

@ -8164,28 +8164,6 @@ ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config(struct ath10k *ar, u32 param)
return skb;
}
size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head)
{
struct ath10k_fw_stats_peer *i;
size_t num = 0;
list_for_each_entry(i, head, list)
++num;
return num;
}
size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head)
{
struct ath10k_fw_stats_vdev *i;
size_t num = 0;
list_for_each_entry(i, head, list)
++num;
return num;
}
static void
ath10k_wmi_fw_pdev_base_stats_fill(const struct ath10k_fw_stats_pdev *pdev,
char *buf, u32 *length)
@ -8462,8 +8440,8 @@ void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
goto unlock;
}
num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
num_peers = list_count_nodes(&fw_stats->peers);
num_vdevs = list_count_nodes(&fw_stats->vdevs);
ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
ath10k_wmi_fw_pdev_tx_stats_fill(pdev, buf, &len);
@ -8520,8 +8498,8 @@ void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
goto unlock;
}
num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
num_peers = list_count_nodes(&fw_stats->peers);
num_vdevs = list_count_nodes(&fw_stats->vdevs);
ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);
@ -8668,8 +8646,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
goto unlock;
}
num_peers = ath10k_wmi_fw_stats_num_peers(&fw_stats->peers);
num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&fw_stats->vdevs);
num_peers = list_count_nodes(&fw_stats->peers);
num_vdevs = list_count_nodes(&fw_stats->vdevs);
ath10k_wmi_fw_pdev_base_stats_fill(pdev, buf, &len);
ath10k_wmi_fw_pdev_extra_stats_fill(pdev, buf, &len);

View File

@ -7502,8 +7502,6 @@ void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
void ath10k_wmi_10x_op_fw_stats_fill(struct ath10k *ar,
struct ath10k_fw_stats *fw_stats,
char *buf);
size_t ath10k_wmi_fw_stats_num_peers(struct list_head *head);
size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head);
void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
struct ath10k_fw_stats *fw_stats,
char *buf);

View File

@ -202,6 +202,9 @@ static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab,
config->twt_ap_sta_count = 1000;
config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI;
config->ema_max_vap_cnt = ab->num_radios;
config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD;
config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt;
}
static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,

View File

@ -64,6 +64,7 @@
#define TARGET_NUM_WDS_ENTRIES 32
#define TARGET_DMA_BURST_SIZE 1
#define TARGET_RX_BATCHMODE 1
#define TARGET_EMA_MAX_PROFILE_PERIOD 8
#define ATH11K_HW_MAX_QUEUES 4
#define ATH11K_QUEUE_LEN 4096

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <net/mac80211.h>
@ -433,7 +433,7 @@ u8 ath11k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
}
static u32
ath11k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
ath11k_mac_max_ht_nss(const u8 *ht_mcs_mask)
{
int nss;
@ -445,7 +445,7 @@ ath11k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
}
static u32
ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
ath11k_mac_max_vht_nss(const u16 *vht_mcs_mask)
{
int nss;
@ -457,7 +457,7 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
}
static u32
ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
ath11k_mac_max_he_nss(const u16 *he_mcs_mask)
{
int nss;
@ -964,7 +964,7 @@ static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
return ret;
}
ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr, NULL, 0, 0);
if (ret) {
ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
vdev_id, ret);
@ -1351,28 +1351,92 @@ err_mon_del:
return ret;
}
static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif,
bool tx_arvif_rsnie_present,
const u8 *profile, u8 profile_len)
{
struct ath11k *ar = arvif->ar;
struct ath11k_base *ab = ar->ab;
struct ieee80211_hw *hw = ar->hw;
struct ieee80211_vif *vif = arvif->vif;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
struct ieee80211_mgmt *mgmt;
u8 *ies;
int ret;
if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {
arvif->rsnie_present = true;
} else if (tx_arvif_rsnie_present) {
int i;
u8 nie_len;
const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,
profile, profile_len);
if (!nie)
return;
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
return 0;
bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!bcn) {
ath11k_warn(ab, "failed to get beacon template from mac80211\n");
return -EPERM;
nie_len = nie[1];
nie += 2;
for (i = 0; i < nie_len; i++) {
if (nie[i] == WLAN_EID_RSN) {
arvif->rsnie_present = false;
break;
}
}
}
}
static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
struct ath11k_vif *arvif,
struct sk_buff *bcn)
{
struct ieee80211_mgmt *mgmt;
const u8 *ies, *profile, *next_profile;
int ies_len;
ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
mgmt = (struct ieee80211_mgmt *)bcn->data;
ies += sizeof(mgmt->u.beacon);
ies_len = skb_tail_pointer(bcn) - ies;
ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);
arvif->rsnie_present = tx_arvif->rsnie_present;
while (ies) {
u8 mbssid_len;
ies_len -= (2 + ies[1]);
mbssid_len = ies[1] - 1;
profile = &ies[3];
while (mbssid_len) {
u8 profile_len;
profile_len = profile[1];
next_profile = profile + (2 + profile_len);
mbssid_len -= (2 + profile_len);
profile += 2;
profile_len -= (2 + profile[1]);
profile += (2 + profile[1]); /* nontx capabilities */
profile_len -= (2 + profile[1]);
profile += (2 + profile[1]); /* SSID */
if (profile[2] == arvif->vif->bss_conf.bssid_index) {
profile_len -= 5;
profile = profile + 5;
ath11k_mac_setup_nontx_vif_rsnie(arvif,
tx_arvif->rsnie_present,
profile,
profile_len);
return true;
}
profile = next_profile;
}
ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,
ies_len);
}
return false;
}
static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
struct sk_buff *bcn)
{
struct ieee80211_mgmt *mgmt;
u8 *ies;
ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
mgmt = (struct ieee80211_mgmt *)bcn->data;
ies += sizeof(mgmt->u.beacon);
if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))
@ -1386,9 +1450,95 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
arvif->wpaie_present = true;
else
arvif->wpaie_present = false;
}
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif)
{
struct ath11k_vif *tx_arvif;
struct ieee80211_ema_beacons *beacons;
int ret = 0;
bool nontx_vif_params_set = false;
u32 params = 0;
u8 i = 0;
tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
beacons = ieee80211_beacon_get_template_ema_list(tx_arvif->ar->hw,
tx_arvif->vif, 0);
if (!beacons || !beacons->cnt) {
ath11k_warn(arvif->ar->ab,
"failed to get ema beacon templates from mac80211\n");
return -EPERM;
}
if (tx_arvif == arvif)
ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb);
else
arvif->wpaie_present = tx_arvif->wpaie_present;
for (i = 0; i < beacons->cnt; i++) {
if (tx_arvif != arvif && !nontx_vif_params_set)
nontx_vif_params_set =
ath11k_mac_set_nontx_vif_params(tx_arvif, arvif,
beacons->bcn[i].skb);
params = beacons->cnt;
params |= (i << WMI_EMA_TMPL_IDX_SHIFT);
params |= ((!i ? 1 : 0) << WMI_EMA_FIRST_TMPL_SHIFT);
params |= ((i + 1 == beacons->cnt ? 1 : 0) << WMI_EMA_LAST_TMPL_SHIFT);
ret = ath11k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id,
&beacons->bcn[i].offs,
beacons->bcn[i].skb, params);
if (ret) {
ath11k_warn(tx_arvif->ar->ab,
"failed to set ema beacon template id %i error %d\n",
i, ret);
break;
}
}
ieee80211_beacon_free_ema_list(beacons);
if (tx_arvif != arvif && !nontx_vif_params_set)
return -EINVAL; /* Profile not found in the beacons */
return ret;
}
static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
{
struct ath11k *ar = arvif->ar;
struct ath11k_base *ab = ar->ab;
struct ath11k_vif *tx_arvif = arvif;
struct ieee80211_hw *hw = ar->hw;
struct ieee80211_vif *vif = arvif->vif;
struct ieee80211_mutable_offsets offs = {};
struct sk_buff *bcn;
int ret;
if (arvif->vif->mbssid_tx_vif) {
tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
if (tx_arvif != arvif) {
ar = tx_arvif->ar;
ab = ar->ab;
hw = ar->hw;
vif = tx_arvif->vif;
}
}
bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
if (!bcn) {
ath11k_warn(ab, "failed to get beacon template from mac80211\n");
return -EPERM;
}
if (tx_arvif == arvif)
ath11k_mac_set_vif_params(tx_arvif, bcn);
else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
return -EINVAL;
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0);
kfree_skb(bcn);
if (ret)
@ -1398,6 +1548,26 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
return ret;
}
static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
{
struct ieee80211_vif *vif = arvif->vif;
if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
return 0;
/* Target does not expect beacon templates for the already up
* non-transmitting interfaces, and results in a crash if sent.
*/
if (vif->mbssid_tx_vif &&
arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up)
return 0;
if (vif->bss_conf.ema_ap && vif->mbssid_tx_vif)
return ath11k_mac_setup_bcn_tmpl_ema(arvif);
return ath11k_mac_setup_bcn_tmpl_mbssid(arvif);
}
void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
{
struct ieee80211_vif *vif = arvif->vif;
@ -1423,6 +1593,7 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
struct ieee80211_bss_conf *info)
{
struct ath11k *ar = arvif->ar;
struct ath11k_vif *tx_arvif = NULL;
int ret = 0;
lockdep_assert_held(&arvif->ar->conf_mutex);
@ -1451,8 +1622,14 @@ static void ath11k_control_beaconing(struct ath11k_vif *arvif,
ether_addr_copy(arvif->bssid, info->bssid);
if (arvif->vif->mbssid_tx_vif)
tx_arvif = (struct ath11k_vif *)arvif->vif->mbssid_tx_vif->drv_priv;
ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
arvif->bssid);
arvif->bssid,
tx_arvif ? tx_arvif->bssid : NULL,
info->bssid_index,
1 << info->bssid_indicator);
if (ret) {
ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n",
arvif->vdev_id, ret);
@ -1658,7 +1835,7 @@ static void ath11k_peer_assoc_h_rates(struct ath11k *ar,
}
static bool
ath11k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
ath11k_peer_assoc_h_ht_masked(const u8 *ht_mcs_mask)
{
int nss;
@ -1670,7 +1847,7 @@ ath11k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
}
static bool
ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[])
ath11k_peer_assoc_h_vht_masked(const u16 *vht_mcs_mask)
{
int nss;
@ -2065,7 +2242,7 @@ static u16 ath11k_peer_assoc_h_he_limit(u16 tx_mcs_set,
}
static bool
ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
ath11k_peer_assoc_h_he_masked(const u16 *he_mcs_mask)
{
int nss;
@ -2879,7 +3056,8 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw,
arvif->aid = vif->cfg.aid;
ether_addr_copy(arvif->bssid, bss_conf->bssid);
ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid,
NULL, 0, 0);
if (ret) {
ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n",
arvif->vdev_id, ret);
@ -4159,6 +4337,20 @@ exit:
return ret;
}
static int
ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask)
{
int num_rates = 0;
int i;
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
num_rates += hweight8(mask->control[band].ht_mcs[i]);
return num_rates;
}
static int
ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar,
enum nl80211_band band,
@ -4288,6 +4480,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif,
return ret;
}
static int
ath11k_mac_set_peer_ht_fixed_rate(struct ath11k_vif *arvif,
struct ieee80211_sta *sta,
const struct cfg80211_bitrate_mask *mask,
enum nl80211_band band)
{
struct ath11k *ar = arvif->ar;
u8 ht_rate, nss = 0;
u32 rate_code;
int ret, i;
lockdep_assert_held(&ar->conf_mutex);
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
nss = i + 1;
ht_rate = ffs(mask->control[band].ht_mcs[i]) - 1;
}
}
if (!nss) {
ath11k_warn(ar->ab, "No single HT Fixed rate found to set for %pM",
sta->addr);
return -EINVAL;
}
/* Avoid updating invalid nss as fixed rate*/
if (nss > sta->deflink.rx_nss)
return -EINVAL;
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
"Setting Fixed HT Rate for peer %pM. Device will not switch to any other selected rates",
sta->addr);
rate_code = ATH11K_HW_RATE_CODE(ht_rate, nss - 1,
WMI_RATE_PREAMBLE_HT);
ret = ath11k_wmi_set_peer_param(ar, sta->addr,
arvif->vdev_id,
WMI_PEER_PARAM_FIXED_RATE,
rate_code);
if (ret)
ath11k_warn(ar->ab,
"failed to update STA %pM HT Fixed Rate %d: %d\n",
sta->addr, rate_code, ret);
return ret;
}
static int ath11k_station_assoc(struct ath11k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@ -4299,7 +4539,7 @@ static int ath11k_station_assoc(struct ath11k *ar,
struct cfg80211_chan_def def;
enum nl80211_band band;
struct cfg80211_bitrate_mask *mask;
u8 num_vht_rates, num_he_rates;
u8 num_ht_rates, num_vht_rates, num_he_rates;
lockdep_assert_held(&ar->conf_mutex);
@ -4327,6 +4567,7 @@ static int ath11k_station_assoc(struct ath11k *ar,
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask);
num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask);
num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask);
/* If single VHT/HE rate is configured (by set_bitrate_mask()),
* peer_assoc will disable VHT/HE. This is now enabled by a peer specific
@ -4343,6 +4584,11 @@ static int ath11k_station_assoc(struct ath11k *ar,
band);
if (ret)
return ret;
} else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {
ret = ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,
band);
if (ret)
return ret;
}
/* Re-assoc is run only to update supported rates for given station. It
@ -4416,7 +4662,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
const u16 *vht_mcs_mask;
const u16 *he_mcs_mask;
u32 changed, bw, nss, smps, bw_prev;
int err, num_vht_rates, num_he_rates;
int err, num_ht_rates, num_vht_rates, num_he_rates;
const struct cfg80211_bitrate_mask *mask;
struct peer_assoc_params peer_arg;
enum wmi_phy_mode peer_phymode;
@ -4532,6 +4778,8 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
mask = &arvif->bitrate_mask;
num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band,
mask);
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,
mask);
num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
@ -4554,6 +4802,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
} else if (sta->deflink.he_cap.has_he && num_he_rates == 1) {
ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
band);
} else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) {
ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask,
band);
} else {
/* If the peer is non-VHT/HE or no fixed VHT/HE rate
* is provided in the new bitrate mask we set the
@ -6181,17 +6432,62 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw)
atomic_set(&ar->num_pending_mgmt_tx, 0);
}
static void
ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
struct vdev_create_params *params)
static int ath11k_mac_setup_vdev_params_mbssid(struct ath11k_vif *arvif,
u32 *flags, u32 *tx_vdev_id)
{
struct ath11k *ar = arvif->ar;
struct ath11k_vif *tx_arvif;
struct ieee80211_vif *tx_vif;
*tx_vdev_id = 0;
tx_vif = arvif->vif->mbssid_tx_vif;
if (!tx_vif) {
*flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP;
return 0;
}
tx_arvif = (void *)tx_vif->drv_priv;
if (arvif->vif->bss_conf.nontransmitted) {
if (ar->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy)
return -EINVAL;
*flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP;
*tx_vdev_id = ath11k_vif_to_arvif(tx_vif)->vdev_id;
} else if (tx_arvif == arvif) {
*flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP;
} else {
return -EINVAL;
}
if (arvif->vif->bss_conf.ema_ap)
*flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE;
return 0;
}
static int ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
struct vdev_create_params *params)
{
struct ath11k *ar = arvif->ar;
struct ath11k_pdev *pdev = ar->pdev;
int ret;
params->if_id = arvif->vdev_id;
params->type = arvif->vdev_type;
params->subtype = arvif->vdev_subtype;
params->pdev_id = pdev->pdev_id;
params->mbssid_flags = 0;
params->mbssid_tx_vdev_id = 0;
if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
ar->ab->wmi_ab.svc_map)) {
ret = ath11k_mac_setup_vdev_params_mbssid(arvif,
&params->mbssid_flags,
&params->mbssid_tx_vdev_id);
if (ret)
return ret;
}
if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
@ -6206,6 +6502,7 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
}
return 0;
}
static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
@ -6500,7 +6797,12 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1);
ath11k_mac_setup_vdev_create_params(arvif, &vdev_param);
ret = ath11k_mac_setup_vdev_create_params(arvif, &vdev_param);
if (ret) {
ath11k_warn(ab, "failed to create vdev parameters %d: %d\n",
arvif->vdev_id, ret);
goto err;
}
ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param);
if (ret) {
@ -6905,6 +7207,17 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
arg.pref_tx_streams = ar->num_tx_chains;
arg.pref_rx_streams = ar->num_rx_chains;
arg.mbssid_flags = 0;
arg.mbssid_tx_vdev_id = 0;
if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT,
ar->ab->wmi_ab.svc_map)) {
ret = ath11k_mac_setup_vdev_params_mbssid(arvif,
&arg.mbssid_flags,
&arg.mbssid_tx_vdev_id);
if (ret)
return ret;
}
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
arg.ssid_len = arvif->u.ap.ssid_len;
@ -7071,7 +7384,8 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
int n_vifs)
{
struct ath11k_base *ab = ar->ab;
struct ath11k_vif *arvif;
struct ath11k_vif *arvif, *tx_arvif = NULL;
struct ieee80211_vif *mbssid_tx_vif;
int ret;
int i;
bool monitor_vif = false;
@ -7125,8 +7439,15 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
ret);
mbssid_tx_vif = arvif->vif->mbssid_tx_vif;
if (mbssid_tx_vif)
tx_arvif = (struct ath11k_vif *)mbssid_tx_vif->drv_priv;
ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
arvif->bssid);
arvif->bssid,
tx_arvif ? tx_arvif->bssid : NULL,
arvif->vif->bss_conf.bssid_index,
1 << arvif->vif->bss_conf.bssid_indicator);
if (ret) {
ath11k_warn(ab, "failed to bring vdev up %d: %d\n",
arvif->vdev_id, ret);
@ -7244,7 +7565,8 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
}
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr);
ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr,
NULL, 0, 0);
if (ret) {
ath11k_warn(ab, "failed put monitor up: %d\n", ret);
return ret;
@ -7542,20 +7864,6 @@ static void ath11k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
ath11k_mac_flush_tx_complete(ar);
}
static int
ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask)
{
int num_rates = 0;
int i;
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
num_rates += hweight16(mask->control[band].ht_mcs[i]);
return num_rates;
}
static bool
ath11k_mac_has_single_legacy_rate(struct ath11k *ar,
enum nl80211_band band,
@ -8892,7 +9200,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
}
if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
if (reg_cap->high_5ghz_chan >= ATH11K_MIN_6G_FREQ) {
channels = kmemdup(ath11k_6ghz_channels,
sizeof(ath11k_6ghz_channels), GFP_KERNEL);
if (!channels) {
@ -9001,19 +9309,23 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
static const u8 ath11k_if_types_ext_capa[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
};
static const u8 ath11k_if_types_ext_capa_sta[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
};
static const u8 ath11k_if_types_ext_capa_ap[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
[9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT,
[10] = WLAN_EXT_CAPA11_EMA_SUPPORT,
};
static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = {
@ -9251,6 +9563,9 @@ static int __ath11k_mac_register(struct ath11k *ar)
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
ar->hw->wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS(ab);
ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;
ath11k_reg_init(ar);
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {

View File

@ -724,6 +724,9 @@ int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr,
cmd->vdev_subtype = param->subtype;
cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX;
cmd->pdev_id = param->pdev_id;
cmd->mbssid_flags = param->mbssid_flags;
cmd->mbssid_tx_vdev_id = param->mbssid_tx_vdev_id;
ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
ptr = skb->data + sizeof(*cmd);
@ -941,6 +944,8 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
cmd->cac_duration_ms = arg->cac_duration_ms;
cmd->regdomain = arg->regdomain;
cmd->he_ops = arg->he_ops;
cmd->mbssid_flags = arg->mbssid_flags;
cmd->mbssid_tx_vdev_id = arg->mbssid_tx_vdev_id;
if (!restart) {
if (arg->ssid) {
@ -996,7 +1001,8 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
return ret;
}
int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid,
u8 *tx_bssid, u32 nontx_profile_idx, u32 nontx_profile_cnt)
{
struct ath11k_pdev_wmi *wmi = ar->wmi;
struct wmi_vdev_up_cmd *cmd;
@ -1020,14 +1026,19 @@ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
ether_addr_copy(cmd->vdev_bssid.addr, bssid);
cmd->nontx_profile_idx = nontx_profile_idx;
cmd->nontx_profile_cnt = nontx_profile_cnt;
if (tx_bssid)
ether_addr_copy(cmd->tx_vdev_bssid.addr, tx_bssid);
if (arvif && arvif->vif->type == NL80211_IFTYPE_STATION) {
bss_conf = &arvif->vif->bss_conf;
if (bss_conf->nontransmitted) {
ether_addr_copy(cmd->trans_bssid.addr,
ether_addr_copy(cmd->tx_vdev_bssid.addr,
bss_conf->transmitter_bssid);
cmd->profile_idx = bss_conf->bssid_index;
cmd->profile_num = bss_conf->bssid_indicator;
cmd->nontx_profile_idx = bss_conf->bssid_index;
cmd->nontx_profile_cnt = bss_conf->bssid_indicator;
}
}
@ -1688,7 +1699,7 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
struct sk_buff *bcn)
struct sk_buff *bcn, u32 ema_params)
{
struct ath11k_pdev_wmi *wmi = ar->wmi;
struct wmi_bcn_tmpl_cmd *cmd;
@ -1726,6 +1737,8 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
}
cmd->buf_len = bcn->len;
cmd->mbssid_ie_offset = offs->mbssid_off;
cmd->ema_params = ema_params;
ptr = skb->data + sizeof(*cmd);
@ -3987,6 +4000,9 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported <<
WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT);
wmi_cfg->flags2 = WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET;
wmi_cfg->ema_max_vap_cnt = tg_cfg->ema_max_vap_cnt;
wmi_cfg->ema_max_profile_period = tg_cfg->ema_max_profile_period;
}
static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
@ -6548,28 +6564,6 @@ int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
&parse);
}
size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head)
{
struct ath11k_fw_stats_vdev *i;
size_t num = 0;
list_for_each_entry(i, head, list)
++num;
return num;
}
static size_t ath11k_wmi_fw_stats_num_bcn(struct list_head *head)
{
struct ath11k_fw_stats_bcn *i;
size_t num = 0;
list_for_each_entry(i, head, list)
++num;
return num;
}
static void
ath11k_wmi_fw_pdev_base_stats_fill(const struct ath11k_fw_stats_pdev *pdev,
char *buf, u32 *length)
@ -6880,7 +6874,7 @@ void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
}
if (stats_id == WMI_REQUEST_BCN_STAT) {
num_bcn = ath11k_wmi_fw_stats_num_bcn(&fw_stats->bcn);
num_bcn = list_count_nodes(&fw_stats->bcn);
len += scnprintf(buf + len, buf_len - len, "\n");
len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",

View File

@ -137,6 +137,14 @@ enum {
WMI_AUTORATE_3200NS_GI = BIT(11),
};
enum {
WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP = 0x00000001,
WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 0x00000002,
WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 0x00000004,
WMI_HOST_VDEV_FLAGS_EMA_MODE = 0x00000008,
WMI_HOST_VDEV_FLAGS_SCAN_MODE_VAP = 0x00000010,
};
/*
* wmi command groups.
*/
@ -2096,6 +2104,7 @@ enum wmi_tlv_service {
WMI_TLV_SERVICE_EXT2_MSG = 220,
WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246,
WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249,
WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253,
WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263,
/* The second 128 bits */
@ -2317,6 +2326,7 @@ struct wmi_init_cmd {
} __packed;
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
#define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9)
#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4
@ -2389,6 +2399,9 @@ struct wmi_resource_config {
u32 msdu_flow_override_config1;
u32 flags2;
u32 host_service_flags;
u32 max_rnr_neighbours;
u32 ema_max_vap_cnt;
u32 ema_max_profile_period;
} __packed;
struct wmi_service_ready_event {
@ -2579,6 +2592,8 @@ struct vdev_create_params {
u8 rx;
} chains[NUM_NL80211_BANDS];
u32 pdev_id;
u32 mbssid_flags;
u32 mbssid_tx_vdev_id;
};
struct wmi_vdev_create_cmd {
@ -2589,6 +2604,8 @@ struct wmi_vdev_create_cmd {
struct wmi_mac_addr vdev_macaddr;
u32 num_cfg_txrx_streams;
u32 pdev_id;
u32 mbssid_flags;
u32 mbssid_tx_vdev_id;
} __packed;
struct wmi_vdev_txrx_streams {
@ -2608,9 +2625,9 @@ struct wmi_vdev_up_cmd {
u32 vdev_id;
u32 vdev_assoc_id;
struct wmi_mac_addr vdev_bssid;
struct wmi_mac_addr trans_bssid;
u32 profile_idx;
u32 profile_num;
struct wmi_mac_addr tx_vdev_bssid;
u32 nontx_profile_idx;
u32 nontx_profile_cnt;
} __packed;
struct wmi_vdev_stop_cmd {
@ -2652,6 +2669,9 @@ struct wmi_vdev_start_request_cmd {
u32 he_ops;
u32 cac_duration_ms;
u32 regdomain;
u32 min_data_rate;
u32 mbssid_flags;
u32 mbssid_tx_vdev_id;
} __packed;
#define MGMT_TX_DL_FRM_LEN 64
@ -2821,6 +2841,9 @@ struct wmi_vdev_start_req_arg {
u32 pref_rx_streams;
u32 pref_tx_streams;
u32 num_noa_descriptors;
u32 min_data_rate;
u32 mbssid_flags;
u32 mbssid_tx_vdev_id;
};
struct peer_create_params {
@ -3543,6 +3566,10 @@ struct wmi_get_pdev_temperature_cmd {
#define WMI_BEACON_TX_BUFFER_SIZE 512
#define WMI_EMA_TMPL_IDX_SHIFT 8
#define WMI_EMA_FIRST_TMPL_SHIFT 16
#define WMI_EMA_LAST_TMPL_SHIFT 24
struct wmi_bcn_tmpl_cmd {
u32 tlv_header;
u32 vdev_id;
@ -3553,6 +3580,11 @@ struct wmi_bcn_tmpl_cmd {
u32 csa_event_bitmap;
u32 mbssid_ie_offset;
u32 esp_ie_offset;
u32 csc_switch_count_offset;
u32 csc_event_bitmap;
u32 mu_edca_ie_offset;
u32 feature_enable_bitmap;
u32 ema_params;
} __packed;
struct wmi_key_seq_counter {
@ -5646,6 +5678,8 @@ struct target_resource_config {
u32 twt_ap_pdev_count;
u32 twt_ap_sta_count;
u8 is_reg_cc_ext_event_supported;
u32 ema_max_vap_cnt;
u32 ema_max_profile_period;
};
enum wmi_debug_log_param {
@ -6273,10 +6307,11 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
struct sk_buff *frame);
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
struct ieee80211_mutable_offsets *offs,
struct sk_buff *bcn);
struct sk_buff *bcn, u32 ema_param);
int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id);
int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid,
const u8 *bssid);
const u8 *bssid, u8 *tx_bssid, u32 nontx_profile_idx,
u32 nontx_profile_cnt);
int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id);
int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
bool restart);
@ -6372,9 +6407,6 @@ int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar,
struct pdev_set_regdomain_params *param);
int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
struct ath11k_fw_stats *stats);
size_t ath11k_wmi_fw_stats_num_peers(struct list_head *head);
size_t ath11k_wmi_fw_stats_num_peers_extd(struct list_head *head);
size_t ath11k_wmi_fw_stats_num_vdevs(struct list_head *head);
void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
struct ath11k_fw_stats *fw_stats, u32 stats_id,
char *buf);

View File

@ -706,6 +706,7 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
idr_for_each(&ar->txmgmt_idr,
ath12k_mac_tx_mgmt_pending_free, ar);
idr_destroy(&ar->txmgmt_idr);
wake_up(&ar->txmgmt_empty_waitq);
}
wake_up(&ab->wmi_ab.tx_credits_wq);

View File

@ -533,6 +533,7 @@ struct ath12k {
/* protects txmgmt_idr data */
spinlock_t txmgmt_idr_lock;
atomic_t num_pending_mgmt_tx;
wait_queue_head_t txmgmt_empty_waitq;
/* cycle count is reported twice for each visited channel during scan.
* access protected by data_lock

View File

@ -978,7 +978,19 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_
return ret;
}
return ret;
if (!ab->hw_params->reoq_lut_support) {
ret = ath12k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id,
peer_mac,
paddr, tid, 1,
ba_win_sz);
if (ret) {
ath12k_warn(ab, "failed to setup peer rx reorder queuefor tid %d: %d\n",
tid, ret);
return ret;
}
}
return 0;
}
rx_tid->tid = tid;
@ -1362,11 +1374,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar,
* Firmware rate's control to be skipped for this?
*/
if (flags == WMI_RATE_PREAMBLE_HE && mcs > 11) {
ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs);
return;
}
if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) {
ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs);
return;

View File

@ -906,6 +906,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
},
{
.name = "wcn7850 hw2.0",
@ -960,6 +961,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.wmi_init = ath12k_wmi_init_wcn7850,
.hal_ops = &hal_wcn7850_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
BIT(CNSS_PCIE_PERST_NO_PULL_V01),
},
{
.name = "qcn9274 hw2.0",
@ -1013,6 +1017,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.wmi_init = ath12k_wmi_init_qcn9274,
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
},
};

View File

@ -184,6 +184,8 @@ struct ath12k_hw_params {
struct ath12k_wmi_resource_config_arg *config);
const struct hal_ops *hal_ops;
u64 qmi_cnss_feature_bitmap;
};
struct ath12k_hw_ops {

View File

@ -381,7 +381,7 @@ u8 ath12k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
}
static u32
ath12k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
ath12k_mac_max_ht_nss(const u8 *ht_mcs_mask)
{
int nss;
@ -393,7 +393,7 @@ ath12k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
}
static u32
ath12k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
ath12k_mac_max_vht_nss(const u16 *vht_mcs_mask)
{
int nss;
@ -771,6 +771,9 @@ static int ath12k_mac_vdev_setup_sync(struct ath12k *ar)
if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
return -ESHUTDOWN;
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "vdev setup timeout %d\n",
ATH12K_VDEV_SETUP_TIMEOUT_HZ);
if (!wait_for_completion_timeout(&ar->vdev_setup_done,
ATH12K_VDEV_SETUP_TIMEOUT_HZ))
return -ETIMEDOUT;
@ -1303,7 +1306,7 @@ static void ath12k_peer_assoc_h_rates(struct ath12k *ar,
}
static bool
ath12k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
ath12k_peer_assoc_h_ht_masked(const u8 *ht_mcs_mask)
{
int nss;
@ -1315,7 +1318,7 @@ ath12k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
}
static bool
ath12k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
ath12k_peer_assoc_h_vht_masked(const u16 *vht_mcs_mask)
{
int nss;
@ -4375,6 +4378,21 @@ static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
return 0;
}
static void ath12k_mgmt_over_wmi_tx_drop(struct ath12k *ar, struct sk_buff *skb)
{
int num_mgmt;
ieee80211_free_txskb(ar->hw, skb);
num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx);
if (num_mgmt < 0)
WARN_ON_ONCE(1);
if (!num_mgmt)
wake_up(&ar->txmgmt_empty_waitq);
}
int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
{
struct sk_buff *msdu = skb;
@ -4391,7 +4409,7 @@ int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
info = IEEE80211_SKB_CB(msdu);
memset(&info->status, 0, sizeof(info->status));
ieee80211_free_txskb(ar->hw, msdu);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
return 0;
}
@ -4475,7 +4493,7 @@ static void ath12k_mgmt_over_wmi_tx_purge(struct ath12k *ar)
struct sk_buff *skb;
while ((skb = skb_dequeue(&ar->wmi_mgmt_tx_queue)) != NULL)
ieee80211_free_txskb(ar->hw, skb);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
}
static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work)
@ -4490,7 +4508,7 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work)
skb_cb = ATH12K_SKB_CB(skb);
if (!skb_cb->vif) {
ath12k_warn(ar->ab, "no vif found for mgmt frame\n");
ieee80211_free_txskb(ar->hw, skb);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
continue;
}
@ -4501,16 +4519,14 @@ static void ath12k_mgmt_over_wmi_tx_work(struct work_struct *work)
if (ret) {
ath12k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",
arvif->vdev_id, ret);
ieee80211_free_txskb(ar->hw, skb);
} else {
atomic_inc(&ar->num_pending_mgmt_tx);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
}
} else {
ath12k_warn(ar->ab,
"dropping mgmt frame for vdev %d, is_started %d\n",
arvif->vdev_id,
arvif->is_started);
ieee80211_free_txskb(ar->hw, skb);
ath12k_mgmt_over_wmi_tx_drop(ar, skb);
}
}
}
@ -4535,12 +4551,13 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb,
return -ENOSPC;
}
if (skb_queue_len(q) == ATH12K_TX_MGMT_NUM_PENDING_MAX) {
if (skb_queue_len_lockless(q) >= ATH12K_TX_MGMT_NUM_PENDING_MAX) {
ath12k_warn(ar->ab, "mgmt tx queue is full\n");
return -ENOSPC;
}
skb_queue_tail(q, skb);
atomic_inc(&ar->num_pending_mgmt_tx);
ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
return 0;
@ -6014,6 +6031,13 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
ATH12K_FLUSH_TIMEOUT);
if (time_left == 0)
ath12k_warn(ar->ab, "failed to flush transmit queue %ld\n", time_left);
time_left = wait_event_timeout(ar->txmgmt_empty_waitq,
(atomic_read(&ar->num_pending_mgmt_tx) == 0),
ATH12K_FLUSH_TIMEOUT);
if (time_left == 0)
ath12k_warn(ar->ab, "failed to flush mgmt transmit queue %ld\n",
time_left);
}
static int
@ -6991,6 +7015,7 @@ int ath12k_mac_register(struct ath12k_base *ab)
if (ret)
goto err_cleanup;
init_waitqueue_head(&ar->txmgmt_empty_waitq);
idr_init(&ar->txmgmt_idr);
spin_lock_init(&ar->txmgmt_idr_lock);
}

View File

@ -1942,8 +1942,10 @@ static int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
req.cal_done_valid = 1;
req.cal_done = ab->qmi.cal_done;
req.feature_list_valid = 1;
req.feature_list = BIT(CNSS_QDSS_CFG_MISS_V01);
if (ab->hw_params->qmi_cnss_feature_bitmap) {
req.feature_list_valid = 1;
req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap;
}
/* BRINGUP: here we are piggybacking a lot of stuff using
* internal_sleep_clock, should it be split?

View File

@ -189,6 +189,7 @@ struct wlfw_host_mlo_chip_info_s_v01 {
enum ath12k_qmi_cnss_feature {
CNSS_FEATURE_MIN_ENUM_VAL_V01 = INT_MIN,
CNSS_QDSS_CFG_MISS_V01 = 3,
CNSS_PCIE_PERST_NO_PULL_V01 = 4,
CNSS_MAX_FEATURE_V01 = 64,
CNSS_FEATURE_MAX_ENUM_VAL_V01 = INT_MAX,
};

View File

@ -4640,6 +4640,7 @@ static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id,
struct sk_buff *msdu;
struct ieee80211_tx_info *info;
struct ath12k_skb_cb *skb_cb;
int num_mgmt;
spin_lock_bh(&ar->txmgmt_idr_lock);
msdu = idr_find(&ar->txmgmt_idr, desc_id);
@ -4663,10 +4664,15 @@ static int wmi_process_mgmt_tx_comp(struct ath12k *ar, u32 desc_id,
ieee80211_tx_status_irqsafe(ar->hw, msdu);
num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx);
/* WARN when we received this event without doing any mgmt tx */
if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0)
if (num_mgmt < 0)
WARN_ON_ONCE(1);
if (!num_mgmt)
wake_up(&ar->txmgmt_empty_waitq);
return 0;
}

View File

@ -2682,7 +2682,7 @@ struct ath12k_wmi_ssid_params {
u8 ssid[ATH12K_WMI_SSID_LEN];
} __packed;
#define ATH12K_VDEV_SETUP_TIMEOUT_HZ (1 * HZ)
#define ATH12K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
struct wmi_vdev_start_request_cmd {
__le32 tlv_header;

View File

@ -1099,17 +1099,22 @@ static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue)
{
u32 dma_dbg_chain, dma_dbg_complete;
u8 dcu_chain_state, dcu_complete_state;
unsigned int dbg_reg, reg_offset;
int i;
for (i = 0; i < NUM_STATUS_READS; i++) {
if (queue < 6)
dma_dbg_chain = REG_READ(ah, AR_DMADBG_4);
else
dma_dbg_chain = REG_READ(ah, AR_DMADBG_5);
if (queue < 6) {
dbg_reg = AR_DMADBG_4;
reg_offset = queue * 5;
} else {
dbg_reg = AR_DMADBG_5;
reg_offset = (queue - 6) * 5;
}
for (i = 0; i < NUM_STATUS_READS; i++) {
dma_dbg_chain = REG_READ(ah, dbg_reg);
dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f;
dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f;
dcu_complete_state = dma_dbg_complete & 0x3;
if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1))
@ -1128,6 +1133,7 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
u8 dcu_chain_state, dcu_complete_state;
bool dcu_wait_frdone = false;
unsigned long chk_dcu = 0;
unsigned int reg_offset;
unsigned int i = 0;
dma_dbg_4 = REG_READ(ah, AR_DMADBG_4);
@ -1139,12 +1145,15 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
goto exit;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (i < 6)
if (i < 6) {
chk_dbg = dma_dbg_4;
else
reg_offset = i * 5;
} else {
chk_dbg = dma_dbg_5;
reg_offset = (i - 6) * 5;
}
dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f;
dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f;
if (dcu_chain_state == 0x6) {
dcu_wait_frdone = true;
chk_dcu |= BIT(i);

View File

@ -221,6 +221,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
if (unlikely(wmi->stopped))
goto free_skb;
/* Validate the obtained SKB. */
if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr)))
goto free_skb;
hdr = (struct wmi_cmd_hdr *) skb->data;
cmd_id = be16_to_cpu(hdr->command_id);

View File

@ -14,7 +14,7 @@ if WLAN_VENDOR_ATMEL
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
depends on CFG80211 && (PCI || PCMCIA)
depends on CFG80211 && (PCI || PCMCIA) && HAS_IOPORT
select WIRELESS_EXT
select WEXT_PRIV
select FW_LOADER

View File

@ -72,6 +72,7 @@ struct local_info {
static int atmel_probe(struct pcmcia_device *p_dev)
{
struct local_info *local;
int ret;
dev_dbg(&p_dev->dev, "atmel_attach()\n");
@ -82,8 +83,16 @@ static int atmel_probe(struct pcmcia_device *p_dev)
p_dev->priv = local;
return atmel_config(p_dev);
} /* atmel_attach */
ret = atmel_config(p_dev);
if (ret)
goto err_free_priv;
return 0;
err_free_priv:
kfree(p_dev->priv);
return ret;
}
static void atmel_detach(struct pcmcia_device *link)
{

View File

@ -972,6 +972,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
u32 regdata;
u32 socitype;
int ret;
const u32 READ_FAILED = 0xFFFFFFFF;
/* Get CC core rev
* Chipid is assume to be at offset 0 from SI_ENUM_BASE
@ -980,6 +981,11 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
*/
regdata = ci->ops->read32(ci->ctx,
CORE_CC_REG(ci->pub.enum_base, chipid));
if (regdata == READ_FAILED) {
brcmf_err("MMIO read failed: 0x%08x\n", regdata);
return -ENODEV;
}
ci->pub.chip = regdata & CID_ID_MASK;
ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;

View File

@ -12,13 +12,13 @@
static int brcmf_wcc_attach(struct brcmf_pub *drvr)
{
pr_err("%s: executing\n", __func__);
pr_debug("%s: executing\n", __func__);
return 0;
}
static void brcmf_wcc_detach(struct brcmf_pub *drvr)
{
pr_err("%s: executing\n", __func__);
pr_debug("%s: executing\n", __func__);
}
const struct brcmf_fwvid_ops brcmf_wcc_ops = {

View File

@ -186,7 +186,7 @@ struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
{
int prec;
if (pq->len == 0)
if (pktq_empty(pq))
return NULL;
for (prec = 0; prec < pq->hi_prec; prec++)
@ -223,7 +223,7 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
struct sk_buff *p;
int prec;
if (pq->len == 0)
if (pktq_empty(pq))
return NULL;
while ((prec = pq->hi_prec) > 0 &&

View File

@ -11,6 +11,7 @@
/* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 78
#define IWL_22500_UCODE_API_MAX 77
/* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39
@ -222,7 +223,6 @@ static const struct iwl_ht_params iwl_gl_a_ht_params = {
};
#define IWL_DEVICE_22000_COMMON \
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
.ucode_api_min = IWL_22000_UCODE_API_MIN, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = 10, \
@ -261,6 +261,7 @@ static const struct iwl_ht_params iwl_gl_a_ht_params = {
#define IWL_DEVICE_22500 \
IWL_DEVICE_22000_COMMON, \
.ucode_api_max = IWL_22500_UCODE_API_MAX, \
.trans.device_family = IWL_DEVICE_FAMILY_22000, \
.trans.base_params = &iwl_22000_base_params, \
.gp2_reg_addr = 0xa02c68, \
@ -277,6 +278,7 @@ static const struct iwl_ht_params iwl_gl_a_ht_params = {
#define IWL_DEVICE_AX210 \
IWL_DEVICE_22000_COMMON, \
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
.trans.umac_prph_offset = 0x300000, \
.trans.device_family = IWL_DEVICE_FAMILY_AX210, \
.trans.base_params = &iwl_ax210_base_params, \
@ -1178,14 +1180,14 @@ const struct iwl_cfg iwl_cfg_bnj_b0_fm_b0 = {
.features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22500_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_SO_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_SO_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));

View File

@ -41,6 +41,34 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
},
},
{ .ident = "GOOGLE-HP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
},
},
{ .ident = "GOOGLE-ASUS",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
},
},
{ .ident = "GOOGLE-SAMSUNG",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
},
},
{ .ident = "DELL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
},
},
{ .ident = "DELL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
},
},
{}
};
@ -1149,7 +1177,15 @@ int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *c
IWL_DEBUG_RADIO(fwrt,
"PPAG table rev is %d but FW supports v1, sending truncated table\n",
fwrt->ppag_ver);
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
if (!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) {
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
IWL_DEBUG_RADIO(fwrt,
"FW doesn't support ppag China bit\n");
} else {
IWL_DEBUG_RADIO(fwrt,
"FW supports ppag China bit\n");
}
}
} else if (cmd_ver >= 2 && cmd_ver <= 4) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2020 Intel Corporation
* Copyright (C) 2012-2014, 2020, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -18,7 +18,7 @@
* ( BINDING_CONTEXT_CMD = 0x2b )
* @id_and_color: ID and color of the relevant Binding,
* &enum iwl_ctxt_id_and_color
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @macs: array of MAC id and colors which belong to the binding,
* &enum iwl_ctxt_id_and_color
* @phy: PHY id and color which belongs to the binding,
@ -38,7 +38,7 @@ struct iwl_binding_cmd_v1 {
* ( BINDING_CONTEXT_CMD = 0x2b )
* @id_and_color: ID and color of the relevant Binding,
* &enum iwl_ctxt_id_and_color
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @macs: array of MAC id and colors which belong to the binding
* &enum iwl_ctxt_id_and_color
* @phy: PHY id and color which belongs to the binding

View File

@ -138,11 +138,6 @@ enum iwl_legacy_cmds {
*/
REMOVE_STA = 0x19,
/**
* @FW_GET_ITEM_CMD: uses &struct iwl_fw_get_item_cmd
*/
FW_GET_ITEM_CMD = 0x1a,
/**
* @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or
* &struct iwl_tx_cmd_gen3,
@ -533,12 +528,6 @@ enum iwl_legacy_cmds {
*/
PROT_OFFLOAD_CONFIG_CMD = 0xd4,
/**
* @OFFLOADS_QUERY_CMD:
* No data in command, response in &struct iwl_wowlan_status
*/
OFFLOADS_QUERY_CMD = 0xd5,
/**
* @D0I3_END_CMD: End D0i3/D3 state, no command data
*/
@ -566,18 +555,22 @@ enum iwl_legacy_cmds {
WOWLAN_TKIP_PARAM = 0xe3,
/**
* @WOWLAN_KEK_KCK_MATERIAL: &struct iwl_wowlan_kek_kck_material_cmd
* @WOWLAN_KEK_KCK_MATERIAL: &struct iwl_wowlan_kek_kck_material_cmd_v2,
* &struct iwl_wowlan_kek_kck_material_cmd_v3 or
* &struct iwl_wowlan_kek_kck_material_cmd_v4
*/
WOWLAN_KEK_KCK_MATERIAL = 0xe4,
/**
* @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status
* @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6,
* &struct iwl_wowlan_status_v7, &struct iwl_wowlan_status_v9 or
* &struct iwl_wowlan_status_v12
*/
WOWLAN_GET_STATUSES = 0xe5,
/**
* @SCAN_OFFLOAD_PROFILES_QUERY_CMD:
* No command data, response is &struct iwl_scan_offload_profiles_query
* @SCAN_OFFLOAD_PROFILES_QUERY_CMD: No command data, response is
* &struct iwl_scan_offload_profiles_query_v1
*/
SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
};

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014 Intel Corporation
* Copyright (C) 2012-2014, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -26,13 +26,18 @@ enum iwl_ctxt_id_and_color {
#define FW_CMD_ID_AND_COLOR(_id, _color) (((_id) << FW_CTXT_ID_POS) |\
((_color) << FW_CTXT_COLOR_POS))
/* Possible actions on PHYs, MACs and Bindings */
/**
* enum iwl_ctxt_action - Posssible actions on PHYs, MACs, Bindings and other
* @FW_CTXT_ACTION_INVALID: unused, invalid action
* @FW_CTXT_ACTION_ADD: add the context
* @FW_CTXT_ACTION_MODIFY: modify the context
* @FW_CTXT_ACTION_REMOVE: remove the context
*/
enum iwl_ctxt_action {
FW_CTXT_ACTION_STUB = 0,
FW_CTXT_ACTION_INVALID = 0,
FW_CTXT_ACTION_ADD,
FW_CTXT_ACTION_MODIFY,
FW_CTXT_ACTION_REMOVE,
FW_CTXT_ACTION_NUM
}; /* COMMON_CONTEXT_ACTION_API_E_VER_1 */
#endif /* __iwl_fw_api_context_h__ */

View File

@ -47,12 +47,14 @@ struct iwl_d3_manager_config {
* @IWL_D3_PROTO_OFFLOAD_NS: NS (Neighbor Solicitation) is enabled
* @IWL_D3_PROTO_IPV4_VALID: IPv4 data is valid
* @IWL_D3_PROTO_IPV6_VALID: IPv6 data is valid
* @IWL_D3_PROTO_REJECT_BTM: reject BTM request
*/
enum iwl_proto_offloads {
IWL_D3_PROTO_OFFLOAD_ARP = BIT(0),
IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
IWL_D3_PROTO_IPV4_VALID = BIT(2),
IWL_D3_PROTO_IPV6_VALID = BIT(3),
IWL_D3_PROTO_REJECT_BTM = BIT(4),
};
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2

View File

@ -38,7 +38,9 @@ enum iwl_data_path_subcmd_ids {
WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD = 0x4,
/**
* @STA_HE_CTXT_CMD: &struct iwl_he_sta_context_cmd
* @STA_HE_CTXT_CMD: &struct iwl_he_sta_context_cmd_v1,
* &struct iwl_he_sta_context_cmd_v2 or
* &struct iwl_he_sta_context_cmd_v3
*/
STA_HE_CTXT_CMD = 0x7,
@ -447,7 +449,7 @@ struct iwl_sad_properties {
* @phy_id: PHY index
* @rlc: RLC properties, &struct iwl_rlc_properties
* @sad: SAD (single antenna diversity) options, &struct iwl_sad_properties
* @flags: flags, &enum iwl_rlc_flags
* @flags: flags (unused)
* @reserved: reserved
*/
struct iwl_rlc_config_cmd {

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*/
#ifndef __iwl_fw_api_location_h__
#define __iwl_fw_api_location_h__
@ -35,8 +35,11 @@ enum iwl_location_subcmd_ids {
*/
TOF_RANGE_REQ_EXT_CMD = 0x3,
/**
* @TOF_RESPONDER_CONFIG_CMD: FTM responder configuration,
* uses &struct iwl_tof_responder_config_cmd
* @TOF_RESPONDER_CONFIG_CMD: FTM responder configuration, one of
* &struct iwl_tof_responder_config_cmd_v6,
* &struct iwl_tof_responder_config_cmd_v7,
* &struct iwl_tof_responder_config_cmd_v8 or
* &struct iwl_tof_responder_config_cmd_v9
*/
TOF_RESPONDER_CONFIG_CMD = 0x4,
/**
@ -69,8 +72,11 @@ enum iwl_location_subcmd_ids {
*/
TOF_MCSI_DEBUG_NOTIF = 0xFE,
/**
* @TOF_RANGE_RESPONSE_NOTIF: ranging response, using
* &struct iwl_tof_range_rsp_ntfy
* @TOF_RANGE_RESPONSE_NOTIF: ranging response, using one of
* &struct iwl_tof_range_rsp_ntfy_v5,
* &struct iwl_tof_range_rsp_ntfy_v6,
* &struct iwl_tof_range_rsp_ntfy_v7 or
* &struct iwl_tof_range_rsp_ntfy_v8
*/
TOF_RANGE_RESPONSE_NOTIF = 0xFF,
};

View File

@ -140,40 +140,60 @@ struct iwl_missed_vap_notif {
*
* @id_and_color: ID and color of the MAC
*/
struct iwl_channel_switch_start_notif {
struct iwl_channel_switch_start_notif_v1 {
__le32 id_and_color;
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
/**
* struct iwl_channel_switch_start_notif - Channel switch start notification
*
* @link_id: FW link id
*/
struct iwl_channel_switch_start_notif {
__le32 link_id;
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_3 */
#define CS_ERR_COUNT_ERROR BIT(0)
#define CS_ERR_LONG_DELAY_AFTER_CS BIT(1)
#define CS_ERR_LONG_TX_BLOCK BIT(2)
#define CS_ERR_TX_BLOCK_TIMER_EXPIRED BIT(3)
/**
* struct iwl_channel_switch_error_notif - Channel switch error notification
* struct iwl_channel_switch_error_notif_v1 - Channel switch error notification
*
* @mac_id: the mac for which the ucode sends the notification for
* @csa_err_mask: mask of channel switch error that can occur
*/
struct iwl_channel_switch_error_notif {
struct iwl_channel_switch_error_notif_v1 {
__le32 mac_id;
__le32 csa_err_mask;
} __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_1 */
/**
* struct iwl_channel_switch_error_notif - Channel switch error notification
*
* @link_id: FW link id
* @csa_err_mask: mask of channel switch error that can occur
*/
struct iwl_channel_switch_error_notif {
__le32 link_id;
__le32 csa_err_mask;
} __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_2 */
/**
* struct iwl_cancel_channel_switch_cmd - Cancel Channel Switch command
*
* @mac_id: the mac that should cancel the channel switch
* @id: the id of the link or mac that should cancel the channel switch
*/
struct iwl_cancel_channel_switch_cmd {
__le32 mac_id;
__le32 id;
} __packed; /* MAC_CANCEL_CHANNEL_SWITCH_S_VER_1 */
/**
* struct iwl_chan_switch_te_cmd - Channel Switch Time Event command
*
* @mac_id: MAC ID for channel switch
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @tsf: beacon tsf
* @cs_count: channel switch count from CSA/eCSA IE
* @cs_delayed_bcn_count: if set to N (!= 0) GO/AP can delay N beacon intervals
@ -211,17 +231,30 @@ struct iwl_mac_low_latency_cmd {
* struct iwl_mac_client_data - configuration data for client MAC context
*
* @is_assoc: 1 for associated state, 0 otherwise
* @esr_transition_timeout: the timeout required by the AP for the
* eSR transition.
* Available only from version 2 of the command.
* This values comes from the EMLSR transition delay in the EML
* Capabilities subfield.
* @reserved: alignment
* @assoc_id: unique ID assigned by the AP during association
* @reserved1: alignment
* @data_policy: see &enum iwl_mac_data_policy
* @reserved2: alignment
* @ctwin: client traffic window in TU (period after TBTT when GO is present).
* 0 indicates that there is no CT window.
*/
struct iwl_mac_client_data {
__le32 is_assoc;
__le32 assoc_id;
__le32 data_policy;
u8 is_assoc;
u8 esr_transition_timeout;
__le16 reserved;
__le16 assoc_id;
__le16 reserved1;
__le16 data_policy;
__le16 reserved2;
__le32 ctwin;
} __packed; /* MAC_CONTEXT_CONFIG_CLIENT_DATA_API_S_VER_1 */
} __packed; /* MAC_CONTEXT_CONFIG_CLIENT_DATA_API_S_VER_2 */
/**
* struct iwl_mac_p2p_dev_data - configuration data for P2P device MAC context
@ -263,7 +296,7 @@ enum iwl_mac_config_filter_flags {
* ( MAC_CONTEXT_CONFIG_CMD = 0x8 )
*
* @id_and_color: ID and color of the MAC
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @mac_type: one of &enum iwl_mac_types
* @local_mld_addr: mld address
* @reserved_for_local_mld_addr: reserved
@ -292,12 +325,12 @@ struct iwl_mac_config_cmd {
__le16 he_ap_support;
__le32 eht_support;
__le32 nic_not_ack_enabled;
/* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_1 */
/* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_2 */
union {
struct iwl_mac_client_data client;
struct iwl_mac_p2p_dev_data p2p_dev;
};
} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_1 */
} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2 */
/**
* enum iwl_link_ctx_modify_flags - indicate to the fw what fields are being
@ -390,7 +423,7 @@ enum iwl_link_ctx_flags {
* in MLD API
* ( LINK_CONFIG_CMD =0x9 )
*
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @link_id: the id of the link that this cmd configures
* @mac_id: interface ID. Relevant only if action is FW_CTXT_ACTION_ADD
* @phy_id: PHY index. Can be changed only if the link was inactive
@ -430,6 +463,7 @@ enum iwl_link_ctx_flags {
* @reserved_for_ref_bssid_addr: reserved
* @bssid_index: index of the associated VAP
* @bss_color: 11ax AP ID that is used in the HE SIG-A to mark inter BSS frame
* @spec_link_id: link_id as the AP knows it
* @reserved: alignment
* @ibss_bssid_addr: bssid for ibss
* @reserved_for_ibss_bssid_addr: reserved
@ -469,7 +503,8 @@ struct iwl_link_config_cmd {
__le16 reserved_for_ref_bssid_addr;
u8 bssid_index;
u8 bss_color;
u8 reserved[2];
u8 spec_link_id;
u8 reserved;
u8 ibss_bssid_addr[6];
__le16 reserved_for_ibss_bssid_addr;
__le32 reserved1[8];

View File

@ -295,7 +295,7 @@ struct iwl_ac_qos {
* struct iwl_mac_ctx_cmd - command structure to configure MAC contexts
* ( MAC_CONTEXT_CMD = 0x28 )
* @id_and_color: ID and color of the MAC
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @mac_type: one of &enum iwl_mac_types
* @tsf_id: TSF HW timer, one of &enum iwl_tsf_id
* @node_addr: MAC address
@ -353,7 +353,7 @@ struct iwl_nonqos_seq_query_cmd {
} __packed; /* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */
/**
* struct iwl_missed_beacons_notif - information on missed beacons
* struct iwl_missed_beacons_notif_ver_3 - information on missed beacons
* ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
* @mac_id: interface ID
* @consec_missed_beacons_since_last_rx: number of consecutive missed
@ -362,7 +362,7 @@ struct iwl_nonqos_seq_query_cmd {
* @num_expected_beacons: number of expected beacons
* @num_recvd_beacons: number of received beacons
*/
struct iwl_missed_beacons_notif {
struct iwl_missed_beacons_notif_ver_3 {
__le32 mac_id;
__le32 consec_missed_beacons_since_last_rx;
__le32 consec_missed_beacons;
@ -370,6 +370,24 @@ struct iwl_missed_beacons_notif {
__le32 num_recvd_beacons;
} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
/**
* struct iwl_missed_beacons_notif - information on missed beacons
* ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
* @link_id: fw link ID
* @consec_missed_beacons_since_last_rx: number of consecutive missed
* beacons since last RX.
* @consec_missed_beacons: number of consecutive missed beacons
* @num_expected_beacons: number of expected beacons
* @num_recvd_beacons: number of received beacons
*/
struct iwl_missed_beacons_notif {
__le32 link_id;
__le32 consec_missed_beacons_since_last_rx;
__le32 consec_missed_beacons;
__le32 num_expected_beacons;
__le32 num_recvd_beacons;
} __packed; /* MISSED_BEACON_NTFY_API_S_VER_4 */
/**
* struct iwl_he_backoff_conf - used for backoff configuration
* Per each trigger-based AC, (set by MU EDCA Parameter set info-element)

View File

@ -17,7 +17,12 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
NVM_ACCESS_COMPLETE = 0x0,
/**
* @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd
* @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd_v1,
* &struct iwl_lari_config_change_cmd_v2,
* &struct iwl_lari_config_change_cmd_v3,
* &struct iwl_lari_config_change_cmd_v4,
* &struct iwl_lari_config_change_cmd_v5 or
* &struct iwl_lari_config_change_cmd_v6
*/
LARI_CONFIG_CHANGE = 0x1,
@ -29,12 +34,12 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
NVM_GET_INFO = 0x2,
/**
* @TAS_CONFIG: &struct iwl_tas_config_cmd
* @TAS_CONFIG: &union iwl_tas_config_cmd
*/
TAS_CONFIG = 0x3,
/**
* @SAR_OFFSET_MAPPING_TABLE_CMD: &iwl_sar_offset_mapping_cmd
* @SAR_OFFSET_MAPPING_TABLE_CMD: &struct iwl_sar_offset_mapping_cmd
*/
SAR_OFFSET_MAPPING_TABLE_CMD = 0x4,

View File

@ -28,7 +28,8 @@ enum iwl_prot_offload_subcmd_ids {
D3_END_NOTIFICATION = 0xFE,
/**
* @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif
* @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif_v2 or
* &struct iwl_stored_beacon_notif_v3
*/
STORED_BEACON_NTF = 0xFF,
};

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
* Copyright (C) 2012-2014, 2018, 2020-2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -116,7 +116,7 @@ struct iwl_phy_context_cmd_tail {
* struct iwl_phy_context_cmd - config of the PHY context
* ( PHY_CONTEXT_CMD = 0x8 )
* @id_and_color: ID and color of the relevant Binding
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @apply_time: 0 means immediate apply and context switch.
* other value means apply new params after X usecs
* @tx_param_color: ???
@ -138,7 +138,7 @@ struct iwl_phy_context_cmd_v1 {
* struct iwl_phy_context_cmd - config of the PHY context
* ( PHY_CONTEXT_CMD = 0x8 )
* @id_and_color: ID and color of the relevant Binding
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @lmac_id: the lmac id the phy context belongs to
* @ci: channel info
* @rxchain_info: ???

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2019-2021 Intel Corporation
* Copyright (C) 2012-2014, 2019-2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -29,12 +29,16 @@ enum iwl_phy_ops_subcmd_ids {
TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
/**
* @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd
* @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd_v1,
* &struct iwl_geo_tx_power_profiles_cmd_v2,
* &struct iwl_geo_tx_power_profiles_cmd_v3,
* &struct iwl_geo_tx_power_profiles_cmd_v4 or
* &struct iwl_geo_tx_power_profiles_cmd_v5
*/
PER_CHAIN_LIMIT_OFFSET_CMD = 0x05,
/**
* @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
* @PER_PLATFORM_ANT_GAIN_CMD: &union iwl_ppag_table_cmd
*/
PER_PLATFORM_ANT_GAIN_CMD = 0x07,

View File

@ -537,7 +537,7 @@ union iwl_ppag_table_cmd {
struct iwl_sar_offset_mapping_cmd {
u8 offset_map[MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE]
[MCC_TO_SAR_OFFSET_TABLE_COL_SIZE];
u16 reserved;
__le16 reserved;
} __packed; /*SAR_OFFSET_MAPPING_TABLE_CMD_API_S*/
/**

View File

@ -367,8 +367,8 @@ enum iwl_rx_phy_eht_data1 {
/* number of EHT-LTF symbols 0 - 1 EHT-LTF, 1 - 2 EHT-LTFs, 2 - 4 EHT-LTFs,
* 3 - 6 EHT-LTFs, 4 - 8 EHT-LTFs */
IWL_RX_PHY_DATA1_EHT_SIG_LTF_NUM = 0x000000e0,
IWL_RX_PHY_DATA1_EHT_B0 = 0x00000100,
IWL_RX_PHY_DATA1_EHT_RU_B1_B7_ALLOC = 0x0000fe00,
IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B0 = 0x00000100,
IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B1_B7 = 0x0000fe00,
};
/* goes into Metadata DW 7 */

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2020, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -292,7 +292,7 @@ struct iwl_hs20_roc_req_tail {
* ( HOT_SPOT_CMD 0x53 )
*
* @id_and_color: ID and color of the MAC
* @action: action to perform, one of FW_CTXT_ACTION_*
* @action: action to perform, see &enum iwl_ctxt_action
* @event_unique_id: If the action FW_CTXT_ACTION_REMOVE then the
* event_unique_id should be the id of the time event assigned by ucode.
* Otherwise ignore the event_unique_id.
@ -377,7 +377,8 @@ enum iwl_mvm_session_prot_conf_id {
* struct iwl_mvm_session_prot_cmd - configure a session protection
* @id_and_color: the id and color of the mac for which this session protection
* is sent
* @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE
* @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE,
* see &enum iwl_ctxt_action
* @conf_id: see &enum iwl_mvm_session_prot_conf_id
* @duration_tu: the duration of the whole protection in TUs.
* @repetition_count: not used

View File

@ -2034,7 +2034,6 @@ static u32
iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_dump_ini_region_data *reg_data)
{
u32 size = 0;
u32 ranges = 0;
u32 imr_enable = fwrt->trans->dbg.imr_data.imr_enable;
u32 imr_size = fwrt->trans->dbg.imr_data.imr_size;
@ -2044,17 +2043,16 @@ iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
IWL_DEBUG_INFO(fwrt,
"WRT: Invalid imr data enable: %d, imr_size: %d, sram_size: %d\n",
imr_enable, imr_size, sram_size);
return size;
}
size = imr_size;
ranges = iwl_dump_ini_imr_ranges(fwrt, reg_data);
if (!size && !ranges) {
IWL_ERR(fwrt, "WRT: imr_size :=%d, ranges :=%d\n", size, ranges);
return 0;
}
size += sizeof(struct iwl_fw_ini_error_dump) +
ranges = iwl_dump_ini_imr_ranges(fwrt, reg_data);
if (!ranges) {
IWL_ERR(fwrt, "WRT: ranges :=%d\n", ranges);
return 0;
}
imr_size += sizeof(struct iwl_fw_ini_error_dump) +
ranges * sizeof(struct iwl_fw_ini_error_dump_range);
return size;
return imr_size;
}
/**

View File

@ -323,6 +323,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
* is supported.
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan (no longer used)
* @IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG: supports fragmented PNVM image
* @IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT: the firmware supports setting
* stabilization latency for SoCs.
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
@ -398,6 +399,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
/* set 1 */
IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG = (__force iwl_ucode_tlv_capa_t)32,
IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT = (__force iwl_ucode_tlv_capa_t)37,
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38,
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39,
@ -462,6 +464,9 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT = (__force iwl_ucode_tlv_capa_t)109,
IWL_UCODE_TLV_CAPA_MLD_API_SUPPORT = (__force iwl_ucode_tlv_capa_t)110,
IWL_UCODE_TLV_CAPA_SCAN_DONT_TOGGLE_ANT = (__force iwl_ucode_tlv_capa_t)111,
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT = (__force iwl_ucode_tlv_capa_t)112,
IWL_UCODE_TLV_CAPA_OFFLOAD_REJ_BTM_SUPPORT = (__force iwl_ucode_tlv_capa_t)113,
IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT = (__force iwl_ucode_tlv_capa_t)114,
#ifdef __CHECKER__
/* sparse says it cannot increment the previous enum member */

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright(c) 2020-2022 Intel Corporation
* Copyright(c) 2020-2023 Intel Corporation
*/
#include "iwl-drv.h"
@ -31,18 +31,18 @@ static bool iwl_pnvm_complete_fn(struct iwl_notif_wait_data *notif_wait,
}
static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
size_t len)
size_t len,
struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
u32 sha1 = 0;
u16 mac_type = 0, rf_id = 0;
u8 *pnvm_data = NULL, *tmp;
bool hw_match = false;
u32 size = 0;
int ret;
IWL_DEBUG_FW(trans, "Handling PNVM section\n");
memset(pnvm_data, 0, sizeof(*pnvm_data));
while (len >= sizeof(*tlv)) {
u32 tlv_len, tlv_type;
@ -55,8 +55,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
ret = -EINVAL;
goto out;
return -EINVAL;
}
data += sizeof(*tlv);
@ -75,6 +74,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
IWL_DEBUG_FW(trans,
"Got IWL_UCODE_TLV_PNVM_VERSION %0x\n",
sha1);
pnvm_data->version = sha1;
break;
case IWL_UCODE_TLV_HW_TYPE:
if (tlv_len < 2 * sizeof(__le16)) {
@ -112,26 +112,26 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
break;
}
if (pnvm_data->n_chunks == IPC_DRAM_MAP_ENTRY_NUM_MAX) {
IWL_DEBUG_FW(trans,
"too many payloads to allocate in DRAM.\n");
return -EINVAL;
}
IWL_DEBUG_FW(trans, "Adding data (size %d)\n",
data_len);
tmp = krealloc(pnvm_data, size + data_len, GFP_KERNEL);
if (!tmp) {
IWL_DEBUG_FW(trans,
"Couldn't allocate (more) pnvm_data\n");
ret = -ENOMEM;
goto out;
}
pnvm_data = tmp;
memcpy(pnvm_data + size, section->data, data_len);
size += data_len;
pnvm_data->chunks[pnvm_data->n_chunks].data = section->data;
pnvm_data->chunks[pnvm_data->n_chunks].len = data_len;
pnvm_data->n_chunks++;
break;
}
case IWL_UCODE_TLV_MEM_DESC:
if (iwl_uefi_handle_tlv_mem_desc(trans, data, tlv_len,
pnvm_data))
return -EINVAL;
break;
case IWL_UCODE_TLV_PNVM_SKU:
IWL_DEBUG_FW(trans,
"New PNVM section started, stop parsing.\n");
@ -152,26 +152,20 @@ done:
"HW mismatch, skipping PNVM section (need mac_type 0x%x rf_id 0x%x)\n",
CSR_HW_REV_TYPE(trans->hw_rev),
CSR_HW_RFID_TYPE(trans->hw_rf_id));
ret = -ENOENT;
goto out;
return -ENOENT;
}
if (!size) {
if (!pnvm_data->n_chunks) {
IWL_DEBUG_FW(trans, "Empty PNVM, skipping.\n");
ret = -ENOENT;
goto out;
return -ENOENT;
}
IWL_INFO(trans, "loaded PNVM version %08x\n", sha1);
ret = iwl_trans_set_pnvm(trans, pnvm_data, size);
out:
kfree(pnvm_data);
return ret;
return 0;
}
static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
size_t len)
size_t len,
struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
@ -212,7 +206,8 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
int ret;
ret = iwl_pnvm_handle_section(trans, data, len);
ret = iwl_pnvm_handle_section(trans, data, len,
pnvm_data);
if (!ret)
return 0;
} else {
@ -255,88 +250,135 @@ static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len)
return 0;
}
int iwl_pnvm_load(struct iwl_trans *trans,
struct iwl_notif_wait_data *notif_wait)
static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len)
{
u8 *data;
size_t len;
struct pnvm_sku_package *package;
u8 *image = NULL;
/* First attempt to get the PNVM from BIOS */
package = iwl_uefi_get_pnvm(trans_p, len);
if (!IS_ERR_OR_NULL(package)) {
if (*len >= sizeof(*package)) {
/* we need only the data */
*len -= sizeof(*package);
image = kmemdup(package->data, *len, GFP_KERNEL);
}
/* free package regardless of whether kmemdup succeeded */
kfree(package);
if (image)
return image;
}
/* If it's not available, try from the filesystem */
if (iwl_pnvm_get_from_fs(trans_p, &image, len))
return NULL;
return image;
}
static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
struct iwl_pnvm_image *pnvm_data = NULL;
u8 *data = NULL;
size_t length;
int ret;
/* failed to get/parse the image in the past, no use trying again */
if (trans->fail_to_parse_pnvm_image)
return;
if (trans->pnvm_loaded)
goto set;
data = iwl_get_pnvm_image(trans, &length);
if (!data) {
trans->fail_to_parse_pnvm_image = true;
return;
}
pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL);
if (!pnvm_data)
goto free;
ret = iwl_pnvm_parse(trans, data, length, pnvm_data);
if (ret) {
trans->fail_to_parse_pnvm_image = true;
goto free;
}
ret = iwl_trans_load_pnvm(trans, pnvm_data, capa);
if (ret)
goto free;
IWL_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version);
set:
iwl_trans_set_pnvm(trans, capa);
free:
kfree(data);
kfree(pnvm_data);
}
static void
iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
struct iwl_pnvm_image *pnvm_data = NULL;
u8 *data = NULL;
size_t length;
int ret;
if (trans->failed_to_load_reduce_power_image)
return;
if (trans->reduce_power_loaded)
goto set;
data = iwl_uefi_get_reduced_power(trans, &length);
if (IS_ERR(data)) {
trans->failed_to_load_reduce_power_image = true;
return;
}
pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL);
if (!pnvm_data)
goto free;
ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data);
if (ret) {
trans->failed_to_load_reduce_power_image = true;
goto free;
}
ret = iwl_trans_load_reduce_power(trans, pnvm_data, capa);
if (ret) {
IWL_DEBUG_FW(trans,
"Failed to load reduce power table %d\n",
ret);
trans->failed_to_load_reduce_power_image = true;
goto free;
}
set:
iwl_trans_set_reduce_power(trans, capa);
free:
kfree(data);
kfree(pnvm_data);
}
int iwl_pnvm_load(struct iwl_trans *trans,
struct iwl_notif_wait_data *notif_wait,
const struct iwl_ucode_capabilities *capa)
{
struct iwl_notification_wait pnvm_wait;
static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
PNVM_INIT_COMPLETE_NTFY) };
int ret;
/* if the SKU_ID is empty, there's nothing to do */
if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2])
return 0;
/*
* If we already loaded (or tried to load) it before, we just
* need to set it again.
*/
if (trans->pnvm_loaded) {
ret = iwl_trans_set_pnvm(trans, NULL, 0);
if (ret)
return ret;
goto skip_parse;
}
/* First attempt to get the PNVM from BIOS */
package = iwl_uefi_get_pnvm(trans, &len);
if (!IS_ERR_OR_NULL(package)) {
if (len >= sizeof(*package)) {
/* we need only the data */
len -= sizeof(*package);
data = kmemdup(package->data, len, GFP_KERNEL);
} else {
data = NULL;
}
/* free package regardless of whether kmemdup succeeded */
kfree(package);
if (data)
goto parse;
}
/* If it's not available, try from the filesystem */
ret = iwl_pnvm_get_from_fs(trans, &data, &len);
if (ret) {
/*
* Pretend we've loaded it - at least we've tried and
* couldn't load it at all, so there's no point in
* trying again over and over.
*/
trans->pnvm_loaded = true;
goto skip_parse;
}
parse:
iwl_pnvm_parse(trans, data, len);
kfree(data);
skip_parse:
/* now try to get the reduce power table, if not loaded yet */
if (!trans->reduce_power_loaded) {
data = iwl_uefi_get_reduced_power(trans, &len);
if (IS_ERR_OR_NULL(data)) {
/*
* Pretend we've loaded it - at least we've tried and
* couldn't load it at all, so there's no point in
* trying again over and over.
*/
trans->reduce_power_loaded = true;
} else {
ret = iwl_trans_set_reduce_power(trans, data, len);
if (ret)
IWL_DEBUG_FW(trans,
"Failed to set reduce power table %d\n",
ret);
kfree(data);
}
}
iwl_pnvm_load_pnvm_to_trans(trans, capa);
iwl_pnvm_load_reduce_power_to_trans(trans, capa);
iwl_init_notification_wait(notif_wait, &pnvm_wait,
ntf_cmds, ARRAY_SIZE(ntf_cmds),

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/******************************************************************************
*
* Copyright(c) 2020-2021 Intel Corporation
* Copyright(c) 2020-2022 Intel Corporation
*
*****************************************************************************/
@ -15,7 +15,8 @@
#define MAX_PNVM_NAME 64
int iwl_pnvm_load(struct iwl_trans *trans,
struct iwl_notif_wait_data *notif_wait);
struct iwl_notif_wait_data *notif_wait,
const struct iwl_ucode_capabilities *capa);
static inline
void iwl_pnvm_get_fs_name(struct iwl_trans *trans,

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright(c) 2021-2022 Intel Corporation
* Copyright(c) 2021-2023 Intel Corporation
*/
#include "iwl-drv.h"
@ -17,52 +17,109 @@
0xb2, 0xec, 0xf5, 0xa3, \
0x59, 0x4f, 0x4a, 0xea)
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
{
void *data;
unsigned long package_size;
efi_status_t status;
struct iwl_uefi_pnvm_mem_desc {
__le32 addr;
__le32 size;
const u8 data[];
} __packed;
*len = 0;
static void *iwl_uefi_get_variable(efi_char16_t *name, efi_guid_t *guid,
unsigned long *data_size)
{
efi_status_t status;
void *data;
if (!data_size)
return ERR_PTR(-EINVAL);
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
return ERR_PTR(-ENODEV);
/*
* TODO: we hardcode a maximum length here, because reading
* from the UEFI is not working. To implement this properly,
* we have to call efivar_entry_size().
*/
package_size = IWL_HARDCODED_PNVM_SIZE;
/* first call with NULL data to get the exact entry size */
*data_size = 0;
status = efi.get_variable(name, guid, NULL, data_size, NULL);
if (status != EFI_BUFFER_TOO_SMALL || !*data_size)
return ERR_PTR(-EIO);
data = kmalloc(package_size, GFP_KERNEL);
data = kmalloc(*data_size, GFP_KERNEL);
if (!data)
return ERR_PTR(-ENOMEM);
status = efi.get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_VAR_GUID,
NULL, &package_size, data);
status = efi.get_variable(name, guid, NULL, data_size, data);
if (status != EFI_SUCCESS) {
IWL_DEBUG_FW(trans,
"PNVM UEFI variable not found 0x%lx (len %lu)\n",
status, package_size);
kfree(data);
return ERR_PTR(-ENOENT);
}
return data;
}
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
{
unsigned long package_size;
void *data;
*len = 0;
data = iwl_uefi_get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_VAR_GUID,
&package_size);
if (IS_ERR(data)) {
IWL_DEBUG_FW(trans,
"PNVM UEFI variable not found 0x%lx (len %lu)\n",
PTR_ERR(data), package_size);
return data;
}
IWL_DEBUG_FW(trans, "Read PNVM from UEFI with size %lu\n", package_size);
*len = package_size;
return data;
}
static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
const u8 *data, size_t len)
int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
u32 tlv_len, struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_uefi_pnvm_mem_desc *desc = (const void *)data;
u32 data_len;
if (tlv_len < sizeof(*desc)) {
IWL_DEBUG_FW(trans, "TLV len (%d) is too small\n", tlv_len);
return -EINVAL;
}
data_len = tlv_len - sizeof(*desc);
IWL_DEBUG_FW(trans,
"Handle IWL_UCODE_TLV_MEM_DESC, len %d data_len %d\n",
tlv_len, data_len);
if (le32_to_cpu(desc->size) != data_len) {
IWL_DEBUG_FW(trans, "invalid mem desc size %d\n", desc->size);
return -EINVAL;
}
if (pnvm_data->n_chunks == IPC_DRAM_MAP_ENTRY_NUM_MAX) {
IWL_DEBUG_FW(trans, "too many payloads to allocate in DRAM.\n");
return -EINVAL;
}
IWL_DEBUG_FW(trans, "Adding data (size %d)\n", data_len);
pnvm_data->chunks[pnvm_data->n_chunks].data = desc->data;
pnvm_data->chunks[pnvm_data->n_chunks].len = data_len;
pnvm_data->n_chunks++;
return 0;
}
static int iwl_uefi_reduce_power_section(struct iwl_trans *trans,
const u8 *data, size_t len,
struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
u8 *reduce_power_data = NULL, *tmp;
u32 size = 0;
IWL_DEBUG_FW(trans, "Handling REDUCE_POWER section\n");
memset(pnvm_data, 0, sizeof(*pnvm_data));
while (len >= sizeof(*tlv)) {
u32 tlv_len, tlv_type;
@ -76,39 +133,17 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
kfree(reduce_power_data);
reduce_power_data = ERR_PTR(-EINVAL);
goto out;
return -EINVAL;
}
data += sizeof(*tlv);
switch (tlv_type) {
case IWL_UCODE_TLV_MEM_DESC: {
IWL_DEBUG_FW(trans,
"Got IWL_UCODE_TLV_MEM_DESC len %d\n",
tlv_len);
IWL_DEBUG_FW(trans, "Adding data (size %d)\n", tlv_len);
tmp = krealloc(reduce_power_data, size + tlv_len, GFP_KERNEL);
if (!tmp) {
IWL_DEBUG_FW(trans,
"Couldn't allocate (more) reduce_power_data\n");
kfree(reduce_power_data);
reduce_power_data = ERR_PTR(-ENOMEM);
goto out;
}
reduce_power_data = tmp;
memcpy(reduce_power_data + size, data, tlv_len);
size += tlv_len;
case IWL_UCODE_TLV_MEM_DESC:
if (iwl_uefi_handle_tlv_mem_desc(trans, data, tlv_len,
pnvm_data))
return -EINVAL;
break;
}
case IWL_UCODE_TLV_PNVM_SKU:
IWL_DEBUG_FW(trans,
"New REDUCE_POWER section started, stop parsing.\n");
@ -124,27 +159,18 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
}
done:
if (!size) {
if (!pnvm_data->n_chunks) {
IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n");
/* Better safe than sorry, but 'reduce_power_data' should
* always be NULL if !size.
*/
kfree(reduce_power_data);
reduce_power_data = ERR_PTR(-ENOENT);
goto out;
return -ENOENT;
}
IWL_INFO(trans, "loaded REDUCE_POWER\n");
out:
return reduce_power_data;
return 0;
}
static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
const u8 *data, size_t len)
int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
const u8 *data, size_t len,
struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
void *sec_data;
IWL_DEBUG_FW(trans, "Parsing REDUCE_POWER data\n");
@ -160,7 +186,7 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
return ERR_PTR(-EINVAL);
return -EINVAL;
}
if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) {
@ -181,11 +207,11 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) &&
trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) &&
trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
sec_data = iwl_uefi_reduce_power_section(trans,
data,
len);
if (!IS_ERR(sec_data))
return sec_data;
int ret = iwl_uefi_reduce_power_section(trans,
data, len,
pnvm_data);
if (!ret)
return 0;
} else {
IWL_DEBUG_FW(trans, "SKU ID didn't match!\n");
}
@ -195,51 +221,45 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
}
}
return ERR_PTR(-ENOENT);
return -ENOENT;
}
void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
{
struct pnvm_sku_package *package;
void *data = NULL;
unsigned long package_size;
efi_status_t status;
u8 *data;
*len = 0;
package = iwl_uefi_get_variable(IWL_UEFI_REDUCED_POWER_NAME,
&IWL_EFI_VAR_GUID, &package_size);
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
return ERR_PTR(-ENODEV);
/*
* TODO: we hardcode a maximum length here, because reading
* from the UEFI is not working. To implement this properly,
* we have to call efivar_entry_size().
*/
package_size = IWL_HARDCODED_REDUCE_POWER_SIZE;
package = kmalloc(package_size, GFP_KERNEL);
if (!package)
return ERR_PTR(-ENOMEM);
status = efi.get_variable(IWL_UEFI_REDUCED_POWER_NAME, &IWL_EFI_VAR_GUID,
NULL, &package_size, package);
if (status != EFI_SUCCESS) {
if (IS_ERR(package)) {
IWL_DEBUG_FW(trans,
"Reduced Power UEFI variable not found 0x%lx (len %lu)\n",
status, package_size);
PTR_ERR(package), package_size);
return ERR_CAST(package);
}
if (package_size < sizeof(*package)) {
IWL_DEBUG_FW(trans,
"Invalid Reduced Power UEFI variable len (%lu)\n",
package_size);
kfree(package);
return ERR_PTR(-ENOENT);
return ERR_PTR(-EINVAL);
}
IWL_DEBUG_FW(trans, "Read reduced power from UEFI with size %lu\n",
package_size);
*len = package_size;
IWL_DEBUG_FW(trans, "rev %d, total_size %d, n_skus %d\n",
package->rev, package->total_size, package->n_skus);
data = iwl_uefi_reduce_power_parse(trans, package->data,
*len - sizeof(*package));
*len = package_size - sizeof(*package);
data = kmemdup(package->data, *len, GFP_KERNEL);
if (!data) {
kfree(package);
return ERR_PTR(-ENOMEM);
}
kfree(package);
@ -264,31 +284,27 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans)
{
struct uefi_cnv_common_step_data *data;
unsigned long package_size;
efi_status_t status;
int ret;
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return;
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
return;
data = iwl_uefi_get_variable(IWL_UEFI_STEP_NAME, &IWL_EFI_VAR_GUID,
&package_size);
/* TODO: we hardcode a maximum length here, because reading
* from the UEFI is not working. To implement this properly,
* we have to call efivar_entry_size().
*/
package_size = IWL_HARDCODED_STEP_SIZE;
data = kmalloc(package_size, GFP_KERNEL);
if (!data)
return;
status = efi.get_variable(IWL_UEFI_STEP_NAME, &IWL_EFI_VAR_GUID,
NULL, &package_size, data);
if (status != EFI_SUCCESS) {
if (IS_ERR(data)) {
IWL_DEBUG_FW(trans,
"STEP UEFI variable not found 0x%lx\n", status);
goto out_free;
"STEP UEFI variable not found 0x%lx\n",
PTR_ERR(data));
return;
}
if (package_size < sizeof(*data)) {
IWL_DEBUG_FW(trans,
"Invalid STEP table UEFI variable len (%lu)\n",
package_size);
kfree(data);
return;
}
IWL_DEBUG_FW(trans, "Read STEP from UEFI with size %lu\n",
@ -298,7 +314,6 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans)
if (ret < 0)
IWL_DEBUG_FW(trans, "Cannot read STEP tables. rev is invalid\n");
out_free:
kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_uefi_get_step_table);
@ -341,29 +356,26 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans,
{
struct uefi_cnv_wlan_sgom_data *data;
unsigned long package_size;
efi_status_t status;
int ret;
if (!fwrt->geo_enabled ||
!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
if (!fwrt->geo_enabled)
return;
/* TODO: we hardcode a maximum length here, because reading
* from the UEFI is not working. To implement this properly,
* we have to call efivar_entry_size().
*/
package_size = IWL_HARDCODED_SGOM_SIZE;
data = kmalloc(package_size, GFP_KERNEL);
if (!data)
return;
status = efi.get_variable(IWL_UEFI_SGOM_NAME, &IWL_EFI_VAR_GUID,
NULL, &package_size, data);
if (status != EFI_SUCCESS) {
data = iwl_uefi_get_variable(IWL_UEFI_SGOM_NAME, &IWL_EFI_VAR_GUID,
&package_size);
if (IS_ERR(data)) {
IWL_DEBUG_FW(trans,
"SGOM UEFI variable not found 0x%lx\n", status);
goto out_free;
"SGOM UEFI variable not found 0x%lx\n",
PTR_ERR(data));
return;
}
if (package_size < sizeof(*data)) {
IWL_DEBUG_FW(trans,
"Invalid SGOM table UEFI variable len (%lu)\n",
package_size);
kfree(data);
return;
}
IWL_DEBUG_FW(trans, "Read SGOM from UEFI with size %lu\n",
@ -373,9 +385,7 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans,
if (ret < 0)
IWL_DEBUG_FW(trans, "Cannot read SGOM tables. rev is invalid\n");
out_free:
kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_uefi_get_sgom_table);
#endif /* CONFIG_ACPI */

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright(c) 2021-2022 Intel Corporation
* Copyright(c) 2021-2023 Intel Corporation
*/
#ifndef __iwl_fw_uefi__
#define __iwl_fw_uefi__
@ -10,16 +10,7 @@
#define IWL_UEFI_SGOM_NAME L"UefiCnvWlanSarGeoOffsetMapping"
#define IWL_UEFI_STEP_NAME L"UefiCnvCommonSTEP"
/*
* TODO: we have these hardcoded values that the caller must pass,
* because reading from the UEFI is not working. To implement this
* properly, we have to change iwl_pnvm_get_from_uefi() to call
* efivar_entry_size() and return the value to the caller instead.
*/
#define IWL_HARDCODED_PNVM_SIZE 4096
#define IWL_HARDCODED_REDUCE_POWER_SIZE 32768
#define IWL_HARDCODED_SGOM_SIZE 339
#define IWL_HARDCODED_STEP_SIZE 6
#define IWL_SGOM_MAP_SIZE 339
struct pnvm_sku_package {
u8 rev;
@ -31,7 +22,7 @@ struct pnvm_sku_package {
struct uefi_cnv_wlan_sgom_data {
u8 revision;
u8 offset_map[IWL_HARDCODED_SGOM_SIZE - 1];
u8 offset_map[IWL_SGOM_MAP_SIZE - 1];
} __packed;
struct uefi_cnv_common_step_data {
@ -50,25 +41,43 @@ struct uefi_cnv_common_step_data {
*/
#ifdef CONFIG_EFI
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len);
void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
const u8 *data, size_t len,
struct iwl_pnvm_image *pnvm_data);
void iwl_uefi_get_step_table(struct iwl_trans *trans);
int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
u32 tlv_len, struct iwl_pnvm_image *pnvm_data);
#else /* CONFIG_EFI */
static inline
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline
void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
static inline int
iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
const u8 *data, size_t len,
struct iwl_pnvm_image *pnvm_data)
{
return -EOPNOTSUPP;
}
static inline u8 *
iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
{
return ERR_PTR(-EOPNOTSUPP);
}
static inline
void iwl_uefi_get_step_table(struct iwl_trans *trans)
static inline void iwl_uefi_get_step_table(struct iwl_trans *trans)
{
}
static inline int
iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
u32 tlv_len, struct iwl_pnvm_image *pnvm_data)
{
return 0;
}
#endif /* CONFIG_EFI */
#if defined(CONFIG_EFI) && defined(CONFIG_ACPI)

View File

@ -13,6 +13,8 @@
#define CSR_IML_SIZE_ADDR 0x128
#define CSR_IML_RESP_ADDR 0x12c
#define UNFRAGMENTED_PNVM_PAYLOADS_NUMBER 2
/* Set bit for enabling automatic function boot */
#define CSR_AUTO_FUNC_BOOT_ENA BIT(1)
/* Set bit for initiating function boot */
@ -96,9 +98,9 @@ struct iwl_prph_scratch_control {
} __packed; /* PERIPH_SCRATCH_CONTROL_S */
/*
* struct iwl_prph_scratch_pnvm_cfg - ror config
* struct iwl_prph_scratch_pnvm_cfg - PNVM scratch
* @pnvm_base_addr: PNVM start address
* @pnvm_size: PNVM size in DWs
* @pnvm_size: the size of the PNVM image in bytes
* @reserved: reserved
*/
struct iwl_prph_scratch_pnvm_cfg {
@ -107,6 +109,14 @@ struct iwl_prph_scratch_pnvm_cfg {
__le32 reserved;
} __packed; /* PERIPH_SCRATCH_PNVM_CFG_S */
/**
* struct iwl_prph_scrath_mem_desc_addr_array
* @mem_descs: array of dram addresses.
* Each address is the beggining of a pnvm payload.
*/
struct iwl_prph_scrath_mem_desc_addr_array {
__le64 mem_descs[IPC_DRAM_MAP_ENTRY_NUM_MAX];
} __packed; /* PERIPH_SCRATCH_MEM_DESC_ADDR_ARRAY_S_VER_1 */
/*
* struct iwl_prph_scratch_hwm_cfg - hwm config
* @hwm_base_addr: hwm start address
@ -132,7 +142,7 @@ struct iwl_prph_scratch_rbd_cfg {
/*
* struct iwl_prph_scratch_uefi_cfg - prph scratch reduce power table
* @base_addr: reduce power table address
* @size: table size in dwords
* @size: the size of the entire power table image
*/
struct iwl_prph_scratch_uefi_cfg {
__le64 base_addr;
@ -277,10 +287,18 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
const struct fw_img *fw);
void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive);
int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
const void *data, u32 len);
int iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
const void *data, u32 len);
int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_payloads,
const struct iwl_ucode_capabilities *capa);
void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
int
iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans,
const struct iwl_pnvm_image *payloads,
const struct iwl_ucode_capabilities *capa);
void
iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
int iwl_trans_pcie_ctx_info_gen3_set_step(struct iwl_trans *trans,
u32 mbx_addr_0_step, u32 mbx_addr_1_step);
#endif /* __iwl_context_info_file_gen3_h__ */

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2020 Intel Corporation
* Copyright (C) 2018-2020, 2022 Intel Corporation
*/
#ifndef __iwl_context_info_file_h__
#define __iwl_context_info_file_h__
@ -177,6 +177,9 @@ void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans);
int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
const struct fw_img *fw,
struct iwl_context_info_dram *ctxt_dram);
void *iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
size_t size,
dma_addr_t *phys);
int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
const void *data, u32 len,
struct iwl_dram_data *dram);

View File

@ -738,7 +738,8 @@ static int iwl_dbg_tlv_update_dram(struct iwl_fw_runtime *fwrt,
if (le32_to_cpu(fwrt->trans->dbg.fw_mon_cfg[alloc_id].buf_location) !=
IWL_FW_INI_LOCATION_DRAM_PATH) {
IWL_DEBUG_FW(fwrt, "DRAM_PATH is not supported alloc_id %u\n", alloc_id);
IWL_DEBUG_FW(fwrt, "WRT: alloc_id %u location is not in DRAM_PATH\n",
alloc_id);
return -1;
}
@ -799,6 +800,10 @@ static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt)
for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1;
i < IWL_FW_INI_ALLOCATION_NUM; i++) {
if (fwrt->trans->dbg.fw_mon_cfg[i].buf_location ==
IWL_FW_INI_LOCATION_INVALID)
continue;
ret = iwl_dbg_tlv_update_dram(fwrt, i, dram_info);
if (!ret)
dram_alloc = true;

View File

@ -464,6 +464,9 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
IEEE80211_VHT_MAX_AMPDU_1024K <<
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
if (!trans->cfg->ht_params->stbc)
vht_cap->cap &= ~IEEE80211_VHT_CAP_RXSTBC_MASK;
if (data->vht160_supported)
vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
IEEE80211_VHT_CAP_SHORT_GI_160;
@ -986,6 +989,13 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
iftype_data->vendor_elems.data = iwl_vendor_caps;
iftype_data->vendor_elems.len = ARRAY_SIZE(iwl_vendor_caps);
}
if (!trans->cfg->ht_params->stbc) {
iftype_data->he_cap.he_cap_elem.phy_cap_info[2] &=
~IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] &=
~IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
}
}
static void iwl_init_he_hw_capab(struct iwl_trans *trans,

View File

@ -459,6 +459,24 @@ struct iwl_trans_rxq_dma_data {
u64 ur_bd_cb;
};
/* maximal number of DRAM MAP entries supported by FW */
#define IPC_DRAM_MAP_ENTRY_NUM_MAX 64
/**
* struct iwl_pnvm_image - contains info about the parsed pnvm image
* @chunks: array of pointers to pnvm payloads and their sizes
* @n_chunks: the number of the pnvm payloads.
* @version: the version of the loaded PNVM image
*/
struct iwl_pnvm_image {
struct {
const void *data;
u32 len;
} chunks[IPC_DRAM_MAP_ENTRY_NUM_MAX];
u32 n_chunks;
u32 version;
};
/**
* struct iwl_trans_ops - transport specific operations
*
@ -541,8 +559,11 @@ struct iwl_trans_rxq_dma_data {
* Note that the transport must fill in the proper file headers.
* @debugfs_cleanup: used in the driver unload flow to make a proper cleanup
* of the trans debugfs
* @load_pnvm: save the pnvm data in DRAM
* @set_pnvm: set the pnvm data in the prph scratch buffer, inside the
* context info.
* @load_reduce_power: copy reduce power table to the corresponding DRAM memory
* @set_reduce_power: set reduce power table addresses in the sratch buffer
* @interrupts: disable/enable interrupts to transport
*/
struct iwl_trans_ops {
@ -614,9 +635,17 @@ struct iwl_trans_ops {
void *sanitize_ctx);
void (*debugfs_cleanup)(struct iwl_trans *trans);
void (*sync_nmi)(struct iwl_trans *trans);
int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len);
int (*set_reduce_power)(struct iwl_trans *trans,
const void *data, u32 len);
int (*load_pnvm)(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_payloads,
const struct iwl_ucode_capabilities *capa);
void (*set_pnvm)(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
int (*load_reduce_power)(struct iwl_trans *trans,
const struct iwl_pnvm_image *payloads,
const struct iwl_ucode_capabilities *capa);
void (*set_reduce_power)(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
void (*interrupts)(struct iwl_trans *trans, bool enable);
int (*imr_dma_data)(struct iwl_trans *trans,
u32 dst_addr, u64 src_addr,
@ -704,6 +733,19 @@ struct iwl_dram_data {
int size;
};
/**
* @drams: array of several DRAM areas that contains the pnvm and power
* reduction table payloads.
* @n_regions: number of DRAM regions that were allocated
* @prph_scratch_mem_desc: points to a structure allocated in dram,
* designed to show FW where all the payloads are.
*/
struct iwl_dram_regions {
struct iwl_dram_data drams[IPC_DRAM_MAP_ENTRY_NUM_MAX];
struct iwl_dram_data prph_scratch_mem_desc;
u8 n_regions;
};
/**
* struct iwl_fw_mon - fw monitor per allocation id
* @num_frags: number of fragments
@ -1004,6 +1046,8 @@ struct iwl_trans_txqs {
* @hw_rev_step: The mac step of the HW
* @pm_support: set to true in start_hw if link pm is supported
* @ltr_enabled: set to true if the LTR is enabled
* @fail_to_parse_pnvm_image: set to true if pnvm parsing failed
* @failed_to_load_reduce_power_image: set to true if pnvm loading failed
* @wide_cmd_header: true when ucode supports wide command header format
* @wait_command_queue: wait queue for sync commands
* @num_rx_queues: number of RX queues allocated by the transport;
@ -1051,7 +1095,9 @@ struct iwl_trans {
bool pm_support;
bool ltr_enabled;
u8 pnvm_loaded:1;
u8 fail_to_parse_pnvm_image:1;
u8 reduce_power_loaded:1;
u8 failed_to_load_reduce_power_image:1;
const struct iwl_hcmd_arr *command_groups;
int command_groups_size;
@ -1160,7 +1206,7 @@ static inline int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
{
might_sleep();
if (!trans->ops->d3_suspend)
return 0;
return -EOPNOTSUPP;
return trans->ops->d3_suspend(trans, test, reset);
}
@ -1171,7 +1217,7 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
{
might_sleep();
if (!trans->ops->d3_resume)
return 0;
return -EOPNOTSUPP;
return trans->ops->d3_resume(trans, status, test, reset);
}
@ -1515,33 +1561,34 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
u32 sw_err_bit);
static inline int iwl_trans_set_pnvm(struct iwl_trans *trans,
const void *data, u32 len)
static inline int iwl_trans_load_pnvm(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_data,
const struct iwl_ucode_capabilities *capa)
{
if (trans->ops->set_pnvm) {
int ret = trans->ops->set_pnvm(trans, data, len);
if (ret)
return ret;
}
trans->pnvm_loaded = true;
return 0;
return trans->ops->load_pnvm(trans, pnvm_data, capa);
}
static inline int iwl_trans_set_reduce_power(struct iwl_trans *trans,
const void *data, u32 len)
static inline void iwl_trans_set_pnvm(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
if (trans->ops->set_reduce_power) {
int ret = trans->ops->set_reduce_power(trans, data, len);
if (trans->ops->set_pnvm)
trans->ops->set_pnvm(trans, capa);
}
if (ret)
return ret;
}
static inline int iwl_trans_load_reduce_power
(struct iwl_trans *trans,
const struct iwl_pnvm_image *payloads,
const struct iwl_ucode_capabilities *capa)
{
return trans->ops->load_reduce_power(trans, payloads, capa);
}
trans->reduce_power_loaded = true;
return 0;
static inline void
iwl_trans_set_reduce_power(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
if (trans->ops->set_reduce_power)
trans->ops->set_reduce_power(trans, capa);
}
static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)

View File

@ -1791,9 +1791,8 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
if (iwl_mei_is_connected()) {
if (mei->amt_enabled)
iwl_mei_send_sap_msg(mei->cldev,
SAP_MSG_NOTIF_WIFIDR_UP,
false);
ops->rfkill(priv, mei->link_prot_state);
SAP_MSG_NOTIF_WIFIDR_UP);
ops->rfkill(priv, mei->link_prot_state, false);
}
}
ret = 0;

View File

@ -433,7 +433,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
/* if reached this point, Alive notification was received */
iwl_mei_alive_notif(true);
ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait);
ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait,
&mvm->fw->ucode_capa);
if (ret) {
IWL_ERR(mvm, "Timeout waiting for PNVM load!\n");
iwl_fw_set_current_image(&mvm->fwrt, old_type);
@ -1104,7 +1105,26 @@ static const struct dmi_system_id dmi_tas_approved_list[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
},
},
{ .ident = "Acer",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
},
},
{ .ident = "ASUS",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
},
},
{ .ident = "MSI",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
},
},
{ .ident = "Honor",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
},
},
/* keep last */
{}
};
@ -1176,6 +1196,10 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
"Unable to add US/Canada to TAS block list, disabling TAS\n");
return;
}
} else {
IWL_DEBUG_RADIO(mvm,
"System vendor '%s' is in the approved list.\n",
dmi_get_system_info(DMI_SYS_VENDOR));
}
/* v4 is the same size as v3, so no need to differentiate here */
@ -1591,6 +1615,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);
}
for (i = 0; i < IWL_MVM_FW_MAX_LINK_ID + 1; i++)
RCU_INIT_POINTER(mvm->link_id_to_link_conf[i], NULL);
memset(&mvm->fw_link_ids_map, 0, sizeof(mvm->fw_link_ids_map));
mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
@ -1699,9 +1726,11 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
iwl_mvm_time_sync_config(mvm, mvm->time_sync.peer_addr,
IWL_TIME_SYNC_PROTOCOL_TM |
IWL_TIME_SYNC_PROTOCOL_FTM);
if (mvm->time_sync.active)
iwl_mvm_time_sync_config(mvm, mvm->time_sync.peer_addr,
IWL_TIME_SYNC_PROTOCOL_TM |
IWL_TIME_SYNC_PROTOCOL_FTM);
}
if (!mvm->ptp_data.ptp_clock)

View File

@ -63,6 +63,9 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvmvif);
if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)
return -EINVAL;
rcu_assign_pointer(mvm->link_id_to_link_conf[link_info->fw_link_id],
link_conf);
}
/* Update SF - Disable if needed. if this fails, SF might still be on
@ -73,6 +76,7 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
cmd.link_id = cpu_to_le32(link_info->fw_link_id);
cmd.mac_id = cpu_to_le32(mvmvif->id);
cmd.spec_link_id = link_conf->link_id;
/* P2P-Device already has a valid PHY context during add */
phyctxt = link_info->phy_ctxt;
if (phyctxt)
@ -262,6 +266,8 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID))
return -EINVAL;
RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id],
NULL);
cmd.link_id = cpu_to_le32(link_info->fw_link_id);
iwl_mvm_release_fw_link_id(mvm, link_info->fw_link_id);
link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;

View File

@ -629,17 +629,17 @@ __le32 iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(struct iwl_mvm *mvm,
IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
}
__le32 iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
u32 iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
__le32 twt_policy = cpu_to_le32(0);
u32 twt_policy = 0;
if (vif->bss_conf.twt_requester && IWL_MVM_USE_TWT)
twt_policy |= cpu_to_le32(TWT_SUPPORTED);
twt_policy |= TWT_SUPPORTED;
if (vif->bss_conf.twt_protected)
twt_policy |= cpu_to_le32(PROTECTED_TWT_SUPPORTED);
twt_policy |= PROTECTED_TWT_SUPPORTED;
if (vif->bss_conf.twt_broadcast)
twt_policy |= cpu_to_le32(BROADCAST_TWT_SUPPORTED);
twt_policy |= BROADCAST_TWT_SUPPORTED;
return twt_policy;
}
@ -711,7 +711,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax) {
cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
ctxt_sta->data_policy |=
iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif);
cpu_to_le32(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif));
}
@ -1555,21 +1555,38 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
u32 rx_missed_bcon, rx_missed_bcon_since_rx;
struct ieee80211_vif *vif;
u32 id = le32_to_cpu(mb->mac_id);
/* Id can be mac/link id depending on the notification version */
u32 id = le32_to_cpu(mb->link_id);
union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
u32 mac_type;
u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
MISSED_BEACONS_NOTIFICATION,
0);
rcu_read_lock();
/* before version four the ID in the notification refers to mac ID */
if (notif_ver < 4) {
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
} else {
struct ieee80211_bss_conf *bss_conf =
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, true);
if (!bss_conf)
goto out;
vif = bss_conf->vif;
}
IWL_DEBUG_INFO(mvm,
"missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
le32_to_cpu(mb->mac_id),
"missed bcn %s_id=%u, consecutive=%u (%u, %u, %u)\n",
notif_ver < 4 ? "mac" : "link",
id,
le32_to_cpu(mb->consec_missed_beacons),
le32_to_cpu(mb->consec_missed_beacons_since_last_rx),
le32_to_cpu(mb->num_recvd_beacons),
le32_to_cpu(mb->num_expected_beacons));
rcu_read_lock();
vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true);
if (!vif)
goto out;
@ -1730,20 +1747,44 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
struct ieee80211_vif *csa_vif, *vif;
struct iwl_mvm_vif *mvmvif;
u32 id_n_color, csa_id, mac_id;
id_n_color = le32_to_cpu(notif->id_and_color);
mac_id = id_n_color & FW_CTXT_ID_MSK;
if (WARN_ON_ONCE(mac_id >= NUM_MAC_INDEX_DRIVER))
return;
struct iwl_mvm_vif *mvmvif, *csa_mvmvif;
u32 id_n_color, csa_id;
/* save mac_id or link_id to use later to cancel csa if needed */
u32 id;
u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
CHANNEL_SWITCH_START_NOTIF, 0);
rcu_read_lock();
vif = rcu_dereference(mvm->vif_id_to_mac[mac_id]);
if (notif_ver < 3) {
struct iwl_channel_switch_start_notif_v1 *notif = (void *)pkt->data;
u32 mac_id;
id_n_color = le32_to_cpu(notif->id_and_color);
mac_id = id_n_color & FW_CTXT_ID_MSK;
vif = iwl_mvm_rcu_dereference_vif_id(mvm, mac_id, true);
if (!vif)
goto out_unlock;
id = mac_id;
} else {
struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
u32 link_id = le32_to_cpu(notif->link_id);
struct ieee80211_bss_conf *bss_conf =
iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_id, true);
if (!bss_conf)
goto out_unlock;
id = link_id;
vif = bss_conf->vif;
}
mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (notif_ver >= 3)
id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
switch (vif->type) {
case NL80211_IFTYPE_AP:
@ -1752,7 +1793,8 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
csa_vif != vif))
goto out_unlock;
csa_id = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
csa_mvmvif = iwl_mvm_vif_from_mac80211(csa_vif);
csa_id = FW_CMD_ID_AND_COLOR(csa_mvmvif->id, csa_mvmvif->color);
if (WARN(csa_id != id_n_color,
"channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
csa_id, id_n_color))
@ -1779,7 +1821,7 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
CHANNEL_SWITCH_ERROR_NOTIF,
0) && !vif->bss_conf.csa_active) {
IWL_DEBUG_INFO(mvm, "Channel Switch was canceled\n");
iwl_mvm_cancel_channel_switch(mvm, vif, mac_id);
iwl_mvm_cancel_channel_switch(mvm, vif, id);
break;
}
@ -1802,7 +1844,7 @@ void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_channel_switch_error_notif *notif = (void *)pkt->data;
struct ieee80211_vif *vif;
u32 id = le32_to_cpu(notif->mac_id);
u32 id = le32_to_cpu(notif->link_id);
u32 csa_err_mask = le32_to_cpu(notif->csa_err_mask);
rcu_read_lock();
@ -1812,7 +1854,7 @@ void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm,
return;
}
IWL_DEBUG_INFO(mvm, "FW reports CSA error: mac_id=%u, csa_err_mask=%u\n",
IWL_DEBUG_INFO(mvm, "FW reports CSA error: id=%u, csa_err_mask=%u\n",
id, csa_err_mask);
if (csa_err_mask & (CS_ERR_COUNT_ERROR |
CS_ERR_LONG_DELAY_AFTER_CS |

View File

@ -1478,21 +1478,37 @@ iwl_mvm_chandef_get_primary_80(struct cfg80211_chan_def *chandef)
return (control_start - data_start) / 80;
}
/*
* Returns true if addding the interface is done
* (either with success or failure)
*
* FIXME: remove this again and merge it in
*/
static bool iwl_mvm_mac_add_interface_common(struct iwl_mvm *mvm,
struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
int *ret)
static int iwl_mvm_alloc_bcast_mcast_sta(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
lockdep_assert_held(&mvm->mutex);
ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
if (ret) {
IWL_ERR(mvm, "Failed to allocate bcast sta\n");
return ret;
}
/* Only queue for this station is the mcast queue,
* which shouldn't be in TFD mask anyway
*/
return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.mcast_sta, 0,
vif->type,
IWL_STA_MULTICAST);
}
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
mutex_lock(&mvm->mutex);
mvmvif->mvm = mvm;
/* the first link always points to the default one */
@ -1510,12 +1526,18 @@ static bool iwl_mvm_mac_add_interface_common(struct iwl_mvm *mvm,
mvmvif->deflink.beacon_stats.num_beacons;
/* Allocate resources for the MAC context, and add it to the fw */
*ret = iwl_mvm_mac_ctxt_init(mvm, vif);
if (*ret)
return true;
ret = iwl_mvm_mac_ctxt_init(mvm, vif);
if (ret)
goto out;
rcu_assign_pointer(mvm->vif_id_to_mac[mvmvif->id], vif);
/* Currently not much to do for NAN */
if (vif->type == NL80211_IFTYPE_NAN) {
ret = 0;
goto out;
}
/*
* The AP binding flow can be done only after the beacon
* template is configured (which happens only in the mac80211
@ -1530,50 +1552,12 @@ static bool iwl_mvm_mac_add_interface_common(struct iwl_mvm *mvm,
if (vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_ADHOC) {
iwl_mvm_vif_dbgfs_register(mvm, vif);
return true;
ret = 0;
goto out;
}
mvmvif->features |= hw->netdev_features;
return false;
}
static int iwl_mvm_alloc_bcast_mcast_sta(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
lockdep_assert_held(&mvm->mutex);
ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
if (ret) {
IWL_ERR(mvm, "Failed to allocate bcast sta\n");
return ret;
}
/*
* Only queue for this station is the mcast queue,
* which shouldn't be in TFD mask anyway
*/
return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.mcast_sta, 0,
vif->type,
IWL_STA_MULTICAST);
}
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
mutex_lock(&mvm->mutex);
/* Common for MLD and non-MLD API */
if (iwl_mvm_mac_add_interface_common(mvm, hw, vif, &ret))
goto out;
ret = iwl_mvm_mac_ctxt_add(mvm, vif);
if (ret)
goto out_unlock;
@ -3054,7 +3038,7 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u64 changes)
{
struct iwl_mvm_bss_info_changed_ops callbacks = {
static const struct iwl_mvm_bss_info_changed_ops callbacks = {
.bss_info_changed_sta = iwl_mvm_bss_info_changed_station,
.bss_info_changed_ap_ibss = iwl_mvm_bss_info_changed_ap_ibss,
};
@ -3067,7 +3051,7 @@ void
iwl_mvm_bss_info_changed_common(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
struct iwl_mvm_bss_info_changed_ops *callbacks,
const struct iwl_mvm_bss_info_changed_ops *callbacks,
u64 changes)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@ -3564,7 +3548,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state)
{
struct iwl_mvm_sta_state_ops callbacks = {
static const struct iwl_mvm_sta_state_ops callbacks = {
.add_sta = iwl_mvm_add_sta,
.update_sta = iwl_mvm_update_sta,
.rm_sta = iwl_mvm_rm_sta,
@ -3669,7 +3653,7 @@ static int
iwl_mvm_sta_state_notexist_to_none(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct iwl_mvm_sta_state_ops *callbacks)
const struct iwl_mvm_sta_state_ops *callbacks)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_link_sta *link_sta;
@ -3713,7 +3697,7 @@ iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw,
struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct iwl_mvm_sta_state_ops *callbacks)
const struct iwl_mvm_sta_state_ops *callbacks)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
@ -3770,7 +3754,7 @@ static int
iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct iwl_mvm_sta_state_ops *callbacks)
const struct iwl_mvm_sta_state_ops *callbacks)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
@ -3805,11 +3789,10 @@ static int
iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct iwl_mvm_sta_state_ops *callbacks)
const struct iwl_mvm_sta_state_ops *callbacks)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
int ret;
lockdep_assert_held(&mvm->mutex);
@ -3828,10 +3811,7 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
mvmvif->authorized = 0;
/* disable beacon filtering */
ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
WARN_ON(ret &&
!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
&mvm->status));
iwl_mvm_disable_beacon_filter(mvm, vif, 0);
}
return 0;
@ -3843,7 +3823,7 @@ int iwl_mvm_mac_sta_state_common(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state,
struct iwl_mvm_sta_state_ops *callbacks)
const struct iwl_mvm_sta_state_ops *callbacks)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@ -4573,7 +4553,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
int duration,
enum ieee80211_roc_type type)
{
struct iwl_mvm_roc_ops ops = {
static const struct iwl_mvm_roc_ops ops = {
.add_aux_sta_for_hs20 = iwl_mvm_add_aux_sta_for_hs20,
.switch_phy_ctxt = iwl_mvm_roc_switch_binding,
};
@ -4585,7 +4565,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_channel *channel, int duration,
enum ieee80211_roc_type type,
struct iwl_mvm_roc_ops *ops)
const struct iwl_mvm_roc_ops *ops)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@ -5092,7 +5072,7 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
static int
iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm,
struct ieee80211_vif_chanctx_switch *vifs,
struct iwl_mvm_switch_vif_chanctx_ops *ops)
const struct iwl_mvm_switch_vif_chanctx_ops *ops)
{
int ret;
@ -5151,7 +5131,7 @@ out:
static int
iwl_mvm_switch_vif_chanctx_reassign(struct iwl_mvm *mvm,
struct ieee80211_vif_chanctx_switch *vifs,
struct iwl_mvm_switch_vif_chanctx_ops *ops)
const struct iwl_mvm_switch_vif_chanctx_ops *ops)
{
int ret;
@ -5194,7 +5174,7 @@ iwl_mvm_switch_vif_chanctx_common(struct ieee80211_hw *hw,
struct ieee80211_vif_chanctx_switch *vifs,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode,
struct iwl_mvm_switch_vif_chanctx_ops *ops)
const struct iwl_mvm_switch_vif_chanctx_ops *ops)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
@ -5223,7 +5203,7 @@ static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode)
{
struct iwl_mvm_switch_vif_chanctx_ops ops = {
static const struct iwl_mvm_switch_vif_chanctx_ops ops = {
.__assign_vif_chanctx = __iwl_mvm_assign_vif_chanctx,
.__unassign_vif_chanctx = __iwl_mvm_unassign_vif_chanctx,
};

View File

@ -51,10 +51,10 @@ static u32 iwl_mvm_get_sec_sta_mask(struct iwl_mvm *mvm,
return iwl_mvm_sta_fw_id_mask(mvm, sta, keyconf->link_id);
}
static u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 flags = 0;
@ -164,13 +164,9 @@ static int __iwl_mvm_sec_key_del(struct iwl_mvm *mvm, u32 sta_mask,
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, flags, sizeof(cmd), &cmd);
}
int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
int iwl_mvm_mld_send_key(struct iwl_mvm *mvm, u32 sta_mask, u32 key_flags,
struct ieee80211_key_conf *keyconf)
{
u32 sta_mask = iwl_mvm_get_sec_sta_mask(mvm, vif, sta, keyconf);
u32 key_flags = iwl_mvm_get_sec_flags(mvm, vif, sta, keyconf);
u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
struct iwl_sec_key_cmd cmd = {
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
@ -223,6 +219,17 @@ int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
return ret;
}
int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
{
u32 sta_mask = iwl_mvm_get_sec_sta_mask(mvm, vif, sta, keyconf);
u32 key_flags = iwl_mvm_get_sec_flags(mvm, vif, sta, keyconf);
return iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
}
static int _iwl_mvm_sec_key_del(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,

View File

@ -115,16 +115,16 @@ static int iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
if (vif->cfg.assoc && !force_assoc_off) {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
cmd.client.is_assoc = cpu_to_le32(1);
cmd.client.is_assoc = 1;
if (!mvmvif->authorized &&
fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO))
cmd.client.data_policy |=
cpu_to_le32(COEX_HIGH_PRIORITY_ENABLE);
cpu_to_le16(COEX_HIGH_PRIORITY_ENABLE);
} else {
cmd.client.is_assoc = cpu_to_le32(0);
cmd.client.is_assoc = 0;
/* Allow beacons to pass through as long as we are not
* associated, or we do not have dtim period information.
@ -132,14 +132,14 @@ static int iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON);
}
cmd.client.assoc_id = cpu_to_le32(vif->cfg.aid);
cmd.client.assoc_id = cpu_to_le16(vif->cfg.aid);
if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p)
cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ);
if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax)
cmd.client.data_policy |=
iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif);
cpu_to_le16(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif));
return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd);
}

View File

@ -492,7 +492,7 @@ static int iwl_mvm_mld_mac_sta_state(struct ieee80211_hw *hw,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state)
{
struct iwl_mvm_sta_state_ops callbacks = {
static const struct iwl_mvm_sta_state_ops callbacks = {
.add_sta = iwl_mvm_mld_add_sta,
.update_sta = iwl_mvm_mld_update_sta,
.rm_sta = iwl_mvm_mld_rm_sta,
@ -779,7 +779,7 @@ iwl_mvm_mld_switch_vif_chanctx(struct ieee80211_hw *hw,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode)
{
struct iwl_mvm_switch_vif_chanctx_ops ops = {
static const struct iwl_mvm_switch_vif_chanctx_ops ops = {
.__assign_vif_chanctx = __iwl_mvm_mld_assign_vif_chanctx,
.__unassign_vif_chanctx = __iwl_mvm_mld_unassign_vif_chanctx,
};
@ -871,7 +871,7 @@ static int iwl_mvm_mld_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_channel *channel, int duration,
enum ieee80211_roc_type type)
{
struct iwl_mvm_roc_ops ops = {
static const struct iwl_mvm_roc_ops ops = {
.add_aux_sta_for_hs20 = iwl_mvm_mld_add_aux_sta,
.switch_phy_ctxt = iwl_mvm_link_switch_phy_ctx,
};

View File

@ -71,6 +71,11 @@ static int iwl_mvm_mld_add_int_sta_to_fw(struct iwl_mvm *mvm,
cmd.station_type = cpu_to_le32(sta->type);
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT) &&
sta->type == STATION_TYPE_BCAST_MGMT)
cmd.mfp = cpu_to_le32(1);
if (addr) {
memcpy(cmd.peer_mld_address, addr, ETH_ALEN);
memcpy(cmd.peer_link_address, addr, ETH_ALEN);
@ -128,11 +133,11 @@ static int iwl_mvm_add_aux_sta_to_fw(struct iwl_mvm *mvm,
/*
* Adds an internal sta to the FW table with its queues
*/
static int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout)
int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout)
{
int ret, txq;
unsigned int wdg_timeout = _wdg_timeout ? *_wdg_timeout :
@ -442,6 +447,11 @@ static int iwl_mvm_mld_cfg_sta(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (mvm_sta->sta_state >= IEEE80211_STA_ASSOC)
cmd.assoc_id = cpu_to_le32(sta->aid);
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT) &&
(sta->mfp || mvm_sta->sta_state < IEEE80211_STA_AUTHORIZED))
cmd.mfp = cpu_to_le32(1);
switch (link_sta->rx_nss) {
case 1:
cmd.mimo = cpu_to_le32(0);

View File

@ -1003,6 +1003,8 @@ struct iwl_mvm {
struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER];
struct ieee80211_bss_conf __rcu *link_id_to_link_conf[IWL_MVM_FW_MAX_LINK_ID + 1];
/* -1 for always, 0 for never, >0 for that many times */
s8 fw_restart;
u8 *error_recovery_buf;
@ -1302,6 +1304,19 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu)
lockdep_is_held(&mvm->mutex));
}
static inline struct ieee80211_bss_conf *
iwl_mvm_rcu_fw_link_id_to_link_conf(struct iwl_mvm *mvm, u8 link_id, bool rcu)
{
if (WARN_ON(link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf)))
return NULL;
if (rcu)
return rcu_dereference(mvm->link_id_to_link_conf[link_id]);
return rcu_dereference_protected(mvm->link_id_to_link_conf[link_id],
lockdep_is_held(&mvm->mutex));
}
static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm)
{
return fw_has_api(&mvm->fw->ucode_capa,
@ -1774,8 +1789,8 @@ void iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(struct iwl_mvm *mvm,
int iwl_mvm_get_mac_type(struct ieee80211_vif *vif);
__le32 iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
__le32 iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
u32 iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
int iwl_mvm_mld_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_mld_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
bool force_assoc_off);
@ -1873,7 +1888,7 @@ void
iwl_mvm_bss_info_changed_common(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
struct iwl_mvm_bss_info_changed_ops *callbacks,
const struct iwl_mvm_bss_info_changed_ops *callbacks,
u64 changes);
void
iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
@ -1907,7 +1922,7 @@ struct iwl_mvm_roc_ops {
int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_channel *channel, int duration,
enum ieee80211_roc_type type,
struct iwl_mvm_roc_ops *ops);
const struct iwl_mvm_roc_ops *ops);
int iwl_mvm_cancel_roc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
/*Session Protection */
@ -2346,6 +2361,12 @@ int iwl_mvm_mld_update_sta_keys(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
u32 old_sta_mask,
u32 new_sta_mask);
int iwl_mvm_mld_send_key(struct iwl_mvm *mvm, u32 sta_mask, u32 key_flags,
struct ieee80211_key_conf *keyconf);
u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf);
bool iwl_rfi_supported(struct iwl_mvm *mvm);
int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm,
@ -2406,7 +2427,7 @@ iwl_mvm_switch_vif_chanctx_common(struct ieee80211_hw *hw,
struct ieee80211_vif_chanctx_switch *vifs,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode,
struct iwl_mvm_switch_vif_chanctx_ops *ops);
const struct iwl_mvm_switch_vif_chanctx_ops *ops);
/* Channel info utils */
static inline bool iwl_mvm_has_ultra_hb_channel(struct iwl_mvm *mvm)

View File

@ -198,6 +198,10 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
memcpy(common->arp_mac_addr, vif->addr, ETH_ALEN);
}
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_OFFLOAD_REJ_BTM_SUPPORT))
enabled |= IWL_D3_PROTO_REJECT_BTM;
if (!disable_offloading)
common->enabled = cpu_to_le32(enabled);

View File

@ -449,7 +449,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(ADD_STA_KEY),
HCMD_NAME(ADD_STA),
HCMD_NAME(REMOVE_STA),
HCMD_NAME(FW_GET_ITEM_CMD),
HCMD_NAME(TX_CMD),
HCMD_NAME(SCD_QUEUE_CFG),
HCMD_NAME(TXPATH_FLUSH),
@ -512,7 +511,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(REPLY_BEACON_FILTERING_CMD),
HCMD_NAME(D3_CONFIG_CMD),
HCMD_NAME(PROT_OFFLOAD_CONFIG_CMD),
HCMD_NAME(OFFLOADS_QUERY_CMD),
HCMD_NAME(MATCH_FOUND_NOTIFICATION),
HCMD_NAME(DTS_MEASUREMENT_NOTIFICATION),
HCMD_NAME(WOWLAN_PATTERNS),

View File

@ -1782,9 +1782,9 @@ static void iwl_mvm_decode_eht_phy_data(struct iwl_mvm *mvm,
eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT);
eht->data[8] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PS160,
IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160);
eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_B0,
eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B0,
IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0);
eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_B1_B7_ALLOC,
eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B1_B7,
IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1);
iwl_mvm_decode_eht_ru(mvm, rx_status, eht);

View File

@ -2070,13 +2070,6 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
cancel_delayed_work(&mvm->tdls_cs.dwork);
}
/*
* Make sure that the tx response code sees the station as -EBUSY and
* calls the drain worker.
*/
spin_lock_bh(&mvm_sta->lock);
spin_unlock_bh(&mvm_sta->lock);
return false;
}
@ -4306,16 +4299,27 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
u16 queue;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_key_conf *keyconf;
unsigned int wdg_timeout =
iwl_mvm_get_wd_timeout(mvm, vif, false, false);
bool mld = iwl_mvm_has_mld_api(mvm->fw);
u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
NL80211_IFTYPE_UNSPECIFIED,
IWL_STA_LINK);
NL80211_IFTYPE_UNSPECIFIED, type);
if (ret)
return ret;
ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color,
addr, sta, &queue,
IWL_MVM_TX_FIFO_BE);
if (mld)
ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, sta, addr,
mvmvif->deflink.fw_link_id,
&queue,
IWL_MAX_TID_COUNT,
&wdg_timeout);
else
ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id,
mvmvif->color, addr, sta,
&queue,
IWL_MVM_TX_FIFO_BE);
if (ret)
goto out;
@ -4328,9 +4332,23 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
keyconf->cipher = cipher;
memcpy(keyconf->key, key, key_len);
keyconf->keylen = key_len;
keyconf->flags = IEEE80211_KEY_FLAG_PAIRWISE;
if (mld) {
/* The MFP flag is set according to the station mfp field. Since
* we don't have a station, set it manually.
*/
u32 key_flags =
iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) |
IWL_SEC_KEY_FLAG_MFP;
u32 sta_mask = BIT(sta->sta_id);
ret = iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
} else {
ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
0, NULL, 0, 0, true);
}
ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
0, NULL, 0, 0, true);
kfree(keyconf);
return 0;
out:
@ -4340,10 +4358,10 @@ out:
void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 mac_id)
u32 id)
{
struct iwl_cancel_channel_switch_cmd cancel_channel_switch_cmd = {
.mac_id = cpu_to_le32(mac_id),
.id = cpu_to_le32(id),
};
int ret;

View File

@ -365,6 +365,7 @@ struct iwl_mvm_link_sta {
* and from Tx response flow, it needs a spinlock.
* @tid_data: per tid data + mgmt. Look at %iwl_mvm_tid_data.
* @tid_to_baid: a simple map of TID to baid
* @vif: a vif pointer
* @reserved_queue: the queue reserved for this STA for DQA purposes
* Every STA has is given one reserved queue to allow it to operate. If no
* such queue can be guaranteed, the STA addition will fail.
@ -378,6 +379,7 @@ struct iwl_mvm_link_sta {
* debugfs. If it's set to 0, it means that it is it's not set via
* debugfs.
* @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
* @sleeping: sta sleep transitions in power management
* @sleep_tx_count: the number of frames that we told the firmware to let out
* even when that station is asleep. This is useful in case the queue
* gets empty before all the frames were sent, which can happen when
@ -580,7 +582,7 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
u8 *key, u32 key_len);
void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 mac_id);
u32 id);
/* Queues */
int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
@ -616,7 +618,7 @@ int iwl_mvm_mac_sta_state_common(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state,
struct iwl_mvm_sta_state_ops *callbacks);
const struct iwl_mvm_sta_state_ops *callbacks);
/* New MLD STA related APIs */
/* STA */
@ -646,6 +648,11 @@ int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
u16 old_links, u16 new_links);
u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
int filter_link_id);
int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout);
/* Queues */
void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,

View File

@ -308,6 +308,54 @@ static u32 iwl_mvm_get_tx_ant(struct iwl_mvm *mvm,
return BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
}
static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info)
{
struct ieee80211_tx_rate *rate = &info->control.rates[0];
u32 result;
/*
* we only care about legacy/HT/VHT so far, so we can
* build in v1 and use iwl_new_rate_from_v1()
*/
if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
u8 mcs = ieee80211_rate_get_vht_mcs(rate);
u8 nss = ieee80211_rate_get_vht_nss(rate);
result = RATE_MCS_VHT_MSK_V1;
result |= u32_encode_bits(mcs, RATE_VHT_MCS_RATE_CODE_MSK);
result |= u32_encode_bits(nss, RATE_MCS_NSS_MSK);
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
result |= RATE_MCS_SGI_MSK_V1;
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1);
else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
result |= u32_encode_bits(2, RATE_MCS_CHAN_WIDTH_MSK_V1);
else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
result |= u32_encode_bits(3, RATE_MCS_CHAN_WIDTH_MSK_V1);
} else if (rate->flags & IEEE80211_TX_RC_MCS) {
result = RATE_MCS_HT_MSK_V1;
result |= u32_encode_bits(rate->idx,
RATE_HT_MCS_RATE_CODE_MSK_V1 |
RATE_HT_MCS_NSS_MSK_V1);
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
result |= RATE_MCS_SGI_MSK_V1;
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
result |= u32_encode_bits(1, RATE_MCS_CHAN_WIDTH_MSK_V1);
if (rate->flags & IEEE80211_TX_CTL_LDPC)
result |= RATE_MCS_LDPC_MSK_V1;
if (u32_get_bits(rate->flags, IEEE80211_TX_CTL_STBC))
result |= RATE_MCS_STBC_MSK;
} else {
return 0;
}
if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6)
return iwl_new_rate_from_v1(result);
return result;
}
static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta, __le16 fc)
@ -317,8 +365,15 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
u32 rate_flags = 0;
bool is_cck;
/* info->control is only relevant for non HW rate control */
if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
u32 result = iwl_mvm_get_inject_tx_rate(mvm, info);
if (result)
return result;
rate_idx = info->control.rates[0].idx;
} else if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
/* info->control is only relevant for non HW rate control */
/* HT rate doesn't make sense for a non data frame */
WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS &&
!ieee80211_is_data(fc),
@ -398,7 +453,8 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
* table is controlled by LINK_QUALITY commands
*/
if (ieee80211_is_data(fc) && sta) {
if (likely(ieee80211_is_data(fc) && sta &&
!(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT))) {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
if (mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED) {

View File

@ -413,16 +413,20 @@ static void iwl_mvm_diversity_iter(void *_data, u8 *mac,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_diversity_iter_data *data = _data;
int i;
int i, link_id;
if (mvmvif->deflink.phy_ctxt != data->ctxt)
return;
for_each_mvm_vif_valid_link(mvmvif, link_id) {
struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id];
for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_STATIC ||
mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_DYNAMIC) {
data->result = false;
break;
if (link_info->phy_ctxt != data->ctxt)
continue;
for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
if (link_info->smps_requests[i] == IEEE80211_SMPS_STATIC ||
link_info->smps_requests[i] == IEEE80211_SMPS_DYNAMIC) {
data->result = false;
break;
}
}
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2018-2022 Intel Corporation
* Copyright (C) 2018-2023 Intel Corporation
*/
#include "iwl-trans.h"
#include "iwl-fh.h"
@ -281,70 +281,273 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive)
trans_pcie->prph_info = NULL;
}
int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
const void *data, u32 len)
static int iwl_pcie_load_payloads_continuously(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_data,
struct iwl_dram_data *dram)
{
u32 len, len0, len1;
if (pnvm_data->n_chunks != UNFRAGMENTED_PNVM_PAYLOADS_NUMBER) {
IWL_DEBUG_FW(trans, "expected 2 payloads, got %d.\n",
pnvm_data->n_chunks);
return -EINVAL;
}
len0 = pnvm_data->chunks[0].len;
len1 = pnvm_data->chunks[1].len;
if (len1 > 0xFFFFFFFF - len0) {
IWL_DEBUG_FW(trans, "sizes of payloads overflow.\n");
return -EINVAL;
}
len = len0 + len1;
dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent(trans, len,
&dram->physical);
if (!dram->block) {
IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA.\n");
return -ENOMEM;
}
dram->size = len;
memcpy(dram->block, pnvm_data->chunks[0].data, len0);
memcpy((u8 *)dram->block + len0, pnvm_data->chunks[1].data, len1);
return 0;
}
static int iwl_pcie_load_payloads_segments
(struct iwl_trans *trans,
struct iwl_dram_regions *dram_regions,
const struct iwl_pnvm_image *pnvm_data)
{
struct iwl_dram_data *cur_payload_dram = &dram_regions->drams[0];
struct iwl_dram_data *desc_dram = &dram_regions->prph_scratch_mem_desc;
struct iwl_prph_scrath_mem_desc_addr_array *addresses;
const void *data;
u32 len;
int i;
/* allocate and init DRAM descriptors array */
len = sizeof(struct iwl_prph_scrath_mem_desc_addr_array);
desc_dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent
(trans,
len,
&desc_dram->physical);
if (!desc_dram->block) {
IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA.\n");
return -ENOMEM;
}
desc_dram->size = len;
memset(desc_dram->block, 0, len);
/* allocate DRAM region for each payload */
dram_regions->n_regions = 0;
for (i = 0; i < pnvm_data->n_chunks; i++) {
len = pnvm_data->chunks[i].len;
data = pnvm_data->chunks[i].data;
if (iwl_pcie_ctxt_info_alloc_dma(trans,
data,
len,
cur_payload_dram)) {
iwl_trans_pcie_free_pnvm_dram_regions(dram_regions,
trans->dev);
return -ENOMEM;
}
dram_regions->n_regions++;
cur_payload_dram++;
}
/* fill desc with the DRAM payloads addresses */
addresses = desc_dram->block;
for (i = 0; i < pnvm_data->n_chunks; i++) {
addresses->mem_descs[i] =
cpu_to_le64(dram_regions->drams[i].physical);
}
return 0;
}
int iwl_trans_pcie_ctx_info_gen3_load_pnvm(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_payloads,
const struct iwl_ucode_capabilities *capa)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
int ret;
struct iwl_dram_regions *dram_regions = &trans_pcie->pnvm_data;
int ret = 0;
/* only allocate the DRAM if not allocated yet */
if (trans->pnvm_loaded)
return 0;
if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
return -EBUSY;
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return 0;
/* only allocate the DRAM if not allocated yet */
if (!trans->pnvm_loaded) {
if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
return -EBUSY;
if (!pnvm_payloads->n_chunks) {
IWL_DEBUG_FW(trans, "no payloads\n");
return -EINVAL;
}
ret = iwl_pcie_ctxt_info_alloc_dma(trans, data, len,
&trans_pcie->pnvm_dram);
if (ret < 0) {
IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA %d.\n",
ret);
return ret;
/* save payloads in several DRAM sections */
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG)) {
ret = iwl_pcie_load_payloads_segments(trans,
dram_regions,
pnvm_payloads);
if (!ret)
trans->pnvm_loaded = true;
} else {
/* save only in one DRAM section */
ret = iwl_pcie_load_payloads_continuously
(trans,
pnvm_payloads,
&dram_regions->drams[0]);
if (!ret) {
dram_regions->n_regions = 1;
trans->pnvm_loaded = true;
}
}
return ret;
}
static inline size_t
iwl_dram_regions_size(const struct iwl_dram_regions *dram_regions)
{
size_t total_size = 0;
int i;
for (i = 0; i < dram_regions->n_regions; i++)
total_size += dram_regions->drams[i].size;
return total_size;
}
static void iwl_pcie_set_pnvm_segments(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
struct iwl_dram_regions *dram_regions = &trans_pcie->pnvm_data;
prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =
cpu_to_le64(trans_pcie->pnvm_dram.physical);
cpu_to_le64(dram_regions->prph_scratch_mem_desc.physical);
prph_sc_ctrl->pnvm_cfg.pnvm_size =
cpu_to_le32(trans_pcie->pnvm_dram.size);
return 0;
cpu_to_le32(iwl_dram_regions_size(dram_regions));
}
int iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
const void *data, u32 len)
static void iwl_pcie_set_continuous_pnvm(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
int ret;
prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =
cpu_to_le64(trans_pcie->pnvm_data.drams[0].physical);
prph_sc_ctrl->pnvm_cfg.pnvm_size =
cpu_to_le32(trans_pcie->pnvm_data.drams[0].size);
}
void iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return;
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG))
iwl_pcie_set_pnvm_segments(trans);
else
iwl_pcie_set_continuous_pnvm(trans);
}
int iwl_trans_pcie_ctx_info_gen3_load_reduce_power(struct iwl_trans *trans,
const struct iwl_pnvm_image *payloads,
const struct iwl_ucode_capabilities *capa)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
struct iwl_dram_regions *dram_regions = &trans_pcie->reduced_tables_data;
int ret = 0;
/* only allocate the DRAM if not allocated yet */
if (trans->reduce_power_loaded)
return 0;
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return 0;
/* only allocate the DRAM if not allocated yet */
if (!trans->reduce_power_loaded) {
if (WARN_ON(prph_sc_ctrl->reduce_power_cfg.size))
return -EBUSY;
if (WARN_ON(prph_sc_ctrl->reduce_power_cfg.size))
return -EBUSY;
ret = iwl_pcie_ctxt_info_alloc_dma(trans, data, len,
&trans_pcie->reduce_power_dram);
if (ret < 0) {
IWL_DEBUG_FW(trans,
"Failed to allocate reduce power DMA %d.\n",
ret);
return ret;
if (!payloads->n_chunks) {
IWL_DEBUG_FW(trans, "no payloads\n");
return -EINVAL;
}
/* save payloads in several DRAM sections */
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG)) {
ret = iwl_pcie_load_payloads_segments(trans,
dram_regions,
payloads);
if (!ret)
trans->reduce_power_loaded = true;
} else {
/* save only in one DRAM section */
ret = iwl_pcie_load_payloads_continuously
(trans,
payloads,
&dram_regions->drams[0]);
if (!ret) {
dram_regions->n_regions = 1;
trans->reduce_power_loaded = true;
}
}
prph_sc_ctrl->reduce_power_cfg.base_addr =
cpu_to_le64(trans_pcie->reduce_power_dram.physical);
prph_sc_ctrl->reduce_power_cfg.size =
cpu_to_le32(trans_pcie->reduce_power_dram.size);
return 0;
return ret;
}
static void iwl_pcie_set_reduce_power_segments(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
struct iwl_dram_regions *dram_regions = &trans_pcie->reduced_tables_data;
prph_sc_ctrl->reduce_power_cfg.base_addr =
cpu_to_le64(dram_regions->prph_scratch_mem_desc.physical);
prph_sc_ctrl->reduce_power_cfg.size =
cpu_to_le32(iwl_dram_regions_size(dram_regions));
}
static void iwl_pcie_set_continuous_reduce_power(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
&trans_pcie->prph_scratch->ctrl_cfg;
prph_sc_ctrl->reduce_power_cfg.base_addr =
cpu_to_le64(trans_pcie->reduced_tables_data.drams[0].physical);
prph_sc_ctrl->reduce_power_cfg.size =
cpu_to_le32(trans_pcie->reduced_tables_data.drams[0].size);
}
void
iwl_trans_pcie_ctx_info_gen3_set_reduce_power(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa)
{
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return;
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG))
iwl_pcie_set_reduce_power_segments(trans);
else
iwl_pcie_set_continuous_reduce_power(trans);
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*/
#include "iwl-trans.h"
#include "iwl-fh.h"
@ -38,9 +38,9 @@ static void *_iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
return result;
}
static void *iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
size_t size,
dma_addr_t *phys)
void *iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
size_t size,
dma_addr_t *phys)
{
return _iwl_pcie_ctxt_info_dma_alloc_coherent(trans, size, phys, 0);
}

View File

@ -23,6 +23,7 @@
#include "iwl-op-mode.h"
#include "iwl-drv.h"
#include "queue/tx.h"
#include "iwl-context-info.h"
/*
* RX related structures and functions
@ -306,7 +307,9 @@ enum iwl_pcie_imr_status {
* @trans: pointer to the generic transport area
* @scd_base_addr: scheduler sram base address in SRAM
* @kw: keep warm address
* @pnvm_dram: DRAM area that contains the PNVM data
* @pnvm_data: holds info about pnvm payloads allocated in DRAM
* @reduced_tables_data: holds info about power reduced tablse
* payloads allocated in DRAM
* @pci_dev: basic pci-network driver stuff
* @hw_base: pci hardware address support
* @ucode_write_complete: indicates that the ucode has been copied.
@ -380,8 +383,9 @@ struct iwl_trans_pcie {
u32 scd_base_addr;
struct iwl_dma_ptr kw;
struct iwl_dram_data pnvm_dram;
struct iwl_dram_data reduce_power_dram;
/* pnvm data */
struct iwl_dram_regions pnvm_data;
struct iwl_dram_regions reduced_tables_data;
struct iwl_txq *txq_memory;
@ -478,6 +482,8 @@ struct iwl_trans
const struct pci_device_id *ent,
const struct iwl_cfg_trans_params *cfg_trans);
void iwl_trans_pcie_free(struct iwl_trans *trans);
void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions,
struct device *dev);
bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
#define _iwl_trans_pcie_grab_nic_access(trans) \

View File

@ -131,13 +131,15 @@ static int iwl_trans_pcie_sw_reset(struct iwl_trans *trans,
bool retake_ownership)
{
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
iwl_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_SW_RESET);
else
usleep_range(10000, 20000);
} else {
iwl_set_bit(trans, CSR_RESET,
CSR_RESET_REG_FLAG_SW_RESET);
usleep_range(5000, 6000);
usleep_range(5000, 6000);
}
if (retake_ownership)
return iwl_pcie_prepare_card_hw(trans);
@ -475,7 +477,7 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
100);
msleep(100);
usleep_range(10000, 20000);
} else {
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
@ -1993,6 +1995,29 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
trans_pcie->fw_reset_handshake = trans_cfg->fw_reset_handshake;
}
void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions,
struct device *dev)
{
u8 i;
struct iwl_dram_data *desc_dram = &dram_regions->prph_scratch_mem_desc;
/* free DRAM payloads */
for (i = 0; i < dram_regions->n_regions; i++) {
dma_free_coherent(dev, dram_regions->drams[i].size,
dram_regions->drams[i].block,
dram_regions->drams[i].physical);
}
dram_regions->n_regions = 0;
/* free DRAM addresses array */
if (desc_dram->block) {
dma_free_coherent(dev, desc_dram->size,
desc_dram->block,
desc_dram->physical);
}
memset(desc_dram, 0, sizeof(*desc_dram));
}
void iwl_trans_pcie_free(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@ -2025,16 +2050,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
iwl_pcie_free_fw_monitor(trans);
if (trans_pcie->pnvm_dram.size)
dma_free_coherent(trans->dev, trans_pcie->pnvm_dram.size,
trans_pcie->pnvm_dram.block,
trans_pcie->pnvm_dram.physical);
if (trans_pcie->reduce_power_dram.size)
dma_free_coherent(trans->dev,
trans_pcie->reduce_power_dram.size,
trans_pcie->reduce_power_dram.block,
trans_pcie->reduce_power_dram.physical);
iwl_trans_pcie_free_pnvm_dram_regions(&trans_pcie->pnvm_data,
trans->dev);
iwl_trans_pcie_free_pnvm_dram_regions(&trans_pcie->reduced_tables_data,
trans->dev);
mutex_destroy(&trans_pcie->mutex);
iwl_trans_free(trans);
@ -3534,7 +3553,9 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
.txq_free = iwl_txq_dyn_free,
.wait_txq_empty = iwl_trans_pcie_wait_txq_empty,
.rxq_dma_data = iwl_trans_pcie_rxq_dma_data,
.load_pnvm = iwl_trans_pcie_ctx_info_gen3_load_pnvm,
.set_pnvm = iwl_trans_pcie_ctx_info_gen3_set_pnvm,
.load_reduce_power = iwl_trans_pcie_ctx_info_gen3_load_reduce_power,
.set_reduce_power = iwl_trans_pcie_ctx_info_gen3_set_reduce_power,
#ifdef CONFIG_IWLWIFI_DEBUGFS
.debugfs_cleanup = iwl_trans_pcie_debugfs_cleanup,

View File

@ -56,7 +56,7 @@ config HOSTAP_FIRMWARE_NVRAM
config HOSTAP_PLX
tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
depends on PCI && HOSTAP
depends on PCI && HOSTAP && HAS_IOPORT
help
Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
PCI adaptors.

View File

@ -96,6 +96,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
{
struct orinoco_private *priv;
struct orinoco_pccard *card;
int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev,
orinoco_cs_hard_reset, NULL);
@ -107,8 +108,16 @@ orinoco_cs_probe(struct pcmcia_device *link)
card->p_dev = link;
link->priv = priv;
return orinoco_cs_config(link);
} /* orinoco_cs_attach */
ret = orinoco_cs_config(link);
if (ret)
goto err_free_orinocodev;
return 0;
err_free_orinocodev:
free_orinocodev(priv);
return ret;
}
static void orinoco_cs_detach(struct pcmcia_device *link)
{

View File

@ -157,6 +157,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
{
struct orinoco_private *priv;
struct orinoco_pccard *card;
int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev,
spectrum_cs_hard_reset,
@ -169,8 +170,16 @@ spectrum_cs_probe(struct pcmcia_device *link)
card->p_dev = link;
link->priv = priv;
return spectrum_cs_config(link);
} /* spectrum_cs_attach */
ret = spectrum_cs_config(link);
if (ret)
goto err_free_orinocodev;
return 0;
err_free_orinocodev:
free_orinocodev(priv);
return ret;
}
static void spectrum_cs_detach(struct pcmcia_device *link)
{

View File

@ -270,13 +270,14 @@ static int ray_probe(struct pcmcia_device *p_dev)
{
ray_dev_t *local;
struct net_device *dev;
int ret;
dev_dbg(&p_dev->dev, "ray_attach()\n");
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
if (!dev)
goto fail_alloc_dev;
return -ENOMEM;
local = netdev_priv(dev);
local->finder = p_dev;
@ -313,16 +314,20 @@ static int ray_probe(struct pcmcia_device *p_dev)
timer_setup(&local->timer, NULL, 0);
this_device = p_dev;
return ray_config(p_dev);
ret = ray_config(p_dev);
if (ret)
goto err_free_dev;
fail_alloc_dev:
return -ENOMEM;
} /* ray_attach */
return 0;
err_free_dev:
free_netdev(dev);
return ret;
}
static void ray_detach(struct pcmcia_device *link)
{
struct net_device *dev;
ray_dev_t *local;
dev_dbg(&link->dev, "ray_detach\n");
@ -331,9 +336,6 @@ static void ray_detach(struct pcmcia_device *link)
ray_release(link);
local = netdev_priv(dev);
del_timer_sync(&local->timer);
if (link->priv) {
unregister_netdev(dev);
free_netdev(dev);
@ -734,11 +736,14 @@ static void ray_release(struct pcmcia_device *link)
dev_dbg(&link->dev, "ray_release\n");
del_timer(&local->timer);
del_timer_sync(&local->timer);
iounmap(local->sram);
iounmap(local->rmem);
iounmap(local->amem);
if (local->sram)
iounmap(local->sram);
if (local->rmem)
iounmap(local->rmem);
if (local->amem)
iounmap(local->amem);
pcmcia_disable_device(link);
dev_dbg(&link->dev, "ray_release ending\n");

View File

@ -1862,6 +1862,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
{
struct net_device *dev;
struct wl3501_card *this;
int ret;
/* The io structure describes IO port mapping */
p_dev->resource[0]->end = 16;
@ -1873,8 +1874,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
dev = alloc_etherdev(sizeof(struct wl3501_card));
if (!dev)
goto out_link;
return -ENOMEM;
dev->netdev_ops = &wl3501_netdev_ops;
dev->watchdog_timeo = 5 * HZ;
@ -1887,9 +1887,15 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
netif_stop_queue(dev);
p_dev->priv = dev;
return wl3501_config(p_dev);
out_link:
return -ENOMEM;
ret = wl3501_config(p_dev);
if (ret)
goto out_free_etherdev;
return 0;
out_free_etherdev:
free_netdev(dev);
return ret;
}
static int wl3501_config(struct pcmcia_device *link)

View File

@ -11,7 +11,8 @@ config RTL8XXXU
parts written to utilize the Linux mac80211 stack.
The driver is known to work with a number of RTL8723AU,
RL8188CU, RTL8188RU, RTL8191CU, RTL8192CU, RTL8723BU, RTL8192EU,
RTL8188FU, RTL8188EU, and RTL8710BU (aka RTL8188GU) devices.
RTL8188FU, RTL8188EU, RTL8710BU (aka RTL8188GU), and RTL8192FU
devices.
This driver is under development and has a limited feature
set. In particular it does not yet support 40MHz channels

View File

@ -3,4 +3,4 @@ obj-$(CONFIG_RTL8XXXU) += rtl8xxxu.o
rtl8xxxu-y := rtl8xxxu_core.o rtl8xxxu_8192e.o rtl8xxxu_8723b.o \
rtl8xxxu_8723a.o rtl8xxxu_8192c.o rtl8xxxu_8188f.o \
rtl8xxxu_8188e.o rtl8xxxu_8710b.o
rtl8xxxu_8188e.o rtl8xxxu_8710b.o rtl8xxxu_8192f.o

View File

@ -39,6 +39,7 @@
#define TX_TOTAL_PAGE_NUM_8188E 0xa9
#define TX_TOTAL_PAGE_NUM_8192E 0xf3
#define TX_TOTAL_PAGE_NUM_8723B 0xf7
#define TX_TOTAL_PAGE_NUM_8192F 0xf7
/* (HPQ + LPQ + NPQ + PUBQ) = TX_TOTAL_PAGE_NUM */
#define TX_PAGE_NUM_PUBQ 0xe7
#define TX_PAGE_NUM_HI_PQ 0x0c
@ -65,6 +66,11 @@
#define TX_PAGE_NUM_LO_PQ_8723B 0x02
#define TX_PAGE_NUM_NORM_PQ_8723B 0x02
#define TX_PAGE_NUM_PUBQ_8192F 0xde
#define TX_PAGE_NUM_HI_PQ_8192F 0x08
#define TX_PAGE_NUM_LO_PQ_8192F 0x08
#define TX_PAGE_NUM_NORM_PQ_8192F 0x08
#define RTL_FW_PAGE_SIZE 4096
#define RTL8XXXU_FIRMWARE_POLL_MAX 1000
@ -81,6 +87,7 @@
#define EFUSE_REAL_CONTENT_LEN_8723A 512
#define EFUSE_BT_MAP_LEN_8723A 1024
#define EFUSE_MAX_WORD_UNIT 4
#define EFUSE_UNDEFINED 0xff
enum rtl8xxxu_rtl_chip {
RTL8192S = 0x81920,
@ -105,6 +112,7 @@ enum rtl8xxxu_rtl_chip {
RTL8195A = 0x8195a,
RTL8188F = 0x8188f,
RTL8710B = 0x8710b,
RTL8192F = 0x8192f,
};
enum rtl8xxxu_rx_type {
@ -1246,6 +1254,40 @@ struct rtl8710bu_efuse {
u8 res7[0x3c];
} __packed;
struct rtl8192fu_efuse {
__le16 rtl_id;
u8 res0[0x0e];
struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */
struct rtl8192eu_efuse_tx_power tx_power_index_B; /* 0x3a */
u8 res2[0x54];
u8 channel_plan; /* 0xb8 */
u8 xtal_k; /* 0xb9 */
u8 thermal_meter; /* 0xba */
u8 iqk_lck; /* 0xbb */
u8 pa_type; /* 0xbc */
u8 lna_type_2g; /* 0xbd */
u8 res3[1];
u8 lna_type_5g; /* 0xbf */
u8 res4[1];
u8 rf_board_option; /* 0xc1 */
u8 rf_feature_option; /* 0xc2 */
u8 rf_bt_setting; /* 0xc3 */
u8 eeprom_version; /* 0xc4 */
u8 eeprom_customer_id; /* 0xc5 */
u8 res5[3];
u8 rf_antenna_option; /* 0xc9 */
u8 rfe_option; /* 0xca */
u8 country_code; /* 0xcb */
u8 res6[52];
u8 vid[2]; /* 0x100 */
u8 pid[2]; /* 0x102 */
u8 usb_optional_function; /* 0x104 */
u8 res7[2];
u8 mac_addr[ETH_ALEN]; /* 0x107 */
u8 device_info[80]; /* 0x10d */
u8 res9[163];
} __packed;
struct rtl8xxxu_reg8val {
u16 reg;
u8 val;
@ -1796,6 +1838,7 @@ struct rtl8xxxu_priv {
u32 cck_agc_report_type:1;
u32 cck_new_agc:1;
u8 default_crystal_cap;
u8 rfe_type;
unsigned int pipe_interrupt;
unsigned int pipe_in;
unsigned int pipe_out[TXDESC_QUEUE_MAX];
@ -1836,6 +1879,7 @@ struct rtl8xxxu_priv {
struct rtl8188fu_efuse efuse8188fu;
struct rtl8188eu_efuse efuse8188eu;
struct rtl8710bu_efuse efuse8710bu;
struct rtl8192fu_efuse efuse8192fu;
} efuse_wifi;
u32 adda_backup[RTL8XXXU_ADDA_REGS];
u32 mac_backup[RTL8XXXU_MAC_REGS];
@ -1944,6 +1988,7 @@ struct rtl8xxxu_fileops {
u8 init_reg_hmtfr:1;
u8 ampdu_max_time;
u8 ustime_tsf_edca;
u16 max_aggr_num;
u8 supports_ap:1;
u16 max_macid_num;
u32 adda_1t_init;
@ -2032,6 +2077,7 @@ void rtl8xxxu_gen1_phy_iq_calibrate(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_init_phy_bb(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen1_set_tx_power(struct rtl8xxxu_priv *priv,
int channel, bool ht40);
void rtl8188f_channel_to_group(int channel, int *group, int *cck_group);
void rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv,
int channel, bool ht40);
void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw);
@ -2096,6 +2142,7 @@ void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt,
void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra);
void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
extern struct rtl8xxxu_fileops rtl8192fu_fops;
extern struct rtl8xxxu_fileops rtl8710bu_fops;
extern struct rtl8xxxu_fileops rtl8188fu_fops;
extern struct rtl8xxxu_fileops rtl8188eu_fops;

View File

@ -351,7 +351,7 @@ out:
return ret;
}
static void rtl8188f_channel_to_group(int channel, int *group, int *cck_group)
void rtl8188f_channel_to_group(int channel, int *group, int *cck_group)
{
if (channel < 3)
*group = 0;
@ -654,7 +654,7 @@ static void rtl8188fu_config_channel(struct ieee80211_hw *hw)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_BB2, val32);
/* RC Corner */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x00140);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00140);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_G2, 0x01c6c);
}
@ -854,8 +854,8 @@ static int rtl8188fu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7);
/* PA,PAD gain adjust */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x5102a);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a);
/* enter IQK mode */
val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
@ -886,7 +886,7 @@ static int rtl8188fu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result)
val32 &= 0x000000ff;
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
/* save LOK result */
*lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC);
@ -927,8 +927,8 @@ static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173);
/* PA,PAD gain adjust */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x5102a);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a);
/*
* Enter IQK mode
@ -967,7 +967,7 @@ static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
val32 &= 0x000000ff;
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
/* Check failed */
reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
@ -1002,8 +1002,8 @@ static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
/*
* PA, PAD setting
*/
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x51000);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x51000);
/*
* Enter IQK mode
@ -1041,7 +1041,7 @@ static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
val32 &= 0x000000ff;
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
/* reload LOK value */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result);
@ -1748,6 +1748,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops = {
.init_reg_hmtfr = 1,
.ampdu_max_time = 0x70,
.ustime_tsf_edca = 0x28,
.max_aggr_num = 0x0c14,
.supports_ap = 1,
.max_macid_num = 16,
.adda_1t_init = 0x03c00014,

View File

@ -716,7 +716,7 @@ static int rtl8192eu_iqk_path_a(struct rtl8xxxu_priv *priv)
* PA/PAD controlled by 0x0
*/
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x00180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, 0x800a0);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000);
@ -776,8 +776,8 @@ static int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf1173);
/* PA/PAD control by 0x56, and set = 0x0 */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x511e0);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x511e0);
/* Enter IQK mode */
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
@ -816,7 +816,7 @@ static int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
} else {
/* PA/PAD controlled by 0x0 */
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
goto out;
}
@ -838,8 +838,8 @@ static int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_TXPA_G2, 0xf7ff2);
/* PA/PAD control by 0x56, and set = 0x0 */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, 0x510e0);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x510e0);
/* Enter IQK mode */
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
@ -869,7 +869,7 @@ static int rtl8192eu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
if (!(reg_eac & BIT(27)) &&
((reg_ea4 & 0x03ff0000) != 0x01320000) &&
@ -889,7 +889,7 @@ static int rtl8192eu_iqk_path_b(struct rtl8xxxu_priv *priv)
int result = 0;
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x00180);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00180);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_WE_LUT, 0x800a0);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_RCK_OS, 0x20000);
@ -952,8 +952,8 @@ static int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173);
/* PA/PAD control by 0x56, and set = 0x0 */
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_56, 0x511e0);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x511e0);
/* Enter IQK mode */
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
@ -995,7 +995,7 @@ static int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv)
* Vendor driver restores RF_A here which I believe is a bug
*/
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180);
goto out;
}
@ -1017,8 +1017,8 @@ static int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2);
/* PA/PAD control by 0x56, and set = 0x0 */
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_56, 0x510e0);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x00980);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_PAD_TXG, 0x510e0);
/* Enter IQK mode */
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x80800000);
@ -1049,7 +1049,7 @@ static int rtl8192eu_rx_iqk_path_b(struct rtl8xxxu_priv *priv)
reg_ecc = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_B_2);
rtl8xxxu_write32(priv, REG_FPGA0_IQK, 0x00000000);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_UNKNOWN_DF, 0x180);
rtl8xxxu_write_rfreg(priv, RF_B, RF6052_REG_GAIN_CCA, 0x180);
if (!(reg_eac & BIT(30)) &&
((reg_ec4 & 0x03ff0000) != 0x01320000) &&

File diff suppressed because it is too large Load Diff

View File

@ -1031,12 +1031,12 @@ static int rtl8710bu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7);
/* PA,PAD gain adjust */
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 |= BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG);
u32p_replace_bits(&val32, 0x1ed, 0x00fff);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32);
/* enter IQK mode */
val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
@ -1068,9 +1068,9 @@ static int rtl8710bu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result)
u32p_replace_bits(&val32, 0, 0xffffff00);
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 &= ~BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
/* save LOK result */
*lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC);
@ -1113,12 +1113,12 @@ static int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173);
/* PA,PAD gain adjust */
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 |= BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG);
u32p_replace_bits(&val32, 0xf, 0x003e0);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32);
/*
* Enter IQK mode
@ -1170,9 +1170,9 @@ static int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
u32p_replace_bits(&val32, 0, 0xffffff00);
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 &= ~BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
return result;
}
@ -1197,12 +1197,12 @@ static int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
/*
* PA, PAD setting
*/
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 |= BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_PAD_TXG);
u32p_replace_bits(&val32, 0x2a, 0x00fff);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_56, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, val32);
/*
* Enter IQK mode
@ -1241,9 +1241,9 @@ static int rtl8710bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
u32p_replace_bits(&val32, 0, 0xffffff00);
rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF);
val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA);
val32 &= ~BIT(11);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, val32);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, val32);
/* reload LOK value */
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result);
@ -1874,6 +1874,7 @@ struct rtl8xxxu_fileops rtl8710bu_fops = {
* but in rtl8xxxu 0x50 causes slow upload and random packet loss. Why?
*/
.ustime_tsf_edca = 0x28,
.max_aggr_num = 0x0c14,
.adda_1t_init = 0x03c00016,
.adda_1t_path_on = 0x03c00016,
.trxff_boundary = 0x3f7f,

View File

@ -824,7 +824,7 @@ static int rtl8723bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
/*
* PA, PAD setting
*/
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0xf80);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0xf80);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55, 0x4021f);
/*
@ -888,7 +888,7 @@ static int rtl8723bu_rx_iqk_path_a(struct rtl8xxxu_priv *priv)
reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_DF, 0x780);
rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x780);
val32 = (reg_eac >> 16) & 0x3ff;
if (val32 & 0x200)
@ -1741,6 +1741,7 @@ struct rtl8xxxu_fileops rtl8723bu_fops = {
.init_reg_hmtfr = 1,
.ampdu_max_time = 0x5e,
.ustime_tsf_edca = 0x50,
.max_aggr_num = 0x0c14,
.adda_1t_init = 0x01c00014,
.adda_1t_path_on = 0x01c00014,
.adda_2t_path_on_a = 0x01c00014,

View File

@ -56,6 +56,7 @@ MODULE_FIRMWARE("rtlwifi/rtl8723bu_bt.bin");
MODULE_FIRMWARE("rtlwifi/rtl8188fufw.bin");
MODULE_FIRMWARE("rtlwifi/rtl8710bufw_SMIC.bin");
MODULE_FIRMWARE("rtlwifi/rtl8710bufw_UMC.bin");
MODULE_FIRMWARE("rtlwifi/rtl8192fufw.bin");
module_param_named(debug, rtl8xxxu_debug, int, 0600);
MODULE_PARM_DESC(debug, "Set debug mask");
@ -642,7 +643,7 @@ const u32 rtl8xxxu_iqk_phy_iq_bb_reg[RTL8XXXU_BB_REGS] = {
REG_OFDM0_XA_RX_IQ_IMBALANCE,
REG_OFDM0_XB_RX_IQ_IMBALANCE,
REG_OFDM0_ENERGY_CCA_THRES,
REG_OFDM0_AGCR_SSI_TABLE,
REG_OFDM0_AGC_RSSI_TABLE,
REG_OFDM0_XA_TX_IQ_IMBALANCE,
REG_OFDM0_XB_TX_IQ_IMBALANCE,
REG_OFDM0_XC_TX_AFE,
@ -2020,12 +2021,18 @@ exit:
static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
{
int pages, remainder, i, ret;
u16 reg_fw_start_address;
u16 reg_mcu_fw_dl;
u8 val8;
u16 val16;
u32 val32;
u8 *fwptr;
if (priv->rtl_chip == RTL8192F)
reg_fw_start_address = REG_FW_START_ADDRESS_8192F;
else
reg_fw_start_address = REG_FW_START_ADDRESS;
if (priv->rtl_chip == RTL8710B) {
reg_mcu_fw_dl = REG_8051FW_CTRL_V1_8710B;
} else {
@ -2081,7 +2088,7 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
val8 |= i;
rtl8xxxu_write8(priv, reg_mcu_fw_dl + 2, val8);
ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
ret = rtl8xxxu_writeN(priv, reg_fw_start_address,
fwptr, RTL_FW_PAGE_SIZE);
if (ret != RTL_FW_PAGE_SIZE) {
ret = -EAGAIN;
@ -2095,7 +2102,7 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
val8 = rtl8xxxu_read8(priv, reg_mcu_fw_dl + 2) & 0xF8;
val8 |= i;
rtl8xxxu_write8(priv, reg_mcu_fw_dl + 2, val8);
ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
ret = rtl8xxxu_writeN(priv, reg_fw_start_address,
fwptr, remainder);
if (ret != remainder) {
ret = -EAGAIN;
@ -2149,6 +2156,7 @@ int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name)
case 0x2300:
case 0x88f0:
case 0x10b0:
case 0x92f0:
break;
default:
ret = -EINVAL;
@ -2595,6 +2603,7 @@ static int rtl8xxxu_init_queue_priority(struct rtl8xxxu_priv *priv)
u16 hiq, mgq, bkq, beq, viq, voq;
int hip, mgp, bkp, bep, vip, vop;
int ret = 0;
u32 val32;
switch (priv->ep_tx_count) {
case 1:
@ -2677,15 +2686,28 @@ static int rtl8xxxu_init_queue_priority(struct rtl8xxxu_priv *priv)
* queue here .... why?
*/
if (!ret) {
val16 = rtl8xxxu_read16(priv, REG_TRXDMA_CTRL);
val16 &= 0x7;
val16 |= (voq << TRXDMA_CTRL_VOQ_SHIFT) |
(viq << TRXDMA_CTRL_VIQ_SHIFT) |
(beq << TRXDMA_CTRL_BEQ_SHIFT) |
(bkq << TRXDMA_CTRL_BKQ_SHIFT) |
(mgq << TRXDMA_CTRL_MGQ_SHIFT) |
(hiq << TRXDMA_CTRL_HIQ_SHIFT);
rtl8xxxu_write16(priv, REG_TRXDMA_CTRL, val16);
/* Only RTL8192F seems to do it like this. */
if (priv->rtl_chip == RTL8192F) {
val32 = rtl8xxxu_read32(priv, REG_TRXDMA_CTRL);
val32 &= 0x7;
val32 |= (voq << TRXDMA_CTRL_VOQ_SHIFT_8192F) |
(viq << TRXDMA_CTRL_VIQ_SHIFT_8192F) |
(beq << TRXDMA_CTRL_BEQ_SHIFT_8192F) |
(bkq << TRXDMA_CTRL_BKQ_SHIFT_8192F) |
(mgq << TRXDMA_CTRL_MGQ_SHIFT_8192F) |
(hiq << TRXDMA_CTRL_HIQ_SHIFT_8192F);
rtl8xxxu_write32(priv, REG_TRXDMA_CTRL, val32);
} else {
val16 = rtl8xxxu_read16(priv, REG_TRXDMA_CTRL);
val16 &= 0x7;
val16 |= (voq << TRXDMA_CTRL_VOQ_SHIFT) |
(viq << TRXDMA_CTRL_VIQ_SHIFT) |
(beq << TRXDMA_CTRL_BEQ_SHIFT) |
(bkq << TRXDMA_CTRL_BKQ_SHIFT) |
(mgq << TRXDMA_CTRL_MGQ_SHIFT) |
(hiq << TRXDMA_CTRL_HIQ_SHIFT);
rtl8xxxu_write16(priv, REG_TRXDMA_CTRL, val16);
}
priv->pipe_out[TXDESC_QUEUE_VO] =
usb_sndbulkpipe(priv->udev, priv->out_ep[vop]);
@ -2856,10 +2878,14 @@ void rtl8xxxu_fill_iqk_matrix_b(struct rtl8xxxu_priv *priv, bool iqk_ok,
reg = (result[candidate][7] >> 6) & 0xf;
val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGCR_SSI_TABLE);
val32 &= ~0x0000f000;
val32 |= (reg << 12);
rtl8xxxu_write32(priv, REG_OFDM0_AGCR_SSI_TABLE, val32);
if (priv->rtl_chip == RTL8192F) {
rtl8xxxu_write32_mask(priv, REG_RXIQB_EXT, 0x000000f0, reg);
} else {
val32 = rtl8xxxu_read32(priv, REG_OFDM0_AGC_RSSI_TABLE);
val32 &= ~0x0000f000;
val32 |= (reg << 12);
rtl8xxxu_write32(priv, REG_OFDM0_AGC_RSSI_TABLE, val32);
}
}
#define MAX_TOLERANCE 5
@ -3958,13 +3984,14 @@ void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv)
val8 |= HT_SINGLE_AMPDU_ENABLE;
rtl8xxxu_write8(priv, REG_HT_SINGLE_AMPDU_8723B, val8);
rtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, 0x0c14);
rtl8xxxu_write16(priv, REG_MAX_AGGR_NUM, priv->fops->max_aggr_num);
rtl8xxxu_write8(priv, REG_AMPDU_MAX_TIME_8723B,
priv->fops->ampdu_max_time);
rtl8xxxu_write32(priv, REG_AGGLEN_LMT, 0xffffffff);
rtl8xxxu_write8(priv, REG_RX_PKT_LIMIT, 0x18);
rtl8xxxu_write8(priv, REG_PIFS, 0x00);
if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8710B) {
if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8710B ||
priv->rtl_chip == RTL8192F) {
rtl8xxxu_write8(priv, REG_FWHW_TXQ_CTRL, FWHW_TXQ_CTRL_AMPDU_RETRY);
rtl8xxxu_write32(priv, REG_FAST_EDCA_CTRL, 0x03086666);
}
@ -4078,9 +4105,14 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
if (ret)
goto exit;
/* Mac APLL Setting */
if (priv->rtl_chip == RTL8192F)
rtl8xxxu_write16_set(priv, REG_AFE_CTRL4, BIT(4) | BIT(15));
/* RFSW Control - clear bit 14 ?? */
if (priv->rtl_chip != RTL8723B && priv->rtl_chip != RTL8192E &&
priv->rtl_chip != RTL8188E && priv->rtl_chip != RTL8710B)
priv->rtl_chip != RTL8188E && priv->rtl_chip != RTL8710B &&
priv->rtl_chip != RTL8192F)
rtl8xxxu_write32(priv, REG_FPGA0_TX_INFO, 0x00000003);
val32 = FPGA0_RF_TRSW | FPGA0_RF_TRSWB | FPGA0_RF_ANTSW |
@ -4094,7 +4126,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
/* 0x860[6:5]= 00 - why? - this sets antenna B */
if (priv->rtl_chip != RTL8192E && priv->rtl_chip != RTL8188E &&
priv->rtl_chip != RTL8710B)
priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192F)
rtl8xxxu_write32(priv, REG_FPGA0_XA_RF_INT_OE, 0x66f60210);
if (!macpower) {
@ -4168,7 +4200,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
rtl8xxxu_write8(priv, 0xa3, val8);
}
if (priv->rtl_chip == RTL8710B)
if (priv->rtl_chip == RTL8710B || priv->rtl_chip == RTL8192F)
rtl8xxxu_write8(priv, REG_EARLY_MODE_CONTROL_8710B, 0);
}
@ -4195,7 +4227,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, val8);
} else if (priv->rtl_chip == RTL8710B) {
rtl8xxxu_write32(priv, REG_HIMR0_8710B, 0);
} else {
} else if (priv->rtl_chip != RTL8192F) {
/*
* Enable all interrupts - not obvious USB needs to do this
*/
@ -4284,7 +4316,8 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
val16 = BEACON_DISABLE_TSF_UPDATE | (BEACON_DISABLE_TSF_UPDATE << 8);
rtl8xxxu_write16(priv, REG_BEACON_CTRL, val16);
rtl8xxxu_write16(priv, REG_TBTT_PROHIBIT, 0x6404);
if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8710B)
if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8710B &&
priv->rtl_chip != RTL8192F)
/* Firmware will control REG_DRVERLYINT when power saving is enable, */
/* so don't set this register on STA mode. */
rtl8xxxu_write8(priv, REG_DRIVER_EARLY_INT, DRIVER_EARLY_INT_TIME);
@ -4335,7 +4368,8 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
/* Disable BAR - not sure if this has any effect on USB */
rtl8xxxu_write32(priv, REG_BAR_MODE_CTRL, 0x0201ffff);
if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8188E && priv->rtl_chip != RTL8710B)
if (priv->rtl_chip != RTL8188F && priv->rtl_chip != RTL8188E &&
priv->rtl_chip != RTL8710B && priv->rtl_chip != RTL8192F)
rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0);
if (fops->init_statistics)
@ -4353,9 +4387,10 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
* Reset USB mode switch setting
*/
rtl8xxxu_write8(priv, REG_ACLK_MON, 0x00);
} else if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8188E) {
} else if (priv->rtl_chip == RTL8188F || priv->rtl_chip == RTL8188E ||
priv->rtl_chip == RTL8192F) {
/*
* Init GPIO settings for 8188f, 8188e
* Init GPIO settings for 8188f, 8188e, 8192f
*/
val8 = rtl8xxxu_read8(priv, REG_GPIO_MUXCFG);
val8 &= ~GPIO_MUXCFG_IO_SEL_ENBT;
@ -5517,8 +5552,10 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
tx_desc->pkt_size = cpu_to_le16(pktlen);
tx_desc->pkt_offset = tx_desc_size;
tx_desc->txdw0 =
TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT;
/* These bits mean different things to the RTL8192F. */
if (priv->rtl_chip != RTL8192F)
tx_desc->txdw0 =
TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT;
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
@ -5588,7 +5625,7 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
rtl8xxxu_calc_tx_desc_csum(tx_desc);
/* avoid zero checksum make tx hang */
if (priv->rtl_chip == RTL8710B)
if (priv->rtl_chip == RTL8710B || priv->rtl_chip == RTL8192F)
tx_desc->csum = ~tx_desc->csum;
usb_fill_bulk_urb(&tx_urb->urb, priv->udev, priv->pipe_out[queue],
@ -7462,6 +7499,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
case 0xf179:
case 0x8179:
case 0xb711:
case 0xf192:
untested = 0;
break;
}
@ -7486,6 +7524,10 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
if (id->idProduct == 0x0109)
untested = 0;
break;
case 0x0b05:
if (id->idProduct == 0x18f1)
untested = 0;
break;
default:
break;
}
@ -7752,6 +7794,16 @@ static const struct usb_device_id dev_table[] = {
/* TOTOLINK N150UA V5 / N150UA-B */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x2005, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8710bu_fops},
/* Comfast CF-826F */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0xf192, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192fu_fops},
/* Asus USB-N13 rev C1 */
{USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x18f1, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192fu_fops},
{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb722, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192fu_fops},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x318b, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192fu_fops},
#ifdef CONFIG_RTL8XXXU_UNTESTED
/* Still supported by rtlwifi */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x8176, 0xff, 0xff, 0xff),

View File

@ -67,6 +67,7 @@
#define REG_SPS0_CTRL 0x0011
#define REG_SPS_OCP_CFG 0x0018
#define REG_8192E_LDOV12_CTRL 0x0014
#define REG_SYS_SWR_CTRL2 0x0014
#define REG_RSV_CTRL 0x001c
#define RSV_CTRL_WLOCK_1C BIT(5)
#define RSV_CTRL_DIS_PRST BIT(6)
@ -215,6 +216,8 @@
#define REG_HMBOX_EXT_2 0x008c
#define REG_HMBOX_EXT_3 0x008e
#define REG_RSVD_1 0x0097
/* Interrupt registers for 8192e/8723bu/8812 */
#define REG_HIMR0 0x00b0
#define IMR0_TXCCK BIT(30) /* TXRPT interrupt when CCX bit
@ -283,6 +286,7 @@
#define REG_BIST_SCAN 0x00d0
#define REG_BIST_RPT 0x00d4
#define REG_BIST_ROM_RPT 0x00d8
#define REG_RSVD_4 0x00dc
#define REG_USB_SIE_INTF 0x00e0
#define REG_PCIE_MIO_INTF 0x00e4
#define REG_PCIE_MIO_INTD 0x00e8
@ -390,6 +394,12 @@
#define TRXDMA_CTRL_BKQ_SHIFT 10
#define TRXDMA_CTRL_MGQ_SHIFT 12
#define TRXDMA_CTRL_HIQ_SHIFT 14
#define TRXDMA_CTRL_VOQ_SHIFT_8192F 4
#define TRXDMA_CTRL_VIQ_SHIFT_8192F 7
#define TRXDMA_CTRL_BEQ_SHIFT_8192F 10
#define TRXDMA_CTRL_BKQ_SHIFT_8192F 13
#define TRXDMA_CTRL_MGQ_SHIFT_8192F 16
#define TRXDMA_CTRL_HIQ_SHIFT_8192F 19
#define TRXDMA_QUEUE_LOW 1
#define TRXDMA_QUEUE_NORMAL 2
#define TRXDMA_QUEUE_HIGH 3
@ -439,7 +449,7 @@
#define LLT_OP_READ (0x2 << 30)
#define LLT_OP_MASK (0x3 << 30)
#define REG_BB_ACCEESS_CTRL 0x01e8
#define REG_BB_ACCESS_CTRL 0x01e8
#define REG_BB_ACCESS_DATA 0x01ec
#define REG_HMBOX_EXT0_8723B 0x01f0
@ -973,12 +983,18 @@
#define FPGA1_TX_OFDM_TXSC_MASK 0x30000000
#define REG_ANT_MAPPING1 0x0914
#define REG_RFE_OPT 0x0920
#define REG_DPDT_CTRL 0x092c /* 8723BU */
#define REG_RFE_CTRL_ANTA_SRC 0x0930 /* 8723BU */
#define REG_RFE_CTRL_ANT_SRC1 0x0934
#define REG_RFE_CTRL_ANT_SRC2 0x0938
#define REG_RFE_CTRL_ANT_SRC3 0x093c
#define REG_RFE_PATH_SELECT 0x0940 /* 8723BU */
#define REG_RFE_BUFFER 0x0944 /* 8723BU */
#define REG_S0S1_PATH_SWITCH 0x0948 /* 8723BU */
#define REG_RX_DFIR_MOD_97F 0x0948
#define REG_OFDM_RX_DFIR 0x954
#define REG_RFE_OPT62 0x0968
#define REG_CCK0_SYSTEM 0x0a00
#define CCK0_SIDEBAND BIT(4)
@ -1038,6 +1054,8 @@
#define REG_OFDM0_FA_RSTC 0x0c0c
#define REG_DOWNSAM_FACTOR 0x0c10
#define REG_OFDM0_XA_RX_AFE 0x0c10
#define REG_OFDM0_XA_RX_IQ_IMBALANCE 0x0c14
#define REG_OFDM0_XB_RX_IQ_IMBALANCE 0x0c1c
@ -1059,7 +1077,7 @@
#define REG_OFDM0_AGC_PARM1 0x0c70
#define REG_OFDM0_AGCR_SSI_TABLE 0x0c78
#define REG_OFDM0_AGC_RSSI_TABLE 0x0c78
#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80
#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88
@ -1074,6 +1092,8 @@
/* 8188eu */
#define REG_ANTDIV_PARA1 0x0ca4
#define REG_RXIQB_EXT 0x0ca8
/* 8723bu */
#define REG_OFDM0_TX_PSDO_NOISE_WEIGHT 0x0ce4
@ -1093,6 +1113,8 @@
#define REG_OFDM1_CSI_FIX_MASK1 0x0d40
#define REG_OFDM1_CSI_FIX_MASK2 0x0d44
#define REG_ANAPWR1 0x0d94
#define REG_TX_AGC_A_RATE18_06 0x0e00
#define REG_TX_AGC_A_RATE54_24 0x0e04
#define REG_TX_AGC_A_CCK1_MCS32 0x0e08
@ -1101,6 +1123,10 @@
#define REG_TX_AGC_A_MCS11_MCS08 0x0e18
#define REG_TX_AGC_A_MCS15_MCS12 0x0e1c
#define REG_NP_ANTA 0x0e20
#define REG_TAP_UPD_97F 0x0e24
#define REG_FPGA0_IQK 0x0e28
#define REG_TX_IQK_TONE_A 0x0e30
@ -1129,19 +1155,23 @@
#define REG_RX_CCK 0x0e8c
#define REG_TX_POWER_BEFORE_IQK_A 0x0e94
#define REG_IQK_RPT_TXA 0x0e98
#define REG_TX_POWER_AFTER_IQK_A 0x0e9c
#define REG_RX_POWER_BEFORE_IQK_A 0x0ea0
#define REG_RX_POWER_BEFORE_IQK_A_2 0x0ea4
#define REG_RX_POWER_AFTER_IQK_A 0x0ea8
#define REG_IQK_RPT_RXA 0x0ea8
#define REG_RX_POWER_AFTER_IQK_A_2 0x0eac
#define REG_TX_POWER_BEFORE_IQK_B 0x0eb4
#define REG_IQK_RPT_TXB 0x0eb8
#define REG_TX_POWER_AFTER_IQK_B 0x0ebc
#define REG_RX_POWER_BEFORE_IQK_B 0x0ec0
#define REG_RX_POWER_BEFORE_IQK_B_2 0x0ec4
#define REG_RX_POWER_AFTER_IQK_B 0x0ec8
#define REG_IQK_RPT_RXB 0x0ec8
#define REG_RX_POWER_AFTER_IQK_B_2 0x0ecc
#define REG_RX_OFDM 0x0ed0
@ -1152,6 +1182,12 @@
#define REG_PMPD_ANAEN 0x0eec
#define REG_FW_START_ADDRESS 0x1000
#define REG_FW_START_ADDRESS_8192F 0x4000
#define REG_SW_GPIO_SHARE_CTRL_0 0x1038
#define REG_SW_GPIO_SHARE_CTRL_1 0x103c
#define REG_GPIO_A0 0x1050
#define REG_GPIO_B0 0x105b
#define REG_USB_INFO 0xfe17
#define REG_USB_HIMR 0xfe38
@ -1316,12 +1352,15 @@
/*
* NextGen regs: 8723BU
*/
#define RF6052_REG_GAIN_P1 0x35
#define RF6052_REG_T_METER_8723B 0x42
#define RF6052_REG_UNKNOWN_43 0x43
#define RF6052_REG_UNKNOWN_55 0x55
#define RF6052_REG_UNKNOWN_56 0x56
#define RF6052_REG_PAD_TXG 0x56
#define RF6052_REG_TXMOD 0x58
#define RF6052_REG_RXG_MIX_SWBW 0x87
#define RF6052_REG_S0S1 0xb0
#define RF6052_REG_UNKNOWN_DF 0xdf
#define RF6052_REG_GAIN_CCA 0xdf
#define RF6052_REG_UNKNOWN_ED 0xed
#define RF6052_REG_WE_LUT 0xef
#define RF6052_REG_GAIN_CTRL 0xf5

View File

@ -452,8 +452,7 @@ static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
/* <1> timer */
timer_setup(&rtlpriv->works.watchdog_timer,
rtl_watch_dog_timer_callback, 0);
timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
rtl_easy_concurrent_retrytimer_callback, 0);
/* <2> work queue */
rtlpriv->works.hw = hw;
rtlpriv->works.rtl_wq = wq;
@ -1905,7 +1904,7 @@ EXPORT_SYMBOL(rtl_rx_ampdu_apply);
void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
return;
@ -1991,7 +1990,7 @@ void rtl_scan_list_expire(struct ieee80211_hw *hw)
void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
unsigned long flags;
@ -2366,19 +2365,6 @@ static void rtl_c2hcmd_wq_callback(struct work_struct *work)
rtl_c2hcmd_launcher(hw, 1);
}
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t)
{
struct rtl_priv *rtlpriv =
from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer);
struct ieee80211_hw *hw = rtlpriv->hw;
struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
if (buddy_priv == NULL)
return;
rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
}
/*********************************************************
*
* frame process functions

View File

@ -124,7 +124,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
u8 rtl_tid_to_ac(u8 tid);
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t);
extern struct rtl_global_var rtl_global_var;
void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);

View File

@ -482,11 +482,6 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
if (!rtlpriv->rtlhal.earlymode_enable)
return;
if (rtlpriv->dm.supp_phymode_switch &&
(rtlpriv->easy_concurrent_ctl.switch_in_process ||
(rtlpriv->buddy_priv &&
rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process)))
return;
/* we just use em for BE/BK/VI/VO */
for (tid = 7; tid >= 0; tid--) {
u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];

View File

@ -674,7 +674,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = hdr->frame_control;
dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,

View File

@ -527,7 +527,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = hdr->frame_control;
dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,

View File

@ -394,7 +394,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
(struct rx_desc_92c *)rxdesc, p_drvinfo);
}
skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE));
hdr = (struct ieee80211_hdr *)(skb->data);
hdr = rtl_get_hdr(skb);
fc = hdr->frame_control;
bv = ieee80211_is_probe_resp(fc);
if (bv)
@ -632,7 +632,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
u8 fw_queue = QSLT_BEACON;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;

View File

@ -665,7 +665,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;

View File

@ -1302,7 +1302,7 @@ static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
u8 u1btmp;
if (rtlhal->driver_going2unload)
if (rtlhal->driver_is_goingto_unload)
rtl_write_byte(rtlpriv, 0x560, 0x0);
/* Power save for BB/RF */
@ -1323,7 +1323,7 @@ static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
rtl_write_word(rtlpriv, CMDR, 0x57FC);
rtl_write_word(rtlpriv, CMDR, 0x0000);
if (rtlhal->driver_going2unload) {
if (rtlhal->driver_is_goingto_unload) {
u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1));
u1btmp &= ~(BIT(0));
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp);
@ -1345,7 +1345,7 @@ static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
/* Power save for MAC */
if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS &&
!rtlhal->driver_going2unload) {
!rtlhal->driver_is_goingto_unload) {
/* enable LED function */
rtl_write_byte(rtlpriv, 0x03, 0xF9);
/* SW/HW radio off or halt adapter!! For example S3/S4 */

Some files were not shown because too many files have changed in this diff Show More