Skip to content

Commit

Permalink
ath10k: Support 'ct-sta-mode' for 9984 firmware that supports it.
Browse files Browse the repository at this point in the history
This is for test equipment makers only.  It should allow multiple
stations to connect to the same AP and still do hw tx/rx crypt
on the NIC.

Signed-off-by: Ben Greear <greearb@candelatech.com>
  • Loading branch information
greearb committed Aug 17, 2018
1 parent 20db9db commit fd92066
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 15 deletions.
10 changes: 10 additions & 0 deletions ath10k-4.13/core.c
Expand Up @@ -404,6 +404,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
[ATH10K_FW_FEATURE_HAS_TX_RC_CT] = "tx-rc-CT",
[ATH10K_FW_FEATURE_CUST_STATS_CT] = "cust-stats-CT",
[ATH10K_FW_FEATURE_RETRY_GT2_CT] = "retry-gt2-CT",
[ATH10K_FW_FEATURE_CT_STA] = "CT-STA",
};

static unsigned int ath10k_core_get_fw_feature_str(char *buf,
Expand Down Expand Up @@ -1206,6 +1207,12 @@ static int ath10k_fetch_fwcfg_file(struct ath10k *ar)
ar->fwcfg.flags |= ATH10K_FWCFG_NOHWCRYPT;
}
}
else if (strcasecmp(filename, "ct_sta_mode") == 0) {
if (kstrtol(val, 0, &t) == 0) {
ar->fwcfg.ct_sta_mode = t;
ar->fwcfg.flags |= ATH10K_FWCFG_CT_STA;
}
}
else if (strcasecmp(filename, "nobeamform_mu") == 0) {
if (kstrtol(val, 0, &t) == 0) {
ar->fwcfg.nobeamform_mu = t;
Expand Down Expand Up @@ -2389,6 +2396,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
return -EINVAL;
}

ar->request_ct_sta = ath10k_modparam_ct_sta;
ar->request_nohwcrypt = ath10k_modparam_nohwcrypt;
ar->request_nobeamform_mu = ath10k_modparam_nobeamform_mu;
ar->request_nobeamform_su = ath10k_modparam_nobeamform_su;
Expand All @@ -2404,6 +2412,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->max_num_stations = ar->fwcfg.stations;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOHWCRYPT)
ar->request_nohwcrypt = ar->fwcfg.nohwcrypt;
if (ar->fwcfg.flags & ATH10K_FWCFG_CT_STA)
ar->request_ct_sta = ar->fwcfg.ct_sta_mode;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOBEAMFORM_MU)
ar->request_nobeamform_mu = ar->fwcfg.nobeamform_mu;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOBEAMFORM_SU)
Expand Down
8 changes: 8 additions & 0 deletions ath10k-4.13/core.h
Expand Up @@ -218,6 +218,8 @@ struct ath10k_fw_stats_vdev {
u32 num_tx_not_acked;
u32 tx_rate_history[10];
u32 beacon_rssi_history[10];

u64 tsf64; /* ct fw only */
};

struct ath10k_fw_stats_pdev {
Expand Down Expand Up @@ -775,6 +777,9 @@ enum ath10k_fw_features {
/* Can the firmware handle a retry limit greater than 2? */
ATH10K_FW_FEATURE_RETRY_GT2_CT = 47,

/* Can the firmware handle CT station feature, sort of like proxy-sta */
ATH10K_FW_FEATURE_CT_STA = 48,

/* keep last */
ATH10K_FW_FEATURE_COUNT,
};
Expand Down Expand Up @@ -1014,6 +1019,7 @@ struct ath10k {
#define ATH10K_FWCFG_MAX_AMSDUS (1<<13)
#define ATH10K_FWCFG_NOBEAMFORM_MU (1<<14)
#define ATH10K_FWCFG_NOBEAMFORM_SU (1<<15)
#define ATH10K_FWCFG_CT_STA (1<<16)

u32 flags; /* let us know which fields have been set */
char calname[100];
Expand All @@ -1024,6 +1030,7 @@ struct ath10k {
u32 stations;
u32 peers;
u32 nohwcrypt;
u32 ct_sta_mode;
u32 nobeamform_mu;
u32 nobeamform_su;
u32 rate_ctrl_objs;
Expand Down Expand Up @@ -1134,6 +1141,7 @@ struct ath10k {
int max_num_tdls_vdevs;
int num_active_peers;
int num_tids;
bool request_ct_sta; /* desired setting */
bool request_nohwcrypt; /* desired setting */
bool request_nobeamform_mu;
bool request_nobeamform_su;
Expand Down
6 changes: 3 additions & 3 deletions ath10k-4.13/htt_rx.c
Expand Up @@ -2498,9 +2498,9 @@ static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
rcu_read_lock();
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find_by_id(ar, peer_id);
if (!peer) {
ath10k_warn(ar, "Invalid peer id %d peer stats buffer\n",
peer_id);
if (!peer || !peer->sta) {
ath10k_warn(ar, "Invalid peer id %d or peer stats buffer, peer: %p sta: %p\n",
peer_id, peer, peer ? peer->sta : NULL);
goto out;
}

Expand Down
13 changes: 10 additions & 3 deletions ath10k-4.13/mac.c
Expand Up @@ -215,6 +215,10 @@ int ath10k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath10k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware rx decrypt feature");

int ath10k_modparam_ct_sta;
module_param_named(ct_sta, ath10k_modparam_ct_sta, int, 0444);
MODULE_PARM_DESC(ct_sta, "Use CT-STA mode, a bit like proxy-STA");

int ath10k_modparam_nobeamform_mu;
module_param_named(nobeamform_mu, ath10k_modparam_nobeamform_mu, int, 0444);
MODULE_PARM_DESC(nobeamform_mu, "Disable TX/RX MU Beamforming capabilities");
Expand Down Expand Up @@ -9360,9 +9364,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);

/* CT firmware can do tx-sw-crypt if properly configured */
if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ath10k_modparam_nohwcrypt)
if ((!(test_bit(ATH10K_FW_FEATURE_CT_STA,
ar->running_fw->fw_file.fw_features) &&
ar->request_ct_sta)) &&
(test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt))
__clear_bit(IEEE80211_HW_SW_CRYPTO_CONTROL, ar->hw->flags);
} else {
ret = ath10k_copy_comb(ar, ath10k_10_4_if_comb,
Expand Down
1 change: 1 addition & 0 deletions ath10k-4.13/mac.h
Expand Up @@ -26,6 +26,7 @@
enum wmi_tlv_tx_pause_id;
enum wmi_tlv_tx_pause_action;

extern int ath10k_modparam_ct_sta;
extern int ath10k_modparam_nohwcrypt;
extern int ath10k_modparam_nobeamform_mu;
extern int ath10k_modparam_nobeamform_su;
Expand Down
46 changes: 42 additions & 4 deletions ath10k-4.13/wmi.c
Expand Up @@ -3055,7 +3055,34 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
list_add_tail(&dst->list, &stats->pdevs);
}

/* fw doesn't implement vdev stats */
/* (stock) fw doesn't implement vdev stats */
for (i = 0; i < num_vdev_stats; i++) {
const struct wmi_vdev_stats_ct *src = (void *)(skb->data);
struct ath10k_fw_stats_vdev *dst;
int sz;

if (!skb_pull(skb, sizeof(*src)))
return -EPROTO;

/* Look for any existing vdev */
dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
if (!dst)
continue;

sz = __le32_to_cpu(src->size);
dst->vdev_id = src->vdev_id;
dst->tsf64 = __le32_to_cpu(src->tsf_hi);
dst->tsf64 <<= 32;
dst->tsf64 |= __le32_to_cpu(src->tsf_lo);

list_add_tail(&dst->list, &stats->vdevs);

if (sz > sizeof(*src)) {
/* Discard any extra for forwards-compat */
if (!skb_pull(skb, sz - sizeof(*src)))
return -EPROTO;
}
}

for (i = 0; i < num_peer_stats; i++) {
const struct wmi_10x_peer_stats *src;
Expand Down Expand Up @@ -6149,7 +6176,8 @@ static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
else if (ar->request_nohwcrypt) {
ath10k_err(ar, "nohwcrypt requested, but firmware does not support this feature. Disabling swcrypt.\n");
}
config.rx_decap_mode |= __cpu_to_le32(ATH10k_USE_TXCOMPL_TXRATE | ATH10k_MGT_CHAIN_RSSI_OK);
config.rx_decap_mode |= __cpu_to_le32(ATH10k_USE_TXCOMPL_TXRATE | ATH10k_MGT_CHAIN_RSSI_OK
| ATH10k_VDEV_CT_STATS_OK);
/* Disable WoW in firmware, could make this module option perhaps? */
config.rx_decap_mode |= __cpu_to_le32(ATH10k_DISABLE_WOW);
config.roam_offload_max_vdev = 0; /* disable roaming */
Expand Down Expand Up @@ -6389,9 +6417,16 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
/* Enabling this kills performance, for whatever reason. */
skid_limit = TARGET_10X_AST_SKID_LIMIT_CT;
#endif
if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
if (test_bit(ATH10K_FW_FEATURE_CT_STA,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt) {
ar->request_ct_sta) {
config.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_RAW |
ATH10k_VDEV_CT_STA_MODE);
ath10k_info(ar, "using CT-STA mode\n");
}
else if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt) {
/* This will disable rx decryption in hardware, enable raw
* rx mode, and native-wifi tx mode. Requires 'CT' firmware.
*/
Expand Down Expand Up @@ -8163,6 +8198,9 @@ ath10k_wmi_fw_vdev_stats_fill(const struct ath10k_fw_stats_vdev *vdev,
"beacon rssi history", i,
vdev->beacon_rssi_history[i]);

len += scnprintf(buf + len, buf_len - len, "%30s %llu\n",
"tsf64", vdev->tsf64);

len += scnprintf(buf + len, buf_len - len, "\n");
*length = len;
}
Expand Down
11 changes: 11 additions & 0 deletions ath10k-4.13/wmi.h
Expand Up @@ -2266,6 +2266,10 @@ struct wmi_resource_config {
#define ATH10k_DISABLE_WOW 0x40000
/* Ask CT firmware to send back per-chain management frame RSSI info */
#define ATH10k_MGT_CHAIN_RSSI_OK 0x80000
#define ATH10k_VDEV_CT_STATS_OK 0x100000
#define ATH10k_VDEV_CT_STA_MODE 0x200000 /* Try to use keys a bit like proxy-sta so we can do hw-crypt
* with many stations to same AP. */
/* NOTE: High 8 bits are spoken for, 'features' */
__le32 rx_decap_mode;

/* what is the maximum number of scan requests that can be queued */
Expand Down Expand Up @@ -6308,6 +6312,13 @@ struct wmi_10_4_peer_assoc_complete_cmd_ct {
struct wmi_ct_assoc_overrides overrides;
} __packed;

struct wmi_vdev_stats_ct {
u32 vdev_id;
u32 size; /* size in bytes of this struct */
u32 tsf_lo;
u32 tsf_hi;
};

struct wmi_peer_assoc_complete_arg {
u8 addr[ETH_ALEN];
u32 vdev_id;
Expand Down
11 changes: 11 additions & 0 deletions ath10k-4.9/core.c
Expand Up @@ -351,6 +351,8 @@ static const char *const ath10k_core_fw_feature_str[] = {
[ATH10K_FW_FEATURE_HAS_GET_TEMP_CT] = "get-temp-CT",
[ATH10K_FW_FEATURE_HAS_TX_RC_CT] = "tx-rc-CT",
[ATH10K_FW_FEATURE_CUST_STATS_CT] = "cust-stats-CT",
[ATH10K_FW_FEATURE_RETRY_GT2_CT] = "retry-gt2-CT",
[ATH10K_FW_FEATURE_CT_STA] = "CT-STA",
};

static unsigned int ath10k_core_get_fw_feature_str(char *buf,
Expand Down Expand Up @@ -1119,6 +1121,12 @@ static int ath10k_fetch_fwcfg_file(struct ath10k *ar)
ar->fwcfg.flags |= ATH10K_FWCFG_NOHWCRYPT;
}
}
else if (strcasecmp(filename, "ct_sta_mode") == 0) {
if (kstrtol(val, 0, &t) == 0) {
ar->fwcfg.ct_sta_mode = t;
ar->fwcfg.flags |= ATH10K_FWCFG_CT_STA;
}
}
else if (strcasecmp(filename, "nobeamform_mu") == 0) {
if (kstrtol(val, 0, &t) == 0) {
ar->fwcfg.nobeamform_mu = t;
Expand Down Expand Up @@ -2250,6 +2258,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
return -EINVAL;
}

ar->request_ct_sta = ath10k_modparam_ct_sta;
ar->request_nohwcrypt = ath10k_modparam_nohwcrypt;
ar->request_nobeamform_mu = ath10k_modparam_nobeamform_mu;
ar->request_nobeamform_su = ath10k_modparam_nobeamform_su;
Expand All @@ -2265,6 +2274,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->max_num_stations = ar->fwcfg.stations;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOHWCRYPT)
ar->request_nohwcrypt = ar->fwcfg.nohwcrypt;
if (ar->fwcfg.flags & ATH10K_FWCFG_CT_STA)
ar->request_ct_sta = ar->fwcfg.ct_sta_mode;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOBEAMFORM_MU)
ar->request_nobeamform_mu = ar->fwcfg.nobeamform_mu;
if (ar->fwcfg.flags & ATH10K_FWCFG_NOBEAMFORM_SU)
Expand Down
9 changes: 9 additions & 0 deletions ath10k-4.9/core.h
Expand Up @@ -732,6 +732,12 @@ enum ath10k_fw_features {
/* Do we support requesting custom stats */
ATH10K_FW_FEATURE_CUST_STATS_CT = 46,

/* Can the firmware handle a retry limit greater than 2? */
ATH10K_FW_FEATURE_RETRY_GT2_CT = 47,

/* Can the firmware handle CT station feature, sort of like proxy-sta */
ATH10K_FW_FEATURE_CT_STA = 48,

/* keep last */
ATH10K_FW_FEATURE_COUNT,
};
Expand Down Expand Up @@ -971,6 +977,7 @@ struct ath10k {
#define ATH10K_FWCFG_MAX_AMSDUS (1<<13)
#define ATH10K_FWCFG_NOBEAMFORM_MU (1<<14)
#define ATH10K_FWCFG_NOBEAMFORM_SU (1<<15)
#define ATH10K_FWCFG_CT_STA (1<<16)

u32 flags; /* let us know which fields have been set */
char calname[100];
Expand All @@ -981,6 +988,7 @@ struct ath10k {
u32 stations;
u32 peers;
u32 nohwcrypt;
u32 ct_sta_mode;
u32 nobeamform_mu;
u32 nobeamform_su;
u32 rate_ctrl_objs;
Expand Down Expand Up @@ -1088,6 +1096,7 @@ struct ath10k {
int max_num_tdls_vdevs;
int num_active_peers;
int num_tids;
bool request_ct_sta; /* desired setting */
bool request_nohwcrypt; /* desired setting */
bool request_nobeamform_mu;
bool request_nobeamform_su;
Expand Down
13 changes: 10 additions & 3 deletions ath10k-4.9/mac.c
Expand Up @@ -214,6 +214,10 @@ int ath10k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath10k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware rx decrypt feature");

int ath10k_modparam_ct_sta;
module_param_named(ct_sta, ath10k_modparam_ct_sta, int, 0444);
MODULE_PARM_DESC(ct_sta, "Use CT-STA mode, a bit like proxy-STA");

int ath10k_modparam_nobeamform_mu;
module_param_named(nobeamform_mu, ath10k_modparam_nobeamform_mu, int, 0444);
MODULE_PARM_DESC(nobeamform_mu, "Disable TX/RX MU Beamforming capabilities");
Expand Down Expand Up @@ -9098,9 +9102,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);

/* CT firmware can do tx-sw-crypt if properly configured */
if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ath10k_modparam_nohwcrypt)
if ((!(test_bit(ATH10K_FW_FEATURE_CT_STA,
ar->running_fw->fw_file.fw_features) &&
ar->request_ct_sta)) &&
(test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt))
__clear_bit(IEEE80211_HW_SW_CRYPTO_CONTROL, ar->hw->flags);
} else {
ret = ath10k_copy_comb(ar, ath10k_10_4_if_comb,
Expand Down
1 change: 1 addition & 0 deletions ath10k-4.9/mac.h
Expand Up @@ -26,6 +26,7 @@
enum wmi_tlv_tx_pause_id;
enum wmi_tlv_tx_pause_action;

extern int ath10k_modparam_ct_sta;
extern int ath10k_modparam_nohwcrypt;
extern int ath10k_modparam_nobeamform_mu;
extern int ath10k_modparam_nobeamform_su;
Expand Down
11 changes: 9 additions & 2 deletions ath10k-4.9/wmi.c
Expand Up @@ -6277,9 +6277,16 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
/* Enabling this kills performance, for whatever reason. */
skid_limit = TARGET_10X_AST_SKID_LIMIT_CT;
#endif
if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
if (test_bit(ATH10K_FW_FEATURE_CT_STA,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt) {
ar->request_ct_sta) {
config.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_RAW |
ATH10k_VDEV_CT_STA_MODE);
ath10k_info(ar, "using CT-STA mode\n");
}
else if (test_bit(ATH10K_FW_FEATURE_CT_RXSWCRYPT,
ar->running_fw->fw_file.fw_features) &&
ar->request_nohwcrypt) {
/* This will disable rx decryption in hardware, enable raw
* rx mode, and native-wifi tx mode. Requires 'CT' firmware.
*/
Expand Down
2 changes: 2 additions & 0 deletions ath10k-4.9/wmi.h
Expand Up @@ -2265,6 +2265,8 @@ struct wmi_resource_config {
/* Ask CT firmware to send back per-chain management frame RSSI info */
#define ATH10k_MGT_CHAIN_RSSI_OK 0x80000
#define ATH10k_VDEV_CT_STATS_OK 0x100000
#define ATH10k_VDEV_CT_STA_MODE 0x200000 /* Try to use keys a bit like proxy-sta so we can do hw-crypt
* with many stations to same AP. */
/* NOTE: High 8 bits are spoken for, 'features' */
__le32 rx_decap_mode;

Expand Down

0 comments on commit fd92066

Please sign in to comment.