mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz. First, report this to user-space by setting the max-tx-speed and max-rx-speed vht capabilities. Second, if the peer rx-speed is configured, and if we are in 160 or 80+80 mode, and the peer rx-speed matches the max speed for 2x2 or 1x1 at 160Mhz (long guard interval), then use that info to set the peer_bw_rxnss_override appropriately. Without this, a 9984 firmware will not use 2x2 ratesets when transmitting to peer (it will be stuck at 1x1), because the firmware would not have configured the rxnss_override. Signed-off-by: Ben Greear <greearb@candelatech.com> [sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup] Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [kvalo@qca.qualcomm.com: use hw_params, rename the title] Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
e509e59477
commit
cc914a5500
@ -72,6 +72,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA9887_HW_1_0_VERSION,
|
||||
@ -93,6 +95,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA6174_HW_2_1_VERSION,
|
||||
@ -113,6 +117,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA6174_HW_2_1_VERSION,
|
||||
@ -133,6 +139,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA6174_HW_3_0_VERSION,
|
||||
@ -153,6 +161,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA6174_HW_3_2_VERSION,
|
||||
@ -176,6 +186,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.target_cpu_freq = 176000000,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA99X0_HW_2_0_DEV_VERSION,
|
||||
@ -202,6 +214,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 4,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA9984_HW_1_0_DEV_VERSION,
|
||||
@ -229,6 +243,12 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 12,
|
||||
|
||||
/* Can do only 2x2 VHT160 or 80+80. 1560Mbps is 4x4 80Mhz
|
||||
* or 2x2 160Mhz, long-guard-interval.
|
||||
*/
|
||||
.vht160_mcs_rx_highest = 1560,
|
||||
.vht160_mcs_tx_highest = 1560,
|
||||
},
|
||||
{
|
||||
.id = QCA9888_HW_2_0_DEV_VERSION,
|
||||
@ -255,6 +275,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 12,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA9377_HW_1_0_DEV_VERSION,
|
||||
@ -275,6 +297,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA9377_HW_1_1_DEV_VERSION,
|
||||
@ -297,6 +321,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.target_cpu_freq = 176000000,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
{
|
||||
.id = QCA4019_HW_1_0_DEV_VERSION,
|
||||
@ -324,6 +350,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 4,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -535,6 +535,12 @@ struct ath10k_hw_params {
|
||||
|
||||
/* Number of bytes to be discarded for each FFT sample */
|
||||
int spectral_bin_discard;
|
||||
|
||||
/* The board may have a restricted NSS for 160 or 80+80 vs what it
|
||||
* can do for 80Mhz.
|
||||
*/
|
||||
int vht160_mcs_rx_highest;
|
||||
int vht160_mcs_tx_highest;
|
||||
};
|
||||
|
||||
struct htt_rx_desc;
|
||||
|
@ -2519,6 +2519,20 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
|
||||
sta->addr, arg->peer_max_mpdu, arg->peer_flags);
|
||||
|
||||
if (arg->peer_vht_rates.rx_max_rate &&
|
||||
(sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
|
||||
switch (arg->peer_vht_rates.rx_max_rate) {
|
||||
case 1560:
|
||||
/* Must be 2x2 at 160Mhz is all it can do. */
|
||||
arg->peer_bw_rxnss_override = 2;
|
||||
break;
|
||||
case 780:
|
||||
/* Can only do 1x1 at 160Mhz (Long Guard Interval) */
|
||||
arg->peer_bw_rxnss_override = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
||||
@ -4362,6 +4376,7 @@ static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
|
||||
static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
|
||||
{
|
||||
struct ieee80211_sta_vht_cap vht_cap = {0};
|
||||
struct ath10k_hw_params *hw = &ar->hw_params;
|
||||
u16 mcs_map;
|
||||
u32 val;
|
||||
int i;
|
||||
@ -4408,6 +4423,17 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
|
||||
vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
|
||||
vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
|
||||
|
||||
/* If we are supporting 160Mhz or 80+80, then the NIC may be able to do
|
||||
* a restricted NSS for 160 or 80+80 vs what it can do for 80Mhz. Give
|
||||
* user-space a clue if that is the case.
|
||||
*/
|
||||
if ((vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) &&
|
||||
(hw->vht160_mcs_rx_highest != 0 ||
|
||||
hw->vht160_mcs_tx_highest != 0)) {
|
||||
vht_cap.vht_mcs.rx_highest = cpu_to_le16(hw->vht160_mcs_rx_highest);
|
||||
vht_cap.vht_mcs.tx_highest = cpu_to_le16(hw->vht160_mcs_tx_highest);
|
||||
}
|
||||
|
||||
return vht_cap;
|
||||
}
|
||||
|
||||
|
@ -6734,7 +6734,12 @@ ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
|
||||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
|
||||
cmd->peer_bw_rxnss_override = 0;
|
||||
if (arg->peer_bw_rxnss_override)
|
||||
cmd->peer_bw_rxnss_override =
|
||||
__cpu_to_le32((arg->peer_bw_rxnss_override - 1) |
|
||||
BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET));
|
||||
else
|
||||
cmd->peer_bw_rxnss_override = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -6028,6 +6028,8 @@ struct wmi_10_2_peer_assoc_complete_cmd {
|
||||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
|
||||
} __packed;
|
||||
|
||||
#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31
|
||||
|
||||
struct wmi_10_4_peer_assoc_complete_cmd {
|
||||
struct wmi_10_2_peer_assoc_complete_cmd cmd;
|
||||
__le32 peer_bw_rxnss_override;
|
||||
@ -6051,6 +6053,7 @@ struct wmi_peer_assoc_complete_arg {
|
||||
u32 peer_vht_caps;
|
||||
enum wmi_phy_mode peer_phymode;
|
||||
struct wmi_vht_rate_set_arg peer_vht_rates;
|
||||
u32 peer_bw_rxnss_override;
|
||||
};
|
||||
|
||||
struct wmi_peer_add_wds_entry_cmd {
|
||||
|
Loading…
Reference in New Issue
Block a user