linux/drivers/net/ethernet/netronome/nfp/abm/main.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
   2/* Copyright (C) 2018 Netronome Systems, Inc. */
   3
   4#ifndef __NFP_ABM_H__
   5#define __NFP_ABM_H__ 1
   6
   7#include <linux/bits.h>
   8#include <linux/list.h>
   9#include <linux/radix-tree.h>
  10#include <net/devlink.h>
  11#include <net/pkt_cls.h>
  12#include <net/pkt_sched.h>
  13
  14/* Dump of 64 PRIOs and 256 REDs seems to take 850us on Xeon v4 @ 2.20GHz;
  15 * 2.5ms / 400Hz seems more than sufficient for stats resolution.
  16 */
  17#define NFP_ABM_STATS_REFRESH_IVAL      (2500 * 1000) /* ns */
  18
  19#define NFP_ABM_LVL_INFINITY            S32_MAX
  20
  21struct nfp_app;
  22struct nfp_net;
  23
  24#define NFP_ABM_PORTID_TYPE     GENMASK(23, 16)
  25#define NFP_ABM_PORTID_ID       GENMASK(7, 0)
  26
  27/* The possible actions if thresholds are exceeded */
  28enum nfp_abm_q_action {
  29        /* mark if ECN capable, otherwise drop */
  30        NFP_ABM_ACT_MARK_DROP           = 0,
  31        /* mark if ECN capable, otherwise goto QM */
  32        NFP_ABM_ACT_MARK_QUEUE          = 1,
  33        NFP_ABM_ACT_DROP                = 2,
  34        NFP_ABM_ACT_QUEUE               = 3,
  35        NFP_ABM_ACT_NOQUEUE             = 4,
  36};
  37
  38/**
  39 * struct nfp_abm - ABM NIC app structure
  40 * @app:        back pointer to nfp_app
  41 * @pf_id:      ID of our PF link
  42 *
  43 * @red_support:        is RED offload supported
  44 * @num_prios:  number of supported DSCP priorities
  45 * @num_bands:  number of supported DSCP priority bands
  46 * @action_mask:        bitmask of supported actions
  47 *
  48 * @thresholds:         current threshold configuration
  49 * @threshold_undef:    bitmap of thresholds which have not been set
  50 * @actions:            current FW action configuration
  51 * @num_thresholds:     number of @thresholds and bits in @threshold_undef
  52 *
  53 * @prio_map_len:       computed length of FW priority map (in bytes)
  54 * @dscp_mask:          mask FW will apply on DSCP field
  55 *
  56 * @eswitch_mode:       devlink eswitch mode, advanced functions only visible
  57 *                      in switchdev mode
  58 *
  59 * @q_lvls:     queue level control area
  60 * @qm_stats:   queue statistics symbol
  61 * @q_stats:    basic queue statistics (only in per-band case)
  62 */
  63struct nfp_abm {
  64        struct nfp_app *app;
  65        unsigned int pf_id;
  66
  67        unsigned int red_support;
  68        unsigned int num_prios;
  69        unsigned int num_bands;
  70        unsigned int action_mask;
  71
  72        u32 *thresholds;
  73        unsigned long *threshold_undef;
  74        u8 *actions;
  75        size_t num_thresholds;
  76
  77        unsigned int prio_map_len;
  78        u8 dscp_mask;
  79
  80        enum devlink_eswitch_mode eswitch_mode;
  81
  82        const struct nfp_rtsym *q_lvls;
  83        const struct nfp_rtsym *qm_stats;
  84        const struct nfp_rtsym *q_stats;
  85};
  86
  87/**
  88 * struct nfp_alink_stats - ABM NIC statistics
  89 * @tx_pkts:            number of TXed packets
  90 * @tx_bytes:           number of TXed bytes
  91 * @backlog_pkts:       momentary backlog length (packets)
  92 * @backlog_bytes:      momentary backlog length (bytes)
  93 * @overlimits:         number of ECN marked TXed packets (accumulative)
  94 * @drops:              number of tail-dropped packets (accumulative)
  95 */
  96struct nfp_alink_stats {
  97        u64 tx_pkts;
  98        u64 tx_bytes;
  99        u64 backlog_pkts;
 100        u64 backlog_bytes;
 101        u64 overlimits;
 102        u64 drops;
 103};
 104
 105/**
 106 * struct nfp_alink_xstats - extended ABM NIC statistics
 107 * @ecn_marked:         number of ECN marked TXed packets
 108 * @pdrop:              number of hard drops due to queue limit
 109 */
 110struct nfp_alink_xstats {
 111        u64 ecn_marked;
 112        u64 pdrop;
 113};
 114
 115enum nfp_qdisc_type {
 116        NFP_QDISC_NONE = 0,
 117        NFP_QDISC_MQ,
 118        NFP_QDISC_RED,
 119        NFP_QDISC_GRED,
 120};
 121
 122#define NFP_QDISC_UNTRACKED     ((struct nfp_qdisc *)1UL)
 123
 124/**
 125 * struct nfp_qdisc - tracked TC Qdisc
 126 * @netdev:             netdev on which Qdisc was created
 127 * @type:               Qdisc type
 128 * @handle:             handle of this Qdisc
 129 * @parent_handle:      handle of the parent (unreliable if Qdisc was grafted)
 130 * @use_cnt:            number of attachment points in the hierarchy
 131 * @num_children:       current size of the @children array
 132 * @children:           pointers to children
 133 *
 134 * @params_ok:          parameters of this Qdisc are OK for offload
 135 * @offload_mark:       offload refresh state - selected for offload
 136 * @offloaded:          Qdisc is currently offloaded to the HW
 137 *
 138 * @mq:                 MQ Qdisc specific parameters and state
 139 * @mq.stats:           current stats of the MQ Qdisc
 140 * @mq.prev_stats:      previously reported @mq.stats
 141 *
 142 * @red:                RED Qdisc specific parameters and state
 143 * @red.num_bands:      Number of valid entries in the @red.band table
 144 * @red.band:           Per-band array of RED instances
 145 * @red.band.ecn:               ECN marking is enabled (rather than drop)
 146 * @red.band.threshold:         ECN marking threshold
 147 * @red.band.stats:             current stats of the RED Qdisc
 148 * @red.band.prev_stats:        previously reported @red.stats
 149 * @red.band.xstats:            extended stats for RED - current
 150 * @red.band.prev_xstats:       extended stats for RED - previously reported
 151 */
 152struct nfp_qdisc {
 153        struct net_device *netdev;
 154        enum nfp_qdisc_type type;
 155        u32 handle;
 156        u32 parent_handle;
 157        unsigned int use_cnt;
 158        unsigned int num_children;
 159        struct nfp_qdisc **children;
 160
 161        bool params_ok;
 162        bool offload_mark;
 163        bool offloaded;
 164
 165        union {
 166                /* NFP_QDISC_MQ */
 167                struct {
 168                        struct nfp_alink_stats stats;
 169                        struct nfp_alink_stats prev_stats;
 170                } mq;
 171                /* TC_SETUP_QDISC_RED, TC_SETUP_QDISC_GRED */
 172                struct {
 173                        unsigned int num_bands;
 174
 175                        struct {
 176                                bool ecn;
 177                                u32 threshold;
 178                                struct nfp_alink_stats stats;
 179                                struct nfp_alink_stats prev_stats;
 180                                struct nfp_alink_xstats xstats;
 181                                struct nfp_alink_xstats prev_xstats;
 182                        } band[MAX_DPs];
 183                } red;
 184        };
 185};
 186
 187/**
 188 * struct nfp_abm_link - port tuple of a ABM NIC
 189 * @abm:        back pointer to nfp_abm
 190 * @vnic:       data vNIC
 191 * @id:         id of the data vNIC
 192 * @queue_base: id of base to host queue within PCIe (not QC idx)
 193 * @total_queues:       number of PF queues
 194 *
 195 * @last_stats_update:  ktime of last stats update
 196 *
 197 * @prio_map:           current map of priorities
 198 * @has_prio:           @prio_map is valid
 199 *
 200 * @def_band:           default band to use
 201 * @dscp_map:           list of DSCP to band mappings
 202 *
 203 * @root_qdisc: pointer to the current root of the Qdisc hierarchy
 204 * @qdiscs:     all qdiscs recorded by major part of the handle
 205 */
 206struct nfp_abm_link {
 207        struct nfp_abm *abm;
 208        struct nfp_net *vnic;
 209        unsigned int id;
 210        unsigned int queue_base;
 211        unsigned int total_queues;
 212
 213        u64 last_stats_update;
 214
 215        u32 *prio_map;
 216        bool has_prio;
 217
 218        u8 def_band;
 219        struct list_head dscp_map;
 220
 221        struct nfp_qdisc *root_qdisc;
 222        struct radix_tree_root qdiscs;
 223};
 224
 225static inline bool nfp_abm_has_prio(struct nfp_abm *abm)
 226{
 227        return abm->num_bands > 1;
 228}
 229
 230static inline bool nfp_abm_has_drop(struct nfp_abm *abm)
 231{
 232        return abm->action_mask & BIT(NFP_ABM_ACT_DROP);
 233}
 234
 235static inline bool nfp_abm_has_mark(struct nfp_abm *abm)
 236{
 237        return abm->action_mask & BIT(NFP_ABM_ACT_MARK_DROP);
 238}
 239
 240void nfp_abm_qdisc_offload_update(struct nfp_abm_link *alink);
 241int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink,
 242                       struct tc_root_qopt_offload *opt);
 243int nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink,
 244                         struct tc_red_qopt_offload *opt);
 245int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
 246                        struct tc_mq_qopt_offload *opt);
 247int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink,
 248                          struct tc_gred_qopt_offload *opt);
 249int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr,
 250                            struct flow_block_offload *opt);
 251
 252int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink);
 253int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm);
 254int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val);
 255int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band,
 256                           unsigned int queue, u32 val);
 257int __nfp_abm_ctrl_set_q_act(struct nfp_abm *abm, unsigned int id,
 258                             enum nfp_abm_q_action act);
 259int nfp_abm_ctrl_set_q_act(struct nfp_abm_link *alink, unsigned int band,
 260                           unsigned int queue, enum nfp_abm_q_action act);
 261int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink,
 262                              unsigned int band, unsigned int queue,
 263                              struct nfp_alink_stats *stats);
 264int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink,
 265                               unsigned int band, unsigned int queue,
 266                               struct nfp_alink_xstats *xstats);
 267u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int i);
 268u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int i);
 269int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm);
 270int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm);
 271void nfp_abm_prio_map_update(struct nfp_abm *abm);
 272int nfp_abm_ctrl_prio_map_update(struct nfp_abm_link *alink, u32 *packed);
 273#endif
 274