Skip to content

Commit

Permalink
ath11k: add interface_modes to hw_params
Browse files Browse the repository at this point in the history
As QCA6390 does not support mesh interfaces, move the interface_modes to
hw_params. Also create interface combinations dynamically so that it's easy to
change the values.

Now QCA6390 does not claim to support mesh interfaces to user space, but
IPQ8074 continues to do that.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1

Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1601399736-3210-4-git-send-email-kvalo@codeaurora.org
  • Loading branch information
Kalle Valo committed Oct 1, 2020
1 parent b091992 commit 2626c26
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 39 deletions.
11 changes: 11 additions & 0 deletions drivers/net/wireless/ath/ath11k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.spectral_fft_sz = 2,

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT),
},
{
.hw_rev = ATH11K_HW_IPQ6018_HW10,
Expand Down Expand Up @@ -88,6 +92,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.htt_peer_map_v2 = true,
.tcl_0_only = false,
.spectral_fft_sz = 4,

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT),
},
{
.name = "qca6390 hw2.0",
Expand Down Expand Up @@ -118,6 +126,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.htt_peer_map_v2 = false,
.tcl_0_only = true,
.spectral_fft_sz = 0,

.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP),
},
};

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/ath/ath11k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ struct ath11k_hw_params {
bool htt_peer_map_v2;
bool tcl_0_only;
u8 spectral_fft_sz;

u16 interface_modes;
};

struct ath11k_hw_ops {
Expand Down
101 changes: 62 additions & 39 deletions drivers/net/wireless/ath/ath11k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -5880,35 +5880,6 @@ static const struct ieee80211_ops ath11k_ops = {
#endif
};

static const struct ieee80211_iface_limit ath11k_if_limits[] = {
{
.max = 1,
.types = BIT(NL80211_IFTYPE_STATION),
},
{
.max = 16,
.types = BIT(NL80211_IFTYPE_AP)
#ifdef CONFIG_MAC80211_MESH
| BIT(NL80211_IFTYPE_MESH_POINT)
#endif
},
};

static const struct ieee80211_iface_combination ath11k_if_comb[] = {
{
.limits = ath11k_if_limits,
.n_limits = ARRAY_SIZE(ath11k_if_limits),
.max_interfaces = 16,
.num_different_channels = 1,
.beacon_int_infra_match = true,
.beacon_int_min_gcd = 100,
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
},
};

static void ath11k_mac_update_ch_list(struct ath11k *ar,
struct ieee80211_supported_band *band,
u32 freq_low, u32 freq_high)
Expand Down Expand Up @@ -6034,6 +6005,50 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
return 0;
}

static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
{
struct ath11k_base *ab = ar->ab;
struct ieee80211_iface_combination *combinations;
struct ieee80211_iface_limit *limits;
int n_limits;

combinations = kzalloc(sizeof(*combinations), GFP_KERNEL);
if (!combinations)
return -ENOMEM;

n_limits = 2;

limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL);
if (!limits)
return -ENOMEM;

limits[0].max = 1;
limits[0].types |= BIT(NL80211_IFTYPE_STATION);

limits[1].max = 16;
limits[1].types |= BIT(NL80211_IFTYPE_AP);

if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);

combinations[0].limits = limits;
combinations[0].n_limits = n_limits;
combinations[0].max_interfaces = 16;
combinations[0].num_different_channels = 1;
combinations[0].beacon_int_infra_match = true;
combinations[0].beacon_int_min_gcd = 100;
combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80);

ar->hw->wiphy->iface_combinations = combinations;
ar->hw->wiphy->n_iface_combinations = 1;

return 0;
}

static const u8 ath11k_if_types_ext_capa[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
Expand Down Expand Up @@ -6084,6 +6099,9 @@ static void __ath11k_mac_unregister(struct ath11k *ar)
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);

kfree(ar->hw->wiphy->iface_combinations[0].limits);
kfree(ar->hw->wiphy->iface_combinations);

SET_IEEE80211_DEV(ar->hw, NULL);
}

Expand Down Expand Up @@ -6135,12 +6153,16 @@ static int __ath11k_mac_register(struct ath11k *ar)
ath11k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);
ath11k_mac_setup_he_cap(ar, cap);

ret = ath11k_mac_setup_iface_combinations(ar);
if (ret) {
ath11k_err(ar->ab, "failed to setup interface combinations: %d\n", ret);
goto err_free_channels;
}

ar->hw->wiphy->available_antennas_rx = cap->rx_chain_mask;
ar->hw->wiphy->available_antennas_tx = cap->tx_chain_mask;

ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT);
ar->hw->wiphy->interface_modes = ab->hw_params.interface_modes;

ieee80211_hw_set(ar->hw, SIGNAL_DBM);
ieee80211_hw_set(ar->hw, SUPPORTS_PS);
Expand Down Expand Up @@ -6202,9 +6224,6 @@ static int __ath11k_mac_register(struct ath11k *ar)
ar->hw->vif_data_size = sizeof(struct ath11k_vif);
ar->hw->sta_data_size = sizeof(struct ath11k_sta);

ar->hw->wiphy->iface_combinations = ath11k_if_comb;
ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ath11k_if_comb);

wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);

Expand All @@ -6226,25 +6245,29 @@ static int __ath11k_mac_register(struct ath11k *ar)
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);
goto err_free;
goto err_free_if_combs;
}

/* Apply the regd received during initialization */
ret = ath11k_regd_update(ar, true);
if (ret) {
ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret);
goto err_free;
goto err_free_if_combs;
}

ret = ath11k_debugfs_register(ar);
if (ret) {
ath11k_err(ar->ab, "debugfs registration failed: %d\n", ret);
goto err_free;
goto err_free_if_combs;
}

return 0;

err_free:
err_free_if_combs:
kfree(ar->hw->wiphy->iface_combinations[0].limits);
kfree(ar->hw->wiphy->iface_combinations);

err_free_channels:
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
Expand Down

0 comments on commit 2626c26

Please sign in to comment.