/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* Copyright (C) 2018 Netronome Systems, Inc. */
#ifndef __NFP_ABM_H__
#define __NFP_ABM_H__ 1
#include <linux/bits.h>
#include <linux/list.h>
#include <linux/radix-tree.h>
#include <net/devlink.h>
#include <net/pkt_cls.h>
#include <net/pkt_sched.h>
/* Dump of 64 PRIOs and 256 REDs seems to take 850us on Xeon v4 @ 2.20GHz;
* 2 . 5 ms / 400 Hz seems more than sufficient for stats resolution .
*/
#define NFP_ABM_STATS_REFRESH_IVAL (2500 * 1000 ) /* ns */
#define NFP_ABM_LVL_INFINITY S32_MAX
struct nfp_app;
struct nfp_net;
#define NFP_ABM_PORTID_TYPE GENMASK(23 , 16 )
#define NFP_ABM_PORTID_ID GENMASK(7 , 0 )
/* The possible actions if thresholds are exceeded */
enum nfp_abm_q_action {
/* mark if ECN capable, otherwise drop */
NFP_ABM_ACT_MARK_DROP = 0 ,
/* mark if ECN capable, otherwise goto QM */
NFP_ABM_ACT_MARK_QUEUE = 1 ,
NFP_ABM_ACT_DROP = 2 ,
NFP_ABM_ACT_QUEUE = 3 ,
NFP_ABM_ACT_NOQUEUE = 4 ,
};
/**
* struct nfp_abm - ABM NIC app structure
* @ app : back pointer to nfp_app
* @ pf_id : ID of our PF link
*
* @ red_support : is RED offload supported
* @ num_prios : number of supported DSCP priorities
* @ num_bands : number of supported DSCP priority bands
* @ action_mask : bitmask of supported actions
*
* @ thresholds : current threshold configuration
* @ threshold_undef : bitmap of thresholds which have not been set
* @ actions : current FW action configuration
* @ num_thresholds : number of @ thresholds and bits in @ threshold_undef
*
* @ prio_map_len : computed length of FW priority map ( in bytes )
* @ dscp_mask : mask FW will apply on DSCP field
*
* @ eswitch_mode : devlink eswitch mode , advanced functions only visible
* in switchdev mode
*
* @ q_lvls : queue level control area
* @ qm_stats : queue statistics symbol
* @ q_stats : basic queue statistics ( only in per - band case )
*/
struct nfp_abm {
struct nfp_app *app;
unsigned int pf_id;
unsigned int red_support;
unsigned int num_prios;
unsigned int num_bands;
unsigned int action_mask;
u32 *thresholds;
unsigned long *threshold_undef;
u8 *actions;
size_t num_thresholds;
unsigned int prio_map_len;
u8 dscp_mask;
enum devlink_eswitch_mode eswitch_mode;
const struct nfp_rtsym *q_lvls;
const struct nfp_rtsym *qm_stats;
const struct nfp_rtsym *q_stats;
};
/**
* struct nfp_alink_stats - ABM NIC statistics
* @ tx_pkts : number of TXed packets
* @ tx_bytes : number of TXed bytes
* @ backlog_pkts : momentary backlog length ( packets )
* @ backlog_bytes : momentary backlog length ( bytes )
* @ overlimits : number of ECN marked TXed packets ( accumulative )
* @ drops : number of tail - dropped packets ( accumulative )
*/
struct nfp_alink_stats {
u64 tx_pkts;
u64 tx_bytes;
u64 backlog_pkts;
u64 backlog_bytes;
u64 overlimits;
u64 drops;
};
/**
* struct nfp_alink_xstats - extended ABM NIC statistics
* @ ecn_marked : number of ECN marked TXed packets
* @ pdrop : number of hard drops due to queue limit
*/
struct nfp_alink_xstats {
u64 ecn_marked;
u64 pdrop;
};
enum nfp_qdisc_type {
NFP_QDISC_NONE = 0 ,
NFP_QDISC_MQ,
NFP_QDISC_RED,
NFP_QDISC_GRED,
};
#define NFP_QDISC_UNTRACKED ((struct nfp_qdisc *)1 UL)
/**
* struct nfp_qdisc - tracked TC Qdisc
* @ netdev : netdev on which Qdisc was created
* @ type : Qdisc type
* @ handle : handle of this Qdisc
* @ parent_handle : handle of the parent ( unreliable if Qdisc was grafted )
* @ use_cnt : number of attachment points in the hierarchy
* @ num_children : current size of the @ children array
* @ children : pointers to children
*
* @ params_ok : parameters of this Qdisc are OK for offload
* @ offload_mark : offload refresh state - selected for offload
* @ offloaded : Qdisc is currently offloaded to the HW
*
* @ mq : MQ Qdisc specific parameters and state
* @ mq . stats : current stats of the MQ Qdisc
* @ mq . prev_stats : previously reported @ mq . stats
*
* @ red : RED Qdisc specific parameters and state
* @ red . num_bands : Number of valid entries in the @ red . band table
* @ red . band : Per - band array of RED instances
* @ red . band . ecn : ECN marking is enabled ( rather than drop )
* @ red . band . threshold : ECN marking threshold
* @ red . band . stats : current stats of the RED Qdisc
* @ red . band . prev_stats : previously reported @ red . stats
* @ red . band . xstats : extended stats for RED - current
* @ red . band . prev_xstats : extended stats for RED - previously reported
*/
struct nfp_qdisc {
struct net_device *netdev;
enum nfp_qdisc_type type;
u32 handle;
u32 parent_handle;
unsigned int use_cnt;
unsigned int num_children;
struct nfp_qdisc **children;
bool params_ok;
bool offload_mark;
bool offloaded;
union {
/* NFP_QDISC_MQ */
struct {
struct nfp_alink_stats stats;
struct nfp_alink_stats prev_stats;
} mq;
/* TC_SETUP_QDISC_RED, TC_SETUP_QDISC_GRED */
struct {
unsigned int num_bands;
struct {
bool ecn;
u32 threshold;
struct nfp_alink_stats stats;
struct nfp_alink_stats prev_stats;
struct nfp_alink_xstats xstats;
struct nfp_alink_xstats prev_xstats;
} band[MAX_DPs];
} red;
};
};
/**
* struct nfp_abm_link - port tuple of a ABM NIC
* @ abm : back pointer to nfp_abm
* @ vnic : data vNIC
* @ id : id of the data vNIC
* @ queue_base : id of base to host queue within PCIe ( not QC idx )
* @ total_queues : number of PF queues
*
* @ last_stats_update : ktime of last stats update
*
* @ prio_map : current map of priorities
* @ has_prio : @ prio_map is valid
*
* @ def_band : default band to use
* @ dscp_map : list of DSCP to band mappings
*
* @ root_qdisc : pointer to the current root of the Qdisc hierarchy
* @ qdiscs : all qdiscs recorded by major part of the handle
*/
struct nfp_abm_link {
struct nfp_abm *abm;
struct nfp_net *vnic;
unsigned int id;
unsigned int queue_base;
unsigned int total_queues;
u64 last_stats_update;
u32 *prio_map;
bool has_prio;
u8 def_band;
struct list_head dscp_map;
struct nfp_qdisc *root_qdisc;
struct radix_tree_root qdiscs;
};
static inline bool nfp_abm_has_prio(struct nfp_abm *abm)
{
return abm->num_bands > 1 ;
}
static inline bool nfp_abm_has_drop(struct nfp_abm *abm)
{
return abm->action_mask & BIT(NFP_ABM_ACT_DROP);
}
static inline bool nfp_abm_has_mark(struct nfp_abm *abm)
{
return abm->action_mask & BIT(NFP_ABM_ACT_MARK_DROP);
}
void nfp_abm_qdisc_offload_update(struct nfp_abm_link *alink);
int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink,
struct tc_root_qopt_offload *opt);
int nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink,
struct tc_red_qopt_offload *opt);
int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
struct tc_mq_qopt_offload *opt);
int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink,
struct tc_gred_qopt_offload *opt);
int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr,
struct flow_block_offload *opt);
int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink);
int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm);
int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val);
int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band,
unsigned int queue, u32 val);
int __nfp_abm_ctrl_set_q_act(struct nfp_abm *abm, unsigned int id,
enum nfp_abm_q_action act);
int nfp_abm_ctrl_set_q_act(struct nfp_abm_link *alink, unsigned int band,
unsigned int queue, enum nfp_abm_q_action act);
int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink,
unsigned int band, unsigned int queue,
struct nfp_alink_stats *stats);
int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink,
unsigned int band, unsigned int queue,
struct nfp_alink_xstats *xstats);
u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int i);
u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int i);
int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm);
int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm);
void nfp_abm_prio_map_update(struct nfp_abm *abm);
int nfp_abm_ctrl_prio_map_update(struct nfp_abm_link *alink, u32 *packed);
#endif
Messung V0.5 in Prozent C=95 H=100 G=97
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-11)
¤
*© Formatika GbR, Deutschland