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 
17 static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr);
18 static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
19 static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
20 static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
21 static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
22 static atomic_t ctrl_net_msg_id;
23 
24 static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf,
25 			  u16 sz, int vfid)
26 {
27 	msg->hdr.s.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
28 	msg->hdr.s.msg_id = atomic_inc_return(&ctrl_net_msg_id) &
29 			    GENMASK(sizeof(msg->hdr.s.msg_id) * BITS_PER_BYTE, 0);
30 	msg->hdr.s.sz = req_hdr_sz + sz;
31 	msg->sg_num = 1;
32 	msg->sg_list[0].msg = buf;
33 	msg->sg_list[0].sz = msg->hdr.s.sz;
34 	if (vfid != OCTEP_CTRL_NET_INVALID_VFID) {
35 		msg->hdr.s.is_vf = 1;
36 		msg->hdr.s.vf_idx = vfid;
37 	}
38 }
39 
40 static int octep_send_mbox_req(struct octep_device *oct,
41 			       struct octep_ctrl_net_wait_data *d,
42 			       bool wait_for_response)
43 {
44 	int err, ret;
45 
46 	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg);
47 	if (err < 0)
48 		return err;
49 
50 	if (!wait_for_response)
51 		return 0;
52 
53 	d->done = 0;
54 	INIT_LIST_HEAD(&d->list);
55 	list_add_tail(&d->list, &oct->ctrl_req_wait_list);
56 	ret = wait_event_interruptible_timeout(oct->ctrl_req_wait_q,
57 					       (d->done != 0),
58 					       jiffies + msecs_to_jiffies(500));
59 	list_del(&d->list);
60 	if (ret == 0 || ret == 1)
61 		return -EAGAIN;
62 
63 	/**
64 	 * (ret == 0)  cond = false && timeout, return 0
65 	 * (ret < 0) interrupted by signal, return 0
66 	 * (ret == 1) cond = true && timeout, return 1
67 	 * (ret >= 1) cond = true && !timeout, return 1
68 	 */
69 
70 	if (d->data.resp.hdr.s.reply != OCTEP_CTRL_NET_REPLY_OK)
71 		return -EAGAIN;
72 
73 	return 0;
74 }
75 
76 int octep_ctrl_net_init(struct octep_device *oct)
77 {
78 	struct octep_ctrl_mbox *ctrl_mbox;
79 	struct pci_dev *pdev = oct->pdev;
80 	int ret;
81 
82 	init_waitqueue_head(&oct->ctrl_req_wait_q);
83 	INIT_LIST_HEAD(&oct->ctrl_req_wait_list);
84 
85 	/* Initialize control mbox */
86 	ctrl_mbox = &oct->ctrl_mbox;
87 	ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf);
88 	ret = octep_ctrl_mbox_init(ctrl_mbox);
89 	if (ret) {
90 		dev_err(&pdev->dev, "Failed to initialize control mbox\n");
91 		return ret;
92 	}
93 	oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz;
94 
95 	return 0;
96 }
97 
98 int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid)
99 {
100 	struct octep_ctrl_net_wait_data d = {0};
101 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
102 	int err;
103 
104 	init_send_req(&d.msg, (void *)req, state_sz, vfid);
105 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
106 	req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
107 	err = octep_send_mbox_req(oct, &d, true);
108 	if (err < 0)
109 		return err;
110 
111 	return d.data.resp.link.state;
112 }
113 
114 int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, bool up,
115 				   bool wait_for_response)
116 {
117 	struct octep_ctrl_net_wait_data d = {0};
118 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
119 
120 	init_send_req(&d.msg, req, state_sz, vfid);
121 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
122 	req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
123 	req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
124 				OCTEP_CTRL_NET_STATE_DOWN;
125 
126 	return octep_send_mbox_req(oct, &d, wait_for_response);
127 }
128 
129 int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool up,
130 				bool wait_for_response)
131 {
132 	struct octep_ctrl_net_wait_data d = {0};
133 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
134 
135 	init_send_req(&d.msg, req, state_sz, vfid);
136 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE;
137 	req->link.cmd = OCTEP_CTRL_NET_CMD_SET;
138 	req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP :
139 				OCTEP_CTRL_NET_STATE_DOWN;
140 
141 	return octep_send_mbox_req(oct, &d, wait_for_response);
142 }
143 
144 int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *addr)
145 {
146 	struct octep_ctrl_net_wait_data d = {0};
147 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
148 	int err;
149 
150 	init_send_req(&d.msg, req, mac_sz, vfid);
151 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
152 	req->link.cmd = OCTEP_CTRL_NET_CMD_GET;
153 	err = octep_send_mbox_req(oct, &d, true);
154 	if (err < 0)
155 		return err;
156 
157 	memcpy(addr, d.data.resp.mac.addr, ETH_ALEN);
158 
159 	return 0;
160 }
161 
162 int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *addr,
163 				bool wait_for_response)
164 {
165 	struct octep_ctrl_net_wait_data d = {0};
166 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
167 
168 	init_send_req(&d.msg, req, mac_sz, vfid);
169 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
170 	req->mac.cmd = OCTEP_CTRL_NET_CMD_SET;
171 	memcpy(&req->mac.addr, addr, ETH_ALEN);
172 
173 	return octep_send_mbox_req(oct, &d, wait_for_response);
174 }
175 
176 int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu,
177 			   bool wait_for_response)
178 {
179 	struct octep_ctrl_net_wait_data d = {0};
180 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
181 
182 	init_send_req(&d.msg, req, mtu_sz, vfid);
183 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
184 	req->mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
185 	req->mtu.val = mtu;
186 
187 	return octep_send_mbox_req(oct, &d, wait_for_response);
188 }
189 
190 int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid,
191 				struct octep_iface_rx_stats *rx_stats,
192 				struct octep_iface_tx_stats *tx_stats)
193 {
194 	struct octep_ctrl_net_wait_data d = {0};
195 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
196 	struct octep_ctrl_net_h2f_resp *resp;
197 	int err;
198 
199 	init_send_req(&d.msg, req, 0, vfid);
200 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
201 	err = octep_send_mbox_req(oct, &d, true);
202 	if (err < 0)
203 		return err;
204 
205 	resp = &d.data.resp;
206 	memcpy(rx_stats, &resp->if_stats.rx_stats, sizeof(struct octep_iface_rx_stats));
207 	memcpy(tx_stats, &resp->if_stats.tx_stats, sizeof(struct octep_iface_tx_stats));
208 	return 0;
209 }
210 
211 int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid,
212 				 struct octep_iface_link_info *link_info)
213 {
214 	struct octep_ctrl_net_wait_data d = {0};
215 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
216 	struct octep_ctrl_net_h2f_resp *resp;
217 	int err;
218 
219 	init_send_req(&d.msg, req, link_info_sz, vfid);
220 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
221 	req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET;
222 	err = octep_send_mbox_req(oct, &d, true);
223 	if (err < 0)
224 		return err;
225 
226 	resp = &d.data.resp;
227 	link_info->supported_modes = resp->link_info.supported_modes;
228 	link_info->advertised_modes = resp->link_info.advertised_modes;
229 	link_info->autoneg = resp->link_info.autoneg;
230 	link_info->pause = resp->link_info.pause;
231 	link_info->speed = resp->link_info.speed;
232 
233 	return 0;
234 }
235 
236 int octep_ctrl_net_set_link_info(struct octep_device *oct, int vfid,
237 				 struct octep_iface_link_info *link_info,
238 				 bool wait_for_response)
239 {
240 	struct octep_ctrl_net_wait_data d = {0};
241 	struct octep_ctrl_net_h2f_req *req = &d.data.req;
242 
243 	init_send_req(&d.msg, req, link_info_sz, vfid);
244 	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
245 	req->link_info.cmd = OCTEP_CTRL_NET_CMD_SET;
246 	req->link_info.info.advertised_modes = link_info->advertised_modes;
247 	req->link_info.info.autoneg = link_info->autoneg;
248 	req->link_info.info.pause = link_info->pause;
249 	req->link_info.info.speed = link_info->speed;
250 
251 	return octep_send_mbox_req(oct, &d, wait_for_response);
252 }
253 
254 static void process_mbox_resp(struct octep_device *oct,
255 			      struct octep_ctrl_mbox_msg *msg)
256 {
257 	struct octep_ctrl_net_wait_data *pos, *n;
258 
259 	list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) {
260 		if (pos->msg.hdr.s.msg_id == msg->hdr.s.msg_id) {
261 			memcpy(&pos->data.resp,
262 			       msg->sg_list[0].msg,
263 			       msg->hdr.s.sz);
264 			pos->done = 1;
265 			wake_up_interruptible_all(&oct->ctrl_req_wait_q);
266 			break;
267 		}
268 	}
269 }
270 
271 static int process_mbox_notify(struct octep_device *oct,
272 			       struct octep_ctrl_mbox_msg *msg)
273 {
274 	struct net_device *netdev = oct->netdev;
275 	struct octep_ctrl_net_f2h_req *req;
276 
277 	req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg;
278 	switch (req->hdr.s.cmd) {
279 	case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
280 		if (netif_running(netdev)) {
281 			if (req->link.state) {
282 				dev_info(&oct->pdev->dev, "netif_carrier_on\n");
283 				netif_carrier_on(netdev);
284 			} else {
285 				dev_info(&oct->pdev->dev, "netif_carrier_off\n");
286 				netif_carrier_off(netdev);
287 			}
288 		}
289 		break;
290 	default:
291 		pr_info("Unknown mbox req : %u\n", req->hdr.s.cmd);
292 		break;
293 	}
294 
295 	return 0;
296 }
297 
298 void octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
299 {
300 	static u16 msg_sz = sizeof(union octep_ctrl_net_max_data);
301 	union octep_ctrl_net_max_data data = {0};
302 	struct octep_ctrl_mbox_msg msg = {0};
303 	int ret;
304 
305 	msg.hdr.s.sz = msg_sz;
306 	msg.sg_num = 1;
307 	msg.sg_list[0].sz = msg_sz;
308 	msg.sg_list[0].msg = &data;
309 	while (true) {
310 		/* mbox will overwrite msg.hdr.s.sz so initialize it */
311 		msg.hdr.s.sz = msg_sz;
312 		ret = octep_ctrl_mbox_recv(&oct->ctrl_mbox, (struct octep_ctrl_mbox_msg *)&msg);
313 		if (ret < 0)
314 			break;
315 
316 		if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP)
317 			process_mbox_resp(oct, &msg);
318 		else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY)
319 			process_mbox_notify(oct, &msg);
320 	}
321 }
322 
323 int octep_ctrl_net_uninit(struct octep_device *oct)
324 {
325 	struct octep_ctrl_net_wait_data *pos, *n;
326 
327 	list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list)
328 		pos->done = 1;
329 
330 	wake_up_interruptible_all(&oct->ctrl_req_wait_q);
331 
332 	octep_ctrl_mbox_uninit(&oct->ctrl_mbox);
333 
334 	return 0;
335 }
336