Commit d385623a authored by Janusz Dziedzic's avatar Janusz Dziedzic Committed by Kalle Valo

ath10k: add implementation for configure max amsdu, ampdu

Allow to setup maximum subframes for AMSDU and AMPDU aggregation
via debugfs htt_max_amsdu_ampdu file.

Eg.
echo "2 64" > htt_max_amsdu_ampdu
will setup maximum amsdu subframes equal 2 and
maximum ampdu subframes equal to 64.
Signed-off-by: default avatarJanusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 4e0561e7
...@@ -290,6 +290,9 @@ struct ath10k_debug { ...@@ -290,6 +290,9 @@ struct ath10k_debug {
struct ath_dfs_pool_stats dfs_pool_stats; struct ath_dfs_pool_stats dfs_pool_stats;
u32 fw_dbglog_mask; u32 fw_dbglog_mask;
u8 htt_max_amsdu;
u8 htt_max_ampdu;
}; };
enum ath10k_state { enum ath10k_state {
......
...@@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = { ...@@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
char buf[64];
u8 amsdu = 3, ampdu = 64;
unsigned int len;
mutex_lock(&ar->conf_mutex);
if (ar->debug.htt_max_amsdu)
amsdu = ar->debug.htt_max_amsdu;
if (ar->debug.htt_max_ampdu)
ampdu = ar->debug.htt_max_ampdu;
mutex_unlock(&ar->conf_mutex);
len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
int res;
char buf[64];
unsigned int amsdu, ampdu;
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
/* make sure that buf is null terminated */
buf[sizeof(buf) - 1] = 0;
res = sscanf(buf, "%u %u", &amsdu, &ampdu);
if (res != 2)
return -EINVAL;
mutex_lock(&ar->conf_mutex);
res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
if (res)
goto out;
res = count;
ar->debug.htt_max_amsdu = amsdu;
ar->debug.htt_max_ampdu = ampdu;
out:
mutex_unlock(&ar->conf_mutex);
return res;
}
static const struct file_operations fops_htt_max_amsdu_ampdu = {
.read = ath10k_read_htt_max_amsdu_ampdu,
.write = ath10k_write_htt_max_amsdu_ampdu,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t ath10k_read_fw_dbglog(struct file *file, static ssize_t ath10k_read_fw_dbglog(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar) ...@@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
* warning from del_timer(). */ * warning from del_timer(). */
if (ar->debug.htt_stats_mask != 0) if (ar->debug.htt_stats_mask != 0)
cancel_delayed_work(&ar->debug.htt_stats_dwork); cancel_delayed_work(&ar->debug.htt_stats_dwork);
ar->debug.htt_max_amsdu = 0;
ar->debug.htt_max_ampdu = 0;
} }
static ssize_t ath10k_write_simulate_radar(struct file *file, static ssize_t ath10k_write_simulate_radar(struct file *file,
...@@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar) ...@@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_htt_stats_mask); ar, &fops_htt_stats_mask);
debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
ar->debug.debugfs_phy, ar,
&fops_htt_max_amsdu_ampdu);
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_fw_dbglog); ar, &fops_fw_dbglog);
......
...@@ -240,16 +240,10 @@ struct htt_oob_sync_req { ...@@ -240,16 +240,10 @@ struct htt_oob_sync_req {
__le16 rsvd0; __le16 rsvd0;
} __packed; } __packed;
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0
struct htt_aggr_conf { struct htt_aggr_conf {
u8 max_num_ampdu_subframes; u8 max_num_ampdu_subframes;
union { /* amsdu_subframes is limited by 0x1F mask */
/* dont use bitfields; undefined behaviour */ u8 max_num_amsdu_subframes;
u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
u8 max_num_amsdu_subframes:5;
} __packed;
} __packed; } __packed;
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32 #define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
...@@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); ...@@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu);
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt); int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
......
...@@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) ...@@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
return 0; return 0;
} }
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu)
{
struct htt_aggr_conf *aggr_conf;
struct sk_buff *skb;
struct htt_cmd *cmd;
int len;
int ret;
/* Firmware defaults are: amsdu = 3 and ampdu = 64 */
if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
return -EINVAL;
if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
return -EINVAL;
len = sizeof(cmd->hdr);
len += sizeof(cmd->aggr_conf);
skb = ath10k_htc_alloc_skb(len);
if (!skb)
return -ENOMEM;
skb_put(skb, len);
cmd = (struct htt_cmd *)skb->data;
cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
aggr_conf = &cmd->aggr_conf;
aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
aggr_conf->max_num_amsdu_subframes,
aggr_conf->max_num_ampdu_subframes);
ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
if (ret) {
dev_kfree_skb_any(skb);
return ret;
}
return 0;
}
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{ {
struct device *dev = htt->ar->dev; struct device *dev = htt->ar->dev;
......
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