xref: /dpdk/drivers/net/ionic/ionic_dev.c (revision 669c8de6)
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 }
13523bf4ddbSAlfredo Cardigliano 
13623bf4ddbSAlfredo Cardigliano /* Port commands */
13723bf4ddbSAlfredo Cardigliano 
13823bf4ddbSAlfredo Cardigliano void
13923bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_identify(struct ionic_dev *idev)
14023bf4ddbSAlfredo Cardigliano {
14123bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
14223bf4ddbSAlfredo Cardigliano 		.port_init.opcode = IONIC_CMD_PORT_IDENTIFY,
14323bf4ddbSAlfredo Cardigliano 		.port_init.index = 0,
14423bf4ddbSAlfredo Cardigliano 	};
14523bf4ddbSAlfredo Cardigliano 
14623bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
14723bf4ddbSAlfredo Cardigliano }
14823bf4ddbSAlfredo Cardigliano 
14923bf4ddbSAlfredo Cardigliano void
15023bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_init(struct ionic_dev *idev)
15123bf4ddbSAlfredo Cardigliano {
15223bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
15323bf4ddbSAlfredo Cardigliano 		.port_init.opcode = IONIC_CMD_PORT_INIT,
15423bf4ddbSAlfredo Cardigliano 		.port_init.index = 0,
15523bf4ddbSAlfredo Cardigliano 		.port_init.info_pa = idev->port_info_pa,
15623bf4ddbSAlfredo Cardigliano 	};
15723bf4ddbSAlfredo Cardigliano 
15823bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
15923bf4ddbSAlfredo Cardigliano }
16023bf4ddbSAlfredo Cardigliano 
16123bf4ddbSAlfredo Cardigliano void
16223bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_reset(struct ionic_dev *idev)
16323bf4ddbSAlfredo Cardigliano {
16423bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
16523bf4ddbSAlfredo Cardigliano 		.port_reset.opcode = IONIC_CMD_PORT_RESET,
16623bf4ddbSAlfredo Cardigliano 		.port_reset.index = 0,
16723bf4ddbSAlfredo Cardigliano 	};
16823bf4ddbSAlfredo Cardigliano 
16923bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
17023bf4ddbSAlfredo Cardigliano }
17123bf4ddbSAlfredo Cardigliano 
17223bf4ddbSAlfredo Cardigliano void
17323bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_state(struct ionic_dev *idev, uint8_t state)
17423bf4ddbSAlfredo Cardigliano {
17523bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
17623bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
17723bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
17823bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_STATE,
17923bf4ddbSAlfredo Cardigliano 		.port_setattr.state = state,
18023bf4ddbSAlfredo Cardigliano 	};
18123bf4ddbSAlfredo Cardigliano 
18223bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
18323bf4ddbSAlfredo Cardigliano }
18423bf4ddbSAlfredo Cardigliano 
18523bf4ddbSAlfredo Cardigliano void
18623bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_speed(struct ionic_dev *idev, uint32_t speed)
18723bf4ddbSAlfredo Cardigliano {
18823bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
18923bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
19023bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
19123bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_SPEED,
19223bf4ddbSAlfredo Cardigliano 		.port_setattr.speed = speed,
19323bf4ddbSAlfredo Cardigliano 	};
19423bf4ddbSAlfredo Cardigliano 
19523bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
19623bf4ddbSAlfredo Cardigliano }
19723bf4ddbSAlfredo Cardigliano 
19823bf4ddbSAlfredo Cardigliano void
19923bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_mtu(struct ionic_dev *idev, uint32_t mtu)
20023bf4ddbSAlfredo Cardigliano {
20123bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
20223bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
20323bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
20423bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_MTU,
20523bf4ddbSAlfredo Cardigliano 		.port_setattr.mtu = mtu,
20623bf4ddbSAlfredo Cardigliano 	};
20723bf4ddbSAlfredo Cardigliano 
20823bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
20923bf4ddbSAlfredo Cardigliano }
21023bf4ddbSAlfredo Cardigliano 
21123bf4ddbSAlfredo Cardigliano void
21223bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, uint8_t an_enable)
21323bf4ddbSAlfredo Cardigliano {
21423bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
21523bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
21623bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
21723bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_AUTONEG,
21823bf4ddbSAlfredo Cardigliano 		.port_setattr.an_enable = an_enable,
21923bf4ddbSAlfredo Cardigliano 	};
22023bf4ddbSAlfredo Cardigliano 
22123bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
22223bf4ddbSAlfredo Cardigliano }
22323bf4ddbSAlfredo Cardigliano 
22423bf4ddbSAlfredo Cardigliano void
22523bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_fec(struct ionic_dev *idev, uint8_t fec_type)
22623bf4ddbSAlfredo Cardigliano {
22723bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
22823bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
22923bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
23023bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_FEC,
23123bf4ddbSAlfredo Cardigliano 		.port_setattr.fec_type = fec_type,
23223bf4ddbSAlfredo Cardigliano 	};
23323bf4ddbSAlfredo Cardigliano 
23423bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
23523bf4ddbSAlfredo Cardigliano }
23623bf4ddbSAlfredo Cardigliano 
23723bf4ddbSAlfredo Cardigliano void
23823bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_pause(struct ionic_dev *idev, uint8_t pause_type)
23923bf4ddbSAlfredo Cardigliano {
24023bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
24123bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
24223bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
24323bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_PAUSE,
24423bf4ddbSAlfredo Cardigliano 		.port_setattr.pause_type = pause_type,
24523bf4ddbSAlfredo Cardigliano 	};
24623bf4ddbSAlfredo Cardigliano 
24723bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
24823bf4ddbSAlfredo Cardigliano }
24923bf4ddbSAlfredo Cardigliano 
25023bf4ddbSAlfredo Cardigliano void
25123bf4ddbSAlfredo Cardigliano ionic_dev_cmd_port_loopback(struct ionic_dev *idev, uint8_t loopback_mode)
25223bf4ddbSAlfredo Cardigliano {
25323bf4ddbSAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
25423bf4ddbSAlfredo Cardigliano 		.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
25523bf4ddbSAlfredo Cardigliano 		.port_setattr.index = 0,
25623bf4ddbSAlfredo Cardigliano 		.port_setattr.attr = IONIC_PORT_ATTR_LOOPBACK,
25723bf4ddbSAlfredo Cardigliano 		.port_setattr.loopback_mode = loopback_mode,
25823bf4ddbSAlfredo Cardigliano 	};
25923bf4ddbSAlfredo Cardigliano 
26023bf4ddbSAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
26123bf4ddbSAlfredo Cardigliano }
262*669c8de6SAlfredo Cardigliano 
263*669c8de6SAlfredo Cardigliano /* LIF commands */
264*669c8de6SAlfredo Cardigliano 
265*669c8de6SAlfredo Cardigliano void
266*669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_identify(struct ionic_dev *idev, uint8_t type, uint8_t ver)
267*669c8de6SAlfredo Cardigliano {
268*669c8de6SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
269*669c8de6SAlfredo Cardigliano 		.lif_identify.opcode = IONIC_CMD_LIF_IDENTIFY,
270*669c8de6SAlfredo Cardigliano 		.lif_identify.type = type,
271*669c8de6SAlfredo Cardigliano 		.lif_identify.ver = ver,
272*669c8de6SAlfredo Cardigliano 	};
273*669c8de6SAlfredo Cardigliano 
274*669c8de6SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
275*669c8de6SAlfredo Cardigliano }
276*669c8de6SAlfredo Cardigliano 
277*669c8de6SAlfredo Cardigliano void
278*669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
279*669c8de6SAlfredo Cardigliano 		       rte_iova_t info_pa)
280*669c8de6SAlfredo Cardigliano {
281*669c8de6SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
282*669c8de6SAlfredo Cardigliano 		.lif_init.opcode = IONIC_CMD_LIF_INIT,
283*669c8de6SAlfredo Cardigliano 		.lif_init.index = lif_index,
284*669c8de6SAlfredo Cardigliano 		.lif_init.info_pa = info_pa,
285*669c8de6SAlfredo Cardigliano 	};
286*669c8de6SAlfredo Cardigliano 
287*669c8de6SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
288*669c8de6SAlfredo Cardigliano }
289*669c8de6SAlfredo Cardigliano 
290*669c8de6SAlfredo Cardigliano void
291*669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_reset(struct ionic_dev *idev, uint16_t lif_index)
292*669c8de6SAlfredo Cardigliano {
293*669c8de6SAlfredo Cardigliano 	union ionic_dev_cmd cmd = {
294*669c8de6SAlfredo Cardigliano 		.lif_init.opcode = IONIC_CMD_LIF_RESET,
295*669c8de6SAlfredo Cardigliano 		.lif_init.index = lif_index,
296*669c8de6SAlfredo Cardigliano 	};
297*669c8de6SAlfredo Cardigliano 
298*669c8de6SAlfredo Cardigliano 	ionic_dev_cmd_go(idev, &cmd);
299*669c8de6SAlfredo Cardigliano }
300