#include <linux/ethtool.h>
#include <linux/ethtool_netlink.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/time.h>
#include <net/gso.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
#include <net/sch_generic.h>
#include <net/sock.h>
#include <net/tcp.h>
#define TAPRIO_STAT_NOT_SET …
#include "sch_mqprio_lib.h"
static LIST_HEAD(taprio_list);
static struct static_key_false taprio_have_broken_mqprio;
static struct static_key_false taprio_have_working_mqprio;
#define TAPRIO_ALL_GATES_OPEN …
#define TXTIME_ASSIST_IS_ENABLED(flags) …
#define FULL_OFFLOAD_IS_ENABLED(flags) …
#define TAPRIO_SUPPORTED_FLAGS …
#define TAPRIO_FLAGS_INVALID …
struct sched_entry { … };
struct sched_gate_list { … };
struct taprio_sched { … };
struct __tc_taprio_qopt_offload { … };
static void taprio_calculate_gate_durations(struct taprio_sched *q,
struct sched_gate_list *sched)
{ … }
static bool taprio_entry_allows_tx(ktime_t skb_end_time,
struct sched_entry *entry, int tc)
{ … }
static ktime_t sched_base_time(const struct sched_gate_list *sched)
{ … }
static ktime_t taprio_mono_to_any(const struct taprio_sched *q, ktime_t mono)
{ … }
static ktime_t taprio_get_time(const struct taprio_sched *q)
{ … }
static void taprio_free_sched_cb(struct rcu_head *head)
{ … }
static void switch_schedules(struct taprio_sched *q,
struct sched_gate_list **admin,
struct sched_gate_list **oper)
{ … }
static s32 get_cycle_time_elapsed(struct sched_gate_list *sched, ktime_t time)
{ … }
static ktime_t get_interval_end_time(struct sched_gate_list *sched,
struct sched_gate_list *admin,
struct sched_entry *entry,
ktime_t intv_start)
{ … }
static int length_to_duration(struct taprio_sched *q, int len)
{ … }
static int duration_to_length(struct taprio_sched *q, u64 duration)
{ … }
static void taprio_update_queue_max_sdu(struct taprio_sched *q,
struct sched_gate_list *sched,
struct qdisc_size_table *stab)
{ … }
static struct sched_entry *find_entry_to_transmit(struct sk_buff *skb,
struct Qdisc *sch,
struct sched_gate_list *sched,
struct sched_gate_list *admin,
ktime_t time,
ktime_t *interval_start,
ktime_t *interval_end,
bool validate_interval)
{ … }
static bool is_valid_interval(struct sk_buff *skb, struct Qdisc *sch)
{ … }
static ktime_t get_tcp_tstamp(struct taprio_sched *q, struct sk_buff *skb)
{ … }
static long get_packet_txtime(struct sk_buff *skb, struct Qdisc *sch)
{ … }
static bool taprio_skb_exceeds_queue_max_sdu(struct Qdisc *sch,
struct sk_buff *skb)
{ … }
static int taprio_enqueue_one(struct sk_buff *skb, struct Qdisc *sch,
struct Qdisc *child, struct sk_buff **to_free)
{ … }
static int taprio_enqueue_segmented(struct sk_buff *skb, struct Qdisc *sch,
struct Qdisc *child,
struct sk_buff **to_free)
{ … }
static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{ … }
static struct sk_buff *taprio_peek(struct Qdisc *sch)
{ … }
static void taprio_set_budgets(struct taprio_sched *q,
struct sched_gate_list *sched,
struct sched_entry *entry)
{ … }
static int taprio_update_budgets(struct sched_entry *entry, size_t len,
int tc_consumed, int num_tc)
{ … }
static struct sk_buff *taprio_dequeue_from_txq(struct Qdisc *sch, int txq,
struct sched_entry *entry,
u32 gate_mask)
{ … }
static void taprio_next_tc_txq(struct net_device *dev, int tc, int *txq)
{ … }
static struct sk_buff *taprio_dequeue_tc_priority(struct Qdisc *sch,
struct sched_entry *entry,
u32 gate_mask)
{ … }
static struct sk_buff *taprio_dequeue_txq_priority(struct Qdisc *sch,
struct sched_entry *entry,
u32 gate_mask)
{ … }
static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
{ … }
static bool should_restart_cycle(const struct sched_gate_list *oper,
const struct sched_entry *entry)
{ … }
static bool should_change_schedules(const struct sched_gate_list *admin,
const struct sched_gate_list *oper,
ktime_t end_time)
{ … }
static enum hrtimer_restart advance_sched(struct hrtimer *timer)
{ … }
static const struct nla_policy entry_policy[TCA_TAPRIO_SCHED_ENTRY_MAX + 1] = …;
static const struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = …;
static const struct netlink_range_validation_signed taprio_cycle_time_range = …;
static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = …;
static int fill_sched_entry(struct taprio_sched *q, struct nlattr **tb,
struct sched_entry *entry,
struct netlink_ext_ack *extack)
{ … }
static int parse_sched_entry(struct taprio_sched *q, struct nlattr *n,
struct sched_entry *entry, int index,
struct netlink_ext_ack *extack)
{ … }
static int parse_sched_list(struct taprio_sched *q, struct nlattr *list,
struct sched_gate_list *sched,
struct netlink_ext_ack *extack)
{ … }
static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
struct sched_gate_list *new,
struct netlink_ext_ack *extack)
{ … }
static int taprio_parse_mqprio_opt(struct net_device *dev,
struct tc_mqprio_qopt *qopt,
struct netlink_ext_ack *extack,
u32 taprio_flags)
{ … }
static int taprio_get_start_time(struct Qdisc *sch,
struct sched_gate_list *sched,
ktime_t *start)
{ … }
static void setup_first_end_time(struct taprio_sched *q,
struct sched_gate_list *sched, ktime_t base)
{ … }
static void taprio_start_sched(struct Qdisc *sch,
ktime_t start, struct sched_gate_list *new)
{ … }
static void taprio_set_picos_per_byte(struct net_device *dev,
struct taprio_sched *q)
{ … }
static int taprio_dev_notifier(struct notifier_block *nb, unsigned long event,
void *ptr)
{ … }
static void setup_txtime(struct taprio_sched *q,
struct sched_gate_list *sched, ktime_t base)
{ … }
static struct tc_taprio_qopt_offload *taprio_offload_alloc(int num_entries)
{ … }
struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
*offload)
{ … }
EXPORT_SYMBOL_GPL(…);
void taprio_offload_free(struct tc_taprio_qopt_offload *offload)
{ … }
EXPORT_SYMBOL_GPL(…);
static void taprio_offload_config_changed(struct taprio_sched *q)
{ … }
static u32 tc_map_to_queue_mask(struct net_device *dev, u32 tc_mask)
{ … }
static void taprio_sched_to_offload(struct net_device *dev,
struct sched_gate_list *sched,
struct tc_taprio_qopt_offload *offload,
const struct tc_taprio_caps *caps)
{ … }
static void taprio_detect_broken_mqprio(struct taprio_sched *q)
{ … }
static void taprio_cleanup_broken_mqprio(struct taprio_sched *q)
{ … }
static int taprio_enable_offload(struct net_device *dev,
struct taprio_sched *q,
struct sched_gate_list *sched,
struct netlink_ext_ack *extack)
{ … }
static int taprio_disable_offload(struct net_device *dev,
struct taprio_sched *q,
struct netlink_ext_ack *extack)
{ … }
static int taprio_parse_clockid(struct Qdisc *sch, struct nlattr **tb,
struct netlink_ext_ack *extack)
{ … }
static int taprio_parse_tc_entry(struct Qdisc *sch,
struct nlattr *opt,
u32 max_sdu[TC_QOPT_MAX_QUEUE],
u32 fp[TC_QOPT_MAX_QUEUE],
unsigned long *seen_tcs,
struct netlink_ext_ack *extack)
{ … }
static int taprio_parse_tc_entries(struct Qdisc *sch,
struct nlattr *opt,
struct netlink_ext_ack *extack)
{ … }
static int taprio_mqprio_cmp(const struct net_device *dev,
const struct tc_mqprio_qopt *mqprio)
{ … }
static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ … }
static void taprio_reset(struct Qdisc *sch)
{ … }
static void taprio_destroy(struct Qdisc *sch)
{ … }
static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ … }
static void taprio_attach(struct Qdisc *sch)
{ … }
static struct netdev_queue *taprio_queue_get(struct Qdisc *sch,
unsigned long cl)
{ … }
static int taprio_graft(struct Qdisc *sch, unsigned long cl,
struct Qdisc *new, struct Qdisc **old,
struct netlink_ext_ack *extack)
{ … }
static int dump_entry(struct sk_buff *msg,
const struct sched_entry *entry)
{ … }
static int dump_schedule(struct sk_buff *msg,
const struct sched_gate_list *root)
{ … }
static int taprio_dump_tc_entries(struct sk_buff *skb,
struct taprio_sched *q,
struct sched_gate_list *sched)
{ … }
static int taprio_put_stat(struct sk_buff *skb, u64 val, u16 attrtype)
{ … }
static int taprio_dump_xstats(struct Qdisc *sch, struct gnet_dump *d,
struct tc_taprio_qopt_offload *offload,
struct tc_taprio_qopt_stats *stats)
{ … }
static int taprio_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
{ … }
static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
{ … }
static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl)
{ … }
static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
{ … }
static int taprio_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{ … }
static int taprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
struct gnet_dump *d)
__releases(d->lock)
__acquires(d->lock)
{ … }
static void taprio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{ … }
static struct netdev_queue *taprio_select_queue(struct Qdisc *sch,
struct tcmsg *tcm)
{ … }
static const struct Qdisc_class_ops taprio_class_ops = …;
static struct Qdisc_ops taprio_qdisc_ops __read_mostly = …;
MODULE_ALIAS_NET_SCH(…) …;
static struct notifier_block taprio_device_notifier = …;
static int __init taprio_module_init(void)
{ … }
static void __exit taprio_module_exit(void)
{ … }
module_init(…) …;
module_exit(taprio_module_exit);
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;