Linux Audio

Check our new training course

Loading...
v6.8
  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
 21static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr);
 22static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
 23static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
 24static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
 25static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
 26static const u32 offloads_sz = sizeof(struct octep_ctrl_net_offloads);
 27static atomic_t ctrl_net_msg_id;
 28
 29/* Control plane version in which OCTEP_CTRL_NET_H2F_CMD was added */
 30static 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 */
 38static 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
 43static 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
 59static 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
101int 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
127int 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
143int 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
158int 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
173int 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
191int 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
205int 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
223int 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
237int 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
258int 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
283int 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
301static 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
318static 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
358void 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
383int 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
405int 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
418int 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
434int 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}
v6.2
  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
 12#include "octep_config.h"
 13#include "octep_main.h"
 14#include "octep_ctrl_net.h"
 
 15
 16int octep_get_link_status(struct octep_device *oct)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 17{
 18	struct octep_ctrl_net_h2f_req req = {};
 19	struct octep_ctrl_net_h2f_resp *resp;
 20	struct octep_ctrl_mbox_msg msg = {};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 21	int err;
 22
 23	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
 24	req.link.cmd = OCTEP_CTRL_NET_CMD_GET;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 25
 26	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
 27	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
 28	msg.msg = &req;
 29	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 30	if (err)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 31		return err;
 32
 33	resp = (struct octep_ctrl_net_h2f_resp *)&req;
 34	return resp->link.state;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 35}
 36
 37void octep_set_link_status(struct octep_device *oct, bool up)
 38{
 39	struct octep_ctrl_net_h2f_req req = {};
 40	struct octep_ctrl_mbox_msg msg = {};
 
 
 
 
 
 
 41
 42	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS;
 43	req.link.cmd = OCTEP_CTRL_NET_CMD_SET;
 44	req.link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_DOWN;
 45
 46	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
 47	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
 48	msg.msg = &req;
 49	octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 50}
 51
 52void octep_set_rx_state(struct octep_device *oct, bool up)
 
 53{
 54	struct octep_ctrl_net_h2f_req req = {};
 55	struct octep_ctrl_mbox_msg msg = {};
 56
 57	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE;
 58	req.link.cmd = OCTEP_CTRL_NET_CMD_SET;
 59	req.link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : OCTEP_CTRL_NET_STATE_DOWN;
 
 60
 61	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
 62	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_STATE_REQ_SZW;
 63	msg.msg = &req;
 64	octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 65}
 66
 67int octep_get_mac_addr(struct octep_device *oct, u8 *addr)
 
 
 68{
 69	struct octep_ctrl_net_h2f_req req = {};
 
 70	struct octep_ctrl_net_h2f_resp *resp;
 71	struct octep_ctrl_mbox_msg msg = {};
 72	int err;
 73
 74	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
 75	req.link.cmd = OCTEP_CTRL_NET_CMD_GET;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 76
 77	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
 78	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MAC_REQ_SZW;
 79	msg.msg = &req;
 80	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 81	if (err)
 82		return err;
 83
 84	resp = (struct octep_ctrl_net_h2f_resp *)&req;
 85	memcpy(addr, resp->mac.addr, ETH_ALEN);
 
 
 
 
 86
 87	return err;
 88}
 89
 90int octep_set_mac_addr(struct octep_device *oct, u8 *addr)
 
 
 91{
 92	struct octep_ctrl_net_h2f_req req = {};
 93	struct octep_ctrl_mbox_msg msg = {};
 94
 95	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
 96	req.mac.cmd = OCTEP_CTRL_NET_CMD_SET;
 97	memcpy(&req.mac.addr, addr, ETH_ALEN);
 
 
 
 
 98
 99	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
100	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MAC_REQ_SZW;
101	msg.msg = &req;
102
103	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104}
105
106int octep_set_mtu(struct octep_device *oct, int mtu)
 
107{
108	struct octep_ctrl_net_h2f_req req = {};
109	struct octep_ctrl_mbox_msg msg = {};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
111	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
112	req.mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
113	req.mtu.val = mtu;
114
115	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
116	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MTU_REQ_SZW;
117	msg.msg = &req;
 
 
 
118
119	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120}
121
122int octep_get_if_stats(struct octep_device *oct)
 
123{
124	void __iomem *iface_rx_stats;
125	void __iomem *iface_tx_stats;
126	struct octep_ctrl_net_h2f_req req = {};
127	struct octep_ctrl_mbox_msg msg = {};
128	int err;
129
130	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
131	req.mac.cmd = OCTEP_CTRL_NET_CMD_GET;
132	req.get_stats.offset = oct->ctrl_mbox_ifstats_offset;
133
134	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
135	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW;
136	msg.msg = &req;
137	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
138	if (err)
139		return err;
140
141	iface_rx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset;
142	iface_tx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset +
143			 sizeof(struct octep_iface_rx_stats);
144	memcpy_fromio(&oct->iface_rx_stats, iface_rx_stats, sizeof(struct octep_iface_rx_stats));
145	memcpy_fromio(&oct->iface_tx_stats, iface_tx_stats, sizeof(struct octep_iface_tx_stats));
146
147	return err;
148}
149
150int octep_get_link_info(struct octep_device *oct)
151{
152	struct octep_ctrl_net_h2f_req req = {};
153	struct octep_ctrl_net_h2f_resp *resp;
154	struct octep_ctrl_mbox_msg msg = {};
155	int err;
 
 
 
156
157	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
158	req.mac.cmd = OCTEP_CTRL_NET_CMD_GET;
159
160	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
161	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW;
162	msg.msg = &req;
163	err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
164	if (err)
165		return err;
166
167	resp = (struct octep_ctrl_net_h2f_resp *)&req;
168	oct->link_info.supported_modes = resp->link_info.supported_modes;
169	oct->link_info.advertised_modes = resp->link_info.advertised_modes;
170	oct->link_info.autoneg = resp->link_info.autoneg;
171	oct->link_info.pause = resp->link_info.pause;
172	oct->link_info.speed = resp->link_info.speed;
173
174	return err;
175}
176
177int octep_set_link_info(struct octep_device *oct, struct octep_iface_link_info *link_info)
178{
179	struct octep_ctrl_net_h2f_req req = {};
180	struct octep_ctrl_mbox_msg msg = {};
 
 
 
 
 
 
181
182	req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO;
183	req.link_info.cmd = OCTEP_CTRL_NET_CMD_SET;
184	req.link_info.info.advertised_modes = link_info->advertised_modes;
185	req.link_info.info.autoneg = link_info->autoneg;
186	req.link_info.info.pause = link_info->pause;
187	req.link_info.info.speed = link_info->speed;
188
189	msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
190	msg.hdr.sizew = OCTEP_CTRL_NET_H2F_LINK_INFO_REQ_SZW;
191	msg.msg = &req;
192
193	return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
194}