1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
3
4#include <linux/printk.h>
5#include <linux/dynamic_debug.h>
6#include <linux/module.h>
7#include <linux/netdevice.h>
8#include <linux/utsname.h>
9#include <generated/utsrelease.h>
10#include <linux/ctype.h>
11
12#include "ionic.h"
13#include "ionic_bus.h"
14#include "ionic_lif.h"
15#include "ionic_debugfs.h"
16
17MODULE_DESCRIPTION(IONIC_DRV_DESCRIPTION);
18MODULE_AUTHOR("Pensando Systems, Inc");
19MODULE_LICENSE("GPL");
20
21static const char *ionic_error_to_str(enum ionic_status_code code)
22{
23	switch (code) {
24	case IONIC_RC_SUCCESS:
25		return "IONIC_RC_SUCCESS";
26	case IONIC_RC_EVERSION:
27		return "IONIC_RC_EVERSION";
28	case IONIC_RC_EOPCODE:
29		return "IONIC_RC_EOPCODE";
30	case IONIC_RC_EIO:
31		return "IONIC_RC_EIO";
32	case IONIC_RC_EPERM:
33		return "IONIC_RC_EPERM";
34	case IONIC_RC_EQID:
35		return "IONIC_RC_EQID";
36	case IONIC_RC_EQTYPE:
37		return "IONIC_RC_EQTYPE";
38	case IONIC_RC_ENOENT:
39		return "IONIC_RC_ENOENT";
40	case IONIC_RC_EINTR:
41		return "IONIC_RC_EINTR";
42	case IONIC_RC_EAGAIN:
43		return "IONIC_RC_EAGAIN";
44	case IONIC_RC_ENOMEM:
45		return "IONIC_RC_ENOMEM";
46	case IONIC_RC_EFAULT:
47		return "IONIC_RC_EFAULT";
48	case IONIC_RC_EBUSY:
49		return "IONIC_RC_EBUSY";
50	case IONIC_RC_EEXIST:
51		return "IONIC_RC_EEXIST";
52	case IONIC_RC_EINVAL:
53		return "IONIC_RC_EINVAL";
54	case IONIC_RC_ENOSPC:
55		return "IONIC_RC_ENOSPC";
56	case IONIC_RC_ERANGE:
57		return "IONIC_RC_ERANGE";
58	case IONIC_RC_BAD_ADDR:
59		return "IONIC_RC_BAD_ADDR";
60	case IONIC_RC_DEV_CMD:
61		return "IONIC_RC_DEV_CMD";
62	case IONIC_RC_ENOSUPP:
63		return "IONIC_RC_ENOSUPP";
64	case IONIC_RC_ERROR:
65		return "IONIC_RC_ERROR";
66	case IONIC_RC_ERDMA:
67		return "IONIC_RC_ERDMA";
68	case IONIC_RC_EBAD_FW:
69		return "IONIC_RC_EBAD_FW";
70	default:
71		return "IONIC_RC_UNKNOWN";
72	}
73}
74
75static int ionic_error_to_errno(enum ionic_status_code code)
76{
77	switch (code) {
78	case IONIC_RC_SUCCESS:
79		return 0;
80	case IONIC_RC_EVERSION:
81	case IONIC_RC_EQTYPE:
82	case IONIC_RC_EQID:
83	case IONIC_RC_EINVAL:
84	case IONIC_RC_ENOSUPP:
85		return -EINVAL;
86	case IONIC_RC_EPERM:
87		return -EPERM;
88	case IONIC_RC_ENOENT:
89		return -ENOENT;
90	case IONIC_RC_EAGAIN:
91		return -EAGAIN;
92	case IONIC_RC_ENOMEM:
93		return -ENOMEM;
94	case IONIC_RC_EFAULT:
95		return -EFAULT;
96	case IONIC_RC_EBUSY:
97		return -EBUSY;
98	case IONIC_RC_EEXIST:
99		return -EEXIST;
100	case IONIC_RC_ENOSPC:
101		return -ENOSPC;
102	case IONIC_RC_ERANGE:
103		return -ERANGE;
104	case IONIC_RC_BAD_ADDR:
105		return -EFAULT;
106	case IONIC_RC_EOPCODE:
107	case IONIC_RC_EINTR:
108	case IONIC_RC_DEV_CMD:
109	case IONIC_RC_ERROR:
110	case IONIC_RC_ERDMA:
111	case IONIC_RC_EIO:
112	default:
113		return -EIO;
114	}
115}
116
117static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
118{
119	switch (opcode) {
120	case IONIC_CMD_NOP:
121		return "IONIC_CMD_NOP";
122	case IONIC_CMD_INIT:
123		return "IONIC_CMD_INIT";
124	case IONIC_CMD_RESET:
125		return "IONIC_CMD_RESET";
126	case IONIC_CMD_IDENTIFY:
127		return "IONIC_CMD_IDENTIFY";
128	case IONIC_CMD_GETATTR:
129		return "IONIC_CMD_GETATTR";
130	case IONIC_CMD_SETATTR:
131		return "IONIC_CMD_SETATTR";
132	case IONIC_CMD_PORT_IDENTIFY:
133		return "IONIC_CMD_PORT_IDENTIFY";
134	case IONIC_CMD_PORT_INIT:
135		return "IONIC_CMD_PORT_INIT";
136	case IONIC_CMD_PORT_RESET:
137		return "IONIC_CMD_PORT_RESET";
138	case IONIC_CMD_PORT_GETATTR:
139		return "IONIC_CMD_PORT_GETATTR";
140	case IONIC_CMD_PORT_SETATTR:
141		return "IONIC_CMD_PORT_SETATTR";
142	case IONIC_CMD_LIF_INIT:
143		return "IONIC_CMD_LIF_INIT";
144	case IONIC_CMD_LIF_RESET:
145		return "IONIC_CMD_LIF_RESET";
146	case IONIC_CMD_LIF_IDENTIFY:
147		return "IONIC_CMD_LIF_IDENTIFY";
148	case IONIC_CMD_LIF_SETATTR:
149		return "IONIC_CMD_LIF_SETATTR";
150	case IONIC_CMD_LIF_GETATTR:
151		return "IONIC_CMD_LIF_GETATTR";
152	case IONIC_CMD_LIF_SETPHC:
153		return "IONIC_CMD_LIF_SETPHC";
154	case IONIC_CMD_RX_MODE_SET:
155		return "IONIC_CMD_RX_MODE_SET";
156	case IONIC_CMD_RX_FILTER_ADD:
157		return "IONIC_CMD_RX_FILTER_ADD";
158	case IONIC_CMD_RX_FILTER_DEL:
159		return "IONIC_CMD_RX_FILTER_DEL";
160	case IONIC_CMD_Q_IDENTIFY:
161		return "IONIC_CMD_Q_IDENTIFY";
162	case IONIC_CMD_Q_INIT:
163		return "IONIC_CMD_Q_INIT";
164	case IONIC_CMD_Q_CONTROL:
165		return "IONIC_CMD_Q_CONTROL";
166	case IONIC_CMD_RDMA_RESET_LIF:
167		return "IONIC_CMD_RDMA_RESET_LIF";
168	case IONIC_CMD_RDMA_CREATE_EQ:
169		return "IONIC_CMD_RDMA_CREATE_EQ";
170	case IONIC_CMD_RDMA_CREATE_CQ:
171		return "IONIC_CMD_RDMA_CREATE_CQ";
172	case IONIC_CMD_RDMA_CREATE_ADMINQ:
173		return "IONIC_CMD_RDMA_CREATE_ADMINQ";
174	case IONIC_CMD_FW_DOWNLOAD:
175		return "IONIC_CMD_FW_DOWNLOAD";
176	case IONIC_CMD_FW_CONTROL:
177		return "IONIC_CMD_FW_CONTROL";
178	case IONIC_CMD_FW_DOWNLOAD_V1:
179		return "IONIC_CMD_FW_DOWNLOAD_V1";
180	case IONIC_CMD_FW_CONTROL_V1:
181		return "IONIC_CMD_FW_CONTROL_V1";
182	case IONIC_CMD_VF_GETATTR:
183		return "IONIC_CMD_VF_GETATTR";
184	case IONIC_CMD_VF_SETATTR:
185		return "IONIC_CMD_VF_SETATTR";
186	default:
187		return "DEVCMD_UNKNOWN";
188	}
189}
190
191const char *ionic_vf_attr_to_str(enum ionic_vf_attr attr)
192{
193	switch (attr) {
194	case IONIC_VF_ATTR_SPOOFCHK:
195		return "IONIC_VF_ATTR_SPOOFCHK";
196	case IONIC_VF_ATTR_TRUST:
197		return "IONIC_VF_ATTR_TRUST";
198	case IONIC_VF_ATTR_LINKSTATE:
199		return "IONIC_VF_ATTR_LINKSTATE";
200	case IONIC_VF_ATTR_MAC:
201		return "IONIC_VF_ATTR_MAC";
202	case IONIC_VF_ATTR_VLAN:
203		return "IONIC_VF_ATTR_VLAN";
204	case IONIC_VF_ATTR_RATE:
205		return "IONIC_VF_ATTR_RATE";
206	case IONIC_VF_ATTR_STATSADDR:
207		return "IONIC_VF_ATTR_STATSADDR";
208	default:
209		return "IONIC_VF_ATTR_UNKNOWN";
210	}
211}
212
213static void ionic_adminq_flush(struct ionic_lif *lif)
214{
215	struct ionic_desc_info *desc_info;
216	unsigned long irqflags;
217	struct ionic_queue *q;
218
219	spin_lock_irqsave(&lif->adminq_lock, irqflags);
220	if (!lif->adminqcq) {
221		spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
222		return;
223	}
224
225	q = &lif->adminqcq->q;
226
227	while (q->tail_idx != q->head_idx) {
228		desc_info = &q->info[q->tail_idx];
229		memset(desc_info->desc, 0, sizeof(union ionic_adminq_cmd));
230		desc_info->cb = NULL;
231		desc_info->cb_arg = NULL;
232		q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
233	}
234	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
235}
236
237void ionic_adminq_netdev_err_print(struct ionic_lif *lif, u8 opcode,
238				   u8 status, int err)
239{
240	const char *stat_str;
241
242	stat_str = (err == -ETIMEDOUT) ? "TIMEOUT" :
243					 ionic_error_to_str(status);
244
245	netdev_err(lif->netdev, "%s (%d) failed: %s (%d)\n",
246		   ionic_opcode_to_str(opcode), opcode, stat_str, err);
247}
248
249static int ionic_adminq_check_err(struct ionic_lif *lif,
250				  struct ionic_admin_ctx *ctx,
251				  const bool timeout,
252				  const bool do_msg)
253{
254	int err = 0;
255
256	if (ctx->comp.comp.status || timeout) {
257		err = timeout ? -ETIMEDOUT :
258				ionic_error_to_errno(ctx->comp.comp.status);
259
260		if (do_msg)
261			ionic_adminq_netdev_err_print(lif, ctx->cmd.cmd.opcode,
262						      ctx->comp.comp.status, err);
263
264		if (timeout)
265			ionic_adminq_flush(lif);
266	}
267
268	return err;
269}
270
271static void ionic_adminq_cb(struct ionic_queue *q,
272			    struct ionic_desc_info *desc_info,
273			    struct ionic_cq_info *cq_info, void *cb_arg)
274{
275	struct ionic_admin_ctx *ctx = cb_arg;
276	struct ionic_admin_comp *comp;
277
278	if (!ctx)
279		return;
280
281	comp = cq_info->cq_desc;
282
283	memcpy(&ctx->comp, comp, sizeof(*comp));
284
285	dev_dbg(q->dev, "comp admin queue command:\n");
286	dynamic_hex_dump("comp ", DUMP_PREFIX_OFFSET, 16, 1,
287			 &ctx->comp, sizeof(ctx->comp), true);
288
289	complete_all(&ctx->work);
290}
291
292bool ionic_adminq_poke_doorbell(struct ionic_queue *q)
293{
294	struct ionic_lif *lif = q->lif;
295	unsigned long now, then, dif;
296	unsigned long irqflags;
297
298	spin_lock_irqsave(&lif->adminq_lock, irqflags);
299
300	if (q->tail_idx == q->head_idx) {
301		spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
302		return false;
303	}
304
305	now = READ_ONCE(jiffies);
306	then = q->dbell_jiffies;
307	dif = now - then;
308
309	if (dif > q->dbell_deadline) {
310		ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
311				 q->dbval | q->head_idx);
312
313		q->dbell_jiffies = now;
314	}
315
316	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
317
318	return true;
319}
320
321int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
322{
323	struct ionic_desc_info *desc_info;
324	unsigned long irqflags;
325	struct ionic_queue *q;
326	int err = 0;
327
328	spin_lock_irqsave(&lif->adminq_lock, irqflags);
329	if (!lif->adminqcq) {
330		spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
331		return -EIO;
332	}
333
334	q = &lif->adminqcq->q;
335
336	if (!ionic_q_has_space(q, 1)) {
337		err = -ENOSPC;
338		goto err_out;
339	}
340
341	err = ionic_heartbeat_check(lif->ionic);
342	if (err)
343		goto err_out;
344
345	desc_info = &q->info[q->head_idx];
346	memcpy(desc_info->desc, &ctx->cmd, sizeof(ctx->cmd));
347
348	dev_dbg(&lif->netdev->dev, "post admin queue command:\n");
349	dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
350			 &ctx->cmd, sizeof(ctx->cmd), true);
351
352	ionic_q_post(q, true, ionic_adminq_cb, ctx);
353
354err_out:
355	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
356
357	return err;
358}
359
360int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx,
361		      const int err, const bool do_msg)
362{
363	struct net_device *netdev = lif->netdev;
364	unsigned long time_limit;
365	unsigned long time_start;
366	unsigned long time_done;
367	unsigned long remaining;
368	const char *name;
369
370	name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
371
372	if (err) {
373		if (do_msg && !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
374			netdev_err(netdev, "Posting of %s (%d) failed: %d\n",
375				   name, ctx->cmd.cmd.opcode, err);
376		ctx->comp.comp.status = IONIC_RC_ERROR;
377		return err;
378	}
379
380	time_start = jiffies;
381	time_limit = time_start + HZ * (ulong)DEVCMD_TIMEOUT;
382	do {
383		remaining = wait_for_completion_timeout(&ctx->work,
384							IONIC_ADMINQ_TIME_SLICE);
385
386		/* check for done */
387		if (remaining)
388			break;
389
390		/* force a check of FW status and break out if FW reset */
391		ionic_heartbeat_check(lif->ionic);
392		if ((test_bit(IONIC_LIF_F_FW_RESET, lif->state) &&
393		     !lif->ionic->idev.fw_status_ready) ||
394		    test_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) {
395			if (do_msg)
396				netdev_warn(netdev, "%s (%d) interrupted, FW in reset\n",
397					    name, ctx->cmd.cmd.opcode);
398			ctx->comp.comp.status = IONIC_RC_ERROR;
399			return -ENXIO;
400		}
401
402	} while (time_before(jiffies, time_limit));
403	time_done = jiffies;
404
405	dev_dbg(lif->ionic->dev, "%s: elapsed %d msecs\n",
406		__func__, jiffies_to_msecs(time_done - time_start));
407
408	return ionic_adminq_check_err(lif, ctx,
409				      time_after_eq(time_done, time_limit),
410				      do_msg);
411}
412
413static int __ionic_adminq_post_wait(struct ionic_lif *lif,
414				    struct ionic_admin_ctx *ctx,
415				    const bool do_msg)
416{
417	int err;
418
419	if (!ionic_is_fw_running(&lif->ionic->idev))
420		return 0;
421
422	err = ionic_adminq_post(lif, ctx);
423
424	return ionic_adminq_wait(lif, ctx, err, do_msg);
425}
426
427int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
428{
429	return __ionic_adminq_post_wait(lif, ctx, true);
430}
431
432int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
433{
434	return __ionic_adminq_post_wait(lif, ctx, false);
435}
436
437static void ionic_dev_cmd_clean(struct ionic *ionic)
438{
439	struct ionic_dev *idev = &ionic->idev;
440
441	iowrite32(0, &idev->dev_cmd_regs->doorbell);
442	memset_io(&idev->dev_cmd_regs->cmd, 0, sizeof(idev->dev_cmd_regs->cmd));
443}
444
445void ionic_dev_cmd_dev_err_print(struct ionic *ionic, u8 opcode, u8 status,
446				 int err)
447{
448	const char *stat_str;
449
450	stat_str = (err == -ETIMEDOUT) ? "TIMEOUT" :
451					 ionic_error_to_str(status);
452
453	dev_err(ionic->dev, "DEV_CMD %s (%d) error, %s (%d) failed\n",
454		ionic_opcode_to_str(opcode), opcode, stat_str, err);
455}
456
457static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
458				const bool do_msg)
459{
460	struct ionic_dev *idev = &ionic->idev;
461	unsigned long start_time;
462	unsigned long max_wait;
463	unsigned long duration;
464	int done = 0;
465	bool fw_up;
466	int opcode;
467	int err;
468
469	/* Wait for dev cmd to complete, retrying if we get EAGAIN,
470	 * but don't wait any longer than max_seconds.
471	 */
472	max_wait = jiffies + (max_seconds * HZ);
473try_again:
474	opcode = idev->opcode;
475	start_time = jiffies;
476	for (fw_up = ionic_is_fw_running(idev);
477	     !done && fw_up && time_before(jiffies, max_wait);
478	     fw_up = ionic_is_fw_running(idev)) {
479		done = ionic_dev_cmd_done(idev);
480		if (done)
481			break;
482		usleep_range(100, 200);
483	}
484	duration = jiffies - start_time;
485
486	dev_dbg(ionic->dev, "DEVCMD %s (%d) done=%d took %ld secs (%ld jiffies)\n",
487		ionic_opcode_to_str(opcode), opcode,
488		done, duration / HZ, duration);
489
490	if (!done && !fw_up) {
491		ionic_dev_cmd_clean(ionic);
492		dev_warn(ionic->dev, "DEVCMD %s (%d) interrupted - FW is down\n",
493			 ionic_opcode_to_str(opcode), opcode);
494		return -ENXIO;
495	}
496
497	if (!done && !time_before(jiffies, max_wait)) {
498		ionic_dev_cmd_clean(ionic);
499		dev_warn(ionic->dev, "DEVCMD %s (%d) timeout after %ld secs\n",
500			 ionic_opcode_to_str(opcode), opcode, max_seconds);
501		return -ETIMEDOUT;
502	}
503
504	err = ionic_dev_cmd_status(&ionic->idev);
505	if (err) {
506		if (err == IONIC_RC_EAGAIN &&
507		    time_before(jiffies, (max_wait - HZ))) {
508			dev_dbg(ionic->dev, "DEV_CMD %s (%d), %s (%d) retrying...\n",
509				ionic_opcode_to_str(opcode), opcode,
510				ionic_error_to_str(err), err);
511
512			iowrite32(0, &idev->dev_cmd_regs->done);
513			msleep(1000);
514			iowrite32(1, &idev->dev_cmd_regs->doorbell);
515			goto try_again;
516		}
517
518		if (!(opcode == IONIC_CMD_FW_CONTROL && err == IONIC_RC_EAGAIN))
519			if (do_msg)
520				ionic_dev_cmd_dev_err_print(ionic, opcode, err,
521							    ionic_error_to_errno(err));
522
523		return ionic_error_to_errno(err);
524	}
525
526	ionic_dev_cmd_clean(ionic);
527
528	return 0;
529}
530
531int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds)
532{
533	return __ionic_dev_cmd_wait(ionic, max_seconds, true);
534}
535
536int ionic_dev_cmd_wait_nomsg(struct ionic *ionic, unsigned long max_seconds)
537{
538	return __ionic_dev_cmd_wait(ionic, max_seconds, false);
539}
540
541int ionic_setup(struct ionic *ionic)
542{
543	int err;
544
545	err = ionic_dev_setup(ionic);
546	if (err)
547		return err;
548	ionic_reset(ionic);
549
550	return 0;
551}
552
553int ionic_identify(struct ionic *ionic)
554{
555	struct ionic_identity *ident = &ionic->ident;
556	struct ionic_dev *idev = &ionic->idev;
557	size_t sz;
558	int err;
559
560	memset(ident, 0, sizeof(*ident));
561
562	ident->drv.os_type = cpu_to_le32(IONIC_OS_TYPE_LINUX);
563	strncpy(ident->drv.driver_ver_str, UTS_RELEASE,
564		sizeof(ident->drv.driver_ver_str) - 1);
565
566	mutex_lock(&ionic->dev_cmd_lock);
567
568	sz = min(sizeof(ident->drv), sizeof(idev->dev_cmd_regs->data));
569	memcpy_toio(&idev->dev_cmd_regs->data, &ident->drv, sz);
570
571	ionic_dev_cmd_identify(idev, IONIC_DEV_IDENTITY_VERSION_2);
572	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
573	if (!err) {
574		sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data));
575		memcpy_fromio(&ident->dev, &idev->dev_cmd_regs->data, sz);
576	}
577	mutex_unlock(&ionic->dev_cmd_lock);
578
579	if (err) {
580		dev_err(ionic->dev, "Cannot identify ionic: %d\n", err);
581		goto err_out;
582	}
583
584	if (isprint(idev->dev_info.fw_version[0]) &&
585	    isascii(idev->dev_info.fw_version[0]))
586		dev_info(ionic->dev, "FW: %.*s\n",
587			 (int)(sizeof(idev->dev_info.fw_version) - 1),
588			 idev->dev_info.fw_version);
589	else
590		dev_info(ionic->dev, "FW: (invalid string) 0x%02x 0x%02x 0x%02x 0x%02x ...\n",
591			 (u8)idev->dev_info.fw_version[0],
592			 (u8)idev->dev_info.fw_version[1],
593			 (u8)idev->dev_info.fw_version[2],
594			 (u8)idev->dev_info.fw_version[3]);
595
596	err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC,
597				 &ionic->ident.lif);
598	if (err) {
599		dev_err(ionic->dev, "Cannot identify LIFs: %d\n", err);
600		goto err_out;
601	}
602
603	return 0;
604
605err_out:
606	return err;
607}
608
609int ionic_init(struct ionic *ionic)
610{
611	struct ionic_dev *idev = &ionic->idev;
612	int err;
613
614	mutex_lock(&ionic->dev_cmd_lock);
615	ionic_dev_cmd_init(idev);
616	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
617	mutex_unlock(&ionic->dev_cmd_lock);
618
619	return err;
620}
621
622int ionic_reset(struct ionic *ionic)
623{
624	struct ionic_dev *idev = &ionic->idev;
625	int err;
626
627	if (!ionic_is_fw_running(idev))
628		return 0;
629
630	mutex_lock(&ionic->dev_cmd_lock);
631	ionic_dev_cmd_reset(idev);
632	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
633	mutex_unlock(&ionic->dev_cmd_lock);
634
635	return err;
636}
637
638int ionic_port_identify(struct ionic *ionic)
639{
640	struct ionic_identity *ident = &ionic->ident;
641	struct ionic_dev *idev = &ionic->idev;
642	size_t sz;
643	int err;
644
645	mutex_lock(&ionic->dev_cmd_lock);
646
647	ionic_dev_cmd_port_identify(idev);
648	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
649	if (!err) {
650		sz = min(sizeof(ident->port), sizeof(idev->dev_cmd_regs->data));
651		memcpy_fromio(&ident->port, &idev->dev_cmd_regs->data, sz);
652	}
653
654	mutex_unlock(&ionic->dev_cmd_lock);
655
656	return err;
657}
658
659int ionic_port_init(struct ionic *ionic)
660{
661	struct ionic_identity *ident = &ionic->ident;
662	struct ionic_dev *idev = &ionic->idev;
663	size_t sz;
664	int err;
665
666	if (!idev->port_info) {
667		idev->port_info_sz = ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
668		idev->port_info = dma_alloc_coherent(ionic->dev,
669						     idev->port_info_sz,
670						     &idev->port_info_pa,
671						     GFP_KERNEL);
672		if (!idev->port_info)
673			return -ENOMEM;
674	}
675
676	sz = min(sizeof(ident->port.config), sizeof(idev->dev_cmd_regs->data));
677
678	mutex_lock(&ionic->dev_cmd_lock);
679
680	memcpy_toio(&idev->dev_cmd_regs->data, &ident->port.config, sz);
681	ionic_dev_cmd_port_init(idev);
682	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
683
684	ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
685	ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
686
687	mutex_unlock(&ionic->dev_cmd_lock);
688	if (err) {
689		dev_err(ionic->dev, "Failed to init port\n");
690		dma_free_coherent(ionic->dev, idev->port_info_sz,
691				  idev->port_info, idev->port_info_pa);
692		idev->port_info = NULL;
693		idev->port_info_pa = 0;
694	}
695
696	return err;
697}
698
699int ionic_port_reset(struct ionic *ionic)
700{
701	struct ionic_dev *idev = &ionic->idev;
702	int err = 0;
703
704	if (!idev->port_info)
705		return 0;
706
707	if (ionic_is_fw_running(idev)) {
708		mutex_lock(&ionic->dev_cmd_lock);
709		ionic_dev_cmd_port_reset(idev);
710		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
711		mutex_unlock(&ionic->dev_cmd_lock);
712	}
713
714	dma_free_coherent(ionic->dev, idev->port_info_sz,
715			  idev->port_info, idev->port_info_pa);
716
717	idev->port_info = NULL;
718	idev->port_info_pa = 0;
719
720	return err;
721}
722
723static int __init ionic_init_module(void)
724{
725	int ret;
726
727	ionic_debugfs_create();
728	ret = ionic_bus_register_driver();
729	if (ret)
730		ionic_debugfs_destroy();
731
732	return ret;
733}
734
735static void __exit ionic_cleanup_module(void)
736{
737	ionic_bus_unregister_driver();
738	ionic_debugfs_destroy();
739
740	pr_info("%s removed\n", IONIC_DRV_NAME);
741}
742
743module_init(ionic_init_module);
744module_exit(ionic_cleanup_module);
745