Commit 559c33d8 authored by John W. Linville's avatar John W. Linville

Merge branch 'for-linville' of git://github.com/kvalo/ath

parents ec665fac 51ab1a0a
......@@ -37,3 +37,10 @@ config ATH10K_TRACING
---help---
Select this to ath10k use tracing infrastructure.
config ATH10K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
default n
---help---
This option enables DFS support for initiating radiation on
ath10k.
......@@ -253,6 +253,9 @@ struct ath10k_vif {
u8 bssid[ETH_ALEN];
} ibss;
} u;
u8 fixed_rate;
u8 fixed_nss;
};
struct ath10k_vif_iter {
......@@ -272,6 +275,8 @@ struct ath10k_debug {
struct delayed_work htt_stats_dwork;
struct ath10k_dfs_stats dfs_stats;
struct ath_dfs_pool_stats dfs_pool_stats;
u32 fw_dbglog_mask;
};
enum ath10k_state {
......@@ -306,6 +311,9 @@ enum ath10k_fw_features {
/* firmware support tx frame management over WMI, otherwise it's HTT */
ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2,
/* Firmware does not support P2P */
ATH10K_FW_FEATURE_NO_P2P = 3,
/* keep last */
ATH10K_FW_FEATURE_COUNT,
};
......@@ -429,6 +437,9 @@ struct ath10k {
struct list_head peers;
wait_queue_head_t peer_mapping_wq;
/* number of created peers; protected by data_lock */
int num_peers;
struct work_struct offchan_tx_work;
struct sk_buff_head offchan_tx_queue;
struct completion offchan_tx_completed;
......
......@@ -614,6 +614,61 @@ static const struct file_operations fops_htt_stats_mask = {
.llseek = default_llseek,
};
static ssize_t ath10k_read_fw_dbglog(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
unsigned int len;
char buf[32];
len = scnprintf(buf, sizeof(buf), "0x%08x\n",
ar->debug.fw_dbglog_mask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t ath10k_write_fw_dbglog(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
unsigned long mask;
int ret;
ret = kstrtoul_from_user(user_buf, count, 0, &mask);
if (ret)
return ret;
mutex_lock(&ar->conf_mutex);
ar->debug.fw_dbglog_mask = mask;
if (ar->state == ATH10K_STATE_ON) {
ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
if (ret) {
ath10k_warn("dbglog cfg failed from debugfs: %d\n",
ret);
goto exit;
}
}
ret = count;
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static const struct file_operations fops_fw_dbglog = {
.read = ath10k_read_fw_dbglog,
.write = ath10k_write_fw_dbglog,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
int ath10k_debug_start(struct ath10k *ar)
{
int ret;
......@@ -625,6 +680,14 @@ int ath10k_debug_start(struct ath10k *ar)
/* continue normally anyway, this isn't serious */
ath10k_warn("failed to start htt stats workqueue: %d\n", ret);
if (ar->debug.fw_dbglog_mask) {
ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
if (ret)
/* not serious */
ath10k_warn("failed to enable dbglog during start: %d",
ret);
}
return 0;
}
......@@ -747,6 +810,9 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_htt_stats_mask);
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_fw_dbglog);
if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
debugfs_create_file("dfs_simulate_radar", S_IWUSR,
ar->debug.debugfs_phy, ar,
......
......@@ -1183,6 +1183,7 @@ struct htt_rx_info {
} rate;
bool fcs_err;
bool amsdu_more;
bool mic_err;
};
struct ath10k_htt {
......
......@@ -838,6 +838,20 @@ static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
return false;
}
static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb)
{
struct htt_rx_desc *rxd;
u32 flags;
rxd = (void *)skb->data - sizeof(*rxd);
flags = __le32_to_cpu(rxd->attention.flags);
if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
return true;
return false;
}
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
{
struct htt_rx_desc *rxd;
......@@ -960,6 +974,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info.skb = msdu_head;
info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
info.signal += rx->ppdu.combined_rssi;
......
......@@ -115,6 +115,7 @@ enum ath10k_mcast2ucast_mode {
#define TARGET_10X_MAC_AGGR_DELIM 0
#define TARGET_10X_AST_SKID_LIMIT 16
#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS))
#define TARGET_10X_NUM_PEERS_MAX 128
#define TARGET_10X_NUM_OFFLOAD_PEERS 0
#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0
#define TARGET_10X_NUM_PEER_KEYS 2
......
This diff is collapsed.
......@@ -182,6 +182,27 @@ TRACE_EVENT(ath10k_htt_stats,
)
);
TRACE_EVENT(ath10k_wmi_dbglog,
TP_PROTO(void *buf, size_t buf_len),
TP_ARGS(buf, buf_len),
TP_STRUCT__entry(
__field(size_t, buf_len)
__dynamic_array(u8, buf, buf_len)
),
TP_fast_assign(
__entry->buf_len = buf_len;
memcpy(__get_dynamic_array(buf), buf, buf_len);
),
TP_printk(
"len %zu",
__entry->buf_len
)
);
#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
/* we don't want to use include/trace/events */
......
......@@ -231,7 +231,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
~IEEE80211_FCTL_PROTECTED);
}
if (info->status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
if (info->mic_err)
status->flag |= RX_FLAG_MMIC_ERROR;
if (info->fcs_err)
......
......@@ -16,6 +16,7 @@
*/
#include <linux/skbuff.h>
#include <linux/ctype.h>
#include "core.h"
#include "htc.h"
......@@ -875,6 +876,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
struct wmi_mgmt_rx_event_v2 *ev_v2;
struct wmi_mgmt_rx_hdr_v1 *ev_hdr;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_channel *ch;
struct ieee80211_hdr *hdr;
u32 rx_status;
u32 channel;
......@@ -927,7 +929,25 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
if (rx_status & WMI_RX_STATUS_ERR_MIC)
status->flag |= RX_FLAG_MMIC_ERROR;
status->band = phy_mode_to_band(phy_mode);
/* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to
* MODE_11B. This means phy_mode is not a reliable source for the band
* of mgmt rx. */
ch = ar->scan_channel;
if (!ch)
ch = ar->rx_channel;
if (ch) {
status->band = ch->band;
if (phy_mode == MODE_11B &&
status->band == IEEE80211_BAND_5GHZ)
ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");
} else {
ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n");
status->band = phy_mode_to_band(phy_mode);
}
status->freq = ieee80211_channel_to_frequency(channel, status->band);
status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
status->rate_idx = get_rate_idx(rate, status->band);
......@@ -937,7 +957,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
hdr = (struct ieee80211_hdr *)skb->data;
fc = le16_to_cpu(hdr->frame_control);
if (fc & IEEE80211_FCTL_PROTECTED) {
/* FW delivers WEP Shared Auth frame with Protected Bit set and
* encrypted payload. However in case of PMF it delivers decrypted
* frames with Protected Bit set. */
if (ieee80211_has_protected(hdr->frame_control) &&
!ieee80211_is_auth(hdr->frame_control)) {
status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
RX_FLAG_MMIC_STRIPPED;
hdr->frame_control = __cpu_to_le16(fc &
......@@ -1047,9 +1071,14 @@ static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");
}
static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
{
ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_MESG_EVENTID\n");
ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
skb->len);
trace_ath10k_wmi_dbglog(skb->data, skb->len);
return 0;
}
static void ath10k_wmi_event_update_stats(struct ath10k *ar,
......@@ -1653,9 +1682,37 @@ static void ath10k_wmi_event_profile_match(struct ath10k *ar,
}
static void ath10k_wmi_event_debug_print(struct ath10k *ar,
struct sk_buff *skb)
struct sk_buff *skb)
{
ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_PRINT_EVENTID\n");
char buf[101], c;
int i;
for (i = 0; i < sizeof(buf) - 1; i++) {
if (i >= skb->len)
break;
c = skb->data[i];
if (c == '\0')
break;
if (isascii(c) && isprint(c))
buf[i] = c;
else
buf[i] = '.';
}
if (i == sizeof(buf) - 1)
ath10k_warn("wmi debug print truncated: %d\n", skb->len);
/* for some reason the debug prints end with \n, remove that */
if (skb->data[i - 1] == '\n')
i--;
/* the last byte is always reserved for the null character */
buf[i] = '\0';
ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf);
}
static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
......@@ -3445,3 +3502,40 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar,
type, delay_ms);
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
}
int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
{
struct wmi_dbglog_cfg_cmd *cmd;
struct sk_buff *skb;
u32 cfg;
skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
if (!skb)
return -ENOMEM;
cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;
if (module_enable) {
cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE,
ATH10K_DBGLOG_CFG_LOG_LVL);
} else {
/* set back defaults, all modules with WARN level */
cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,
ATH10K_DBGLOG_CFG_LOG_LVL);
module_enable = ~0;
}
cmd->module_enable = __cpu_to_le32(module_enable);
cmd->module_valid = __cpu_to_le32(~0);
cmd->config_enable = __cpu_to_le32(cfg);
cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);
ath10k_dbg(ATH10K_DBG_WMI,
"wmi dbglog cfg modules %08x %08x config %08x %08x\n",
__le32_to_cpu(cmd->module_enable),
__le32_to_cpu(cmd->module_valid),
__le32_to_cpu(cmd->config_enable),
__le32_to_cpu(cmd->config_valid));
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
}
......@@ -3003,6 +3003,18 @@ struct wmi_vdev_install_key_arg {
const void *key_data;
};
/*
* vdev fixed rate format:
* - preamble - b7:b6 - see WMI_RATE_PREMABLE_
* - nss - b5:b4 - ss number (0 mean 1ss)
* - rate_mcs - b3:b0 - as below
* CCK: 0 - 11Mbps, 1 - 5,5Mbps, 2 - 2Mbps, 3 - 1Mbps,
* 4 - 11Mbps (s), 5 - 5,5Mbps (s), 6 - 2Mbps (s)
* OFDM: 0 - 48Mbps, 1 - 24Mbps, 2 - 12Mbps, 3 - 6Mbps,
* 4 - 54Mbps, 5 - 36Mbps, 6 - 18Mbps, 7 - 9Mbps
* HT/VHT: MCS index
*/
/* Preamble types to be used with VDEV fixed rate configuration */
enum wmi_rate_preamble {
WMI_RATE_PREAMBLE_OFDM,
......@@ -4090,6 +4102,54 @@ struct wmi_force_fw_hang_cmd {
__le32 delay_ms;
} __packed;
enum ath10k_dbglog_level {
ATH10K_DBGLOG_LEVEL_VERBOSE = 0,
ATH10K_DBGLOG_LEVEL_INFO = 1,
ATH10K_DBGLOG_LEVEL_WARN = 2,
ATH10K_DBGLOG_LEVEL_ERR = 3,
};
/* VAP ids to enable dbglog */
#define ATH10K_DBGLOG_CFG_VAP_LOG_LSB 0
#define ATH10K_DBGLOG_CFG_VAP_LOG_MASK 0x0000ffff
/* to enable dbglog in the firmware */
#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_LSB 16
#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_MASK 0x00010000
/* timestamp resolution */
#define ATH10K_DBGLOG_CFG_RESOLUTION_LSB 17
#define ATH10K_DBGLOG_CFG_RESOLUTION_MASK 0x000E0000
/* number of queued messages before sending them to the host */
#define ATH10K_DBGLOG_CFG_REPORT_SIZE_LSB 20
#define ATH10K_DBGLOG_CFG_REPORT_SIZE_MASK 0x0ff00000
/*
* Log levels to enable. This defines the minimum level to enable, this is
* not a bitmask. See enum ath10k_dbglog_level for the values.
*/
#define ATH10K_DBGLOG_CFG_LOG_LVL_LSB 28
#define ATH10K_DBGLOG_CFG_LOG_LVL_MASK 0x70000000
/*
* Note: this is a cleaned up version of a struct firmware uses. For
* example, config_valid was hidden inside an array.
*/
struct wmi_dbglog_cfg_cmd {
/* bitmask to hold mod id config*/
__le32 module_enable;
/* see ATH10K_DBGLOG_CFG_ */
__le32 config_enable;
/* mask of module id bits to be changed */
__le32 module_valid;
/* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */
__le32 config_valid;
} __packed;
#define ATH10K_RTS_MAX 2347
#define ATH10K_FRAGMT_THRESHOLD_MIN 540
#define ATH10K_FRAGMT_THRESHOLD_MAX 2346
......@@ -4167,5 +4227,6 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
int ath10k_wmi_force_fw_hang(struct ath10k *ar,
enum wmi_force_fw_hang_type type, u32 delay_ms);
int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable);
#endif /* _WMI_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment