Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

csi over relayfs #98

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ath10k-5.2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ath10k_core-y += mac.o \
swap.o

ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += spectral.o
ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += csi.o
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
ath10k_core-$(CONFIG_THERMAL) += thermal.o
Expand Down
10 changes: 10 additions & 0 deletions ath10k-5.2/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3708,11 +3708,19 @@ static void ath10k_core_register_work(struct work_struct *work)
goto err_spectral_destroy;
}

status = ath10k_csi_create(ar);
if (status) {
ath10k_err(ar, "failed to initialize spectral\n");
goto err_csi_destroy;
}

set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
return;

err_spectral_destroy:
ath10k_spectral_destroy(ar);
err_csi_destroy:
ath10k_csi_destroy(ar);
err_debug_destroy:
ath10k_debug_destroy(ar);
err_unregister_coredump:
Expand Down Expand Up @@ -3777,6 +3785,8 @@ void ath10k_core_unregister(struct ath10k *ar)
*/
ath10k_spectral_destroy(ar);

ath10k_csi_destroy(ar);

/* We must unregister from mac80211 before we stop HTC and HIF.
* Otherwise we will fail to submit commands to FW and mac80211 will be
* unhappy about callback failures.
Expand Down
11 changes: 11 additions & 0 deletions ath10k-5.2/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "../regd.h"
#include "../dfs_pattern_detector.h"
#include "spectral.h"
#include "csi.h"
#include "thermal.h"
#include "wow.h"
#include "swap.h"
Expand Down Expand Up @@ -591,6 +592,7 @@ struct ath10k_vif {
bool is_started;
bool is_up;
bool spectral_enabled;
bool csi_enabled;
bool ps;
u32 aid;
u8 bssid[ETH_ALEN];
Expand Down Expand Up @@ -1419,6 +1421,15 @@ struct ath10k {
enum ath10k_spectral_mode mode;
struct ath10k_spec_scan config;
} spectral;

struct {
/* relay(fs) channel for csi */
struct rchan *rfs_chan_csi;

/* csi_mode is protected by conf_mutex */
enum ath10k_csi_mode mode;
} csi;

#endif
u32 wmi_get_temp_count;

Expand Down
238 changes: 238 additions & 0 deletions ath10k-5.2/csi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
* Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
*/

#include <linux/relay.h>
#include "core.h"
#include "debug.h"
#include "wmi-ops.h"

static void send_csi_sample(struct ath10k *ar,
const struct csi_sample_tlv *csi_sample_tlv)
{
int length;

if (!ar->csi.rfs_chan_csi)
return;

length = __be16_to_cpu(csi_sample_tlv->length) +
sizeof(*csi_sample_tlv);

relay_write(ar->csi.rfs_chan_csi, csi_sample_tlv, length);
}

int ath10k_csi_process(struct ath10k *ar, u8 *buf, u16 length)
{
int ret = 0;
u8 *ibuf;
u16 ilen;
struct csi_sample_ath10k *csi_sample;
u8 mbuf[sizeof(*csi_sample) + CSI_ATH10K_MAX_SIZE];

/* ath10k: CSI report accumulator. */
//u8 csi_data[4096];
//u16 csi_data_len;

ibuf = ar->csi_data;
ilen = ar->csi_data_len;

if (ilen < 64 || ilen > CSI_ATH10K_MAX_SIZE)
{
ath10k_warn(ar, "Cannot send CSI over relayFS with length %d\n", ilen);
return -EINVAL;
}

csi_sample = (struct csi_sample_ath10k *)&mbuf;
csi_sample->tlv.type = 0;
csi_sample->tlv.length = __cpu_to_be16(ilen);
memcpy(csi_sample->data, ibuf, ilen);
ath10k_warn(ar, "Send CSI over relayFS, length %d\n", ilen);

send_csi_sample(ar, &csi_sample->tlv);

return ret;
}

static struct ath10k_vif *ath10k_get_csi_vdev(struct ath10k *ar)
{
struct ath10k_vif *arvif;

lockdep_assert_held(&ar->conf_mutex);

if (list_empty(&ar->arvifs))
return NULL;

/* if there already is a vif reporting csi, return that. */
list_for_each_entry(arvif, &ar->arvifs, list)
if (arvif->csi_enabled)
return arvif;

/* otherwise, return the first vif. */
return list_first_entry(&ar->arvifs, typeof(*arvif), list);
}

static int ath10k_csi_config(struct ath10k *ar,
enum ath10k_csi_mode mode)
{
struct ath10k_vif *arvif;
int vdev_id, count, res = 0;

lockdep_assert_held(&ar->conf_mutex);

if (mode == CSI_DISABLED)
{
ar->eeprom_overrides.ct_csi = 0;
ath10k_warn(ar, "Disable CSI dump\n");
}

if (mode == CSI_ENABLED)
{
ar->eeprom_overrides.ct_csi = 1;
ath10k_warn(ar, "Enable CSI dump\n");
}

ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_CSI, ar->eeprom_overrides.ct_csi);

return 0;
}

static ssize_t read_file_csi_ctl(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
char *mode = "";
size_t len;
enum ath10k_csi_mode csi_mode;

mutex_lock(&ar->conf_mutex);
csi_mode = ar->csi.mode;
mutex_unlock(&ar->conf_mutex);

switch (csi_mode) {
case CSI_DISABLED:
mode = "disable";
break;
case CSI_ENABLED:
mode = "enable";
break;
}

len = strlen(mode);
return simple_read_from_buffer(user_buf, count, ppos, mode, len);
}

static ssize_t write_file_csi_ctl(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
char buf[32];
ssize_t len;
int res;

len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;

buf[len] = '\0';

mutex_lock(&ar->conf_mutex);

if (strncmp("enable", buf, 6) == 0) {
res = ath10k_csi_config(ar, CSI_ENABLED);
} else if (strncmp("disable", buf, 7) == 0) {
res = ath10k_csi_config(ar, CSI_DISABLED);
} else {
res = -EINVAL;
ath10k_warn(ar, "Unknown command for CSI dump\n");
}

mutex_unlock(&ar->conf_mutex);

if (res < 0)
return res;

return count;
}

static const struct file_operations fops_csi_ctl = {
.read = read_file_csi_ctl,
.write = write_file_csi_ctl,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};


static struct dentry *create_buf_file_handler(const char *filename,
struct dentry *parent,
umode_t mode,
struct rchan_buf *buf,
int *is_global)
{
struct dentry *buf_file;

buf_file = debugfs_create_file(filename, mode, parent, buf,
&relay_file_operations);
if (IS_ERR(buf_file))
return NULL;

*is_global = 1;
return buf_file;
}

static int remove_buf_file_handler(struct dentry *dentry)
{
debugfs_remove(dentry);

return 0;
}

static struct rchan_callbacks rfs_csi_cb = {
.create_buf_file = create_buf_file_handler,
.remove_buf_file = remove_buf_file_handler,
};

int ath10k_csi_start(struct ath10k *ar)
{
struct ath10k_vif *arvif;

lockdep_assert_held(&ar->conf_mutex);

list_for_each_entry(arvif, &ar->arvifs, list)
arvif->csi_enabled = 0;

ar->csi.mode = CSI_DISABLED;

return 0;
}

int ath10k_csi_vif_stop(struct ath10k_vif *arvif)
{
if (!arvif->csi_enabled)
return 0;

return ath10k_csi_config(arvif->ar, CSI_DISABLED);
}

int ath10k_csi_create(struct ath10k *ar)
{
ar->csi.rfs_chan_csi = relay_open("csi",
ar->debug.debugfs_phy,
1140, 2500,
&rfs_csi_cb, NULL);
debugfs_create_file("csi_ctl",
0600,
ar->debug.debugfs_phy, ar,
&fops_csi_ctl);

return 0;
}

void ath10k_csi_destroy(struct ath10k *ar)
{
if (ar->csi.rfs_chan_csi) {
relay_close(ar->csi.rfs_chan_csi);
ar->csi.rfs_chan_csi = NULL;
}
}
71 changes: 71 additions & 0 deletions ath10k-5.2/csi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
*/

#ifndef CSI_H
#define CSI_H

/* enum ath10k_csi_mode:
*
* @CSI_DISABLED: csi mode is disabled
* @CSI_ENABLED: csi mode is enabled
*/
enum ath10k_csi_mode {
CSI_DISABLED = 0,
CSI_ENABLED,
};

struct csi_sample_tlv {
u8 type;
__be16 length;
/* type dependent data follows */
} __packed;

struct csi_sample_ath10k {
struct csi_sample_tlv tlv;
u8 data[0];
} __packed;

#define CSI_ATH10K_MAX_SIZE 4000

#ifdef CONFIG_ATH10K_SPECTRAL

int ath10k_csi_process(struct ath10k *ar, u8 *buf, u16 length);
int ath10k_csi_start(struct ath10k *ar);
int ath10k_csi_vif_stop(struct ath10k_vif *arvif);
int ath10k_csi_create(struct ath10k *ar);
void ath10k_csi_destroy(struct ath10k *ar);

#else

static inline int
ath10k_csi_process(struct ath10k *ar,
struct wmi_phyerr_ev_arg *phyerr,
const struct phyerr_fft_report *fftr,
size_t bin_len, u64 tsf)
{
return 0;
}

static inline int ath10k_csi_start(struct ath10k *ar)
{
return 0;
}

static inline int ath10k_csi_vif_stop(struct ath10k_vif *arvif)
{
return 0;
}

static inline int ath10k_csi_create(struct ath10k *ar)
{
return 0;
}

static inline void ath10k_csi_destroy(struct ath10k *ar)
{
}

#endif /* CONFIG_ATH10K_SPECTRAL */

#endif /* CSI_H */
Loading