linux/drivers/hwtracing/ptt/hisi_ptt.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for HiSilicon PCIe tune and trace device
 *
 * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
 * Author: Yicong Yang <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cpuhotplug.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/sysfs.h>
#include <linux/vmalloc.h>

#include "hisi_ptt.h"

/* Dynamic CPU hotplug state used by PTT */
static enum cpuhp_state hisi_ptt_pmu_online;

static bool hisi_ptt_wait_tuning_finish(struct hisi_ptt *hisi_ptt)
{}

static ssize_t hisi_ptt_tune_attr_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{}

static ssize_t hisi_ptt_tune_attr_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{}

#define HISI_PTT_TUNE_ATTR(_name, _val, _show, _store)

#define HISI_PTT_TUNE_ATTR_COMMON(_name, _val)

/*
 * The value of the tuning event are composed of two parts: main event code
 * in BIT[0,15] and subevent code in BIT[16,23]. For example, qox_tx_cpl is
 * a subevent of 'Tx path QoS control' which for tuning the weight of Tx
 * completion TLPs. See hisi_ptt.rst documentation for more information.
 */
#define HISI_PTT_TUNE_QOS_TX_CPL
#define HISI_PTT_TUNE_QOS_TX_NP
#define HISI_PTT_TUNE_QOS_TX_P
#define HISI_PTT_TUNE_RX_ALLOC_BUF_LEVEL
#define HISI_PTT_TUNE_TX_ALLOC_BUF_LEVEL

HISI_PTT_TUNE_ATTR_COMMON();
HISI_PTT_TUNE_ATTR_COMMON();
HISI_PTT_TUNE_ATTR_COMMON();
HISI_PTT_TUNE_ATTR_COMMON();
HISI_PTT_TUNE_ATTR_COMMON();

static struct attribute *hisi_ptt_tune_attrs[] =;

static struct attribute_group hisi_ptt_tune_group =;

static u16 hisi_ptt_get_filter_val(u16 devid, bool is_port)
{}

static bool hisi_ptt_wait_trace_hw_idle(struct hisi_ptt *hisi_ptt)
{}

static void hisi_ptt_wait_dma_reset_done(struct hisi_ptt *hisi_ptt)
{}

static void hisi_ptt_trace_end(struct hisi_ptt *hisi_ptt)
{}

static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
{}

static int hisi_ptt_update_aux(struct hisi_ptt *hisi_ptt, int index, bool stop)
{}

static irqreturn_t hisi_ptt_isr(int irq, void *context)
{}

static void hisi_ptt_irq_free_vectors(void *pdev)
{}

static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
{}

static void hisi_ptt_del_free_filter(struct hisi_ptt *hisi_ptt,
				      struct hisi_ptt_filter_desc *filter)
{}

static struct hisi_ptt_filter_desc *
hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
{}

static ssize_t hisi_ptt_filter_show(struct device *dev, struct device_attribute *attr,
				    char *buf)
{}

static int hisi_ptt_create_rp_filter_attr(struct hisi_ptt *hisi_ptt,
					  struct hisi_ptt_filter_desc *filter)
{}

static void hisi_ptt_remove_rp_filter_attr(struct hisi_ptt *hisi_ptt,
					  struct hisi_ptt_filter_desc *filter)
{}

static int hisi_ptt_create_req_filter_attr(struct hisi_ptt *hisi_ptt,
					   struct hisi_ptt_filter_desc *filter)
{}

static void hisi_ptt_remove_req_filter_attr(struct hisi_ptt *hisi_ptt,
					   struct hisi_ptt_filter_desc *filter)
{}

static int hisi_ptt_create_filter_attr(struct hisi_ptt *hisi_ptt,
				       struct hisi_ptt_filter_desc *filter)
{}

static void hisi_ptt_remove_filter_attr(struct hisi_ptt *hisi_ptt,
					struct hisi_ptt_filter_desc *filter)
{}

static void hisi_ptt_remove_all_filter_attributes(void *data)
{}

static int hisi_ptt_init_filter_attributes(struct hisi_ptt *hisi_ptt)
{}

static void hisi_ptt_update_filters(struct work_struct *work)
{}

/*
 * A PCI bus notifier is used here for dynamically updating the filter
 * list.
 */
static int hisi_ptt_notifier_call(struct notifier_block *nb, unsigned long action,
				  void *data)
{}

static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
{}

static void hisi_ptt_release_filters(void *data)
{}

static int hisi_ptt_config_trace_buf(struct hisi_ptt *hisi_ptt)
{}

static int hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
{}

static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{}
static DEVICE_ATTR_RO(cpumask);

static struct attribute *hisi_ptt_cpumask_attrs[] =;

static const struct attribute_group hisi_ptt_cpumask_attr_group =;

/*
 * Bit 19 indicates the filter type, 1 for Root Port filter and 0 for Requester
 * filter. Bit[15:0] indicates the filter value, for Root Port filter it's
 * a bit mask of desired ports and for Requester filter it's the Requester ID
 * of the desired PCIe function. Bit[18:16] is reserved for extension.
 *
 * See hisi_ptt.rst documentation for detailed information.
 */
PMU_FORMAT_ATTR();
PMU_FORMAT_ATTR();
PMU_FORMAT_ATTR();
PMU_FORMAT_ATTR();

static struct attribute *hisi_ptt_pmu_format_attrs[] =;

static struct attribute_group hisi_ptt_pmu_format_group =;

static ssize_t hisi_ptt_filter_multiselect_show(struct device *dev,
						struct device_attribute *attr,
						char *buf)
{}

static struct dev_ext_attribute root_port_filters_multiselect =;

static struct attribute *hisi_ptt_pmu_root_ports_attrs[] =;

static struct attribute_group hisi_ptt_pmu_root_ports_group =;

static struct dev_ext_attribute requester_filters_multiselect =;

static struct attribute *hisi_ptt_pmu_requesters_attrs[] =;

static struct attribute_group hisi_ptt_pmu_requesters_group =;

static const struct attribute_group *hisi_ptt_pmu_groups[] =;

static int hisi_ptt_trace_valid_direction(u32 val)
{}

static int hisi_ptt_trace_valid_type(u32 val)
{}

static int hisi_ptt_trace_valid_format(u32 val)
{}

static int hisi_ptt_trace_valid_filter(struct hisi_ptt *hisi_ptt, u64 config)
{}

static void hisi_ptt_pmu_init_configs(struct hisi_ptt *hisi_ptt, struct perf_event *event)
{}

static int hisi_ptt_pmu_event_init(struct perf_event *event)
{}

static void *hisi_ptt_pmu_setup_aux(struct perf_event *event, void **pages,
				    int nr_pages, bool overwrite)
{}

static void hisi_ptt_pmu_free_aux(void *aux)
{}

static void hisi_ptt_pmu_start(struct perf_event *event, int flags)
{}

static void hisi_ptt_pmu_stop(struct perf_event *event, int flags)
{}

static int hisi_ptt_pmu_add(struct perf_event *event, int flags)
{}

static void hisi_ptt_pmu_del(struct perf_event *event, int flags)
{}

static void hisi_ptt_pmu_read(struct perf_event *event)
{}

static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node)
{}

static void hisi_ptt_unregister_pmu(void *pmu)
{}

static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
{}

static void hisi_ptt_unregister_filter_update_notifier(void *data)
{}

/* Register the bus notifier for dynamically updating the filter list */
static int hisi_ptt_register_filter_update_notifier(struct hisi_ptt *hisi_ptt)
{}

/*
 * The DMA of PTT trace can only use direct mappings due to some
 * hardware restriction. Check whether there is no IOMMU or the
 * policy of the IOMMU domain is passthrough, otherwise the trace
 * cannot work.
 *
 * The PTT device is supposed to behind an ARM SMMUv3, which
 * should have passthrough the device by a quirk.
 */
static int hisi_ptt_check_iommu_mapping(struct pci_dev *pdev)
{}

static int hisi_ptt_probe(struct pci_dev *pdev,
			  const struct pci_device_id *id)
{}

static const struct pci_device_id hisi_ptt_id_tbl[] =;
MODULE_DEVICE_TABLE(pci, hisi_ptt_id_tbl);

static struct pci_driver hisi_ptt_driver =;

static int hisi_ptt_cpu_teardown(unsigned int cpu, struct hlist_node *node)
{}

static int __init hisi_ptt_init(void)
{}
module_init();

static void __exit hisi_ptt_exit(void)
{}
module_exit(hisi_ptt_exit);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();