GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / ethernet / marvell / octeon_ep / octep_ctrl_net.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell Octeon EP (EndPoint) Ethernet Driver
3  *
4  * Copyright (C) 2020 Marvell.
5  *
6  */
7 #include <linux/string.h>
8 #include <linux/types.h>
9 #include <linux/etherdevice.h>
10 #include <linux/pci.h>
11 #include <linux/wait.h>
12
13 #include "octep_config.h"
14 #include "octep_main.h"
15 #include "octep_ctrl_net.h"
16 #include "octep_pfvf_mbox.h"
17
18 /* Control plane version */
19 #define OCTEP_CP_VERSION_CURRENT        OCTEP_CP_VERSION(1, 0, 0)
20
21 static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr);
22 static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
23 static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
24 static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
25 static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
26 static const u32 offloads_sz = sizeof(struct octep_ctrl_net_offloads);
27 static atomic_t ctrl_net_msg_id;
28
29 /* Control plane version in which OCTEP_CTRL_NET_H2F_CMD was added */
30 static const u32 octep_ctrl_net_h2f_cmd_versions[OCTEP_CTRL_NET_H2F_CMD_MAX] = {
31         [OCTEP_CTRL_NET_H2F_CMD_INVALID ... OCTEP_CTRL_NET_H2F_CMD_DEV_REMOVE] =
32          OCTEP_CP_VERSION(1, 0, 0),
33         [OCTEP_CTRL_NET_H2F_CMD_OFFLOADS] = OCTEP_CP_VERSION(1, 0, 1)
34
35 };
36
37 /* Control plane version in which OCTEP_CTRL_NET_F2H_CMD was added */
38 static const u32 octep_ctrl_net_f2h_cmd_versions[OCTEP_CTRL_NET_F2H_CMD_MAX] = {
39         [OCTEP_CTRL_NET_F2H_CMD_INVALID ... OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS] =
40          OCTEP_CP_VERSION(1, 0, 0)
41 };
42
43 static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf,
44                           u16 sz, int vfid)
45 {
46         msg->hdr.s.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
47         msg->hdr.s.msg_id = atomic_inc_return(&ctrl_net_msg_id) &
48                             GENMASK(sizeof(msg->hdr.s.msg_id) * BITS_PER_BYTE, 0);
49         msg->hdr.s.sz = req_hdr_sz + sz;
50         msg->sg_num = 1;
51         msg->sg_list[0].msg = buf;
52         msg->sg_list[0].sz = msg->hdr.s.sz;
53         if (vfid != OCTEP_CTRL_NET_INVALID_VFID) {
54                 msg->hdr.s.is_vf = 1;
55                 msg->hdr.s.vf_idx = vfid;
56         }
57 }
58
59 static int octep_send_mbox_req(struct octep_device *oct,
60                                struct octep_ctrl_net_wait_data *d,
61                                bool wait_for_response)
62 {
63         int err, ret, cmd;
64
65         /* check if firmware is compatible for this request */
66         cmd = d->data.req.hdr.s.cmd;
67         if (octep_ctrl_net_h2f_cmd_versions[cmd] > oct->ctrl_mbox.max_fw_version ||
68             octep_ctrl_net_h2f_cmd_versions[cmd] < oct->ctrl_mbox.min_fw_version)
69                 return -EOPNOTSUPP;
70
71         err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg);
72         if (err < 0)
73                 return err;
74
75         if (!wait_for_response)
76                 return 0;
77
78         d->done = 0;
79         INIT_LIST_HEAD(&d->list);
80         list_add_tail(&d->list, &oct->ctrl_req_wait_list);
81         ret = wait_event_interruptible_timeout(oct->ctrl_req_wait_q,
82                                                (d->done != 0),
83                                                msecs_to_jiffies(500));
84         list_del(&d->list);
85         if (ret == 0 || ret == 1)
86                 return -EAGAIN;
87
88         /**
89          * (ret == 0)  cond = false && timeout, return 0
90          * (ret < 0) interrupted by signal, return 0
91          * (ret == 1) cond = true && timeout, return 1
92          * (ret >= 1) cond = true && !timeout, return 1
93          */
94
95         if (d->data.resp.hdr.s.reply != OCTEP_CTRL_NET_REPLY_OK)
96                 return -EAGAIN;
97
98         return 0;
99 }
100
101 int octep_ctrl_net_init(struct octep_device *oct)
102 {
103         struct octep_ctrl_mbox *ctrl_mbox;
104         struct pci_dev *pdev = oct->pdev;
105         int ret;
106
107         init_waitqueue_head(&oct->ctrl_req_wait_q);
108         INIT_LIST_HEAD(&oct->ctrl_req_wait_list);
109
110         /* Initialize control mbox */
111         ctrl_mbox = &oct->ctrl_mbox;
112         ctrl_mbox->version = OCTEP_CP_VERSION_CURRENT;
113         ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf);
114         ret = octep_ctrl_mbox_init(ctrl_mbox);
115         if (ret) {
116                 dev_err(&pdev->dev, "Failed to initialize control mbox\n");
117                 return ret;
118         }
119         dev_info(&pdev->dev, "Control plane versions host: %llx, firmware: %x:%x\n",
120                  ctrl_mbox->version, ctrl_mbox->min_fw_version,
121                  ctrl_mbox->max_fw_version);
122         oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz;
123
124         return 0;
125 }
126
127 int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid)
128 {
129         struct octep_ctrl_net_wait_data d = {};
130         struct octep_ctrl_net_h2f_req *req = &d.data.req;
131         int err;
132
133         init_send_req(&d.msg, (void *)req, state_sz, vfid);
134         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
135         req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
136         err = octep_send_mbox_req(oct, &d, true);
137         if (err < 0)
138                 return err;
139
140         return d.data.resp.link.state;
141 }
142
143 int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, bool up,
144                                    bool wait_for_response)
145 {
146         struct octep_ctrl_net_wait_data d = {};
147         struct octep_ctrl_net_h2f_req *req = &d.data.req;
148
149         init_send_req(&d.msg, req, state_sz, vfid);
150         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
151         req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
152         req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
153                                 OCTEP_CTRL_NET_STATE_DOWN;
154
155         return octep_send_mbox_req(oct, &d, wait_for_response);
156 }
157
158 int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool up,
159                                 bool wait_for_response)
160 {
161         struct octep_ctrl_net_wait_data d = {};
162         struct octep_ctrl_net_h2f_req *req = &d.data.req;
163
164         init_send_req(&d.msg, req, state_sz, vfid);
165         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE;
166         req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
167         req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
168                                 OCTEP_CTRL_NET_STATE_DOWN;
169
170         return octep_send_mbox_req(oct, &d, wait_for_response);
171 }
172
173 int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *addr)
174 {
175         struct octep_ctrl_net_wait_data d = {};
176         struct octep_ctrl_net_h2f_req *req = &d.data.req;
177         int err;
178
179         init_send_req(&d.msg, req, mac_sz, vfid);
180         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
181         req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
182         err = octep_send_mbox_req(oct, &d, true);
183         if (err < 0)
184                 return err;
185
186         memcpy(addr, d.data.resp.mac.addr, ETH_ALEN);
187
188         return 0;
189 }
190
191 int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *addr,
192                                 bool wait_for_response)
193 {
194         struct octep_ctrl_net_wait_data d = {};
195         struct octep_ctrl_net_h2f_req *req = &d.data.req;
196
197         init_send_req(&d.msg, req, mac_sz, vfid);
198         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
199         req->mac.cmd = OCTEP_CTRL_NET_CMD_SET;
200         memcpy(&req->mac.addr, addr, ETH_ALEN);
201
202         return octep_send_mbox_req(oct, &d, wait_for_response);
203 }
204
205 int octep_ctrl_net_get_mtu(struct octep_device *oct, int vfid)
206 {
207         struct octep_ctrl_net_wait_data d = {};
208         struct octep_ctrl_net_h2f_req *req;
209         int err;
210
211         req = &d.data.req;
212         init_send_req(&d.msg, req, mtu_sz, vfid);
213         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
214         req->mtu.cmd = OCTEP_CTRL_NET_CMD_GET;
215
216         err = octep_send_mbox_req(oct, &d, true);
217         if (err < 0)
218                 return err;
219
220         return d.data.resp.mtu.val;
221 }
222
223 int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
224                            bool wait_for_response)
225 {
226         struct octep_ctrl_net_wait_data d = {};
227         struct octep_ctrl_net_h2f_req *req = &d.data.req;
228
229         init_send_req(&d.msg, req, mtu_sz, vfid);
230         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
231         req->mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
232         req->mtu.val = mtu;
233
234         return octep_send_mbox_req(oct, &d, wait_for_response);
235 }
236
237 int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid,
238                                 struct octep_iface_rx_stats *rx_stats,
239                                 struct octep_iface_tx_stats *tx_stats)
240 {
241         struct octep_ctrl_net_wait_data d = {};
242         struct octep_ctrl_net_h2f_req *req = &d.data.req;
243         struct octep_ctrl_net_h2f_resp *resp;
244         int err;
245
246         init_send_req(&d.msg, req, 0, vfid);
247         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
248         err = octep_send_mbox_req(oct, &d, true);
249         if (err < 0)
250                 return err;
251
252         resp = &d.data.resp;
253         memcpy(rx_stats, &resp->if_stats.rx_stats, sizeof(struct octep_iface_rx_stats));
254         memcpy(tx_stats, &resp->if_stats.tx_stats, sizeof(struct octep_iface_tx_stats));
255         return 0;
256 }
257
258 int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid,
259                                  struct octep_iface_link_info *link_info)
260 {
261         struct octep_ctrl_net_wait_data d = {};
262         struct octep_ctrl_net_h2f_req *req = &d.data.req;
263         struct octep_ctrl_net_h2f_resp *resp;
264         int err;
265
266         init_send_req(&d.msg, req, link_info_sz, vfid);
267         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
268         req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET;
269         err = octep_send_mbox_req(oct, &d, true);
270         if (err < 0)
271                 return err;
272
273         resp = &d.data.resp;
274         link_info->supported_modes = resp->link_info.supported_modes;
275         link_info->advertised_modes = resp->link_info.advertised_modes;
276         link_info->autoneg = resp->link_info.autoneg;
277         link_info->pause = resp->link_info.pause;
278         link_info->speed = resp->link_info.speed;
279
280         return 0;
281 }
282
283 int octep_ctrl_net_set_link_info(struct octep_device *oct, int vfid,
284                                  struct octep_iface_link_info *link_info,
285                                  bool wait_for_response)
286 {
287         struct octep_ctrl_net_wait_data d = {};
288         struct octep_ctrl_net_h2f_req *req = &d.data.req;
289
290         init_send_req(&d.msg, req, link_info_sz, vfid);
291         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
292         req->link_info.cmd = OCTEP_CTRL_NET_CMD_SET;
293         req->link_info.info.advertised_modes = link_info->advertised_modes;
294         req->link_info.info.autoneg = link_info->autoneg;
295         req->link_info.info.pause = link_info->pause;
296         req->link_info.info.speed = link_info->speed;
297
298         return octep_send_mbox_req(oct, &d, wait_for_response);
299 }
300
301 static void process_mbox_resp(struct octep_device *oct,
302                               struct octep_ctrl_mbox_msg *msg)
303 {
304         struct octep_ctrl_net_wait_data *pos, *n;
305
306         list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) {
307                 if (pos->msg.hdr.s.msg_id == msg->hdr.s.msg_id) {
308                         memcpy(&pos->data.resp,
309                                msg->sg_list[0].msg,
310                                msg->hdr.s.sz);
311                         pos->done = 1;
312                         wake_up_interruptible_all(&oct->ctrl_req_wait_q);
313                         break;
314                 }
315         }
316 }
317
318 static int process_mbox_notify(struct octep_device *oct,
319                                struct octep_ctrl_mbox_msg *msg)
320 {
321         struct net_device *netdev = oct->netdev;
322         struct octep_ctrl_net_f2h_req *req;
323         int cmd;
324
325         req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg;
326         cmd = req->hdr.s.cmd;
327
328         /* check if we support this command */
329         if (octep_ctrl_net_f2h_cmd_versions[cmd] > OCTEP_CP_VERSION_CURRENT ||
330             octep_ctrl_net_f2h_cmd_versions[cmd] < OCTEP_CP_VERSION_CURRENT)
331                 return -EOPNOTSUPP;
332
333         if (msg->hdr.s.is_vf) {
334                 octep_pfvf_notify(oct, msg);
335                 return 0;
336         }
337
338         switch (cmd) {
339         case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
340                 if (netif_running(netdev)) {
341                         if (req->link.state) {
342                                 dev_info(&oct->pdev->dev, "netif_carrier_on\n");
343                                 netif_carrier_on(netdev);
344                         } else {
345                                 dev_info(&oct->pdev->dev, "netif_carrier_off\n");
346                                 netif_carrier_off(netdev);
347                         }
348                 }
349                 break;
350         default:
351                 pr_info("Unknown mbox req : %u\n", req->hdr.s.cmd);
352                 break;
353         }
354
355         return 0;
356 }
357
358 void octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
359 {
360         static u16 msg_sz = sizeof(union octep_ctrl_net_max_data);
361         union octep_ctrl_net_max_data data = {};
362         struct octep_ctrl_mbox_msg msg = {};
363         int ret;
364
365         msg.hdr.s.sz = msg_sz;
366         msg.sg_num = 1;
367         msg.sg_list[0].sz = msg_sz;
368         msg.sg_list[0].msg = &data;
369         while (true) {
370                 /* mbox will overwrite msg.hdr.s.sz so initialize it */
371                 msg.hdr.s.sz = msg_sz;
372                 ret = octep_ctrl_mbox_recv(&oct->ctrl_mbox, (struct octep_ctrl_mbox_msg *)&msg);
373                 if (ret < 0)
374                         break;
375
376                 if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP)
377                         process_mbox_resp(oct, &msg);
378                 else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY)
379                         process_mbox_notify(oct, &msg);
380         }
381 }
382
383 int octep_ctrl_net_get_info(struct octep_device *oct, int vfid,
384                             struct octep_fw_info *info)
385 {
386         struct octep_ctrl_net_wait_data d = {};
387         struct octep_ctrl_net_h2f_resp *resp;
388         struct octep_ctrl_net_h2f_req *req;
389         int err;
390
391         req = &d.data.req;
392         init_send_req(&d.msg, req, 0, vfid);
393         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_INFO;
394         req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET;
395         err = octep_send_mbox_req(oct, &d, true);
396         if (err < 0)
397                 return err;
398
399         resp = &d.data.resp;
400         memcpy(info, &resp->info.fw_info, sizeof(struct octep_fw_info));
401
402         return 0;
403 }
404
405 int octep_ctrl_net_dev_remove(struct octep_device *oct, int vfid)
406 {
407         struct octep_ctrl_net_wait_data d = {};
408         struct octep_ctrl_net_h2f_req *req;
409
410         req = &d.data.req;
411         dev_dbg(&oct->pdev->dev, "Sending dev_unload msg to fw\n");
412         init_send_req(&d.msg, req, sizeof(int), vfid);
413         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_DEV_REMOVE;
414
415         return octep_send_mbox_req(oct, &d, false);
416 }
417
418 int octep_ctrl_net_set_offloads(struct octep_device *oct, int vfid,
419                                 struct octep_ctrl_net_offloads *offloads,
420                                 bool wait_for_response)
421 {
422         struct octep_ctrl_net_wait_data d = {};
423         struct octep_ctrl_net_h2f_req *req;
424
425         req = &d.data.req;
426         init_send_req(&d.msg, req, offloads_sz, vfid);
427         req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_OFFLOADS;
428         req->offloads.cmd = OCTEP_CTRL_NET_CMD_SET;
429         req->offloads.offloads = *offloads;
430
431         return octep_send_mbox_req(oct, &d, wait_for_response);
432 }
433
434 int octep_ctrl_net_uninit(struct octep_device *oct)
435 {
436         struct octep_ctrl_net_wait_data *pos, *n;
437
438         octep_ctrl_net_dev_remove(oct, OCTEP_CTRL_NET_INVALID_VFID);
439
440         list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list)
441                 pos->done = 1;
442
443         wake_up_interruptible_all(&oct->ctrl_req_wait_q);
444
445         octep_ctrl_mbox_uninit(&oct->ctrl_mbox);
446
447         return 0;
448 }