[PATCH v5 1/7] ath10k: allow empty ssid vdev config
It doesn't make much sense to reject a valid firmware configuration combination. Since SSID isn't known early on it might make sense to allow driver to start vdev without SSID and restart it later. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 -- drivers/net/wireless/ath/ath10k/wmi.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 467d88c780c7..d4804645f8c2 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -1518,8 +1518,6 @@ ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar, void *ptr; u32 flags = 0; - if (WARN_ON(arg-ssid arg-ssid_len == 0)) - return ERR_PTR(-EINVAL); if (WARN_ON(arg-hidden_ssid !arg-ssid)) return ERR_PTR(-EINVAL); if (WARN_ON(arg-ssid_len sizeof(cmd-ssid.ssid))) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 1f47636f204b..3ef41105b95c 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4248,8 +4248,6 @@ ath10k_wmi_op_gen_vdev_start(struct ath10k *ar, const char *cmdname; u32 flags = 0; - if (WARN_ON(arg-ssid arg-ssid_len == 0)) - return ERR_PTR(-EINVAL); if (WARN_ON(arg-hidden_ssid !arg-ssid)) return ERR_PTR(-EINVAL); if (WARN_ON(arg-ssid_len sizeof(cmd-ssid.ssid))) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ath10k: don't call quiet mode if it's not implemented
qca6174 and wmi-tlv doesn't have quiet mode implemented. Don't even attempt to call it. This fixes a warning when bringing first interface up: failed to set quiet mode period 100 duarion 0 enabled 0 ret -95 Fixes: 8515b5c79a54 (ath10k: configure thermal throttle while powering up) Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: (based on pending branch) drivers/net/wireless/ath/ath10k/thermal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c index 01bae867cae9..1a899d70dc5d 100644 --- a/drivers/net/wireless/ath/ath10k/thermal.c +++ b/drivers/net/wireless/ath/ath10k/thermal.c @@ -140,6 +140,9 @@ void ath10k_thermal_set_throttling(struct ath10k *ar) lockdep_assert_held(ar-conf_mutex); + if (!ar-wmi.ops-gen_pdev_set_quiet_mode) + return; + if (ar-state != ATH10K_STATE_ON) return; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ath10k: fix survey reporting
Number of channels is stored in a separate macro in a header file and channel list is constructed independently. The macro is used to define survey array. This fixes a recent regression introduced after adding support for 144 channel. The regression would lead to a warning and incomplete survey data on channel 165: chan info: invalid frequency 5825 (idx 38 out of bounds) Also make sure to enforce the sizes and avoid this kind of problem in the future. Fixes: 4a7898fed5f3 (ath10k: enable channel 144 on 5GHz band) Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: (based on pending branch) drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 4 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d50408822f39..7fa171fa55e3 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -45,7 +45,7 @@ #define WMI_READY_TIMEOUT (5 * HZ) #define ATH10K_FLUSH_TIMEOUT_HZ (5*HZ) #define ATH10K_CONNECTION_LOSS_HZ (3*HZ) -#define ATH10K_NUM_CHANS 38 +#define ATH10K_NUM_CHANS 39 /* Antenna noise floor */ #define ATH10K_DEFAULT_NOISE_FLOOR -95 diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 5f9705deb430..75cc304d32d4 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6014,6 +6014,10 @@ int ath10k_mac_register(struct ath10k *ar) ht_cap = ath10k_get_ht_cap(ar); vht_cap = ath10k_create_vht_cap(ar); + BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) + + ARRAY_SIZE(ath10k_5ghz_channels)) != +ATH10K_NUM_CHANS); + if (ar-phy_capability WHAL_WLAN_11G_CAPABILITY) { channels = kmemdup(ath10k_2ghz_channels, sizeof(ath10k_2ghz_channels), -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 7/7] ath10k: allocate fw resources for iface combinations
The number of 3 vdevs wasn't enough to handle the worst case for interface combinations in practice. wpa_supplicant may need up to 4 vifs to have 2 vifs actually connected, i.e. p2pdev + client + 2x p2p (either p2p client or p2p go). This fixes worst case warning: Free vdev map is empty, no more interfaces allowed. This keeps the ability to associate 32 stations in AP mode at the cost of not being able to guarantee that under all circumstances, i.e. some combinations may consume additional fw peer entries for internal purposes leaving less resource for stations in AP mode. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- drivers/net/wireless/ath/ath10k/hw.h | 6 ++ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 8 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 34fcb6d5786d..1e9a781a45b4 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -280,11 +280,9 @@ enum ath10k_hw_rate_cck { #define TARGET_10_2_DMA_BURST_SIZE 1 /* Target specific defines for WMI-TLV firmware */ -#define TARGET_TLV_NUM_VDEVS 3 +#define TARGET_TLV_NUM_VDEVS 4 #define TARGET_TLV_NUM_STATIONS32 -#define TARGET_TLV_NUM_PEERS ((TARGET_TLV_NUM_STATIONS) + \ -(TARGET_TLV_NUM_VDEVS) + \ -2) +#define TARGET_TLV_NUM_PEERS 35 #define TARGET_TLV_NUM_TDLS_VDEVS 1 #define TARGET_TLV_NUM_TIDS((TARGET_TLV_NUM_PEERS) * 2) #define TARGET_TLV_NUM_MSDU_DESC (1024 + 32) diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 73cf3d00c2d0..f42ff9d97b00 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -1318,8 +1318,8 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) cfg-num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS); if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar-wmi.svc_map)) { - cfg-num_offload_peers = __cpu_to_le32(3); - cfg-num_offload_reorder_bufs = __cpu_to_le32(3); + cfg-num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); + cfg-num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); } else { cfg-num_offload_peers = __cpu_to_le32(0); cfg-num_offload_reorder_bufs = __cpu_to_le32(0); @@ -1336,8 +1336,8 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) cfg-rx_timeout_pri[3] = __cpu_to_le32(0x28); cfg-rx_decap_mode = __cpu_to_le32(1); cfg-scan_max_pending_reqs = __cpu_to_le32(4); - cfg-bmiss_offload_max_vdev = __cpu_to_le32(3); - cfg-roam_offload_max_vdev = __cpu_to_le32(3); + cfg-bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); + cfg-roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); cfg-roam_offload_max_ap_profiles = __cpu_to_le32(8); cfg-num_mcast_groups = __cpu_to_le32(0); cfg-num_mcast_table_elems = __cpu_to_le32(0); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 4/7] ath10k: rework tx queue locking
Tx queue locking was very simple until now. Multi-channel support will require a more flexible and fine grained control. This introduces a per-hw and per-vif (each with a bitmask of reasons) tx queue locking. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: v4: * use ieee80211_iterate_active_interfaces_atomic() instead of ar-arvifs drivers/net/wireless/ath/ath10k/core.h | 8 +++ drivers/net/wireless/ath/ath10k/htt_tx.c | 4 +- drivers/net/wireless/ath/ath10k/mac.c| 88 +++- drivers/net/wireless/ath/ath10k/mac.h| 5 ++ 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index f3ddd199eedb..cbb58ff8fc25 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -314,6 +314,7 @@ struct ath10k_vif { enum ath10k_beacon_state beacon_state; void *beacon_buf; dma_addr_t beacon_paddr; + unsigned long tx_paused; /* arbitrary values defined by target */ struct ath10k *ar; struct ieee80211_vif *vif; @@ -519,6 +520,11 @@ static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state) return unknown; } +enum ath10k_tx_pause_reason { + ATH10K_TX_PAUSE_Q_FULL, + ATH10K_TX_PAUSE_MAX, +}; + struct ath10k { struct ath_common ath_common; struct ieee80211_hw *hw; @@ -683,6 +689,8 @@ struct ath10k { struct dfs_pattern_detector *dfs_detector; + unsigned long tx_paused; /* see ATH10K_TX_PAUSE_ */ + #ifdef CONFIG_ATH10K_DEBUGFS struct ath10k_debug debug; #endif diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 5b2c61b0390a..a60ef7d1d5fc 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -26,7 +26,7 @@ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt) { htt-num_pending_tx--; if (htt-num_pending_tx == htt-max_num_pending_tx - 1) - ieee80211_wake_queues(htt-ar-hw); + ath10k_mac_tx_unlock(htt-ar, ATH10K_TX_PAUSE_Q_FULL); } static void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt) @@ -49,7 +49,7 @@ static int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt) htt-num_pending_tx++; if (htt-num_pending_tx == htt-max_num_pending_tx) - ieee80211_stop_queues(htt-ar-hw); + ath10k_mac_tx_lock(htt-ar, ATH10K_TX_PAUSE_Q_FULL); exit: spin_unlock_bh(htt-tx_lock); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 17e8c083839e..182e0e54db4a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2840,6 +2840,72 @@ static void ath10k_reg_notifier(struct wiphy *wiphy, /* TX handlers */ /***/ +void ath10k_mac_tx_lock(struct ath10k *ar, int reason) +{ + lockdep_assert_held(ar-htt.tx_lock); + + WARN_ON(reason = ATH10K_TX_PAUSE_MAX); + ar-tx_paused |= BIT(reason); + ieee80211_stop_queues(ar-hw); +} + +static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct ath10k *ar = data; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + + if (arvif-tx_paused) + return; + + ieee80211_wake_queue(ar-hw, arvif-vdev_id); +} + +void ath10k_mac_tx_unlock(struct ath10k *ar, int reason) +{ + lockdep_assert_held(ar-htt.tx_lock); + + WARN_ON(reason = ATH10K_TX_PAUSE_MAX); + ar-tx_paused = ~BIT(reason); + + if (ar-tx_paused) + return; + + ieee80211_iterate_active_interfaces_atomic(ar-hw, + IEEE80211_IFACE_ITER_RESUME_ALL, + ath10k_mac_tx_unlock_iter, + ar); +} + +void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason) +{ + struct ath10k *ar = arvif-ar; + + lockdep_assert_held(ar-htt.tx_lock); + + WARN_ON(reason = BITS_PER_LONG); + arvif-tx_paused |= BIT(reason); + ieee80211_stop_queue(ar-hw, arvif-vdev_id); +} + +void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason) +{ + struct ath10k *ar = arvif-ar; + + lockdep_assert_held(ar-htt.tx_lock); + + WARN_ON(reason = BITS_PER_LONG); + arvif-tx_paused = ~BIT(reason); + + if (ar-tx_paused) + return; + + if (arvif-tx_paused) + return; + + ieee80211_wake_queue(ar-hw, arvif-vdev_id); +} + static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr) { if (ieee80211_is_mgmt(hdr-frame_control)) @@ -3429,6 +3495,7 @@ void ath10k_halt(struct ath10k *ar) ath10k_monitor_stop(ar); ar-monitor_started =
[PATCH v5 2/7] ath10k: implement chanctx API
The chanctx API will allow ath10k to support multi-channel operation. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: v2: * prevent null deref in ath10k_peer_assoc_h_vht() after rebasing to latest master branch v3: * remove chanctx internal ath10k list [Johannes] (I still keep local chandef copy) * remove arvif-arctx and use vif-chanctx_conf directly * remove ar-chandef * fix typo sanity check (arvif-arctx was checked twice in rx_h_peer_channel; arvif itself should be checked too) * skip presp template setup for IBSS v4; * fix CSA * refactor monitor recalc code a bit drivers/net/wireless/ath/ath10k/core.h | 10 + drivers/net/wireless/ath/ath10k/htt_rx.c | 102 - drivers/net/wireless/ath/ath10k/mac.c| 684 +-- drivers/net/wireless/ath/ath10k/mac.h| 11 + drivers/net/wireless/ath/ath10k/wmi.c| 13 +- 5 files changed, 697 insertions(+), 123 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d50408822f39..f3ddd199eedb 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -284,6 +284,15 @@ struct ath10k_sta { #endif }; +struct ath10k_chanctx { + /* Used to story copy of chanctx_conf to avoid inconsistencies. Ideally +* mac80211 should allow some sort of explicit locking to guarantee +* that the publicly available chanctx_conf can be accessed safely at +* all times. +*/ + struct ieee80211_chanctx_conf conf; +}; + #define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) enum ath10k_beacon_state { @@ -610,6 +619,7 @@ struct ath10k { struct cfg80211_chan_def chandef; unsigned long long free_vdev_map; + struct ath10k_vif *monitor_arvif; bool monitor; int monitor_vdev_id; bool monitor_started; diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 157dc8dd2ee0..98d4d150ad15 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -723,8 +723,89 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, } } +static struct ieee80211_channel * +ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd) +{ + struct ath10k_peer *peer; + struct ath10k_vif *arvif; + struct ath10k_chanctx *arctx; + u16 peer_id; + + lockdep_assert_held(ar-data_lock); + + if (!rxd) + return NULL; + + if (rxd-attention.flags + __cpu_to_le32(RX_ATTENTION_FLAGS_PEER_IDX_INVALID)) + return NULL; + + if (!(rxd-msdu_end.info0 + __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU))) + return NULL; + + peer_id = MS(__le32_to_cpu(rxd-mpdu_start.info0), +RX_MPDU_START_INFO0_PEER_IDX); + + peer = ath10k_peer_find_by_id(ar, peer_id); + if (!peer) + return NULL; + + arvif = ath10k_get_arvif(ar, peer-vdev_id); + if (WARN_ON_ONCE(!arvif)) + return NULL; + + arctx = ath10k_mac_vif_ctx(arvif); + if (WARN_ON_ONCE(!arctx)) + return NULL; + + return arctx-conf.def.chan; +} + +static struct ieee80211_channel * +ath10k_htt_rx_h_vdev_channel(struct ath10k *ar, u32 vdev_id) +{ + struct ath10k_vif *arvif; + struct ath10k_chanctx *arctx; + + lockdep_assert_held(ar-data_lock); + + list_for_each_entry(arvif, ar-arvifs, list) { + arctx = ath10k_mac_vif_ctx(arvif); + + if (arvif-vdev_id == vdev_id arctx) + return arctx-conf.def.chan; + } + + return NULL; +} + +static void +ath10k_htt_rx_h_any_chan_iter(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf, + void *data) +{ + struct cfg80211_chan_def *def = data; + + *def = conf-def; +} + +static struct ieee80211_channel * +ath10k_htt_rx_h_any_channel(struct ath10k *ar) +{ + struct cfg80211_chan_def def = {}; + + ieee80211_iter_chan_contexts_atomic(ar-hw, + ath10k_htt_rx_h_any_chan_iter, + def); + + return def.chan; +} + static bool ath10k_htt_rx_h_channel(struct ath10k *ar, - struct ieee80211_rx_status *status) + struct ieee80211_rx_status *status, + struct htt_rx_desc *rxd, + u32 vdev_id) { struct ieee80211_channel *ch; @@ -732,6 +813,12 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, ch = ar-scan_channel; if (!ch) ch = ar-rx_channel; + if (!ch) + ch = ath10k_htt_rx_h_peer_channel(ar,
[PATCH v5 5/7] ath10k: implement tx pause wmi event
qca6174 wmi-tlv firmware defines a new wmi event for host tx pausing (i.e. stop/wake tx queues). Map these events to ath10k/mac80211 tx queue control. This is important for multi-channel throughput performance. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: v2: * s/thourghput/throughput/ in commit log v4: * use ieee80211_iterate_active_interfaces_atomic() instead of ar-arvifs drivers/net/wireless/ath/ath10k/mac.c | 90 +++ drivers/net/wireless/ath/ath10k/mac.h | 8 +++ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 48 + drivers/net/wireless/ath/ath10k/wmi-tlv.h | 42 +++ 4 files changed, 188 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 182e0e54db4a..1d6191d89586 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -28,6 +28,7 @@ #include txrx.h #include testmode.h #include wmi.h +#include wmi-tlv.h #include wmi-ops.h #include wow.h @@ -2906,6 +2907,83 @@ void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason) ieee80211_wake_queue(ar-hw, arvif-vdev_id); } +static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif, + enum wmi_tlv_tx_pause_id pause_id, + enum wmi_tlv_tx_pause_action action) +{ + struct ath10k *ar = arvif-ar; + + lockdep_assert_held(ar-htt.tx_lock); + + switch (pause_id) { + case WMI_TLV_TX_PAUSE_ID_MCC: + case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: + case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: + case WMI_TLV_TX_PAUSE_ID_AP_PS: + case WMI_TLV_TX_PAUSE_ID_IBSS_PS: + switch (action) { + case WMI_TLV_TX_PAUSE_ACTION_STOP: + ath10k_mac_vif_tx_lock(arvif, pause_id); + break; + case WMI_TLV_TX_PAUSE_ACTION_WAKE: + ath10k_mac_vif_tx_unlock(arvif, pause_id); + break; + default: + ath10k_warn(ar, received unknown tx pause action %d on vdev %i, ignoring\n, + action, arvif-vdev_id); + break; + } + break; + case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: + case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: + case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: + case WMI_TLV_TX_PAUSE_ID_HOST: + default: + /* FIXME: Some pause_ids aren't vdev specific. Instead they +* target peer_id and tid. Implementing these could improve +* traffic scheduling fairness across multiple connected +* stations in AP/IBSS modes. +*/ + ath10k_dbg(ar, ATH10K_DBG_MAC, + mac ignoring unsupported tx pause vdev %i id %d\n, + arvif-vdev_id, pause_id); + break; + } +} + +struct ath10k_mac_tx_pause { + u32 vdev_id; + enum wmi_tlv_tx_pause_id pause_id; + enum wmi_tlv_tx_pause_action action; +}; + +static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + struct ath10k_mac_tx_pause *arg = data; + + ath10k_mac_vif_handle_tx_pause(arvif, arg-pause_id, arg-action); +} + +void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id, + enum wmi_tlv_tx_pause_id pause_id, + enum wmi_tlv_tx_pause_action action) +{ + struct ath10k_mac_tx_pause arg = { + .vdev_id = vdev_id, + .pause_id = pause_id, + .action = action, + }; + + spin_lock_bh(ar-htt.tx_lock); + ieee80211_iterate_active_interfaces_atomic(ar-hw, + IEEE80211_IFACE_ITER_RESUME_ALL, + ath10k_mac_handle_tx_pause_iter, + arg); + spin_unlock_bh(ar-htt.tx_lock); +} + static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr) { if (ieee80211_is_mgmt(hdr-frame_control)) @@ -4161,6 +4239,14 @@ err: return ret; } +static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif) +{ + int i; + + for (i = 0; i BITS_PER_LONG; i++) + ath10k_mac_vif_tx_unlock(arvif, i); +} + static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -4227,6 +4313,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, failed to recalc monitor: %d\n, ret); } + spin_lock_bh(ar-htt.tx_lock); +
[PATCH v5 3/7] ath10k: implement adaptive qcs command
This command will be used to configure multi-channel scheduler in firmware. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- drivers/net/wireless/ath/ath10k/wmi-ops.h | 16 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 30 ++ drivers/net/wireless/ath/ath10k/wmi-tlv.h | 4 drivers/net/wireless/ath/ath10k/wmi.c | 3 +++ drivers/net/wireless/ath/ath10k/wmi.h | 1 + 5 files changed, 54 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h index 5d7bbec17b53..47fe2e756bec 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h @@ -173,6 +173,7 @@ struct wmi_ops { const struct wmi_tdls_peer_update_cmd_arg *arg, const struct wmi_tdls_peer_capab_arg *cap, const struct wmi_channel_arg *chan); + struct sk_buff *(*gen_adaptive_qcs)(struct ath10k *ar, bool enable); }; int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); @@ -1232,4 +1233,19 @@ ath10k_wmi_tdls_peer_update(struct ath10k *ar, ar-wmi.cmd-tdls_peer_update_cmdid); } +static inline int +ath10k_wmi_adaptive_qcs(struct ath10k *ar, bool enable) +{ + struct sk_buff *skb; + + if (!ar-wmi.ops-gen_adaptive_qcs) + return -EOPNOTSUPP; + + skb = ar-wmi.ops-gen_adaptive_qcs(ar, enable); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + return ath10k_wmi_cmd_send(ar, skb, ar-wmi.cmd-adaptive_qcs_cmdid); +} + #endif diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index d4804645f8c2..04a83308778f 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -2948,6 +2948,34 @@ ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id, return skb; } +static struct sk_buff * +ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable) +{ + struct wmi_tlv_adaptive_qcs *cmd; + struct wmi_tlv *tlv; + struct sk_buff *skb; + void *ptr; + size_t len; + + len = sizeof(*tlv) + sizeof(*cmd); + skb = ath10k_wmi_alloc_skb(ar, len); + if (!skb) + return ERR_PTR(-ENOMEM); + + ptr = (void *)skb-data; + tlv = ptr; + tlv-tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD); + tlv-len = __cpu_to_le16(sizeof(*cmd)); + cmd = (void *)tlv-value; + cmd-enable = __cpu_to_le32(enable ? 1 : 0); + + ptr += sizeof(*tlv); + ptr += sizeof(*cmd); + + ath10k_dbg(ar, ATH10K_DBG_WMI, wmi tlv adaptive qcs %d\n, enable); + return skb; +} + // /* TLV mappings */ // @@ -3074,6 +3102,7 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = { .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID, .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID, + .adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID, }; static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { @@ -3255,6 +3284,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern, .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state, .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, + .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, }; // diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h index f65b6148cc77..8d41492f3aff 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -1576,6 +1576,10 @@ struct wmi_tdls_peer_capab { __le32 pref_offchan_bw; } __packed; +struct wmi_tlv_adaptive_qcs { + __le32 enable; +} __packed; + void ath10k_wmi_tlv_attach(struct ath10k *ar); #endif diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 9694cd0a0249..20fd9f61fbad 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -5212,6 +5212,7 @@ static const struct wmi_ops wmi_ops = { /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ + /* .gen_adaptive_qcs not implemented */ }; static const struct wmi_ops wmi_10_1_ops = { @@ -5275,6 +5276,7 @@ static const struct wmi_ops wmi_10_1_ops = { /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ + /* .gen_adaptive_qcs not implemented */ }; static const struct wmi_ops
[PATCH v5 6/7] ath10k: enable multi-channel on supported devices
This effectively enables multi-channel operation on qca6174 WLAN.RM.2.0-00073 (and possibly any newer firmware release for qca6174). This adds appopriate interface combinations and initializes firmware channel scheduler. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- Notes: v5: * fix combination definition: increase vif limit from 2 to 3 drivers/net/wireless/ath/ath10k/mac.c | 81 ++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1d6191d89586..47f0c77b9271 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3721,6 +3721,15 @@ static int ath10k_start(struct ieee80211_hw *hw) goto err_core_stop; } + if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar-wmi.svc_map)) { + ret = ath10k_wmi_adaptive_qcs(ar, true); + if (ret) { + ath10k_warn(ar, failed to enable adaptive qcs: %d\n, + ret); + goto err_core_stop; + } + } + if (ar-cfg_tx_chainmask) __ath10k_set_antenna(ar, ar-cfg_tx_chainmask, ar-cfg_rx_chainmask); @@ -6474,6 +6483,64 @@ static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = { }, }; +static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION) | +BIT(NL80211_IFTYPE_AP) | +BIT(NL80211_IFTYPE_P2P_CLIENT) | +BIT(NL80211_IFTYPE_P2P_GO), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE), + }, +}; + +static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_ADHOC), + }, +}; + +/* FIXME: This is not thouroughly tested. These combinations may over- or + * underestimate hw/fw capabilities. + */ +static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = { + { + .limits = ath10k_tlv_if_limit, + .num_different_channels = 1, + .max_interfaces = 3, + .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit), + }, + { + .limits = ath10k_tlv_if_limit_ibss, + .num_different_channels = 1, + .max_interfaces = 2, + .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss), + }, +}; + +static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = { + { + .limits = ath10k_tlv_if_limit, + .num_different_channels = 2, + .max_interfaces = 3, + .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit), + }, + { + .limits = ath10k_tlv_if_limit_ibss, + .num_different_channels = 1, + .max_interfaces = 2, + .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss), + }, +}; + static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) { struct ieee80211_sta_vht_cap vht_cap = {0}; @@ -6766,12 +6833,24 @@ int ath10k_mac_register(struct ath10k *ar) switch (ar-wmi.op_version) { case ATH10K_FW_WMI_OP_VERSION_MAIN: - case ATH10K_FW_WMI_OP_VERSION_TLV: ar-hw-wiphy-iface_combinations = ath10k_if_comb; ar-hw-wiphy-n_iface_combinations = ARRAY_SIZE(ath10k_if_comb); ar-hw-wiphy-interface_modes |= BIT(NL80211_IFTYPE_ADHOC); break; + case ATH10K_FW_WMI_OP_VERSION_TLV: + if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar-wmi.svc_map)) { + ar-hw-wiphy-iface_combinations = + ath10k_tlv_qcs_if_comb; + ar-hw-wiphy-n_iface_combinations = + ARRAY_SIZE(ath10k_tlv_qcs_if_comb); + } else { + ar-hw-wiphy-iface_combinations = ath10k_tlv_if_comb; + ar-hw-wiphy-n_iface_combinations = + ARRAY_SIZE(ath10k_tlv_if_comb); + } + ar-hw-wiphy-interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + break; case ATH10K_FW_WMI_OP_VERSION_10_1: case ATH10K_FW_WMI_OP_VERSION_10_2: case ATH10K_FW_WMI_OP_VERSION_10_2_4: -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] ath10k: implement more versatile set_bitrate_mask
Until now only a single fixed tx rate or nss was allowed to be set. The patch attempts to improve this by allowing most bitrate masks. The limitation is VHT MCS rates cannot be expressed separately and only the following VHT MCS ranges are supported: none, 0-7, 0-8, and 0-9. This keeps the old behaviour when requesting single tx rate or single nss. The new bitrate mask logic is only applied to other cases that would return -EINVAL until now. Depending on firmware revisions some combinations may crash firmware so use with care, please. Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/mac.c | 265 ++--- 2 files changed, 247 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 7ab88fc611a9..ec639cce76ea 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -354,6 +354,7 @@ struct ath10k_vif { struct wmi_wmm_params_all_arg wmm_params; struct work_struct ap_csa_work; struct delayed_work connection_loss_work; + struct cfg80211_bitrate_mask bitrate_mask; }; struct ath10k_vif_iter { diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c8cb7aa6856b..2c990271e1e3 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -130,6 +130,30 @@ static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss) return 0; } +static u32 +ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) +{ + int nss; + + for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss = 0; nss--) + if (ht_mcs_mask[nss]) + return nss + 1; + + return 1; +} + +static u32 +ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) +{ + int nss; + + for (nss = NL80211_VHT_NSS_MAX - 1; nss = 0; nss--) + if (vht_mcs_mask[nss]) + return nss + 1; + + return 1; +} + /**/ /* Crypto */ /**/ @@ -2008,6 +2032,7 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar, struct ath10k_chanctx *arctx = ath10k_mac_vif_ctx(arvif); const struct ieee80211_supported_band *sband; const struct ieee80211_rate *rates; + enum ieee80211_band band; u32 ratemask; u8 rate; int i; @@ -2017,8 +2042,10 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar, if (WARN_ON(!arctx)) return; - sband = ar-hw-wiphy-bands[arctx-conf.def.chan-band]; - ratemask = sta-supp_rates[arctx-conf.def.chan-band]; + band = arctx-conf.def.chan-band; + sband = ar-hw-wiphy-bands[band]; + ratemask = sta-supp_rates[band]; + ratemask = arvif-bitrate_mask.control[band].legacy; rates = sband-bitrates; rateset-num_rates = 0; @@ -2033,19 +2060,58 @@ static void ath10k_peer_assoc_h_rates(struct ath10k *ar, } } +static bool ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) +{ + int nss; + + for (nss = 0; nss IEEE80211_HT_MCS_MASK_LEN; nss++) + if (ht_mcs_mask[nss]) + return false; + + return true; +} + +static bool ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) +{ + int nss; + + for (nss = 0; nss NL80211_VHT_NSS_MAX; nss++) + if (vht_mcs_mask[nss]) + return false; + + return true; +} + static void ath10k_peer_assoc_h_ht(struct ath10k *ar, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct wmi_peer_assoc_complete_arg *arg) { const struct ieee80211_sta_ht_cap *ht_cap = sta-ht_cap; - int i, n; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + struct ath10k_chanctx *arctx = ath10k_mac_vif_ctx(arvif); + enum ieee80211_band band; + const u8 *ht_mcs_mask; + const u16 *vht_mcs_mask; + int i, n, max_nss; u32 stbc; lockdep_assert_held(ar-conf_mutex); + if (WARN_ON(!arctx)) + return; + if (!ht_cap-ht_supported) return; + band = arctx-conf.def.chan-band; + ht_mcs_mask = arvif-bitrate_mask.control[band].ht_mcs; + vht_mcs_mask = arvif-bitrate_mask.control[band].vht_mcs; + + if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) + ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) + return; + arg-peer_flags |= WMI_PEER_HT; arg-peer_max_mpdu = (1 (IEEE80211_HT_MAX_AMPDU_FACTOR + ht_cap-ampdu_factor)) - 1; @@ -2064,11 +2130,13 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
[PATCH 0/2] ath10k: improve set_bitrate_mask
This makes set_bitrate_mask more flexible by allowing more than applying simple single rate or max nss limits. This still isn't ideal and VHT MCSs can't be set separately (only a few range-options are allowed). This depends on: * ath10k: add multi-channel support * ath10k: cleanups 2015-03-20 Based on: * Kalle's pending branch + multi-channel support This will not apply cleanly without multi-channel support and conflict resolution will be non-trivial. Michal Kazior (2): ath10k: clean up set_bitrate_mask handling ath10k: implement more versatile set_bitrate_mask drivers/net/wireless/ath/ath10k/core.h | 4 +- drivers/net/wireless/ath/ath10k/mac.c | 705 +++-- 2 files changed, 419 insertions(+), 290 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] ath10k: clean up set_bitrate_mask handling
The code was a bit convoluted. Clean it up and prepare for future changes. While at it this fixes incorrect verification of 'single nss' case when ss2 rates were missing while ss1 and ss3 were requested resulting in nss=3 being set: iw wlan1 set bitrates legacy-5 ht-mcs-5 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 vht-mcs-5 1:0-9 3:0-9 Signed-off-by: Michal Kazior michal.kaz...@tieto.com --- drivers/net/wireless/ath/ath10k/core.h | 3 - drivers/net/wireless/ath/ath10k/mac.c | 446 + 2 files changed, 175 insertions(+), 274 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index cbb58ff8fc25..7ab88fc611a9 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -348,9 +348,6 @@ struct ath10k_vif { } ap; } u; - u8 fixed_rate; - u8 fixed_nss; - u8 force_sgi; bool use_cts_prot; int num_legacy_stations; int txpower; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 47f0c77b9271..c8cb7aa6856b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -120,6 +120,16 @@ u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband, return 0; } +static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss) +{ + switch ((mcs_map (2 * nss)) 0x3) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1; + case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1; + case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1; + } + return 0; +} + /**/ /* Crypto */ /**/ @@ -5579,327 +5589,221 @@ exit: return ret; } -/* Check if only one bit set */ -static int ath10k_check_single_mask(u32 mask) +static bool +ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar, + enum ieee80211_band band, + const struct cfg80211_bitrate_mask *mask) { - int bit; + int num_rates = 0; + int i; + + num_rates += hweight32(mask-control[band].legacy); + + for (i = 0; i ARRAY_SIZE(mask-control[band].ht_mcs); i++) + num_rates += hweight8(mask-control[band].ht_mcs[i]); + + for (i = 0; i ARRAY_SIZE(mask-control[band].vht_mcs); i++) + num_rates += hweight16(mask-control[band].vht_mcs[i]); + + return num_rates == 1; +} + +static bool +ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar, + enum ieee80211_band band, + const struct cfg80211_bitrate_mask *mask, + int *nss) +{ + struct ieee80211_supported_band *sband = ar-mac.sbands[band]; + u16 vht_mcs_map = le16_to_cpu(sband-vht_cap.vht_mcs.tx_mcs_map); + u8 ht_nss_mask = 0; + u8 vht_nss_mask = 0; + int i; + + if (mask-control[band].legacy) + return false; + + for (i = 0; i ARRAY_SIZE(mask-control[band].ht_mcs); i++) { + if (mask-control[band].ht_mcs[i] == 0) + continue; + else if (mask-control[band].ht_mcs[i] == +sband-ht_cap.mcs.rx_mask[i]) + ht_nss_mask |= BIT(i); + else + return false; + } + + for (i = 0; i ARRAY_SIZE(mask-control[band].vht_mcs); i++) { + if (mask-control[band].vht_mcs[i] == 0) + continue; + else if (mask-control[band].vht_mcs[i] == +ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i)) + vht_nss_mask |= BIT(i); + else + return false; + } + + if (ht_nss_mask != vht_nss_mask) + return false; + + if (ht_nss_mask == 0) + return false; + + if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask) + return false; + + *nss = fls(ht_nss_mask); + + return true; +} + +static int +ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar, + enum ieee80211_band band, + const struct cfg80211_bitrate_mask *mask, + u8 *rate, u8 *nss) +{ + struct ieee80211_supported_band *sband = ar-mac.sbands[band]; + int rate_idx; + int i; + u16 bitrate; + u8 preamble; + u8 hw_rate; + + if (hweight32(mask-control[band].legacy) == 1) { + rate_idx = ffs(mask-control[band].legacy) - 1; + + hw_rate = sband-bitrates[rate_idx].hw_value; + bitrate = sband-bitrates[rate_idx].bitrate; + + if (ath10k_mac_bitrate_is_cck(bitrate)) + preamble = WMI_RATE_PREAMBLE_CCK; +
Re: [PATCH v7 0/6] wlcore: add device-tree support
Hi Eliad, On 03/18/2015 06:38 PM, Eliad Peller wrote: Add device-tree support to the wlcore (wl12xx/wl18xx) driver. Update the current users to use the bindings instead of pdata-quirks. Finally, remove the deprecated wl12xx_platform_data struct (along with the da850 board file code that still uses it) Tested-by: Nikita Kiryanov nik...@compulab.co.il Tested on am437x-gp-evm with WL1835MODCOM8B -- Regards, Nikita Kiryanov -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] mac80111: aes_ccm: cleanup ieee80211_aes_key_setup_encrypt()
On 23 March 2015 at 15:08, Dan Carpenter dan.carpen...@oracle.com wrote: This code is written using an anti-pattern called success handling which makes it hard to read, especially if you are used to normal kernel style. It should instead be written as a list of directives in a row with branches for error handling. Signed-off-by: Dan Carpenter dan.carpen...@oracle.com Acked-by: Ard Biesheuvel ard.biesheu...@linaro.org Thanks, Ard. diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 7869bb40..208df7c 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -85,11 +85,15 @@ struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], return tfm; err = crypto_aead_setkey(tfm, key, key_len); - if (!err) - err = crypto_aead_setauthsize(tfm, mic_len); - if (!err) - return tfm; + if (err) + goto free_aead; + err = crypto_aead_setauthsize(tfm, mic_len); + if (err) + goto free_aead; + + return tfm; +free_aead: crypto_free_aead(tfm); return ERR_PTR(err); } -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] iwlwifi: Fix memory leak in iwl_req_fw_callback()
On Mon, 2015-03-23 at 14:07 -0500, Larry Finger wrote: In this routine, kzalloc allocates a memory block. This allocation is freed in the error paths, but not in the normal exit, thus the allocation is leaked. The kmemleak facility was used to find the leak. Picked up - thanks. Signed-off-by: Larry Finger larry.fin...@lwfinger.net Cc: Johannes Berg johannes.b...@intel.com Cc: Emmanuel Grumbach emmanuel.grumb...@intel.com Cc: Intel Linux Wireless i...@linux.intel.com --- drivers/net/wireless/iwlwifi/iwl-drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 66ca000..aefdd9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1319,6 +1319,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) op-name, err); #endif } + kfree(pieces); return; try_again:
Fwd: [Battlemesh] Announcing Battlemesh V8 Maribor, Slovenia
I'm sure there are some on this list who will be interested in joining! Please spread the word. :) -- Forwarded Message -- Subject: [Battlemesh] Announcing Battlemesh V8 Maribor, Slovenia Date: Monday 23 March 2015, 17:13:18 From: Musti mu...@wlan-si.net To: Battle of the Mesh Mailing List battlem...@ml.ninux.org == Announcing the Wireless Battle Mesh v8 (3rd - 9th of August 2015, Maribor, Slovenia) == The next 'Wireless Battle of the Mesh' will take place from Mon 3rd till Sun 9th of August at Dom Obrambe Pekre, Maribor, Slovenia. The event aims to bring together people from across the globe to test the performance of different routing protocols for ad-hoc networks, like Babel, B.A.T.M.A.N., BMX, OLSR, and 802.11s. Of course, new protocols (working on OpenWrt) are always welcome! It is not required to be active within the mentioned protocols, so if you are a mesh networking enthusiast, community networking activist, or have an interest in mesh networks in general, you have to check this out! Information about the event is gathered at: http://battlemesh.org/BattleMeshV8 Location The event takes place at the Dom Obrambe Pekre, Maribor, Slovenia. It features one large dining hall with an attached smaller hall for talks, a large lecture theater, several smaller classrooms and an outdoor auditorium. Expect to find nice community WiFi internet connection (open.wlan-si.net), video projectors, beverage and snack supplies and some curious hackers. Participant Registration and Fee The event itself is free of charge and open for all, so to register without hotel and food supply, simply add your name to the participant table. http://battlemesh.org/BattleMeshV8/Participants If you wish low cost accommodation, a special group booking has been arranged. Payment in advance is required to get the full benefit of the discount. Therefore, like for the previous event, this year's edition features an early bird low cost registration program with two accomodation options: Hotel Milena: - Hotel Milena is a family run hotel under mountain Pohorje for which the accommodation is offered in a package. Rooms are for 2-4 people, some rooms have a double bed only. In the case of a large number of participants some accommodation will be in the neighbouring hotels as well. Breakfast is included. There is a 15min walk to the conference venue. Early bird booking is available for 6 nights (August 3rd to 9th) for 150 EUR if payment is received before 18th April. The price goes up to EUR 175,00 for all later payments. These late arrangements are subject to availability. Camping: Camping Kekec is a camping place in the vicinity of Hotel Milena, all the usual camping amnesties available. No breakfast included. There are shops nearby, walking to the conference venue takes 18 minutes. Early bird booking is available for 6 nights (August 3rd to 9th) for 45 EUR if payment is received before 18th April The price goes up to EUR 55,00 for all later payments. These late arrangements are subject to availability. General: For any additional information, requests and inquiries get in touch with the local organization team: battlemeshv8 at wlan-si.net Of course, this package is not compulsory. You can also find your own bed and food supply yourself during the event if you wish to do so. Payment information can be found be found here on the Battlemesh Wiki: http://battlemesh.org/BattleMeshV8#Participant_Registration_and_Fee Spread the Word === Feel free to spread the word by forwarding this mail to all lists / people that might be interested in it. Blogging about the event is more than welcome, and if you do so, please add a ping-back to the wiki page: http://battlemesh.org/BattleMeshV8 Contact === * Web: http://battlemesh.org/BattleMeshV8 * Email: http://ml.ninux.org/mailman/listinfo/battlemesh * IRC: irc.freenode.net #battlemesh Kind regards, Musti ___ Battlemesh mailing list battlem...@ml.ninux.org http://ml.ninux.org/mailman/listinfo/battlemesh - signature.asc Description: This is a digitally signed message part.
Re: [PATCH] staging: rtl8723au: Update RT_TRACE macro and uses
Joe Perches j...@perches.com writes: Create an rt_trace function using %pV to reduce overall code size. Update the macro uses to remove unnecessary and now harmful parentheses. Miscellanea around these changes: o Coalesce formats o Realign arguments o Remove commented-out RT_TRACE uses o Spelling fixes in formats o Add missing newlines to formats o Remove multiple newlines from formats o Neaten formats where noticed o Use %pM in one instance Reduces code size ~20KB Signed-off-by: Joe Perches j...@perches.com --- Mostly done by various scriptsemacs. Compiled, untested, no hardware, This could be further improved by fixing up all the places where the function name is hard coded into the print statement, instead of using __func__. In particular as a lot of it is carried over from old code and has been renamed since. It's OK with me to do this in a follow-on patch though. Jes -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/10] Improve Minstrels Minstrel-HTs common code base statistics
On 2015-03-24 21:09, Thomas Huehn wrote: This patch series adds several improvements to the readability, the output format of rc_stats and the calculated statistics of Minstrel and Minstrel-HT. Variable names got more consistent and functions got unified between both rate control algorithms. Acked-by: Felix Fietkau n...@openwrt.org -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: informations about Linux wifi driver's architecture today
Thank you very much Arend, in particular for the documentation. If i understand correctly, the levels are: userspace nl802111 cfg80211 firmware No mac80211 because is a fullmac. Correct? Thank u, Stefano. Da: Arend van Spriel ar...@broadcom.com Inviato: lunedì 23 marzo 2015 11.03 A: Stefano Cappa Cc: linux-wireless@vger.kernel.org Oggetto: Re: informations about Linux wifi driver's architecture today On 03/22/15 22:21, Stefano Cappa wrote: Hi I prefer a generic version, without specific things, like this one: h**p://postimg.org/image/hfkpjt3ux/ created by Johannes Berg. And, if available something for the broadcom chip bcm4339. Hi Stefano, The bcm4339 is supported by the brcmfmac driver and is a cfg8211-based driver aka fullmac device where the 802.11 stack runs on the device. I did write up some stuff about the driver internally, but we can consider putting it on wireless.kernel.org under creative commons license. Regards, Arend Thank you. Da: Kathy Giorikathy.gi...@gmail.com Inviato: domenica 22 marzo 2015 19.35 A: Stefano Cappa Cc: linux-wireless@vger.kernel.org Oggetto: Re: informations about Linux wifi driver's architecture today On Sun, Mar 22, 2015 at 11:19 AM, Stefano Cappa stefano.ca...@mail.polimi.it wrote: Hi! some months ago, i saw the presentation of Johannes Berg in PDF, but now it isn't available, probably because it's very old. This slides will be updated to a new release? I have this slide and in page 5/35 (2009-02-26) there is the Architecture - planned. This is the actual architecture or there are some differences in 2015? If yes, where i can find the new version of this page, with a little diagram? Ciao Stefano, Perhaps Johannes can post a current overview diagram on the Linux wireless wiki (if you share with him which diagram you want to be updated). In terms of vendor-specific architecture, and how it fits in, Kalle Valo posted a high-level diagram for ath10k: https://wireless.wiki.kernel.org/en/users/drivers/ath10k/architecture Are you mainly interested in the architecture of vendor-agnostic upper layers or a description of a specific vendor driver? kg-- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] staging: rtl8723au: Remove uses of MAC_FMT and MAC_ARG
Joe Perches j...@perches.com writes: Use the standard vsprintf kernel extension to format mac addresses. This reduces object code size a bit. Miscellanea: o Coalesce formats o Realign arguments o Remove the now unused MAC_FMT and MAC_ARG #defines Signed-off-by: Joe Perches j...@perches.com --- drivers/staging/rtl8723au/core/rtw_ap.c | 41 ++--- drivers/staging/rtl8723au/core/rtw_mlme.c | 26 drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 72 +++ drivers/staging/rtl8723au/core/rtw_recv.c | 42 + drivers/staging/rtl8723au/core/rtw_wlan_util.c| 6 +- drivers/staging/rtl8723au/core/rtw_xmit.c | 8 +-- drivers/staging/rtl8723au/include/ieee80211.h | 3 - drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 18 +++--- drivers/staging/rtl8723au/os_dep/os_intfs.c | 7 +-- 9 files changed, 101 insertions(+), 122 deletions(-) Looks good to me Acked-by: Jes Sorensen jes.soren...@redhat.com -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: pull-request: wireless-drivers 2015-03-24
From: Kalle Valo kv...@qca.qualcomm.com Date: Tue, 24 Mar 2015 08:29:54 +0200 here are few more fixes I would like to still get to 4.0 if possible, detailed info in the tag below. Please let me know if there are any problems. Pulled, thanks Kalle. -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 0/6] wlcore: add device-tree support
hi Nikita, On Tue, Mar 24, 2015 at 1:37 PM, Nikita Kiryanov nik...@compulab.co.il wrote: Hi Eliad, On 03/18/2015 06:38 PM, Eliad Peller wrote: Add device-tree support to the wlcore (wl12xx/wl18xx) driver. Update the current users to use the bindings instead of pdata-quirks. Finally, remove the deprecated wl12xx_platform_data struct (along with the da850 board file code that still uses it) Tested-by: Nikita Kiryanov nik...@compulab.co.il Tested on am437x-gp-evm with WL1835MODCOM8B thanks for testing it! Eliad. -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
pull-request: wireless-drivers 2015-03-24
Hi Dave, here are few more fixes I would like to still get to 4.0 if possible, detailed info in the tag below. Please let me know if there are any problems. Kalle The following changes since commit 3f1615340acea54e21f4b9d4d65921540dca84b2: brcmfmac: Perform bound checking on vendor command buffer (2015-03-07 10:52:30 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git tags/wireless-drivers-for-davem-2015-03-24 for you to fetch changes up to 6ae4ccfee09efe5baa3951d1c1d27050a46a1469: Merge tag 'iwlwifi-for-kalle-2014-03-22' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes (2015-03-23 06:43:43 +0200) iwlwifi: * avoid panic with lots of IBSS stations * Fix dvm's behavior after suspend resume * Allow to keep connection after CSA failure * Remove a noisy by harmless WARN_ON * New device IDs rtlwifi: * fix IOMMU mapping leak in AP mode brcmfmac: * disable MBSS feature for BCM43362 to get AP mode working again ath9k: * disable Transmit Power Control (TPC) again due to regressions * fix beaconing issue with AP+STA setup Arend van Spriel (1): brcmfmac: disable MBSS feature for BCM43362 Emmanuel Grumbach (2): iwlwifi: dvm: drop VO packets when mac80211 tells us to iwlwifi: dvm: run INIT firmware again upon .start() Felix Fietkau (2): ath9k: fix tracking of enabled AP beacons ath9k: disable TPC support again (for now) Johannes Berg (3): iwlwifi: mvm: disconnect if CSA time event fails scheduling iwlwifi: mvm: protect rate scaling against non-mvm IBSS stations iwlwifi: mvm: remove WARN_ON for invalid BA notification Kalle Valo (1): Merge tag 'iwlwifi-for-kalle-2014-03-22' of https://git.kernel.org/.../iwlwifi/iwlwifi-fixes Larry Finger (1): rtlwifi: Fix IOMMU mapping leak in AP mode Oren Givon (1): iwlwifi: add new 3165 series PCI IDs drivers/net/wireless/ath/ath9k/beacon.c | 20 ++--- drivers/net/wireless/ath/ath9k/common.h |2 +- drivers/net/wireless/ath/ath9k/hw.c |2 +- drivers/net/wireless/brcm80211/brcmfmac/feature.c |3 ++- drivers/net/wireless/iwlwifi/dvm/dev.h|1 - drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 --- drivers/net/wireless/iwlwifi/dvm/ucode.c |5 - drivers/net/wireless/iwlwifi/mvm/rs.c | 24 +++-- drivers/net/wireless/iwlwifi/mvm/time-event.c |2 ++ drivers/net/wireless/iwlwifi/mvm/tx.c |6 -- drivers/net/wireless/iwlwifi/pcie/drv.c |6 -- drivers/net/wireless/rtlwifi/pci.c| 12 ++- 12 files changed, 68 insertions(+), 32 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ath10k: What will happens when radar is detected ?
On 23 March 2015 at 16:16, Cedric VONCKEN cedric.vonc...@acksys.fr wrote: In 802.11ac standard, it is possible to dynamically reduce the channel width used. My question is: If I use a channel with 80 or 40 MHz width, what will happen if I detect radar? The ath10k card/driver reduces automatically the channel width. Currently entire chandef occupied will be marked as unavailable and AP will stop/switch to a different non-overlapping chandef via CSA. I guess it should be possible to implement what you suggest, i.e. change only chandef width when radar is narrow and located at a suitable part of the chandef. This would require hw to be capable of detecting radar center freq and width accurately. I'm not sure if QCA988X is capable of that although firmware interface seems to be able to carry this kind of information already. I wonder why would you want this behaviour in the first place? Wouldn't this actually end up with having less bandwidth and lower throughput (which is already penalized when radar detection is active)? Michał -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ath10k: share board file loading code across FW APIs
On 23 March 2015 at 17:01, Kalle Valo kv...@qca.qualcomm.com wrote: Michal Kazior michal.kaz...@tieto.com writes: There's no need to implement the same thing twice. Reduce code duplication. Signed-off-by: Michal Kazior michal.kaz...@tieto.com [...] @@ -730,6 +716,12 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) /* calibration file is optional, don't check for any errors */ ath10k_fetch_cal_file(ar); + ret = ath10k_core_fetch_board_file(ar); + if (ret) { + ath10k_err(ar, failed to fetch board file: %d\n, ret); + return ret; + } + ar-fw_api = 4; ath10k_dbg(ar, ATH10K_DBG_BOOT, trying fw api %d\n, ar-fw_api); There was a conflict here, please check the resolution in the pending branch. Looks good, thanks! Michał -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: ath10k: What will happens when radar is detected ?
-Message d'origine- De : Michal Kazior [mailto:michal.kaz...@tieto.com] Envoyé : mardi 24 mars 2015 07:56 À : Cedric VONCKEN Cc : linux-wireless Objet : Re: ath10k: What will happens when radar is detected ? On 23 March 2015 at 16:16, Cedric VONCKEN cedric.vonc...@acksys.fr wrote: In 802.11ac standard, it is possible to dynamically reduce the channel width used. My question is: If I use a channel with 80 or 40 MHz width, what will happen if I detect radar? The ath10k card/driver reduces automatically the channel width. Currently entire chandef occupied will be marked as unavailable and AP will stop/switch to a different non-overlapping chandef via CSA. Thanks for your answer. I guess it should be possible to implement what you suggest, i.e. change only chandef width when radar is narrow and located at a suitable part of the chandef. This would require hw to be capable of detecting radar center freq and width accurately. I'm not sure if QCA988X is capable of that although firmware interface seems to be able to carry this kind of information already. I wonder why would you want this behaviour in the first place? Wouldn't this actually end up with having less bandwidth and lower throughput (which is already penalized when radar detection is active)? In an industrial environment we prefer to reduce the throughput but keep the link without gap. I think it can be a parameter in AP software for example. Cédric -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
Marek Puzyniak marek.puzyn...@tieto.com writes: On 23 March 2015 at 11:53, Kalle Valo kv...@qca.qualcomm.com wrote: Marek Puzyniak marek.puzyn...@tieto.com writes: As a part of tdls implementation introduce tdls related wmi data structures, constant values and functions. Signed-off-by: Marek Puzyniak marek.puzyn...@tieto.com This patch had non-trivial conflicts, please check carefully my resolution in the pending branch. CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h -- Kalle Valo It looks OK, but there is one small thing in file drivers/net/wireless/ath/ath10k/wmi-tlv.c. There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update and ath10k_wmi_tlv_op_gen_wow_enable. Thanks, fixed now. -- Kalle Valo -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/10] Improve Minstrels Minstrel-HTs common code base statistics
This patch series adds several improvements to the readability, the output format of rc_stats and the calculated statistics of Minstrel and Minstrel-HT. Variable names got more consistent and functions got unified between both rate control algorithms. Greetings Thomas --- Changes in v2: - fix define MACRO from CPTCFG_* into CONFIG_* - change standard deviation symbol sigma into sd Changes in v3: - fix coding style of return value parts - move tp_max calculation into tp_avg function in Minstrel-HT - reorder function changes to make patch series consistent (thx to Felix Fietkau for his review comments) Changes in v4: - move tp_max calculation into tp_avg function in legacy Minstrel - remove unused function declaration (thx to Felix Fietkau for his review comments) [PATCH v4 01/10] mac80211: enhance readability of Minstrels rc_stats [PATCH v4 02/10] mac80211: enhance readability of Minstrel-HTs [PATCH v4 03/10] mac80211: add new Minstrel statistic output via csv [PATCH v4 04/10] mac80211: add new Minstrel-HT statistic output via [PATCH v4 05/10] mac80211: unify Minstrel Minstrel-HTs calculation [PATCH v4 06/10] mac80211: improve Minstrel variable function [PATCH v4 07/10] mac80211: restructure per-rate throughput [PATCH v4 08/10] mac80211: add max lossless throughput per rate [PATCH v4 09/10] mac80211: reduce calculation costs of EWMA [PATCH v4 10/10] mac80211: add standard deviation to Minstrel stats -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 01/10] mac80211: enhance readability of Minstrels rc_stats output
This patch restructures the rc_stats debugfs table of Minstrel in order to achieve better human readability. A new layout of the statistics and a new header is added. In addition to the old layout there are two new columns of information added: idx - representing the rate index of each rate in mac80211 which can be used to set specific rates as fixed rate via debugfs airtime - the tx-time in micro seconds that a 1200 Byte packet takes to be transmitted over the air at the given rate The old layout of rc_stats: rate tpt eprob *prob ret *ok(*cum)ok( cum) DP 1 0.9 93.5 100.0 10( 0) 2(2) 2 0.4 40.0 100.0 00( 0) 4(10) 5.50.0 0.0 0.0 00( 0) 0(0) ... is changed into this new layout: best ___rate___statistics__last___ __sum-of rate [name idx tx-time] [ ø(tp) ø(prob)] [prob.|retry|suc|att] [#success | #attempts] DP 1 0 9738 0.993.5 100.0 1 1 1 2 2 2 1 4922 0.440.0 100.0 1 0 0 4 10 5.5 2 1858 0.0 0.0 0.0 2 0 0 0 0 ... Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de Signed-off-by: Stefan Venz ikstrea...@gmail.com --- net/mac80211/rc80211_minstrel_debugfs.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index 2acab1b..2d70081 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c @@ -68,8 +68,12 @@ minstrel_stats_open(struct inode *inode, struct file *file) file-private_data = ms; p = ms-buf; - p += sprintf(p, rate tpt eprob *prob - *ok(*cum)ok( cum)\n); + p += sprintf(p, \n); + p += sprintf(p, best ___rate___statistics__ + last_____sum-of\n); + p += sprintf(p, rate [name idx airtime] [ ø(tp) ø(prob)] + [prob.|retry|suc|att] [#success | #attempts]\n); + for (i = 0; i mi-n_rates; i++) { struct minstrel_rate *mr = mi-r[i]; struct minstrel_rate_stats *mrs = mi-r[i].stats; @@ -79,18 +83,22 @@ minstrel_stats_open(struct inode *inode, struct file *file) *(p++) = (i == mi-max_tp_rate[2]) ? 'C' : ' '; *(p++) = (i == mi-max_tp_rate[3]) ? 'D' : ' '; *(p++) = (i == mi-max_prob_rate) ? 'P' : ' '; - p += sprintf(p, %3u%s, mr-bitrate / 2, + + p += sprintf(p, %3u%s , mr-bitrate / 2, (mr-bitrate 1 ? .5 : )); + p += sprintf(p, %3u , i); + p += sprintf(p, %6u , mr-perfect_tx_time); tp = MINSTREL_TRUNC(mrs-cur_tp / 10); prob = MINSTREL_TRUNC(mrs-cur_prob * 1000); eprob = MINSTREL_TRUNC(mrs-probability * 1000); - p += sprintf(p, %4u.%1u %3u.%1u %3u.%1u -%4u(%4u) %9llu(%9llu)\n, + p += sprintf(p, %4u.%1u %3u.%1u %3u.%1u %3u + %3u %-3u %9llu %-9llu\n, tp / 10, tp % 10, eprob / 10, eprob % 10, prob / 10, prob % 10, + mrs-retry_count, mrs-last_success, mrs-last_attempts, (unsigned long long)mrs-succ_hist, -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 08/10] mac80211: add max lossless throughput per rate
This patch adds the new statistic maximum possible lossless throughput to Minstrels and Minstrel-HTs rc_stats (in debugfs). This enables comprehensive comparison between current per-rate throughput and max. achievable per-rate throughput. Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de --- net/mac80211/rc80211_minstrel.c| 27 +++--- net/mac80211/rc80211_minstrel.h| 2 +- net/mac80211/rc80211_minstrel_debugfs.c| 22 net/mac80211/rc80211_minstrel_ht.c | 84 -- net/mac80211/rc80211_minstrel_ht.h | 3 +- net/mac80211/rc80211_minstrel_ht_debugfs.c | 24 + 6 files changed, 93 insertions(+), 69 deletions(-) diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index d985227..18f1d72 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -70,7 +70,7 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) } /* return current EMWA throughput */ -int minstrel_get_tp_avg(struct minstrel_rate *mr) +int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma) { int usecs; @@ -81,8 +81,11 @@ int minstrel_get_tp_avg(struct minstrel_rate *mr) /* reset thr. below 10% success */ if (mr-stats.prob_ewma MINSTREL_FRAC(10, 100)) return 0; + + if (prob_ewma MINSTREL_FRAC(90, 100)) + return MINSTREL_TRUNC(10 * (MINSTREL_FRAC(90, 100) / usecs)); else - return MINSTREL_TRUNC(mr-stats.prob_ewma * (10 / usecs)); + return MINSTREL_TRUNC(10 * (prob_ewma / usecs)); } /* find sort topmost throughput rates */ @@ -90,10 +93,14 @@ static inline void minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) { int j = MAX_THR_RATES; + struct minstrel_rate_stats *tmp_mrs = mi-r[j - 1].stats; + struct minstrel_rate_stats *cur_mrs = mi-r[i].stats; - while (j 0 (minstrel_get_tp_avg(mi-r[i]) - minstrel_get_tp_avg(mi-r[tp_list[j - 1]]))) + while (j 0 (minstrel_get_tp_avg(mi-r[i], cur_mrs-prob_ewma) + minstrel_get_tp_avg(mi-r[tp_list[j - 1]], tmp_mrs-prob_ewma))) { j--; + tmp_mrs = mi-r[tp_list[j - 1]].stats; + } if (j MAX_THR_RATES - 1) memmove(tp_list[j + 1], tp_list[j], MAX_THR_RATES - (j + 1)); @@ -184,6 +191,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) for (i = 0; i mi-n_rates; i++) { struct minstrel_rate *mr = mi-r[i]; struct minstrel_rate_stats *mrs = mi-r[i].stats; + struct minstrel_rate_stats *tmp_mrs = mi-r[tmp_prob_rate].stats; /* Update success probabilities per rate */ minstrel_calc_rate_stats(mrs); @@ -212,12 +220,13 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) * (2) if all success probabilities 95%, the rate with * highest success probability is chosen as max_prob_rate */ if (mrs-prob_ewma = MINSTREL_FRAC(95, 100)) { - tmp_cur_tp = minstrel_get_tp_avg(mr); - tmp_prob_tp = minstrel_get_tp_avg(mi-r[tmp_prob_rate]); + tmp_cur_tp = minstrel_get_tp_avg(mr, mrs-prob_ewma); + tmp_prob_tp = minstrel_get_tp_avg(mi-r[tmp_prob_rate], + tmp_mrs-prob_ewma); if (tmp_cur_tp = tmp_prob_tp) tmp_prob_rate = i; } else { - if (mrs-prob_ewma = mi-r[tmp_prob_rate].stats.prob_ewma) + if (mrs-prob_ewma = tmp_mrs-prob_ewma) tmp_prob_rate = i; } } @@ -684,13 +693,15 @@ minstrel_free(void *priv) static u32 minstrel_get_expected_throughput(void *priv_sta) { struct minstrel_sta_info *mi = priv_sta; + struct minstrel_rate_stats *tmp_mrs; int idx = mi-max_tp_rate[0]; int tmp_cur_tp; /* convert pkt per sec in kbps (1200 is the average pkt size used for * computing cur_tp */ - tmp_cur_tp = minstrel_get_tp_avg(mi-r[idx]); + tmp_mrs = mi-r[idx].stats; + tmp_cur_tp = minstrel_get_tp_avg(mi-r[idx], tmp_mrs-prob_ewma); tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; return tmp_cur_tp; diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 490df3b..0083036 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h @@ -134,7 +134,7 @@ void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); /* Recalculate success probabilities and counters for a given rate using EWMA */ void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); -int minstrel_get_tp_avg(struct
[PATCH v4 03/10] mac80211: add new Minstrel statistic output via csv
This patch adds a new debugfs file rc_stats_csv to output Minstrels statistics in a common csv format that is easy to parse. Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de Signed-off-by: Stefan Venz ikstrea...@gmail.com --- net/mac80211/rc80211_minstrel.h | 6 +-- net/mac80211/rc80211_minstrel_debugfs.c | 95 + 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 410efe6..9613e73 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h @@ -13,7 +13,6 @@ #define EWMA_DIV 128 #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ - /* scaled fraction values */ #define MINSTREL_SCALE 16 #define MINSTREL_FRAC(val, div) (((val) MINSTREL_SCALE) / div) @@ -24,7 +23,7 @@ /* * Perform EWMA (Exponentially Weighted Moving Average) calculation - */ + */ static inline int minstrel_ewma(int old, int new, int weight) { @@ -95,6 +94,7 @@ struct minstrel_sta_info { #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *dbg_stats; + struct dentry *dbg_stats_csv; #endif }; @@ -121,7 +121,6 @@ struct minstrel_priv { u32 fixed_rate_idx; struct dentry *dbg_fixed_rate; #endif - }; struct minstrel_debugfs_info { @@ -135,6 +134,7 @@ void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); /* debugfs */ int minstrel_stats_open(struct inode *inode, struct file *file); +int minstrel_stats_csv_open(struct inode *inode, struct file *file); ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); int minstrel_stats_release(struct inode *inode, struct file *file); diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index 2d70081..8c35402 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c @@ -54,6 +54,22 @@ #include net/mac80211.h #include rc80211_minstrel.h +ssize_t +minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +{ + struct minstrel_debugfs_info *ms; + + ms = file-private_data; + return simple_read_from_buffer(buf, len, ppos, ms-buf, ms-len); +} + +int +minstrel_stats_release(struct inode *inode, struct file *file) +{ + kfree(file-private_data); + return 0; +} + int minstrel_stats_open(struct inode *inode, struct file *file) { @@ -115,25 +131,76 @@ minstrel_stats_open(struct inode *inode, struct file *file) return 0; } -ssize_t -minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +static const struct file_operations minstrel_stat_fops = { + .owner = THIS_MODULE, + .open = minstrel_stats_open, + .read = minstrel_stats_read, + .release = minstrel_stats_release, + .llseek = default_llseek, +}; + +int +minstrel_stats_csv_open(struct inode *inode, struct file *file) { + struct minstrel_sta_info *mi = inode-i_private; struct minstrel_debugfs_info *ms; + struct timeval tv; + unsigned int i, tp, prob, eprob; + char *p; - ms = file-private_data; - return simple_read_from_buffer(buf, len, ppos, ms-buf, ms-len); -} + ms = kmalloc(2048, GFP_KERNEL); + if (!ms) + return -ENOMEM; + + file-private_data = ms; + p = ms-buf; + + do_gettimeofday(tv); + + for (i = 0; i mi-n_rates; i++) { + struct minstrel_rate *mr = mi-r[i]; + struct minstrel_rate_stats *mrs = mi-r[i].stats; + + p += sprintf(p, %ld.%.6ld,, tv.tv_sec, tv.tv_usec); + p += sprintf(p, %s ,((i == mi-max_tp_rate[0]) ? A : )); + p += sprintf(p, %s ,((i == mi-max_tp_rate[1]) ? B : )); + p += sprintf(p, %s ,((i == mi-max_tp_rate[2]) ? C : )); + p += sprintf(p, %s ,((i == mi-max_tp_rate[3]) ? D : )); + p += sprintf(p, %s ,((i == mi-max_prob_rate) ? P : )); + + p += sprintf(p, ,%u%s, mr-bitrate / 2, + (mr-bitrate 1 ? .5, : ,)); + p += sprintf(p, %u,, i); + p += sprintf(p, %u,,mr-perfect_tx_time); + + tp = MINSTREL_TRUNC(mrs-cur_tp / 10); + prob = MINSTREL_TRUNC(mrs-cur_prob * 1000); + eprob = MINSTREL_TRUNC(mrs-probability * 1000); + + p += sprintf(p, %u.%u,%u.%u,%u.%u,%u,%u,%u, + %llu,%llu,%d,%d\n, + tp / 10, tp % 10, + eprob / 10, eprob % 10, + prob / 10, prob % 10, + mrs-retry_count, + mrs-last_success, + mrs-last_attempts, + (unsigned long long)mrs-succ_hist, + (unsigned long
[PATCH v4 02/10] mac80211: enhance readability of Minstrel-HTs rc_stats output
This patch restructures the rc_stats debugfs table of Minstrel-HT in order to achieve better human readability. A new layout of the statistics and a new header is added. In addition to the old layout there are two new columns of information added: idx - representing the rate index of each rate in mac80211 which can be used to set specific rates as fixed rate via debugfs airtime - the tx-time in micro seconds that a 1200 Byte packet takes to be transmitted over the air at the given rate The old layout of rc_stats: type rate tpt eprob *prob ret *ok(*cum)ok( cum) HT20/LGI MCS0 5.6 100.0 100.0 10( 0) 1(1) HT20/LGI B MCS1 10.5 100.0 100.0 00( 0) 1(1) HT20/LGI AMCS2 14.8 100.0 100.0 00( 0) 1(1) ... is changed into this new layout: best rate____statistics__last___ __sum-of mode guard # rate [name idx airtime] [ ø(tp) ø(prob)] [prob.|retry|suc|att] [#success | #attempts] HT20 LGI 1 MCS0 01480 0.0 0.0 0.0 1 0 0 0 0 HT20 LGI 1 B MCS1 1 740 10.5100.0100.0 0 0 0 1 1 HT20 LGI 1AMCS2 2 496 14.8100.0100.0 0 0 0 1 1 ... Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de Signed-off-by: Stefan Venz ikstrea...@gmail.com --- net/mac80211/rc80211_minstrel_ht_debugfs.c | 49 +- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 20c676b..7fc690f 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -19,7 +19,7 @@ static char * minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) { const struct mcs_group *mg; - unsigned int j, tp, prob, eprob; + unsigned int j, tp, prob, eprob, tx_time; char htmode = '2'; char gimode = 'L'; u32 gflags; @@ -45,12 +45,19 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (!(mi-groups[i].supported BIT(j))) continue; - if (gflags IEEE80211_TX_RC_MCS) - p += sprintf(p, HT%c0/%cGI , htmode, gimode); - else if (gflags IEEE80211_TX_RC_VHT_MCS) - p += sprintf(p, VHT%c0/%cGI , htmode, gimode); - else - p += sprintf(p, CCK/%cP , j 4 ? 'L' : 'S'); + if (gflags IEEE80211_TX_RC_MCS) { + p += sprintf(p, HT%c0 , htmode); + p += sprintf(p, %cGI , gimode); + p += sprintf(p, %d , mg-streams); + } else if (gflags IEEE80211_TX_RC_VHT_MCS) { + p += sprintf(p, VHT%c0 , htmode); + p += sprintf(p, %cGI , gimode); + p += sprintf(p, %d , mg-streams); + } else { + p += sprintf(p, CCK); + p += sprintf(p, %cP , j 4 ? 'L' : 'S'); + p += sprintf(p, 1 ); + } *(p++) = (idx == mi-max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi-max_tp_rate[1]) ? 'B' : ' '; @@ -59,21 +66,27 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) *(p++) = (idx == mi-max_prob_rate) ? 'P' : ' '; if (gflags IEEE80211_TX_RC_MCS) { - p += sprintf(p, MCS%-2u , (mg-streams - 1) * 8 + j); + p += sprintf(p, MCS%-2u, (mg-streams - 1) * 8 + j); } else if (gflags IEEE80211_TX_RC_VHT_MCS) { - p += sprintf(p, MCS%-1u/%1u, j, mg-streams); + p += sprintf(p, MCS%-1u/%1u, j, mg-streams); } else { int r = bitrates[j % 4]; - p += sprintf(p, %2u.%1uM , r / 10, r % 10); + p += sprintf(p,%2u.%1uM, r / 10, r % 10); } + p += sprintf(p, %3u , idx); + + /* tx_time[rate(i)] in usec */ + tx_time = DIV_ROUND_CLOSEST(mg-duration[j], 1000); + p += sprintf(p, %6u , tx_time); + tp = mr-cur_tp / 10; prob = MINSTREL_TRUNC(mr-cur_prob * 1000); eprob = MINSTREL_TRUNC(mr-probability * 1000); - p += sprintf(p, %4u.%1u %3u.%1u %3u.%1u - %3u %4u(%4u) %9llu(%9llu)\n, + p += sprintf(p, %4u.%1u %3u.%1u %3u.%1u + %3u %3u %-3u %9llu %-9llu\n, tp / 10, tp % 10,
[PATCH v4 05/10] mac80211: unify Minstrel Minstrel-HTs calculation of rate statistics
This patch unifies the calculation of Minstrels and Minstrel-HTs per-rate statistic. The new common function minstrel_calc_rate_stats() is called when a statistic update is performed. Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de --- net/mac80211/rc80211_minstrel.c| 44 -- net/mac80211/rc80211_minstrel.h| 3 +++ net/mac80211/rc80211_minstrel_ht.c | 28 +--- 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 7c86a00..4858e67 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -127,6 +127,32 @@ minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) rate_control_set_rates(mp-hw, mi-sta, ratetbl); } +/* +* Recalculate success probabilities and counters for a given rate using EWMA +*/ +void +minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) +{ + if (unlikely(mrs-attempts 0)) { + mrs-sample_skipped = 0; + mrs-cur_prob = MINSTREL_FRAC(mrs-success, mrs-attempts); + if (unlikely(!mrs-att_hist)) + mrs-probability = mrs-cur_prob; + else + mrs-probability = minstrel_ewma(mrs-probability, +mrs-cur_prob, EWMA_LEVEL); + mrs-att_hist += mrs-attempts; + mrs-succ_hist += mrs-success; + } else { + mrs-sample_skipped++; + } + + mrs-last_success = mrs-success; + mrs-last_attempts = mrs-attempts; + mrs-success = 0; + mrs-attempts = 0; +} + static void minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) { @@ -146,22 +172,8 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) if (!usecs) usecs = 100; - if (unlikely(mrs-attempts 0)) { - mrs-sample_skipped = 0; - mrs-cur_prob = MINSTREL_FRAC(mrs-success, - mrs-attempts); - mrs-succ_hist += mrs-success; - mrs-att_hist += mrs-attempts; - mrs-probability = minstrel_ewma(mrs-probability, -mrs-cur_prob, -EWMA_LEVEL); - } else - mrs-sample_skipped++; - - mrs-last_success = mrs-success; - mrs-last_attempts = mrs-attempts; - mrs-success = 0; - mrs-attempts = 0; + /* Update success probabilities per rate */ + minstrel_calc_rate_stats(mrs); /* Update throughput per rate, reset thr. below 10% success */ if (mrs-probability MINSTREL_FRAC(10, 100)) diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 9613e73..728144c 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h @@ -132,6 +132,9 @@ extern const struct rate_control_ops mac80211_minstrel; void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); +/* Recalculate success probabilities and counters for a given rate using EWMA */ +void minstrel_calc_rate_stats(struct minstrel_rate_stats *mr); + /* debugfs */ int minstrel_stats_open(struct inode *inode, struct file *file); int minstrel_stats_csv_open(struct inode *inode, struct file *file); diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 60698fc..7afa562 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -313,32 +313,6 @@ minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) return mi-groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; } - -/* - * Recalculate success probabilities and counters for a rate using EWMA - */ -static void -minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr) -{ - if (unlikely(mr-attempts 0)) { - mr-sample_skipped = 0; - mr-cur_prob = MINSTREL_FRAC(mr-success, mr-attempts); - if (!mr-att_hist) - mr-probability = mr-cur_prob; - else - mr-probability = minstrel_ewma(mr-probability, - mr-cur_prob, EWMA_LEVEL); - mr-att_hist += mr-attempts; - mr-succ_hist += mr-success; - } else { - mr-sample_skipped++; - } - mr-last_success = mr-success; - mr-last_attempts = mr-attempts; - mr-success = 0; - mr-attempts = 0; -} - /* * Calculate throughput based on the average A-MPDU length, taking
[PATCH v4 09/10] mac80211: reduce calculation costs of EWMA
This patch reduces the calculation costs of the EWMA macro from 2x multiplication and 1 addition down to 1x multiplication and 2x additions. This slightly improves performance depending on the CPU architecture. Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de --- net/mac80211/rc80211_minstrel.h | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 0083036..9c85a61 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h @@ -27,7 +27,12 @@ static inline int minstrel_ewma(int old, int new, int weight) { - return (new * (EWMA_DIV - weight) + old * weight) / EWMA_DIV; + int diff, incr; + + diff = new - old; + incr = (EWMA_DIV - weight) * diff / EWMA_DIV; + + return old + incr; } struct minstrel_rate_stats { -- 2.3.0 -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 10/10] mac80211: add standard deviation to Minstrel stats
This patch adds the statistical descriptor standard deviation to better describe the current properties of Minstrel and Minstrel-HTs success probability distribution. The standard deviation (SD) is calculated as exponential weighted moving standard deviation (EWMSD) and its current value is added as new column in all rc_stats (in debugfs). Signed-off-by: Thomas Huehn tho...@net.t-labs.tu-berlin.de --- net/mac80211/rc80211_minstrel.c| 19 ++- net/mac80211/rc80211_minstrel.h| 22 +- net/mac80211/rc80211_minstrel_debugfs.c| 19 --- net/mac80211/rc80211_minstrel_ht_debugfs.c | 14 +- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 18f1d72..b4562a8 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -153,7 +153,7 @@ minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) } /* -* Recalculate success probabilities and counters for a given rate using EWMA +* Recalculate statistics and counters of a given rate */ void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) @@ -161,11 +161,20 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) if (unlikely(mrs-attempts 0)) { mrs-sample_skipped = 0; mrs-cur_prob = MINSTREL_FRAC(mrs-success, mrs-attempts); - if (unlikely(!mrs-att_hist)) + if (unlikely(!mrs-att_hist)) { mrs-prob_ewma = mrs-cur_prob; - else + } else { + /* update exponential weighted moving variance */ + mrs-prob_ewmsd = minstrel_ewmsd(mrs-prob_ewmsd, +mrs-cur_prob, +mrs-prob_ewma, +EWMA_LEVEL); + + /*update exponential weighted moving avarage */ mrs-prob_ewma = minstrel_ewma(mrs-prob_ewma, -mrs-cur_prob, EWMA_LEVEL); + mrs-cur_prob, + EWMA_LEVEL); + } mrs-att_hist += mrs-attempts; mrs-succ_hist += mrs-success; } else { @@ -193,7 +202,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) struct minstrel_rate_stats *mrs = mi-r[i].stats; struct minstrel_rate_stats *tmp_mrs = mi-r[tmp_prob_rate].stats; - /* Update success probabilities per rate */ + /* Update statistics of success probability per rate */ minstrel_calc_rate_stats(mrs); /* Sample less often below the 10% chance of success. diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 9c85a61..c230bbe 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h @@ -35,6 +35,24 @@ minstrel_ewma(int old, int new, int weight) return old + incr; } +/* + * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation + */ +static inline int +minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight) +{ + int diff, incr, tmp_var; + + /* calculate exponential weighted moving variance */ + diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 100); + incr = (EWMA_DIV - weight) * diff / EWMA_DIV; + tmp_var = old_ewmsd * old_ewmsd; + tmp_var = weight * (tmp_var + diff * incr / 100) / EWMA_DIV; + + /* return standard deviation */ + return (u16) int_sqrt(tmp_var); +} + struct minstrel_rate_stats { /* current / last sampling period attempts/success counters */ u16 attempts, last_attempts; @@ -45,9 +63,11 @@ struct minstrel_rate_stats { /* statistis of packet delivery probability * cur_prob - current prob within last update intervall -* prob_ewma - exponential weighted moving average of prob */ +* prob_ewma - exponential weighted moving average of prob +* prob_ewmsd - exp. weighted moving standard deviation of prob */ unsigned int cur_prob; unsigned int prob_ewma; + u16 prob_ewmsd; /* maximum retry counts */ u8 retry_count; diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index d6480ad..64d722f 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c @@ -85,10 +85,12 @@ minstrel_stats_open(struct inode *inode, struct file *file) file-private_data = ms; p = ms-buf; p += sprintf(p, \n); - p += sprintf(p, best __rate_
[PATCH] staging: rtl8723au: Remove uses of MAC_FMT and MAC_ARG
Use the standard vsprintf kernel extension to format mac addresses. This reduces object code size a bit. Miscellanea: o Coalesce formats o Realign arguments o Remove the now unused MAC_FMT and MAC_ARG #defines Signed-off-by: Joe Perches j...@perches.com --- drivers/staging/rtl8723au/core/rtw_ap.c | 41 ++--- drivers/staging/rtl8723au/core/rtw_mlme.c | 26 drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 72 +++ drivers/staging/rtl8723au/core/rtw_recv.c | 42 + drivers/staging/rtl8723au/core/rtw_wlan_util.c| 6 +- drivers/staging/rtl8723au/core/rtw_xmit.c | 8 +-- drivers/staging/rtl8723au/include/ieee80211.h | 3 - drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 18 +++--- drivers/staging/rtl8723au/os_dep/os_intfs.c | 7 +-- 9 files changed, 101 insertions(+), 122 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index bed13db..6456689 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -260,15 +260,17 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter) list_del_init(psta-asoc_list); pstapriv-asoc_list_cnt--; - DBG_8723A(asoc expire MAC_FMT, state = 0x%x\n, MAC_ARG(psta-hwaddr), psta-state); + DBG_8723A(asoc expire %pM, state = 0x%x\n, + psta-hwaddr, psta-state); updated = ap_free_sta23a(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING); } else { /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ if (psta-sleepq_len (NR_XMITFRAME/pstapriv-asoc_list_cnt) padapter-xmitpriv.free_xmitframe_cnt ((NR_XMITFRAME/pstapriv-asoc_list_cnt)/2) ) { - DBG_8723A(%s sta:MAC_FMT, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n, __func__, - MAC_ARG(psta-hwaddr), + DBG_8723A(%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n, + __func__, + psta-hwaddr, psta-sleepq_len, padapter-xmitpriv.free_xmitframe_cnt, pstapriv-asoc_list_cnt); @@ -305,7 +307,8 @@ voidexpire_timeout_chk23a(struct rtw_adapter *padapter) psta-keep_alive_trycnt++; if (ret == _SUCCESS) { - DBG_8723A(asoc check, sta( MAC_FMT ) is alive\n, MAC_ARG(psta-hwaddr)); + DBG_8723A(asoc check, sta(%pM) is alive\n, + psta-hwaddr); psta-expire_to = pstapriv-expire_to; psta-keep_alive_trycnt = 0; continue; @@ -317,7 +320,8 @@ voidexpire_timeout_chk23a(struct rtw_adapter *padapter) psta-keep_alive_trycnt = 0; - DBG_8723A(asoc expire MAC_FMT, state = 0x%x\n, MAC_ARG(psta-hwaddr), psta-state); + DBG_8723A(asoc expire %pM, state = 0x%x\n, + psta-hwaddr, psta-state); spin_lock_bh(pstapriv-asoc_list_lock); if (!list_empty(psta-asoc_list)) { list_del_init(psta-asoc_list); @@ -1044,7 +1048,7 @@ int rtw_acl_add_sta23a(struct rtw_adapter *padapter, u8 *addr) struct wlan_acl_pool *pacl_list = pstapriv-acl_list; struct rtw_queue *pacl_node_q = pacl_list-acl_node_q; - DBG_8723A(%s(acl_num =%d) = MAC_FMT \n, __func__, pacl_list-num, MAC_ARG(addr)); + DBG_8723A(%s(acl_num =%d) =%pM\n, __func__, pacl_list-num, addr); if ((NUM_ACL-1) pacl_list-num) return -1; @@ -1476,8 +1480,8 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info if (psta-flags WLAN_STA_HT) { u16 ht_capab = le16_to_cpu(psta-htpriv.ht_cap.cap_info); - DBG_8723A(HT: STA MAC_FMT HT Capabilities Info: 0x%04x\n, - MAC_ARG(psta-hwaddr), ht_capab); + DBG_8723A(HT: STA %pM HT Capabilities Info: 0x%04x\n, + psta-hwaddr, ht_capab); if (psta-no_ht_set) { psta-no_ht_set = 0; @@ -1489,10 +1493,9 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info psta-no_ht_gf_set = 1; pmlmepriv-num_sta_ht_no_gf++; } - DBG_8723A(%s STA MAC_FMT
Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
On 23 March 2015 at 11:53, Kalle Valo kv...@qca.qualcomm.com wrote: Marek Puzyniak marek.puzyn...@tieto.com writes: As a part of tdls implementation introduce tdls related wmi data structures, constant values and functions. Signed-off-by: Marek Puzyniak marek.puzyn...@tieto.com This patch had non-trivial conflicts, please check carefully my resolution in the pending branch. CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h -- Kalle Valo It looks OK, but there is one small thing in file drivers/net/wireless/ath/ath10k/wmi-tlv.c. There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update and ath10k_wmi_tlv_op_gen_wow_enable. Thanks, Marek -- To unsubscribe from this list: send the line unsubscribe linux-wireless in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html