summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath10k/mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/mac.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3029f257a19a..4674ff33d320 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -457,7 +457,8 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
for (;;) {
/* since ath10k_install_key we can't hold data_lock all the
- * time, so we try to remove the keys incrementally */
+ * time, so we try to remove the keys incrementally
+ */
spin_lock_bh(&ar->data_lock);
i = 0;
list_for_each_entry(peer, &ar->peers, list) {
@@ -609,7 +610,8 @@ static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
case 2:
case 3:
/* Our lower layer calculations limit our precision to
- 1 microsecond */
+ * 1 microsecond
+ */
return 1;
case 4:
return 2;
@@ -978,7 +980,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
arg.channel.band_center_freq2 = chandef->center_freq2;
/* TODO setup this dynamically, what in case we
- don't have any vifs? */
+ * don't have any vifs?
+ */
arg.channel.mode = chan_to_phymode(chandef);
arg.channel.chan_radar =
!!(channel->flags & IEEE80211_CHAN_RADAR);
@@ -2373,9 +2376,10 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
}
/* TODO setup this based on STA listen interval and
- beacon interval. Currently we don't know
- sta->listen_interval - mac80211 patch required.
- Currently use 10 seconds */
+ * beacon interval. Currently we don't know
+ * sta->listen_interval - mac80211 patch required.
+ * Currently use 10 seconds
+ */
ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
10);
@@ -2451,6 +2455,8 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
enum nl80211_band band;
const u16 *vht_mcs_mask;
u8 ampdu_factor;
+ u8 max_nss, vht_mcs;
+ int i;
if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
return;
@@ -2478,7 +2484,8 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
/* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
* zero in VHT IE. Using it would result in degraded throughput.
* arg->peer_max_mpdu at this point contains HT max_mpdu so keep
- * it if VHT max_mpdu is smaller. */
+ * it if VHT max_mpdu is smaller.
+ */
arg->peer_max_mpdu = max(arg->peer_max_mpdu,
(1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
ampdu_factor)) - 1);
@@ -2489,6 +2496,18 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
arg->peer_flags |= ar->wmi.peer_flags->bw160;
+ /* Calculate peer NSS capability from VHT capabilities if STA
+ * supports VHT.
+ */
+ for (i = 0, max_nss = 0, vht_mcs = 0; i < NL80211_VHT_NSS_MAX; i++) {
+ vht_mcs = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) >>
+ (2 * i) & 3;
+
+ if ((vht_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) &&
+ vht_mcs_mask[i])
+ max_nss = i + 1;
+ }
+ arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
arg->peer_vht_rates.rx_max_rate =
__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
arg->peer_vht_rates.rx_mcs_set =
@@ -2779,7 +2798,8 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
}
/* ap_sta must be accessed only within rcu section which must be left
- * before calling ath10k_setup_peer_smps() which might sleep. */
+ * before calling ath10k_setup_peer_smps() which might sleep.
+ */
ht_cap = ap_sta->ht_cap;
vht_cap = ap_sta->vht_cap;
@@ -3050,7 +3070,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
/* FIXME: why use only legacy modes, why not any
* HT/VHT modes? Would that even make any
- * difference? */
+ * difference?
+ */
if (channel->band == NL80211_BAND_2GHZ)
ch->mode = MODE_11G;
else
@@ -3114,7 +3135,8 @@ static void ath10k_regd_update(struct ath10k *ar)
}
/* Target allows setting up per-band regdomain but ath_common provides
- * a combined one only */
+ * a combined one only
+ */
ret = ath10k_wmi_pdev_set_regdomain(ar,
regpair->reg_domain,
regpair->reg_domain, /* 2ghz */
@@ -3126,6 +3148,21 @@ static void ath10k_regd_update(struct ath10k *ar)
ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
}
+static void ath10k_mac_update_channel_list(struct ath10k *ar,
+ struct ieee80211_supported_band *band)
+{
+ int i;
+
+ if (ar->low_5ghz_chan && ar->high_5ghz_chan) {
+ for (i = 0; i < band->n_channels; i++) {
+ if (band->channels[i].center_freq < ar->low_5ghz_chan ||
+ band->channels[i].center_freq > ar->high_5ghz_chan)
+ band->channels[i].flags |=
+ IEEE80211_CHAN_DISABLED;
+ }
+ }
+}
+
static void ath10k_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
@@ -3149,6 +3186,10 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
if (ar->state == ATH10K_STATE_ON)
ath10k_regd_update(ar);
mutex_unlock(&ar->conf_mutex);
+
+ if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
+ ath10k_mac_update_channel_list(ar,
+ ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
}
/***************/
@@ -3644,7 +3685,8 @@ void ath10k_offchan_tx_work(struct work_struct *work)
* never transmitted. We delete the peer upon tx completion.
* It is unlikely that a peer for offchannel tx will already be
* present. However it may be in some rare cases so account for that.
- * Otherwise we might remove a legitimate peer and break stuff. */
+ * Otherwise we might remove a legitimate peer and break stuff.
+ */
for (;;) {
skb = skb_dequeue(&ar->offchan_tx_queue);
@@ -4684,6 +4726,7 @@ static void ath10k_stop(struct ieee80211_hw *hw)
}
mutex_unlock(&ar->conf_mutex);
+ cancel_work_sync(&ar->set_coverage_class_work);
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->restart_work);
}
@@ -5683,7 +5726,8 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
/* the peer should not disappear in mid-way (unless FW goes awry) since
- * we already hold conf_mutex. we just make sure its there now. */
+ * we already hold conf_mutex. we just make sure its there now.
+ */
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
spin_unlock_bh(&ar->data_lock);
@@ -5695,8 +5739,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = -EOPNOTSUPP;
goto exit;
} else {
- /* if the peer doesn't exist there is no key to disable
- * anymore */
+ /* if the peer doesn't exist there is no key to disable anymore */
goto exit;
}
}
@@ -6555,7 +6598,8 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
long time_left;
/* mac80211 doesn't care if we really xmit queued frames or not
- * we'll collect those frames either way if we stop/delete vdevs */
+ * we'll collect those frames either way if we stop/delete vdevs
+ */
if (drop)
return;
@@ -6606,7 +6650,8 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
mutex_lock(&ar->conf_mutex);
/* If device failed to restart it will be in a different state, e.g.
- * ATH10K_STATE_WEDGED */
+ * ATH10K_STATE_WEDGED
+ */
if (ar->state == ATH10K_STATE_RESTARTED) {
ath10k_info(ar, "device successfully recovered\n");
ar->state = ATH10K_STATE_ON;
@@ -7129,7 +7174,7 @@ ath10k_mac_update_rx_channel(struct ath10k *ar,
lockdep_assert_held(&ar->data_lock);
WARN_ON(ctx && vifs);
- WARN_ON(vifs && n_vifs != 1);
+ WARN_ON(vifs && !n_vifs);
/* FIXME: Sort of an optimization and a workaround. Peers and vifs are
* on a linked list now. Doing a lookup peer -> vif -> chanctx for each
@@ -8248,6 +8293,8 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->cipher_suites = cipher_suites;
ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);