xref: /dpdk/drivers/net/ionic/ionic_main.c (revision 23bf4ddb)
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_memzone.h>
6 
7 #include "ionic.h"
8 
9 static int
10 ionic_dev_cmd_wait(struct ionic_dev *idev, unsigned long max_wait)
11 {
12 	unsigned long step_msec = 100;
13 	unsigned int max_wait_msec = max_wait * 1000;
14 	unsigned long elapsed_msec = 0;
15 	int done;
16 
17 	/* Wait for dev cmd to complete.. but no more than max_wait sec */
18 
19 	do {
20 		done = ionic_dev_cmd_done(idev);
21 		if (done) {
22 			IONIC_PRINT(DEBUG, "DEVCMD %d done took %ld msecs",
23 				idev->dev_cmd->cmd.cmd.opcode,
24 				elapsed_msec);
25 			return 0;
26 		}
27 
28 		msec_delay(step_msec);
29 
30 		elapsed_msec += step_msec;
31 	} while (elapsed_msec < max_wait_msec);
32 
33 	IONIC_PRINT(DEBUG, "DEVCMD %d timeout after %ld msecs",
34 		idev->dev_cmd->cmd.cmd.opcode,
35 		elapsed_msec);
36 
37 	return -ETIMEDOUT;
38 }
39 
40 static int
41 ionic_dev_cmd_check_error(struct ionic_dev *idev)
42 {
43 	uint8_t status;
44 
45 	status = ionic_dev_cmd_status(idev);
46 	if (status == 0)
47 		return 0;
48 
49 	return -EIO;
50 }
51 
52 int
53 ionic_dev_cmd_wait_check(struct ionic_dev *idev, unsigned long max_wait)
54 {
55 	int err;
56 
57 	err = ionic_dev_cmd_wait(idev, max_wait);
58 	if (err)
59 		return err;
60 
61 	return ionic_dev_cmd_check_error(idev);
62 }
63 
64 int
65 ionic_setup(struct ionic_adapter *adapter)
66 {
67 	return ionic_dev_setup(adapter);
68 }
69 
70 int
71 ionic_identify(struct ionic_adapter *adapter)
72 {
73 	struct ionic_dev *idev = &adapter->idev;
74 	struct ionic_identity *ident = &adapter->ident;
75 	int err = 0;
76 	uint32_t i;
77 	unsigned int nwords;
78 	uint32_t drv_size = sizeof(ident->drv.words) /
79 		sizeof(ident->drv.words[0]);
80 	uint32_t cmd_size = sizeof(idev->dev_cmd->data) /
81 		sizeof(idev->dev_cmd->data[0]);
82 	uint32_t dev_size = sizeof(ident->dev.words) /
83 		sizeof(ident->dev.words[0]);
84 
85 	memset(ident, 0, sizeof(*ident));
86 
87 	ident->drv.os_type = IONIC_OS_TYPE_LINUX;
88 	ident->drv.os_dist = 0;
89 	snprintf(ident->drv.os_dist_str,
90 		sizeof(ident->drv.os_dist_str), "Unknown");
91 	ident->drv.kernel_ver = 0;
92 	snprintf(ident->drv.kernel_ver_str,
93 		sizeof(ident->drv.kernel_ver_str), "DPDK");
94 	strncpy(ident->drv.driver_ver_str, IONIC_DRV_VERSION,
95 		sizeof(ident->drv.driver_ver_str) - 1);
96 
97 	nwords = RTE_MIN(drv_size, cmd_size);
98 	for (i = 0; i < nwords; i++)
99 		iowrite32(ident->drv.words[i], &idev->dev_cmd->data[i]);
100 
101 	ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1);
102 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
103 	if (!err) {
104 		nwords = RTE_MIN(dev_size, cmd_size);
105 		for (i = 0; i < nwords; i++)
106 			ident->dev.words[i] = ioread32(&idev->dev_cmd->data[i]);
107 	}
108 
109 	return err;
110 }
111 
112 int
113 ionic_init(struct ionic_adapter *adapter)
114 {
115 	struct ionic_dev *idev = &adapter->idev;
116 	int err;
117 
118 	ionic_dev_cmd_init(idev);
119 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
120 	return err;
121 }
122 
123 int
124 ionic_reset(struct ionic_adapter *adapter)
125 {
126 	struct ionic_dev *idev = &adapter->idev;
127 	int err;
128 
129 	ionic_dev_cmd_reset(idev);
130 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
131 	return err;
132 }
133 
134 int
135 ionic_port_identify(struct ionic_adapter *adapter)
136 {
137 	struct ionic_dev *idev = &adapter->idev;
138 	struct ionic_identity *ident = &adapter->ident;
139 	unsigned int port_words = sizeof(ident->port.words) /
140 		sizeof(ident->port.words[0]);
141 	unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
142 		sizeof(idev->dev_cmd->data[0]);
143 	unsigned int i;
144 	unsigned int nwords;
145 	int err;
146 
147 	ionic_dev_cmd_port_identify(idev);
148 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
149 	if (!err) {
150 		nwords = RTE_MIN(port_words, cmd_words);
151 		for (i = 0; i < nwords; i++)
152 			ident->port.words[i] =
153 				ioread32(&idev->dev_cmd->data[i]);
154 	}
155 
156 	IONIC_PRINT(INFO, "speed %d ", ident->port.config.speed);
157 	IONIC_PRINT(INFO, "mtu %d ", ident->port.config.mtu);
158 	IONIC_PRINT(INFO, "state %d ", ident->port.config.state);
159 	IONIC_PRINT(INFO, "an_enable %d ", ident->port.config.an_enable);
160 	IONIC_PRINT(INFO, "fec_type %d ", ident->port.config.fec_type);
161 	IONIC_PRINT(INFO, "pause_type %d ", ident->port.config.pause_type);
162 	IONIC_PRINT(INFO, "loopback_mode %d",
163 		ident->port.config.loopback_mode);
164 
165 	return err;
166 }
167 
168 static const struct rte_memzone *
169 ionic_memzone_reserve(const char *name, uint32_t len, int socket_id)
170 {
171 	const struct rte_memzone *mz;
172 
173 	mz = rte_memzone_lookup(name);
174 	if (mz)
175 		return mz;
176 
177 	mz = rte_memzone_reserve_aligned(name, len, socket_id,
178 		RTE_MEMZONE_IOVA_CONTIG, IONIC_ALIGN);
179 	return mz;
180 }
181 
182 int
183 ionic_port_init(struct ionic_adapter *adapter)
184 {
185 	struct ionic_dev *idev = &adapter->idev;
186 	struct ionic_identity *ident = &adapter->ident;
187 	char z_name[RTE_MEMZONE_NAMESIZE];
188 	unsigned int config_words = sizeof(ident->port.config.words) /
189 		sizeof(ident->port.config.words[0]);
190 	unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
191 		sizeof(idev->dev_cmd->data[0]);
192 	unsigned int nwords;
193 	unsigned int i;
194 	int err;
195 
196 	if (idev->port_info)
197 		return 0;
198 
199 	idev->port_info_sz = RTE_ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
200 
201 	snprintf(z_name, sizeof(z_name), "%s_port_%s_info",
202 		IONIC_DRV_NAME,
203 		adapter->pci_dev->device.name);
204 
205 	idev->port_info_z = ionic_memzone_reserve(z_name, idev->port_info_sz,
206 		SOCKET_ID_ANY);
207 	if (!idev->port_info_z) {
208 		IONIC_PRINT(ERR, "Cannot reserve port info DMA memory");
209 		return -ENOMEM;
210 	}
211 
212 	idev->port_info = idev->port_info_z->addr;
213 	idev->port_info_pa = idev->port_info_z->iova;
214 
215 	nwords = RTE_MIN(config_words, cmd_words);
216 
217 	for (i = 0; i < nwords; i++)
218 		iowrite32(ident->port.config.words[i], &idev->dev_cmd->data[i]);
219 
220 	ionic_dev_cmd_port_init(idev);
221 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
222 	if (err) {
223 		IONIC_PRINT(ERR, "Failed to init port");
224 		return err;
225 	}
226 
227 	ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
228 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
229 	if (err) {
230 		IONIC_PRINT(WARNING, "Failed to bring port UP");
231 		return err;
232 	}
233 
234 	return 0;
235 }
236 
237 int
238 ionic_port_reset(struct ionic_adapter *adapter)
239 {
240 	struct ionic_dev *idev = &adapter->idev;
241 	int err;
242 
243 	if (!idev->port_info)
244 		return 0;
245 
246 	ionic_dev_cmd_port_reset(idev);
247 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
248 	if (err) {
249 		IONIC_PRINT(ERR, "Failed to reset port");
250 		return err;
251 	}
252 
253 	idev->port_info = NULL;
254 	idev->port_info_pa = 0;
255 
256 	return 0;
257 }
258