Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
Please pull this batch of updates for the 3.14 stream!

For the mac80211 bits, Johannes says:

"This time I have uAPSD fixes since I was working on that, hwsim
improvements to make dynamic radios possible for the test suite, the
evidently long-overdue channel_change_time removal and a few other small
collected fix and improvements."

For the iwlwifi bits, Emmanuel says:

"Besides a few trivial patches, I have an important workaround for a HW
issue that has kept me busy for a long time. Along with it, a fix that
prevents an error from being printed.
Eyal fixes our behavior against SISO APs and Ilan fixes an issue with
multiple interface scenarios.
Eliad fixes an error path in our init flow.
We also have a few 'static analyzers' fix."

For the NFC bits, Samuel says:

"It includes:

* A new NFC driver for Marvell's 8897, and a few NCI fixes and
  improvements needed to support this chipset.

* An LLCP fix for how we were setting the default MIU on a p2p link. If
  there is no explicit MIU extension announced at connection time, we
  must use the default one and not the one announced at LLCP link
  establishement time.

* A pn544 EEPROM config update. Some of the currently EEPROM configured
  values are overwriting the firmware ones while other should not be set
  by the driver itself.

* Some NFC digital stack fixes and improvements. Asynchronous functions
  are better documented, RF technologies and CRC functions are set upon
  PSL_REQ reception, and a few minor bugs are fixed.

* Minor and miscelaneous pn533, mei_phy and port100 fixes."

For the ath bits, Kalle says:

"Janusz added Kconfig option for DFS. The DFS code was there already, but
after fixes to mac80211 we can now enable it.

Bartosz added a runtime firmware feature flag to disable P2P. Our 10.1
firmware branch doesn't support P2P and ath10k can now disable that. He
also added a limit for how many clients can connect to ath10k AP.

Michal fixed WEP shared authentication, in case someone still uses it.
And I added firmware debug log to help the firmware engineers."

Along with that is a small batch of ath9k updates and a few other bits
here and there.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2014-01-17 17:30:55 -08:00
129 changed files with 3817 additions and 1803 deletions
-1
View File
@@ -1865,7 +1865,6 @@ static int adm8211_probe(struct pci_dev *pdev,
dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->channel_change_time = 1000;
dev->max_signal = 100; /* FIXME: find better value */
dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
-1
View File
@@ -2112,7 +2112,6 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
priv->pm_period = 0;
/* unit us */
priv->hw->channel_change_time = 100000;
return priv;
}
+2
View File
@@ -17,6 +17,7 @@
#ifndef ATH_H
#define ATH_H
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/spinlock.h>
@@ -165,6 +166,7 @@ struct ath_common {
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
u32 len,
gfp_t gfp_mask);
bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr);
void ath_hw_setbssidmask(struct ath_common *common);
void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key);
+7
View File
@@ -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.
+11
View File
@@ -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;
+66
View File
@@ -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,
+1
View File
@@ -1183,6 +1183,7 @@ struct htt_rx_info {
} rate;
bool fcs_err;
bool amsdu_more;
bool mic_err;
};
struct ath10k_htt {
+15
View File
@@ -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;
+1
View File
@@ -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
+358 -17
View File
@@ -332,6 +332,9 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
ath10k_warn("Failed to wait for created wmi peer: %i\n", ret);
return ret;
}
spin_lock_bh(&ar->data_lock);
ar->num_peers++;
spin_unlock_bh(&ar->data_lock);
return 0;
}
@@ -377,6 +380,10 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
if (ret)
return ret;
spin_lock_bh(&ar->data_lock);
ar->num_peers--;
spin_unlock_bh(&ar->data_lock);
return 0;
}
@@ -396,6 +403,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
list_del(&peer->list);
kfree(peer);
ar->num_peers--;
}
spin_unlock_bh(&ar->data_lock);
}
@@ -411,6 +419,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
list_del(&peer->list);
kfree(peer);
}
ar->num_peers = 0;
spin_unlock_bh(&ar->data_lock);
}
@@ -2205,7 +2214,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
enum wmi_sta_powersave_param param;
int ret = 0;
u32 value;
u32 value, param_id;
int bit;
u32 vdev_param;
@@ -2297,6 +2306,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
ath10k_warn("Failed to create peer for AP: %d\n", ret);
goto err_vdev_delete;
}
param_id = ar->wmi.pdev_param->sta_kickout_th;
/* Disable STA KICKOUT functionality in FW */
ret = ath10k_wmi_pdev_set_param(ar, param_id, 0);
if (ret)
ath10k_warn("Failed to disable STA KICKOUT\n");
}
if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
@@ -2842,6 +2858,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
{
struct ath10k *ar = hw->priv;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
int max_num_peers;
int ret = 0;
mutex_lock(&ar->conf_mutex);
@@ -2852,9 +2869,21 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
/*
* New station addition.
*/
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1;
else
max_num_peers = TARGET_NUM_PEERS;
if (ar->num_peers >= max_num_peers) {
ath10k_warn("Number of peers exceeded: peers number %d (max peers %d)\n",
ar->num_peers, max_num_peers);
ret = -ENOBUFS;
goto exit;
}
ath10k_dbg(ATH10K_DBG_MAC,
"mac vdev %d peer create %pM (new sta)\n",
arvif->vdev_id, sta->addr);
"mac vdev %d peer create %pM (new sta) num_peers %d\n",
arvif->vdev_id, sta->addr, ar->num_peers);
ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
if (ret)
@@ -2904,7 +2933,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
ath10k_warn("Failed to disassociate station: %pM\n",
sta->addr);
}
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
@@ -3310,6 +3339,307 @@ exit:
return ret;
}
/* Helper table for legacy fixed_rate/bitrate_mask */
static const u8 cck_ofdm_rate[] = {
/* CCK */
3, /* 1Mbps */
2, /* 2Mbps */
1, /* 5.5Mbps */
0, /* 11Mbps */
/* OFDM */
3, /* 6Mbps */
7, /* 9Mbps */
2, /* 12Mbps */
6, /* 18Mbps */
1, /* 24Mbps */
5, /* 36Mbps */
0, /* 48Mbps */
4, /* 54Mbps */
};
/* Check if only one bit set */
static int ath10k_check_single_mask(u32 mask)
{
int bit;
bit = ffs(mask);
if (!bit)
return 0;
mask &= ~BIT(bit - 1);
if (mask)
return 2;
return 1;
}
static bool
ath10k_default_bitrate_mask(struct ath10k *ar,
enum ieee80211_band band,
const struct cfg80211_bitrate_mask *mask)
{
u32 legacy = 0x00ff;
u8 ht = 0xff, i;
u16 vht = 0x3ff;
switch (band) {
case IEEE80211_BAND_2GHZ:
legacy = 0x00fff;
vht = 0;
break;
case IEEE80211_BAND_5GHZ:
break;
default:
return false;
}
if (mask->control[band].legacy != legacy)
return false;
for (i = 0; i < ar->num_rf_chains; i++)
if (mask->control[band].ht_mcs[i] != ht)
return false;
for (i = 0; i < ar->num_rf_chains; i++)
if (mask->control[band].vht_mcs[i] != vht)
return false;
return true;
}
static bool
ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask,
enum ieee80211_band band,
u8 *fixed_nss)
{
int ht_nss = 0, vht_nss = 0, i;
/* check legacy */
if (ath10k_check_single_mask(mask->control[band].legacy))
return false;
/* check HT */
for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
if (mask->control[band].ht_mcs[i] == 0xff)
continue;
else if (mask->control[band].ht_mcs[i] == 0x00)
break;
else
return false;
}
ht_nss = i;
/* check VHT */
for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
if (mask->control[band].vht_mcs[i] == 0x03ff)
continue;
else if (mask->control[band].vht_mcs[i] == 0x0000)
break;
else
return false;
}
vht_nss = i;
if (ht_nss > 0 && vht_nss > 0)
return false;
if (ht_nss)
*fixed_nss = ht_nss;
else if (vht_nss)
*fixed_nss = vht_nss;
else
return false;
return true;
}
static bool
ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask,
enum ieee80211_band band,
enum wmi_rate_preamble *preamble)
{
int legacy = 0, ht = 0, vht = 0, i;
*preamble = WMI_RATE_PREAMBLE_OFDM;
/* check legacy */
legacy = ath10k_check_single_mask(mask->control[band].legacy);
if (legacy > 1)
return false;
/* check HT */
for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
ht += ath10k_check_single_mask(mask->control[band].ht_mcs[i]);
if (ht > 1)
return false;
/* check VHT */
for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
vht += ath10k_check_single_mask(mask->control[band].vht_mcs[i]);
if (vht > 1)
return false;
/* Currently we support only one fixed_rate */
if ((legacy + ht + vht) != 1)
return false;
if (ht)
*preamble = WMI_RATE_PREAMBLE_HT;
else if (vht)
*preamble = WMI_RATE_PREAMBLE_VHT;
return true;
}
static bool
ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask,
enum ieee80211_band band,
u8 *fixed_rate,
u8 *fixed_nss)
{
u8 rate = 0, pream = 0, nss = 0, i;
enum wmi_rate_preamble preamble;
/* Check if single rate correct */
if (!ath10k_bitrate_mask_correct(mask, band, &preamble))
return false;
pream = preamble;
switch (preamble) {
case WMI_RATE_PREAMBLE_CCK:
case WMI_RATE_PREAMBLE_OFDM:
i = ffs(mask->control[band].legacy) - 1;
if (band == IEEE80211_BAND_2GHZ && i < 4)
pream = WMI_RATE_PREAMBLE_CCK;
if (band == IEEE80211_BAND_5GHZ)
i += 4;
if (i >= ARRAY_SIZE(cck_ofdm_rate))
return false;
rate = cck_ofdm_rate[i];
break;
case WMI_RATE_PREAMBLE_HT:
for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
if (mask->control[band].ht_mcs[i])
break;
if (i == IEEE80211_HT_MCS_MASK_LEN)
return false;
rate = ffs(mask->control[band].ht_mcs[i]) - 1;
nss = i;
break;
case WMI_RATE_PREAMBLE_VHT:
for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
if (mask->control[band].vht_mcs[i])
break;
if (i == NL80211_VHT_NSS_MAX)
return false;
rate = ffs(mask->control[band].vht_mcs[i]) - 1;
nss = i;
break;
}
*fixed_nss = nss + 1;
nss <<= 4;
pream <<= 6;
ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
pream, nss, rate);
*fixed_rate = pream | nss | rate;
return true;
}
static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask,
enum ieee80211_band band,
u8 *fixed_rate,
u8 *fixed_nss)
{
/* First check full NSS mask, if we can simply limit NSS */
if (ath10k_bitrate_mask_nss(mask, band, fixed_nss))
return true;
/* Next Check single rate is set */
return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss);
}
static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
u8 fixed_rate,
u8 fixed_nss)
{
struct ath10k *ar = arvif->ar;
u32 vdev_param;
int ret = 0;
mutex_lock(&ar->conf_mutex);
if (arvif->fixed_rate == fixed_rate &&
arvif->fixed_nss == fixed_nss)
goto exit;
if (fixed_rate == WMI_FIXED_RATE_NONE)
ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n");
vdev_param = ar->wmi.vdev_param->fixed_rate;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
vdev_param, fixed_rate);
if (ret) {
ath10k_warn("Could not set fixed_rate param 0x%02x: %d\n",
fixed_rate, ret);
ret = -EINVAL;
goto exit;
}
arvif->fixed_rate = fixed_rate;
vdev_param = ar->wmi.vdev_param->nss;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
vdev_param, fixed_nss);
if (ret) {
ath10k_warn("Could not set fixed_nss param %d: %d\n",
fixed_nss, ret);
ret = -EINVAL;
goto exit;
}
arvif->fixed_nss = fixed_nss;
exit:
mutex_unlock(&ar->conf_mutex);
return ret;
}
static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
{
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
struct ath10k *ar = arvif->ar;
enum ieee80211_band band = ar->hw->conf.chandef.chan->band;
u8 fixed_rate = WMI_FIXED_RATE_NONE;
u8 fixed_nss = ar->num_rf_chains;
if (!ath10k_default_bitrate_mask(ar, band, mask)) {
if (!ath10k_get_fixed_rate_nss(mask, band,
&fixed_rate,
&fixed_nss))
return -EINVAL;
}
return ath10k_set_fixed_rate_param(arvif, fixed_rate, fixed_nss);
}
static const struct ieee80211_ops ath10k_ops = {
.tx = ath10k_tx,
.start = ath10k_start,
@@ -3332,6 +3662,7 @@ static const struct ieee80211_ops ath10k_ops = {
.tx_last_beacon = ath10k_tx_last_beacon,
.restart_complete = ath10k_restart_complete,
.get_survey = ath10k_get_survey,
.set_bitrate_mask = ath10k_set_bitrate_mask,
#ifdef CONFIG_PM
.suspend = ath10k_suspend,
.resume = ath10k_resume,
@@ -3464,14 +3795,12 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
},
};
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
static const struct ieee80211_iface_limit ath10k_if_dfs_limits[] = {
static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
{
.max = 8,
.types = BIT(NL80211_IFTYPE_AP)
},
};
#endif
static const struct ieee80211_iface_combination ath10k_if_comb[] = {
{
@@ -3481,19 +3810,22 @@ static const struct ieee80211_iface_combination ath10k_if_comb[] = {
.num_different_channels = 1,
.beacon_int_infra_match = true,
},
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
};
static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
{
.limits = ath10k_if_dfs_limits,
.n_limits = ARRAY_SIZE(ath10k_if_dfs_limits),
.limits = ath10k_10x_if_limits,
.n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
.max_interfaces = 8,
.num_different_channels = 1,
.beacon_int_infra_match = true,
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
}
#endif
},
};
static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
@@ -3672,9 +4004,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
BIT(NL80211_IFTYPE_AP);
if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
ar->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
@@ -3704,7 +4039,6 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->vif_data_size = sizeof(struct ath10k_vif);
ar->hw->channel_change_time = 5000;
ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
@@ -3717,8 +4051,15 @@ int ath10k_mac_register(struct ath10k *ar)
*/
ar->hw->queues = 4;
ar->hw->wiphy->iface_combinations = ath10k_if_comb;
ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ath10k_if_comb);
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
ar->hw->wiphy->n_iface_combinations =
ARRAY_SIZE(ath10k_10x_if_comb);
} else {
ar->hw->wiphy->iface_combinations = ath10k_if_comb;
ar->hw->wiphy->n_iface_combinations =
ARRAY_SIZE(ath10k_if_comb);
}
ar->hw->netdev_features = NETIF_F_HW_CSUM;
+21
View File
@@ -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 */
+1 -1
View File
@@ -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)
+100 -6
View File
@@ -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);
}
+61
View File
@@ -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_ */
+8 -26
View File
@@ -1238,14 +1238,11 @@ static void
ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
struct ieee80211_rx_status *rxs)
{
struct ath_common *common = ath5k_hw_common(ah);
u64 tsf, bc_tstamp;
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
if (ieee80211_is_beacon(mgmt->frame_control) &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) {
if (le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS) {
/*
* Received an IBSS beacon with the same BSSID. Hardware *must*
* have updated the local TSF. We have to work around various
@@ -1301,23 +1298,6 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
}
}
static void
ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
struct ath_common *common = ath5k_hw_common(ah);
/* only beacons from our BSSID */
if (!ieee80211_is_beacon(mgmt->frame_control) ||
!ether_addr_equal_64bits(mgmt->bssid, common->curbssid))
return;
ewma_add(&ah->ah_beacon_rssi_avg, rssi);
/* in IBSS mode we should keep RSSI statistics per neighbour */
/* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
}
/*
* Compute padding position. skb must contain an IEEE 802.11 frame
*/
@@ -1390,6 +1370,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
struct ath5k_rx_status *rs)
{
struct ieee80211_rx_status *rxs;
struct ath_common *common = ath5k_hw_common(ah);
ath5k_remove_padding(skb);
@@ -1442,11 +1423,13 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
trace_ath5k_rx(ah, skb);
ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi);
if (ath_is_mybeacon(common, (struct ieee80211_hdr *)skb->data)) {
ewma_add(&ah->ah_beacon_rssi_avg, rs->rs_rssi);
/* check beacons in IBSS mode */
if (ah->opmode == NL80211_IFTYPE_ADHOC)
ath5k_check_ibss_tsf(ah, skb, rxs);
/* check beacons in IBSS mode */
if (ah->opmode == NL80211_IFTYPE_ADHOC)
ath5k_check_ibss_tsf(ah, skb, rxs);
}
ieee80211_rx(ah->hw, skb);
}
@@ -2549,7 +2532,6 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
hw->wiphy->available_antennas_rx = 0x3;
hw->extra_tx_headroom = 2;
hw->channel_change_time = 5000;
/*
* Mark the device as detached to avoid processing
+8
View File
@@ -65,6 +65,14 @@ config ATH9K_DEBUGFS
Also required for changing debug message flags at run time.
config ATH9K_STATION_STATISTICS
bool "Detailed station statistics"
depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS
select MAC80211_DEBUGFS
default n
---help---
This option enables detailed statistics for association stations.
config ATH9K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH9K && CFG80211_CERTIFICATION_ONUS
+2
View File
@@ -19,6 +19,8 @@ ath9k-$(CONFIG_ATH9K_WOW) += wow.o
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \
spectral.o
ath9k-$(CONFIG_ATH9K_STATION_STATISTICS) += debug_sta.o
obj-$(CONFIG_ATH9K) += ath9k.o
ath9k_hw-y:= \
+16 -3
View File
@@ -565,7 +565,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
const s32 result_shift = 1 << 15;
struct ath_common *common = ath9k_hw_common(ah);
f2 = (f1 * f1 + f3 * f3) / result_shift;
f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9;
if (!f2) {
ath_dbg(common, CALIBRATE, "Divide by 0\n");
@@ -655,8 +655,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
if (i2_m_q2_a0_d1 > 0x800)
i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
if (i2_p_q2_a0_d1 > 0x800)
i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
if (i2_p_q2_a0_d1 > 0x1000)
i2_p_q2_a0_d1 = -((0x1fff - i2_p_q2_a0_d1) + 1);
if (iq_corr_a0_d1 > 0x800)
iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
@@ -700,6 +700,19 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
return false;
}
if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) ||
(i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
(i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
(i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
(i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
(i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
(i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
(i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
(i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
(i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
return false;
}
mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
+9 -1
View File
@@ -146,7 +146,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
#define IS_HT_RATE(rate) (rate & 0x80)
#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
#define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf))
struct ath_txq {
int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
@@ -262,6 +264,10 @@ struct ath_node {
bool sleeping;
bool no_ps_filter;
#ifdef CONFIG_ATH9K_STATION_STATISTICS
struct ath_rx_rate_stats rx_rate_stats;
#endif
};
struct ath_tx_control {
@@ -685,6 +691,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define DEFAULT_CACHELINE 32
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
#define MAX_GTT_CNT 5
enum sc_op_flags {
SC_OP_INVALID,
@@ -727,6 +734,7 @@ struct ath_softc {
unsigned long sc_flags;
unsigned long driver_data;
u8 gtt_cnt;
u32 intrstatus;
u16 ps_flags; /* PS_* */
u16 curtxpow;
+74 -123
View File
@@ -943,14 +943,10 @@ static const struct file_operations fops_reset = {
static ssize_t read_file_recv(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
#define PHY_ERR(s, p) \
len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
sc->debug.stats.rxstats.phy_err_stats[p]);
#define RXS_ERR(s, e) \
do { \
len += scnprintf(buf + len, size - len, \
"%22s : %10u\n", s, \
"%18s : %10u\n", s, \
sc->debug.stats.rxstats.e);\
} while (0)
@@ -963,6 +959,12 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
if (buf == NULL)
return -ENOMEM;
RXS_ERR("PKTS-ALL", rx_pkts_all);
RXS_ERR("BYTES-ALL", rx_bytes_all);
RXS_ERR("BEACONS", rx_beacons);
RXS_ERR("FRAGS", rx_frags);
RXS_ERR("SPECTRAL", rx_spectral);
RXS_ERR("CRC ERR", crc_err);
RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
RXS_ERR("PHY ERR", phy_err);
@@ -970,43 +972,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
RXS_ERR("RX-LENGTH-ERR", rx_len_err);
RXS_ERR("RX-OOM-ERR", rx_oom_err);
RXS_ERR("RX-RATE-ERR", rx_rate_err);
RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
RXS_ERR("RX-Pkts-All", rx_pkts_all);
RXS_ERR("RX-Bytes-All", rx_bytes_all);
RXS_ERR("RX-Beacons", rx_beacons);
RXS_ERR("RX-Frags", rx_frags);
RXS_ERR("RX-Spectral", rx_spectral);
RXS_ERR("LENGTH-ERR", rx_len_err);
RXS_ERR("OOM-ERR", rx_oom_err);
RXS_ERR("RATE-ERR", rx_rate_err);
RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
if (len > size)
len = size;
@@ -1017,7 +986,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
return retval;
#undef RXS_ERR
#undef PHY_ERR
}
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
@@ -1056,6 +1024,67 @@ static const struct file_operations fops_recv = {
.llseek = default_llseek,
};
static ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
#define PHY_ERR(s, p) \
len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
sc->debug.stats.rxstats.phy_err_stats[p]);
struct ath_softc *sc = file->private_data;
char *buf;
unsigned int len = 0, size = 1600;
ssize_t retval = 0;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
#undef PHY_ERR
}
static const struct file_operations fops_phy_err = {
.read = read_file_phy_err,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1322,86 +1351,6 @@ static const struct file_operations fops_btcoex = {
};
#endif
static ssize_t read_file_node_stat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_node *an = file->private_data;
struct ath_softc *sc = an->sc;
struct ath_atx_tid *tid;
struct ath_atx_ac *ac;
struct ath_txq *txq;
u32 len = 0, size = 4096;
char *buf;
size_t retval;
int tidno, acno;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
if (!an->sta->ht_cap.ht_supported) {
len = scnprintf(buf, size, "%s\n",
"HT not supported");
goto exit;
}
len = scnprintf(buf, size, "Max-AMPDU: %d\n",
an->maxampdu);
len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n",
an->mpdudensity);
len += scnprintf(buf + len, size - len,
"%2s%7s\n", "AC", "SCHED");
for (acno = 0, ac = &an->ac[acno];
acno < IEEE80211_NUM_ACS; acno++, ac++) {
txq = ac->txq;
ath_txq_lock(sc, txq);
len += scnprintf(buf + len, size - len,
"%2d%7d\n",
acno, ac->sched);
ath_txq_unlock(sc, txq);
}
len += scnprintf(buf + len, size - len,
"\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
"TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
"BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
for (tidno = 0, tid = &an->tid[tidno];
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
txq = tid->ac->txq;
ath_txq_lock(sc, txq);
len += scnprintf(buf + len, size - len,
"%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
tid->tidno, tid->seq_start, tid->seq_next,
tid->baw_size, tid->baw_head, tid->baw_tail,
tid->bar_index, tid->sched, tid->paused);
ath_txq_unlock(sc, txq);
}
exit:
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_node_stat = {
.read = read_file_node_stat,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct dentry *dir)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
debugfs_create_file("node_stat", S_IRUGO, dir, an, &fops_node_stat);
}
/* Ethtool support for get-stats */
#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
@@ -1569,6 +1518,8 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_reset);
debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_recv);
debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_phy_err);
debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
&ah->rxchainmask);
debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy,

Some files were not shown because too many files have changed in this diff Show More