1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2018 Netronome Systems, Inc. */
4 #include <linux/kernel.h>
6 #include "../nfpcore/nfp_cpp.h"
7 #include "../nfpcore/nfp_nffw.h"
8 #include "../nfp_app.h"
9 #include "../nfp_abi.h"
10 #include "../nfp_main.h"
11 #include "../nfp_net.h"
14 #define NFP_QLVL_SYM_NAME "_abi_nfd_out_q_lvls_%u"
15 #define NFP_QLVL_STRIDE 16
16 #define NFP_QLVL_BLOG_BYTES 0
17 #define NFP_QLVL_BLOG_PKTS 4
18 #define NFP_QLVL_THRS 8
20 #define NFP_QMSTAT_SYM_NAME "_abi_nfdqm%u_stats"
21 #define NFP_QMSTAT_STRIDE 32
22 #define NFP_QMSTAT_NON_STO 0
23 #define NFP_QMSTAT_STO 8
24 #define NFP_QMSTAT_DROP 16
25 #define NFP_QMSTAT_ECN 24
28 nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
29 unsigned int stride, unsigned int offset, unsigned int i,
30 bool is_u64, u64 *res)
32 struct nfp_cpp *cpp = alink->abm->app->cpp;
37 sym_offset = (alink->queue_base + i) * stride + offset;
39 err = __nfp_rtsym_readq(cpp, sym, 3, 0, sym_offset, &val);
41 err = __nfp_rtsym_readl(cpp, sym, 3, 0, sym_offset, &val32);
44 "RED offload reading stat failed on vNIC %d queue %d\n",
49 *res = is_u64 ? val : val32;
54 nfp_abm_ctrl_stat_all(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
55 unsigned int stride, unsigned int offset, bool is_u64,
62 for (i = 0; i < alink->vnic->max_rx_rings; i++) {
63 err = nfp_abm_ctrl_stat(alink, sym, stride, offset, i,
74 int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int i, u32 val)
76 struct nfp_cpp *cpp = alink->abm->app->cpp;
80 sym_offset = (alink->queue_base + i) * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
81 err = __nfp_rtsym_writel(cpp, alink->abm->q_lvls, 4, 0,
84 nfp_err(cpp, "RED offload setting level failed on vNIC %d queue %d\n",
92 int nfp_abm_ctrl_set_all_q_lvls(struct nfp_abm_link *alink, u32 val)
96 for (i = 0; i < alink->vnic->max_rx_rings; i++) {
97 err = nfp_abm_ctrl_set_q_lvl(alink, i, val);
105 u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int i)
109 if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats, NFP_QMSTAT_STRIDE,
110 NFP_QMSTAT_NON_STO, i, true, &val))
115 u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int i)
119 if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats, NFP_QMSTAT_STRIDE,
120 NFP_QMSTAT_STO, i, true, &val))
125 int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink, unsigned int i,
126 struct nfp_alink_stats *stats)
130 stats->tx_pkts = nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i));
131 stats->tx_bytes = nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i) + 8);
133 err = nfp_abm_ctrl_stat(alink, alink->abm->q_lvls,
134 NFP_QLVL_STRIDE, NFP_QLVL_BLOG_BYTES,
135 i, false, &stats->backlog_bytes);
139 err = nfp_abm_ctrl_stat(alink, alink->abm->q_lvls,
140 NFP_QLVL_STRIDE, NFP_QLVL_BLOG_PKTS,
141 i, false, &stats->backlog_pkts);
145 err = nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
146 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
147 i, true, &stats->drops);
151 return nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
152 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
153 i, true, &stats->overlimits);
156 int nfp_abm_ctrl_read_stats(struct nfp_abm_link *alink,
157 struct nfp_alink_stats *stats)
159 u64 pkts = 0, bytes = 0;
162 for (i = 0; i < alink->vnic->max_rx_rings; i++) {
163 pkts += nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i));
164 bytes += nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i) + 8);
166 stats->tx_pkts = pkts;
167 stats->tx_bytes = bytes;
169 err = nfp_abm_ctrl_stat_all(alink, alink->abm->q_lvls,
170 NFP_QLVL_STRIDE, NFP_QLVL_BLOG_BYTES,
171 false, &stats->backlog_bytes);
175 err = nfp_abm_ctrl_stat_all(alink, alink->abm->q_lvls,
176 NFP_QLVL_STRIDE, NFP_QLVL_BLOG_PKTS,
177 false, &stats->backlog_pkts);
181 err = nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
182 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
183 true, &stats->drops);
187 return nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
188 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
189 true, &stats->overlimits);
192 int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink, unsigned int i,
193 struct nfp_alink_xstats *xstats)
197 err = nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
198 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
199 i, true, &xstats->pdrop);
203 return nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
204 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
205 i, true, &xstats->ecn_marked);
208 int nfp_abm_ctrl_read_xstats(struct nfp_abm_link *alink,
209 struct nfp_alink_xstats *xstats)
213 err = nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
214 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
215 true, &xstats->pdrop);
219 return nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
220 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
221 true, &xstats->ecn_marked);
224 int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm)
226 return nfp_mbox_cmd(abm->app->pf, NFP_MBOX_PCIE_ABM_ENABLE,
230 int nfp_abm_ctrl_qm_disable(struct nfp_abm *abm)
232 return nfp_mbox_cmd(abm->app->pf, NFP_MBOX_PCIE_ABM_DISABLE,
236 void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink)
238 alink->queue_base = nn_readl(alink->vnic, NFP_NET_CFG_START_RXQ);
239 alink->queue_base /= alink->vnic->stride_rx;
242 static const struct nfp_rtsym *
243 nfp_abm_ctrl_find_rtsym(struct nfp_pf *pf, const char *name, unsigned int size)
245 const struct nfp_rtsym *sym;
247 sym = nfp_rtsym_lookup(pf->rtbl, name);
249 nfp_err(pf->cpp, "Symbol '%s' not found\n", name);
250 return ERR_PTR(-ENOENT);
252 if (nfp_rtsym_size(sym) != size) {
254 "Symbol '%s' wrong size: expected %u got %llu\n",
255 name, size, nfp_rtsym_size(sym));
256 return ERR_PTR(-EINVAL);
262 static const struct nfp_rtsym *
263 nfp_abm_ctrl_find_q_rtsym(struct nfp_pf *pf, const char *name,
266 return nfp_abm_ctrl_find_rtsym(pf, name, size * NFP_NET_MAX_RX_RINGS);
269 int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm)
271 struct nfp_pf *pf = abm->app->pf;
272 const struct nfp_rtsym *sym;
276 pf_id = nfp_cppcore_pcie_unit(pf->cpp);
279 snprintf(pf_symbol, sizeof(pf_symbol), NFP_QLVL_SYM_NAME, pf_id);
280 sym = nfp_abm_ctrl_find_q_rtsym(pf, pf_symbol, NFP_QLVL_STRIDE);
285 snprintf(pf_symbol, sizeof(pf_symbol), NFP_QMSTAT_SYM_NAME, pf_id);
286 sym = nfp_abm_ctrl_find_q_rtsym(pf, pf_symbol, NFP_QMSTAT_STRIDE);