net/mlx5: support matching on VXLAN reserved field
[dpdk.git] / drivers / common / cnxk / roc_nix_fc.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 static inline struct mbox *
9 get_mbox(struct roc_nix *roc_nix)
10 {
11         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12         struct dev *dev = &nix->dev;
13
14         return dev->mbox;
15 }
16
17 static int
18 nix_fc_rxchan_bpid_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
19 {
20         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
21
22         if (nix->chan_cnt != 0)
23                 fc_cfg->rxchan_cfg.enable = true;
24         else
25                 fc_cfg->rxchan_cfg.enable = false;
26
27         fc_cfg->cq_cfg_valid = false;
28
29         return 0;
30 }
31
32 static int
33 nix_fc_rxchan_bpid_set(struct roc_nix *roc_nix, bool enable)
34 {
35         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
36         struct mbox *mbox = get_mbox(roc_nix);
37         struct nix_bp_cfg_req *req;
38         struct nix_bp_cfg_rsp *rsp;
39         int rc = -ENOSPC;
40
41         if (roc_nix_is_sdp(roc_nix))
42                 return 0;
43
44         if (enable) {
45                 req = mbox_alloc_msg_nix_bp_enable(mbox);
46                 if (req == NULL)
47                         return rc;
48                 req->chan_base = 0;
49                 req->chan_cnt = 1;
50                 req->bpid_per_chan = 0;
51
52                 rc = mbox_process_msg(mbox, (void *)&rsp);
53                 if (rc || (req->chan_cnt != rsp->chan_cnt))
54                         goto exit;
55
56                 nix->bpid[0] = rsp->chan_bpid[0];
57                 nix->chan_cnt = rsp->chan_cnt;
58         } else {
59                 req = mbox_alloc_msg_nix_bp_disable(mbox);
60                 if (req == NULL)
61                         return rc;
62                 req->chan_base = 0;
63                 req->chan_cnt = 1;
64
65                 rc = mbox_process(mbox);
66                 if (rc)
67                         goto exit;
68
69                 memset(nix->bpid, 0, sizeof(uint16_t) * NIX_MAX_CHAN);
70                 nix->chan_cnt = 0;
71         }
72
73 exit:
74         return rc;
75 }
76
77 static int
78 nix_fc_cq_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
79 {
80         struct mbox *mbox = get_mbox(roc_nix);
81         struct nix_aq_enq_rsp *rsp;
82         int rc;
83
84         if (roc_model_is_cn9k()) {
85                 struct nix_aq_enq_req *aq;
86
87                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
88                 aq->qidx = fc_cfg->cq_cfg.rq;
89                 aq->ctype = NIX_AQ_CTYPE_CQ;
90                 aq->op = NIX_AQ_INSTOP_READ;
91         } else {
92                 struct nix_cn10k_aq_enq_req *aq;
93
94                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
95                 aq->qidx = fc_cfg->cq_cfg.rq;
96                 aq->ctype = NIX_AQ_CTYPE_CQ;
97                 aq->op = NIX_AQ_INSTOP_READ;
98         }
99
100         rc = mbox_process_msg(mbox, (void *)&rsp);
101         if (rc)
102                 goto exit;
103
104         fc_cfg->cq_cfg.cq_drop = rsp->cq.bp;
105         fc_cfg->cq_cfg.enable = rsp->cq.bp_ena;
106         fc_cfg->cq_cfg_valid = true;
107
108 exit:
109         return rc;
110 }
111
112 static int
113 nix_fc_cq_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
114 {
115         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
116         struct mbox *mbox = get_mbox(roc_nix);
117
118         if (roc_model_is_cn9k()) {
119                 struct nix_aq_enq_req *aq;
120
121                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
122                 aq->qidx = fc_cfg->cq_cfg.rq;
123                 aq->ctype = NIX_AQ_CTYPE_CQ;
124                 aq->op = NIX_AQ_INSTOP_WRITE;
125
126                 if (fc_cfg->cq_cfg.enable) {
127                         aq->cq.bpid = nix->bpid[0];
128                         aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
129                         aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
130                         aq->cq_mask.bp = ~(aq->cq_mask.bp);
131                 }
132
133                 aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
134                 aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
135         } else {
136                 struct nix_cn10k_aq_enq_req *aq;
137
138                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
139                 aq->qidx = fc_cfg->cq_cfg.rq;
140                 aq->ctype = NIX_AQ_CTYPE_CQ;
141                 aq->op = NIX_AQ_INSTOP_WRITE;
142
143                 if (fc_cfg->cq_cfg.enable) {
144                         aq->cq.bpid = nix->bpid[0];
145                         aq->cq_mask.bpid = ~(aq->cq_mask.bpid);
146                         aq->cq.bp = fc_cfg->cq_cfg.cq_drop;
147                         aq->cq_mask.bp = ~(aq->cq_mask.bp);
148                 }
149
150                 aq->cq.bp_ena = !!(fc_cfg->cq_cfg.enable);
151                 aq->cq_mask.bp_ena = ~(aq->cq_mask.bp_ena);
152         }
153
154         return mbox_process(mbox);
155 }
156
157 int
158 roc_nix_fc_config_get(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
159 {
160         if (roc_nix_is_vf_or_sdp(roc_nix))
161                 return 0;
162
163         if (fc_cfg->cq_cfg_valid)
164                 return nix_fc_cq_config_get(roc_nix, fc_cfg);
165         else
166                 return nix_fc_rxchan_bpid_get(roc_nix, fc_cfg);
167 }
168
169 int
170 roc_nix_fc_config_set(struct roc_nix *roc_nix, struct roc_nix_fc_cfg *fc_cfg)
171 {
172         if (roc_nix_is_vf_or_sdp(roc_nix))
173                 return 0;
174
175         if (fc_cfg->cq_cfg_valid)
176                 return nix_fc_cq_config_set(roc_nix, fc_cfg);
177         else
178                 return nix_fc_rxchan_bpid_set(roc_nix,
179                                               fc_cfg->rxchan_cfg.enable);
180 }
181
182 enum roc_nix_fc_mode
183 roc_nix_fc_mode_get(struct roc_nix *roc_nix)
184 {
185         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
186         struct mbox *mbox = get_mbox(roc_nix);
187         struct cgx_pause_frm_cfg *req, *rsp;
188         enum roc_nix_fc_mode mode;
189         int rc = -ENOSPC;
190
191         if (roc_nix_is_lbk(roc_nix))
192                 return ROC_NIX_FC_NONE;
193
194         req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
195         if (req == NULL)
196                 return rc;
197         req->set = 0;
198
199         rc = mbox_process_msg(mbox, (void *)&rsp);
200         if (rc)
201                 goto exit;
202
203         if (rsp->rx_pause && rsp->tx_pause)
204                 mode = ROC_NIX_FC_FULL;
205         else if (rsp->rx_pause)
206                 mode = ROC_NIX_FC_RX;
207         else if (rsp->tx_pause)
208                 mode = ROC_NIX_FC_TX;
209         else
210                 mode = ROC_NIX_FC_NONE;
211
212         nix->rx_pause = rsp->rx_pause;
213         nix->tx_pause = rsp->tx_pause;
214         return mode;
215
216 exit:
217         return ROC_NIX_FC_NONE;
218 }
219
220 int
221 roc_nix_fc_mode_set(struct roc_nix *roc_nix, enum roc_nix_fc_mode mode)
222 {
223         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
224         struct mbox *mbox = get_mbox(roc_nix);
225         struct cgx_pause_frm_cfg *req;
226         uint8_t tx_pause, rx_pause;
227         int rc = -ENOSPC;
228
229         if (roc_nix_is_lbk(roc_nix))
230                 return NIX_ERR_OP_NOTSUP;
231
232         rx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_RX);
233         tx_pause = (mode == ROC_NIX_FC_FULL) || (mode == ROC_NIX_FC_TX);
234
235         req = mbox_alloc_msg_cgx_cfg_pause_frm(mbox);
236         if (req == NULL)
237                 return rc;
238         req->set = 1;
239         req->rx_pause = rx_pause;
240         req->tx_pause = tx_pause;
241
242         rc = mbox_process(mbox);
243         if (rc)
244                 goto exit;
245
246         nix->rx_pause = rx_pause;
247         nix->tx_pause = tx_pause;
248
249 exit:
250         return rc;
251 }