diff options
| author | Ben Greear <greearb@candelatech.com> | 2014-05-16 10:15:38 -0400 |
|---|---|---|
| committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-05-22 12:55:09 -0400 |
| commit | 46acf7bb9b61289ea3353561142e3bf41119bd3e (patch) | |
| tree | 1201b3c0c3081e33f79a8e342e00729a40de26f7 | |
| parent | eeab266c0f3c9c85ef649ba737e2d553742a2532 (diff) | |
ath10k: support get/set antenna configurations.
Verified that target's tx/rx chain register is set appropriately,
and that the tx rate goes down as number of chains
decrease, but I did not actually try to verify antenna
ceased to transmit when disabled.
kvalo: move ar->supp_*_chainmask initialisation to ath10k_mac_register()
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 80 |
2 files changed, 86 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 2c1dfd719146..679b2a32331b 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
| @@ -440,6 +440,12 @@ struct ath10k { | |||
| 440 | bool radar_enabled; | 440 | bool radar_enabled; |
| 441 | int num_started_vdevs; | 441 | int num_started_vdevs; |
| 442 | 442 | ||
| 443 | /* Protected by conf-mutex */ | ||
| 444 | u8 supp_tx_chainmask; | ||
| 445 | u8 supp_rx_chainmask; | ||
| 446 | u8 cfg_tx_chainmask; | ||
| 447 | u8 cfg_rx_chainmask; | ||
| 448 | |||
| 443 | struct wmi_pdev_set_wmm_params_arg wmm_params; | 449 | struct wmi_pdev_set_wmm_params_arg wmm_params; |
| 444 | struct completion install_key_done; | 450 | struct completion install_key_done; |
| 445 | 451 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 12518047bd31..8c997626f45f 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
| @@ -2332,6 +2332,68 @@ void ath10k_halt(struct ath10k *ar) | |||
| 2332 | spin_unlock_bh(&ar->data_lock); | 2332 | spin_unlock_bh(&ar->data_lock); |
| 2333 | } | 2333 | } |
| 2334 | 2334 | ||
| 2335 | static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | ||
| 2336 | { | ||
| 2337 | struct ath10k *ar = hw->priv; | ||
| 2338 | |||
| 2339 | mutex_lock(&ar->conf_mutex); | ||
| 2340 | |||
| 2341 | if (ar->cfg_tx_chainmask) { | ||
| 2342 | *tx_ant = ar->cfg_tx_chainmask; | ||
| 2343 | *rx_ant = ar->cfg_rx_chainmask; | ||
| 2344 | } else { | ||
| 2345 | *tx_ant = ar->supp_tx_chainmask; | ||
| 2346 | *rx_ant = ar->supp_rx_chainmask; | ||
| 2347 | } | ||
| 2348 | |||
| 2349 | mutex_unlock(&ar->conf_mutex); | ||
| 2350 | |||
| 2351 | return 0; | ||
| 2352 | } | ||
| 2353 | |||
| 2354 | static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) | ||
| 2355 | { | ||
| 2356 | int ret; | ||
| 2357 | |||
| 2358 | lockdep_assert_held(&ar->conf_mutex); | ||
| 2359 | |||
| 2360 | ar->cfg_tx_chainmask = tx_ant; | ||
| 2361 | ar->cfg_rx_chainmask = rx_ant; | ||
| 2362 | |||
| 2363 | if ((ar->state != ATH10K_STATE_ON) && | ||
| 2364 | (ar->state != ATH10K_STATE_RESTARTED)) | ||
| 2365 | return 0; | ||
| 2366 | |||
| 2367 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask, | ||
| 2368 | tx_ant); | ||
| 2369 | if (ret) { | ||
| 2370 | ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n", | ||
| 2371 | ret, tx_ant); | ||
| 2372 | return ret; | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask, | ||
| 2376 | rx_ant); | ||
| 2377 | if (ret) { | ||
| 2378 | ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n", | ||
| 2379 | ret, rx_ant); | ||
| 2380 | return ret; | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | return 0; | ||
| 2384 | } | ||
| 2385 | |||
| 2386 | static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) | ||
| 2387 | { | ||
| 2388 | struct ath10k *ar = hw->priv; | ||
| 2389 | int ret; | ||
| 2390 | |||
| 2391 | mutex_lock(&ar->conf_mutex); | ||
| 2392 | ret = __ath10k_set_antenna(ar, tx_ant, rx_ant); | ||
| 2393 | mutex_unlock(&ar->conf_mutex); | ||
| 2394 | return ret; | ||
| 2395 | } | ||
| 2396 | |||
| 2335 | static int ath10k_start(struct ieee80211_hw *hw) | 2397 | static int ath10k_start(struct ieee80211_hw *hw) |
| 2336 | { | 2398 | { |
| 2337 | struct ath10k *ar = hw->priv; | 2399 | struct ath10k *ar = hw->priv; |
| @@ -2373,6 +2435,10 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
| 2373 | if (ret) | 2435 | if (ret) |
| 2374 | ath10k_warn("failed to enable dynamic BW: %d\n", ret); | 2436 | ath10k_warn("failed to enable dynamic BW: %d\n", ret); |
| 2375 | 2437 | ||
| 2438 | if (ar->cfg_tx_chainmask) | ||
| 2439 | __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, | ||
| 2440 | ar->cfg_rx_chainmask); | ||
| 2441 | |||
| 2376 | /* | 2442 | /* |
| 2377 | * By default FW set ARP frames ac to voice (6). In that case ARP | 2443 | * By default FW set ARP frames ac to voice (6). In that case ARP |
| 2378 | * exchange is not working properly for UAPSD enabled AP. ARP requests | 2444 | * exchange is not working properly for UAPSD enabled AP. ARP requests |
| @@ -4256,6 +4322,8 @@ static const struct ieee80211_ops ath10k_ops = { | |||
| 4256 | .set_frag_threshold = ath10k_set_frag_threshold, | 4322 | .set_frag_threshold = ath10k_set_frag_threshold, |
| 4257 | .flush = ath10k_flush, | 4323 | .flush = ath10k_flush, |
| 4258 | .tx_last_beacon = ath10k_tx_last_beacon, | 4324 | .tx_last_beacon = ath10k_tx_last_beacon, |
| 4325 | .set_antenna = ath10k_set_antenna, | ||
| 4326 | .get_antenna = ath10k_get_antenna, | ||
| 4259 | .restart_complete = ath10k_restart_complete, | 4327 | .restart_complete = ath10k_restart_complete, |
| 4260 | .get_survey = ath10k_get_survey, | 4328 | .get_survey = ath10k_get_survey, |
| 4261 | .set_bitrate_mask = ath10k_set_bitrate_mask, | 4329 | .set_bitrate_mask = ath10k_set_bitrate_mask, |
| @@ -4605,6 +4673,18 @@ int ath10k_mac_register(struct ath10k *ar) | |||
| 4605 | BIT(NL80211_IFTYPE_ADHOC) | | 4673 | BIT(NL80211_IFTYPE_ADHOC) | |
| 4606 | BIT(NL80211_IFTYPE_AP); | 4674 | BIT(NL80211_IFTYPE_AP); |
| 4607 | 4675 | ||
| 4676 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | ||
| 4677 | /* TODO: Have to deal with 2x2 chips if/when the come out. */ | ||
| 4678 | ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK; | ||
| 4679 | ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK; | ||
| 4680 | } else { | ||
| 4681 | ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK; | ||
| 4682 | ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK; | ||
| 4683 | } | ||
| 4684 | |||
| 4685 | ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; | ||
| 4686 | ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask; | ||
| 4687 | |||
| 4608 | if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) | 4688 | if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) |
| 4609 | ar->hw->wiphy->interface_modes |= | 4689 | ar->hw->wiphy->interface_modes |= |
| 4610 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4690 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
