xref: /dpdk/drivers/net/ionic/ionic_dev.c (revision 23bf4ddb)
15ef51809SAlfredo Cardigliano /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
25ef51809SAlfredo Cardigliano  * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
35ef51809SAlfredo Cardigliano  */
45ef51809SAlfredo Cardigliano 
55ef51809SAlfredo Cardigliano #include <rte_malloc.h>
65ef51809SAlfredo Cardigliano 
75ef51809SAlfredo Cardigliano #include "ionic_dev.h"
85ef51809SAlfredo Cardigliano #include "ionic.h"
95ef51809SAlfredo Cardigliano 
105ef51809SAlfredo Cardigliano int
115ef51809SAlfredo Cardigliano ionic_dev_setup(struct ionic_adapter *adapter)
125ef51809SAlfredo Cardigliano {
135ef51809SAlfredo Cardigliano 	struct ionic_dev_bar *bar = adapter->bars;
145ef51809SAlfredo Cardigliano 	unsigned int num_bars = adapter->num_bars;
155ef51809SAlfredo Cardigliano 	struct ionic_dev *idev = &adapter->idev;
165ef51809SAlfredo Cardigliano 	uint32_t sig;
175ef51809SAlfredo Cardigliano 	u_char *bar0_base;
185ef51809SAlfredo Cardigliano 
195ef51809SAlfredo Cardigliano 	/* BAR0: dev_cmd and interrupts */
205ef51809SAlfredo Cardigliano 	if (num_bars < 1) {
215ef51809SAlfredo Cardigliano 		IONIC_PRINT(ERR, "No bars found, aborting");
225ef51809SAlfredo Cardigliano 		return -EFAULT;
235ef51809SAlfredo Cardigliano 	}
245ef51809SAlfredo Cardigliano 
255ef51809SAlfredo Cardigliano 	if (bar->len < IONIC_BAR0_SIZE) {
265ef51809SAlfredo Cardigliano 		IONIC_PRINT(ERR,
275ef51809SAlfredo Cardigliano 			"Resource bar size %lu too small, aborting",
285ef51809SAlfredo Cardigliano 			bar->len);
295ef51809SAlfredo Cardigliano 		return -EFAULT;
305ef51809SAlfredo Cardigliano 	}
315ef51809SAlfredo Cardigliano 
325ef51809SAlfredo Cardigliano 	bar0_base = bar->vaddr;
335ef51809SAlfredo Cardigliano 	idev->dev_info = (union ionic_dev_info_regs *)
345ef51809SAlfredo Cardigliano 		&bar0_base[IONIC_BAR0_DEV_INFO_REGS_OFFSET];
355ef51809SAlfredo Cardigliano 	idev->dev_cmd = (union ionic_dev_cmd_regs *)
365ef51809SAlfredo Cardigliano 		&bar0_base[IONIC_BAR0_DEV_CMD_REGS_OFFSET];
375ef51809SAlfredo Cardigliano 	idev->intr_status = (struct ionic_intr_status *)
385ef51809SAlfredo Cardigliano 		&bar0_base[IONIC_BAR0_INTR_STATUS_OFFSET];
395ef51809SAlfredo Cardigliano 	idev->intr_ctrl = (struct ionic_intr *)
405ef51809SAlfredo Cardigliano 		&bar0_base[IONIC_BAR0_INTR_CTRL_OFFSET];
415ef51809SAlfredo Cardigliano 
425ef51809SAlfredo Cardigliano 	sig = ioread32(&idev->dev_info->signature);
435ef51809SAlfredo Cardigliano 	if (sig != IONIC_DEV_INFO_SIGNATURE) {
445ef51809SAlfredo Cardigliano 		IONIC_PRINT(ERR, "Incompatible firmware signature %" PRIx32 "",
455ef51809SAlfredo Cardigliano 			sig);
465ef51809SAlfredo Cardigliano 		return -EFAULT;
475ef51809SAlfredo Cardigliano 	}
485ef51809SAlfredo Cardigliano 
495ef51809SAlfredo Cardigliano 	/* BAR1: doorbells */
505ef51809SAlfredo Cardigliano 	bar++;
515ef51809SAlfredo Cardigliano 	if (num_bars < 2) {
525ef51809SAlfredo Cardigliano 		IONIC_PRINT(ERR, "Doorbell bar missing, aborting");
535ef51809SAlfredo Cardigliano 		return -EFAULT;
545ef51809SAlfredo Cardigliano 	}
555ef51809SAlfredo Cardigliano 
565ef51809SAlfredo Cardigliano 	idev->db_pages = bar->vaddr;
575ef51809SAlfredo Cardigliano 	idev->phy_db_pages = bar->bus_addr;
585ef51809SAlfredo Cardigliano 
595ef51809SAlfredo Cardigliano 	return 0;
605ef51809SAlfredo Cardigliano }
615ef51809SAlfredo Cardigliano 
625ef51809SAlfredo Cardigliano /* Devcmd Interface */
635ef51809SAlfredo Cardigliano 
645ef51809SAlfredo Cardigliano uint8_t
655ef51809SAlfredo Cardigliano ionic_dev_cmd_status(struct ionic_dev *idev)
665ef51809SAlfredo Cardigliano {
675ef51809SAlfredo Cardigliano 	return ioread8(&idev->dev_cmd->comp.comp.status);
685ef51809SAlfredo Cardigliano }
695ef51809SAlfredo Cardigliano 
705ef51809SAlfredo Cardigliano bool
715ef51809SAlfredo Cardigliano ionic_dev_cmd_done(struct ionic_dev *idev)
725ef51809SAlfredo Cardigliano {
735ef51809SAlfredo Cardigliano 	return ioread32(&idev->dev_cmd->done) & IONIC_DEV_CMD_DONE;
745ef51809SAlfredo Cardigliano }
755ef51809SAlfredo Cardigliano 
765ef51809SAlfredo Cardigliano void
775ef51809SAlfredo Cardigliano ionic_dev_cmd_comp(struct ionic_dev *idev, void *mem)
785ef51809SAlfredo Cardigliano {
795ef51809SAlfredo Cardigliano 	union ionic_dev_cmd_comp *comp = mem;
805ef51809SAlfredo Cardigliano 	unsigned int i;
815ef51809SAlfredo Cardigliano 	uint32_t comp_size = sizeof(comp->words) /
825ef51809SAlfredo Cardigliano 		sizeof(comp->words[0]);
835ef51809SAlfredo Cardigliano 
845ef51809SAlfredo Cardigliano 	for (i = 0; i < comp_size; i++)
855ef51809SAlfredo Cardigliano 		comp->words[i] = ioread32(&idev->dev_cmd->comp.words[i]);
865ef51809SAlfredo Cardigliano }
875ef51809SAlfredo Cardigliano 
885ef51809SAlfredo Cardigliano void
895ef51809SAlfredo Cardigliano ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
905ef51809SAlfredo Cardigliano {
915ef51809SAlfredo Cardigliano 	unsigned int i;
925ef51809SAlfredo Cardigliano 	uint32_t cmd_size = sizeof(cmd->words) /
935ef51809SAlfredo Cardigliano 		sizeof(cmd->words[0]);
945ef51809SAlfredo Cardigliano 
955ef51809SAlfredo Cardigliano 	for (i = 0; i < cmd_size; i++)
965ef51809SAlfredo Cardigliano 		iowrite32(cmd->words[i], &idev->dev_cmd->cmd.words[i]);
975ef51809SAlfredo Cardigliano 
985ef51809SAlfredo Cardigliano 	iowrite32(0, &idev->dev_cmd->done);
995ef51809SAlfredo Cardigliano 	iowrite32(1, &idev->dev_cmd->doorbell);
1005ef51809SAlfredo Cardigliano }
1015ef51809SAlfredo Cardigliano 
1025ef51809SAlfredo Cardigliano /* Device commands */
1035ef51809SAlfredo Cardigliano 
1045ef51809SAlfredo Cardigliano void
1055ef51809SAlfredo Cardigliano ionic_dev_cmd_identify(struct ionic_dev *idev, uint8_t ver)
1065ef51809SAlfredo Cardigliano {
1075ef51809SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
1085ef51809SAlfredo Cardigliano 		.identify.opcode = IONIC_CMD_IDENTIFY,
1095ef51809SAlfredo Cardigliano 		.identify.ver = ver,
1105ef51809SAlfredo Cardigliano 	};
1115ef51809SAlfredo Cardigliano 
1125ef51809SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
1135ef51809SAlfredo Cardigliano }
1145ef51809SAlfredo Cardigliano 
1155ef51809SAlfredo Cardigliano void
1165ef51809SAlfredo Cardigliano ionic_dev_cmd_init(struct ionic_dev *idev)
1175ef51809SAlfredo Cardigliano {
1185ef51809SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
1195ef51809SAlfredo Cardigliano 		.init.opcode = IONIC_CMD_INIT,
1205ef51809SAlfredo Cardigliano 		.init.type = 0,
1215ef51809SAlfredo Cardigliano 	};
1225ef51809SAlfredo Cardigliano 
1235ef51809SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
1245ef51809SAlfredo Cardigliano }
1255ef51809SAlfredo Cardigliano 
1265ef51809SAlfredo Cardigliano void
1275ef51809SAlfredo Cardigliano ionic_dev_cmd_reset(struct ionic_dev *idev)
1285ef51809SAlfredo Cardigliano {
1295ef51809SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
1305ef51809SAlfredo Cardigliano 		.reset.opcode = IONIC_CMD_RESET,
1315ef51809SAlfredo Cardigliano 	};
1325ef51809SAlfredo Cardigliano 
1335ef51809SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
1345ef51809SAlfredo Cardigliano }
135*23bf4ddbSAlfredo Cardigliano 
136*23bf4ddbSAlfredo Cardigliano /* Port commands */
137*23bf4ddbSAlfredo Cardigliano 
138*23bf4ddbSAlfredo Cardigliano void
139*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_identify(struct ionic_dev *idev)
140*23bf4ddbSAlfredo Cardigliano {
141*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
142*23bf4ddbSAlfredo Cardigliano 		.port_init.opcode = IONIC_CMD_PORT_IDENTIFY,
143*23bf4ddbSAlfredo Cardigliano 		.port_init.index = 0,
144*23bf4ddbSAlfredo Cardigliano 	};
145*23bf4ddbSAlfredo Cardigliano 
146*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
147*23bf4ddbSAlfredo Cardigliano }
148*23bf4ddbSAlfredo Cardigliano 
149*23bf4ddbSAlfredo Cardigliano void
150*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_init(struct ionic_dev *idev)
151*23bf4ddbSAlfredo Cardigliano {
152*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
153*23bf4ddbSAlfredo Cardigliano 		.port_init.opcode = IONIC_CMD_PORT_INIT,
154*23bf4ddbSAlfredo Cardigliano 		.port_init.index = 0,
155*23bf4ddbSAlfredo Cardigliano 		.port_init.info_pa = idev->port_info_pa,
156*23bf4ddbSAlfredo Cardigliano 	};
157*23bf4ddbSAlfredo Cardigliano 
158*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
159*23bf4ddbSAlfredo Cardigliano }
160*23bf4ddbSAlfredo Cardigliano 
161*23bf4ddbSAlfredo Cardigliano void
162*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_reset(struct ionic_dev *idev)
163*23bf4ddbSAlfredo Cardigliano {
164*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
165*23bf4ddbSAlfredo Cardigliano 		.port_reset.opcode = IONIC_CMD_PORT_RESET,
166*23bf4ddbSAlfredo Cardigliano 		.port_reset.index = 0,
167*23bf4ddbSAlfredo Cardigliano 	};
168*23bf4ddbSAlfredo Cardigliano 
169*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
170*23bf4ddbSAlfredo Cardigliano }
171*23bf4ddbSAlfredo Cardigliano 
172*23bf4ddbSAlfredo Cardigliano void
173*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_state(struct ionic_dev *idev, uint8_t state)
174*23bf4ddbSAlfredo Cardigliano {
175*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
176*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
177*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
178*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_STATE,
179*23bf4ddbSAlfredo Cardigliano 		.port_setattr.state = state,
180*23bf4ddbSAlfredo Cardigliano 	};
181*23bf4ddbSAlfredo Cardigliano 
182*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
183*23bf4ddbSAlfredo Cardigliano }
184*23bf4ddbSAlfredo Cardigliano 
185*23bf4ddbSAlfredo Cardigliano void
186*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_speed(struct ionic_dev *idev, uint32_t speed)
187*23bf4ddbSAlfredo Cardigliano {
188*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
189*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
190*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
191*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_SPEED,
192*23bf4ddbSAlfredo Cardigliano 		.port_setattr.speed = speed,
193*23bf4ddbSAlfredo Cardigliano 	};
194*23bf4ddbSAlfredo Cardigliano 
195*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
196*23bf4ddbSAlfredo Cardigliano }
197*23bf4ddbSAlfredo Cardigliano 
198*23bf4ddbSAlfredo Cardigliano void
199*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_mtu(struct ionic_dev *idev, uint32_t mtu)
200*23bf4ddbSAlfredo Cardigliano {
201*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
202*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
203*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
204*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_MTU,
205*23bf4ddbSAlfredo Cardigliano 		.port_setattr.mtu = mtu,
206*23bf4ddbSAlfredo Cardigliano 	};
207*23bf4ddbSAlfredo Cardigliano 
208*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
209*23bf4ddbSAlfredo Cardigliano }
210*23bf4ddbSAlfredo Cardigliano 
211*23bf4ddbSAlfredo Cardigliano void
212*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, uint8_t an_enable)
213*23bf4ddbSAlfredo Cardigliano {
214*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
215*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
216*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
217*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_AUTONEG,
218*23bf4ddbSAlfredo Cardigliano 		.port_setattr.an_enable = an_enable,
219*23bf4ddbSAlfredo Cardigliano 	};
220*23bf4ddbSAlfredo Cardigliano 
221*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
222*23bf4ddbSAlfredo Cardigliano }
223*23bf4ddbSAlfredo Cardigliano 
224*23bf4ddbSAlfredo Cardigliano void
225*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_fec(struct ionic_dev *idev, uint8_t fec_type)
226*23bf4ddbSAlfredo Cardigliano {
227*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
228*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
229*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
230*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_FEC,
231*23bf4ddbSAlfredo Cardigliano 		.port_setattr.fec_type = fec_type,
232*23bf4ddbSAlfredo Cardigliano 	};
233*23bf4ddbSAlfredo Cardigliano 
234*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
235*23bf4ddbSAlfredo Cardigliano }
236*23bf4ddbSAlfredo Cardigliano 
237*23bf4ddbSAlfredo Cardigliano void
238*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_pause(struct ionic_dev *idev, uint8_t pause_type)
239*23bf4ddbSAlfredo Cardigliano {
240*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
241*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
242*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
243*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_PAUSE,
244*23bf4ddbSAlfredo Cardigliano 		.port_setattr.pause_type = pause_type,
245*23bf4ddbSAlfredo Cardigliano 	};
246*23bf4ddbSAlfredo Cardigliano 
247*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
248*23bf4ddbSAlfredo Cardigliano }
249*23bf4ddbSAlfredo Cardigliano 
250*23bf4ddbSAlfredo Cardigliano void
251*23bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_loopback(struct ionic_dev *idev, uint8_t loopback_mode)
252*23bf4ddbSAlfredo Cardigliano {
253*23bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
254*23bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
255*23bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
256*23bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_LOOPBACK,
257*23bf4ddbSAlfredo Cardigliano 		.port_setattr.loopback_mode = loopback_mode,
258*23bf4ddbSAlfredo Cardigliano 	};
259*23bf4ddbSAlfredo Cardigliano 
260*23bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
261*23bf4ddbSAlfredo Cardigliano }
262