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 *
nix_to_mbox(struct nix * nix)9 nix_to_mbox(struct nix *nix)
10 {
11 struct dev *dev = &nix->dev;
12
13 return dev->mbox;
14 }
15
16 int
roc_nix_mac_rxtx_start_stop(struct roc_nix * roc_nix,bool start)17 roc_nix_mac_rxtx_start_stop(struct roc_nix *roc_nix, bool start)
18 {
19 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
20 struct mbox *mbox = nix_to_mbox(nix);
21
22 if (roc_nix_is_vf_or_sdp(roc_nix))
23 return NIX_ERR_OP_NOTSUP;
24
25 if (start)
26 mbox_alloc_msg_cgx_start_rxtx(mbox);
27 else
28 mbox_alloc_msg_cgx_stop_rxtx(mbox);
29
30 return mbox_process(mbox);
31 }
32
33 int
roc_nix_mac_link_event_start_stop(struct roc_nix * roc_nix,bool start)34 roc_nix_mac_link_event_start_stop(struct roc_nix *roc_nix, bool start)
35 {
36 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
37 struct mbox *mbox = nix_to_mbox(nix);
38
39 if (roc_nix_is_vf_or_sdp(roc_nix))
40 return NIX_ERR_OP_NOTSUP;
41
42 if (start)
43 mbox_alloc_msg_cgx_start_linkevents(mbox);
44 else
45 mbox_alloc_msg_cgx_stop_linkevents(mbox);
46
47 return mbox_process(mbox);
48 }
49
50 int
roc_nix_mac_loopback_enable(struct roc_nix * roc_nix,bool enable)51 roc_nix_mac_loopback_enable(struct roc_nix *roc_nix, bool enable)
52 {
53 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
54 struct mbox *mbox = nix_to_mbox(nix);
55
56 if (enable && roc_nix_is_vf_or_sdp(roc_nix))
57 return NIX_ERR_OP_NOTSUP;
58
59 if (enable)
60 mbox_alloc_msg_cgx_intlbk_enable(mbox);
61 else
62 mbox_alloc_msg_cgx_intlbk_disable(mbox);
63
64 return mbox_process(mbox);
65 }
66
67 int
roc_nix_mac_addr_set(struct roc_nix * roc_nix,const uint8_t addr[])68 roc_nix_mac_addr_set(struct roc_nix *roc_nix, const uint8_t addr[])
69 {
70 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
71 struct mbox *mbox = nix_to_mbox(nix);
72 struct cgx_mac_addr_set_or_get *req;
73
74 if (roc_nix_is_vf_or_sdp(roc_nix))
75 return NIX_ERR_OP_NOTSUP;
76
77 if (dev_active_vfs(&nix->dev))
78 return NIX_ERR_OP_NOTSUP;
79
80 req = mbox_alloc_msg_cgx_mac_addr_set(mbox);
81 mbox_memcpy(req->mac_addr, addr, PLT_ETHER_ADDR_LEN);
82
83 return mbox_process(mbox);
84 }
85
86 int
roc_nix_mac_max_entries_get(struct roc_nix * roc_nix)87 roc_nix_mac_max_entries_get(struct roc_nix *roc_nix)
88 {
89 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
90 struct cgx_max_dmac_entries_get_rsp *rsp;
91 struct mbox *mbox = nix_to_mbox(nix);
92 int rc;
93
94 if (roc_nix_is_vf_or_sdp(roc_nix))
95 return NIX_ERR_OP_NOTSUP;
96
97 mbox_alloc_msg_cgx_mac_max_entries_get(mbox);
98 rc = mbox_process_msg(mbox, (void *)&rsp);
99 if (rc)
100 return rc;
101
102 return rsp->max_dmac_filters ? rsp->max_dmac_filters : 1;
103 }
104
105 int
roc_nix_mac_addr_add(struct roc_nix * roc_nix,uint8_t addr[])106 roc_nix_mac_addr_add(struct roc_nix *roc_nix, uint8_t addr[])
107 {
108 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
109 struct mbox *mbox = nix_to_mbox(nix);
110 struct cgx_mac_addr_add_req *req;
111 struct cgx_mac_addr_add_rsp *rsp;
112 int rc;
113
114 if (roc_nix_is_vf_or_sdp(roc_nix))
115 return NIX_ERR_OP_NOTSUP;
116
117 if (dev_active_vfs(&nix->dev))
118 return NIX_ERR_OP_NOTSUP;
119
120 req = mbox_alloc_msg_cgx_mac_addr_add(mbox);
121 mbox_memcpy(req->mac_addr, addr, PLT_ETHER_ADDR_LEN);
122
123 rc = mbox_process_msg(mbox, (void *)&rsp);
124 if (rc < 0)
125 return rc;
126
127 return rsp->index;
128 }
129
130 int
roc_nix_mac_addr_del(struct roc_nix * roc_nix,uint32_t index)131 roc_nix_mac_addr_del(struct roc_nix *roc_nix, uint32_t index)
132 {
133 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
134 struct mbox *mbox = nix_to_mbox(nix);
135 struct cgx_mac_addr_del_req *req;
136 int rc = -ENOSPC;
137
138 if (roc_nix_is_vf_or_sdp(roc_nix))
139 return NIX_ERR_OP_NOTSUP;
140
141 req = mbox_alloc_msg_cgx_mac_addr_del(mbox);
142 if (req == NULL)
143 return rc;
144 req->index = index;
145
146 return mbox_process(mbox);
147 }
148
149 int
roc_nix_mac_promisc_mode_enable(struct roc_nix * roc_nix,int enable)150 roc_nix_mac_promisc_mode_enable(struct roc_nix *roc_nix, int enable)
151 {
152 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
153 struct mbox *mbox = nix_to_mbox(nix);
154
155 if (roc_nix_is_vf_or_sdp(roc_nix))
156 return NIX_ERR_OP_NOTSUP;
157
158 if (enable)
159 mbox_alloc_msg_cgx_promisc_enable(mbox);
160 else
161 mbox_alloc_msg_cgx_promisc_disable(mbox);
162
163 return mbox_process(mbox);
164 }
165
166 int
roc_nix_mac_link_info_get(struct roc_nix * roc_nix,struct roc_nix_link_info * link_info)167 roc_nix_mac_link_info_get(struct roc_nix *roc_nix,
168 struct roc_nix_link_info *link_info)
169 {
170 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
171 struct mbox *mbox = nix_to_mbox(nix);
172 struct cgx_link_info_msg *rsp;
173 int rc;
174
175 mbox_alloc_msg_cgx_get_linkinfo(mbox);
176 rc = mbox_process_msg(mbox, (void *)&rsp);
177 if (rc)
178 return rc;
179
180 link_info->status = rsp->link_info.link_up;
181 link_info->full_duplex = rsp->link_info.full_duplex;
182 link_info->lmac_type_id = rsp->link_info.lmac_type_id;
183 link_info->speed = rsp->link_info.speed;
184 link_info->autoneg = rsp->link_info.an;
185 link_info->fec = rsp->link_info.fec;
186 link_info->port = rsp->link_info.port;
187
188 return 0;
189 }
190
191 int
roc_nix_mac_link_state_set(struct roc_nix * roc_nix,uint8_t up)192 roc_nix_mac_link_state_set(struct roc_nix *roc_nix, uint8_t up)
193 {
194 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
195 struct mbox *mbox = nix_to_mbox(nix);
196 struct cgx_set_link_state_msg *req;
197 int rc = -ENOSPC;
198
199 req = mbox_alloc_msg_cgx_set_link_state(mbox);
200 if (req == NULL)
201 return rc;
202 req->enable = up;
203 return mbox_process(mbox);
204 }
205
206 int
roc_nix_mac_link_info_set(struct roc_nix * roc_nix,struct roc_nix_link_info * link_info)207 roc_nix_mac_link_info_set(struct roc_nix *roc_nix,
208 struct roc_nix_link_info *link_info)
209 {
210 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
211 struct mbox *mbox = nix_to_mbox(nix);
212 struct cgx_set_link_mode_req *req;
213 int rc;
214
215 rc = roc_nix_mac_link_state_set(roc_nix, link_info->status);
216 if (rc)
217 return rc;
218
219 req = mbox_alloc_msg_cgx_set_link_mode(mbox);
220 if (req == NULL)
221 return -ENOSPC;
222 req->args.speed = link_info->speed;
223 req->args.duplex = link_info->full_duplex;
224 req->args.an = link_info->autoneg;
225
226 return mbox_process(mbox);
227 }
228
229 int
roc_nix_mac_mtu_set(struct roc_nix * roc_nix,uint16_t mtu)230 roc_nix_mac_mtu_set(struct roc_nix *roc_nix, uint16_t mtu)
231 {
232 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
233 struct mbox *mbox = nix_to_mbox(nix);
234 struct nix_frs_cfg *req;
235 bool sdp_link = false;
236 int rc = -ENOSPC;
237
238 if (roc_nix_is_sdp(roc_nix))
239 sdp_link = true;
240
241 req = mbox_alloc_msg_nix_set_hw_frs(mbox);
242 if (req == NULL)
243 return rc;
244 req->maxlen = mtu;
245 req->update_smq = true;
246 req->sdp_link = sdp_link;
247
248 rc = mbox_process(mbox);
249 if (rc)
250 return rc;
251
252 /* Save MTU for later use */
253 nix->mtu = mtu;
254 return 0;
255 }
256
257 int
roc_nix_mac_max_rx_len_set(struct roc_nix * roc_nix,uint16_t maxlen)258 roc_nix_mac_max_rx_len_set(struct roc_nix *roc_nix, uint16_t maxlen)
259 {
260 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
261 struct mbox *mbox = nix_to_mbox(nix);
262 struct nix_frs_cfg *req;
263 bool sdp_link = false;
264 int rc = -ENOSPC;
265
266 if (roc_nix_is_sdp(roc_nix))
267 sdp_link = true;
268
269 req = mbox_alloc_msg_nix_set_hw_frs(mbox);
270 if (req == NULL)
271 return rc;
272 req->sdp_link = sdp_link;
273 req->maxlen = maxlen;
274
275 return mbox_process(mbox);
276 }
277
278 int
roc_nix_mac_link_cb_register(struct roc_nix * roc_nix,link_status_t link_update)279 roc_nix_mac_link_cb_register(struct roc_nix *roc_nix, link_status_t link_update)
280 {
281 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
282 struct dev *dev = &nix->dev;
283
284 if (link_update == NULL)
285 return NIX_ERR_PARAM;
286
287 dev->ops->link_status_update = (link_info_t)link_update;
288 return 0;
289 }
290
291 void
roc_nix_mac_link_cb_unregister(struct roc_nix * roc_nix)292 roc_nix_mac_link_cb_unregister(struct roc_nix *roc_nix)
293 {
294 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
295 struct dev *dev = &nix->dev;
296
297 dev->ops->link_status_update = NULL;
298 }
299
300 int
roc_nix_mac_link_info_get_cb_register(struct roc_nix * roc_nix,link_info_get_t link_info_get)301 roc_nix_mac_link_info_get_cb_register(struct roc_nix *roc_nix,
302 link_info_get_t link_info_get)
303 {
304 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
305 struct dev *dev = &nix->dev;
306
307 if (link_info_get == NULL)
308 return NIX_ERR_PARAM;
309
310 dev->ops->link_status_get = (link_info_t)link_info_get;
311 return 0;
312 }
313
314 void
roc_nix_mac_link_info_get_cb_unregister(struct roc_nix * roc_nix)315 roc_nix_mac_link_info_get_cb_unregister(struct roc_nix *roc_nix)
316 {
317 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
318 struct dev *dev = &nix->dev;
319
320 dev->ops->link_status_get = NULL;
321 }
322