net/ionic: register and initialize adapter
[dpdk.git] / drivers / net / ionic / ionic_dev.c
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
3  */
4
5 #include <rte_malloc.h>
6
7 #include "ionic_dev.h"
8 #include "ionic.h"
9
10 int
11 ionic_dev_setup(struct ionic_adapter *adapter)
12 {
13         struct ionic_dev_bar *bar = adapter->bars;
14         unsigned int num_bars = adapter->num_bars;
15         struct ionic_dev *idev = &adapter->idev;
16         uint32_t sig;
17         u_char *bar0_base;
18
19         /* BAR0: dev_cmd and interrupts */
20         if (num_bars < 1) {
21                 IONIC_PRINT(ERR, "No bars found, aborting");
22                 return -EFAULT;
23         }
24
25         if (bar->len < IONIC_BAR0_SIZE) {
26                 IONIC_PRINT(ERR,
27                         "Resource bar size %lu too small, aborting",
28                         bar->len);
29                 return -EFAULT;
30         }
31
32         bar0_base = bar->vaddr;
33         idev->dev_info = (union ionic_dev_info_regs *)
34                 &bar0_base[IONIC_BAR0_DEV_INFO_REGS_OFFSET];
35         idev->dev_cmd = (union ionic_dev_cmd_regs *)
36                 &bar0_base[IONIC_BAR0_DEV_CMD_REGS_OFFSET];
37         idev->intr_status = (struct ionic_intr_status *)
38                 &bar0_base[IONIC_BAR0_INTR_STATUS_OFFSET];
39         idev->intr_ctrl = (struct ionic_intr *)
40                 &bar0_base[IONIC_BAR0_INTR_CTRL_OFFSET];
41
42         sig = ioread32(&idev->dev_info->signature);
43         if (sig != IONIC_DEV_INFO_SIGNATURE) {
44                 IONIC_PRINT(ERR, "Incompatible firmware signature %" PRIx32 "",
45                         sig);
46                 return -EFAULT;
47         }
48
49         /* BAR1: doorbells */
50         bar++;
51         if (num_bars < 2) {
52                 IONIC_PRINT(ERR, "Doorbell bar missing, aborting");
53                 return -EFAULT;
54         }
55
56         idev->db_pages = bar->vaddr;
57         idev->phy_db_pages = bar->bus_addr;
58
59         return 0;
60 }
61
62 /* Devcmd Interface */
63
64 uint8_t
65 ionic_dev_cmd_status(struct ionic_dev *idev)
66 {
67         return ioread8(&idev->dev_cmd->comp.comp.status);
68 }
69
70 bool
71 ionic_dev_cmd_done(struct ionic_dev *idev)
72 {
73         return ioread32(&idev->dev_cmd->done) & IONIC_DEV_CMD_DONE;
74 }
75
76 void
77 ionic_dev_cmd_comp(struct ionic_dev *idev, void *mem)
78 {
79         union ionic_dev_cmd_comp *comp = mem;
80         unsigned int i;
81         uint32_t comp_size = sizeof(comp->words) /
82                 sizeof(comp->words[0]);
83
84         for (i = 0; i < comp_size; i++)
85                 comp->words[i] = ioread32(&idev->dev_cmd->comp.words[i]);
86 }
87
88 void
89 ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
90 {
91         unsigned int i;
92         uint32_t cmd_size = sizeof(cmd->words) /
93                 sizeof(cmd->words[0]);
94
95         for (i = 0; i < cmd_size; i++)
96                 iowrite32(cmd->words[i], &idev->dev_cmd->cmd.words[i]);
97
98         iowrite32(0, &idev->dev_cmd->done);
99         iowrite32(1, &idev->dev_cmd->doorbell);
100 }
101
102 /* Device commands */
103
104 void
105 ionic_dev_cmd_identify(struct ionic_dev *idev, uint8_t ver)
106 {
107         union ionic_dev_cmd cmd = {
108                 .identify.opcode = IONIC_CMD_IDENTIFY,
109                 .identify.ver = ver,
110         };
111
112         ionic_dev_cmd_go(idev, &cmd);
113 }
114
115 void
116 ionic_dev_cmd_init(struct ionic_dev *idev)
117 {
118         union ionic_dev_cmd cmd = {
119                 .init.opcode = IONIC_CMD_INIT,
120                 .init.type = 0,
121         };
122
123         ionic_dev_cmd_go(idev, &cmd);
124 }
125
126 void
127 ionic_dev_cmd_reset(struct ionic_dev *idev)
128 {
129         union ionic_dev_cmd cmd = {
130                 .reset.opcode = IONIC_CMD_RESET,
131         };
132
133         ionic_dev_cmd_go(idev, &cmd);
134 }