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