1*669c8de6SAlfredo Cardigliano /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2*669c8de6SAlfredo Cardigliano * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved. 3*669c8de6SAlfredo Cardigliano */ 4*669c8de6SAlfredo Cardigliano 5*669c8de6SAlfredo Cardigliano #include <rte_malloc.h> 6*669c8de6SAlfredo Cardigliano #include <rte_ethdev_driver.h> 7*669c8de6SAlfredo Cardigliano 8*669c8de6SAlfredo Cardigliano #include "ionic.h" 9*669c8de6SAlfredo Cardigliano #include "ionic_logs.h" 10*669c8de6SAlfredo Cardigliano #include "ionic_lif.h" 11*669c8de6SAlfredo Cardigliano #include "ionic_ethdev.h" 12*669c8de6SAlfredo Cardigliano 13*669c8de6SAlfredo Cardigliano int 14*669c8de6SAlfredo Cardigliano ionic_lif_alloc(struct ionic_lif *lif) 15*669c8de6SAlfredo Cardigliano { 16*669c8de6SAlfredo Cardigliano uint32_t socket_id = rte_socket_id(); 17*669c8de6SAlfredo Cardigliano 18*669c8de6SAlfredo Cardigliano snprintf(lif->name, sizeof(lif->name), "lif%u", lif->index); 19*669c8de6SAlfredo Cardigliano 20*669c8de6SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Allocating Lif Info"); 21*669c8de6SAlfredo Cardigliano 22*669c8de6SAlfredo Cardigliano lif->info_sz = RTE_ALIGN(sizeof(*lif->info), PAGE_SIZE); 23*669c8de6SAlfredo Cardigliano 24*669c8de6SAlfredo Cardigliano lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev, 25*669c8de6SAlfredo Cardigliano "lif_info", 0 /* queue_idx*/, 26*669c8de6SAlfredo Cardigliano lif->info_sz, IONIC_ALIGN, socket_id); 27*669c8de6SAlfredo Cardigliano if (!lif->info_z) { 28*669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate lif info memory"); 29*669c8de6SAlfredo Cardigliano return -ENOMEM; 30*669c8de6SAlfredo Cardigliano } 31*669c8de6SAlfredo Cardigliano 32*669c8de6SAlfredo Cardigliano lif->info = lif->info_z->addr; 33*669c8de6SAlfredo Cardigliano lif->info_pa = lif->info_z->iova; 34*669c8de6SAlfredo Cardigliano 35*669c8de6SAlfredo Cardigliano return 0; 36*669c8de6SAlfredo Cardigliano } 37*669c8de6SAlfredo Cardigliano 38*669c8de6SAlfredo Cardigliano void 39*669c8de6SAlfredo Cardigliano ionic_lif_free(struct ionic_lif *lif) 40*669c8de6SAlfredo Cardigliano { 41*669c8de6SAlfredo Cardigliano if (lif->info) { 42*669c8de6SAlfredo Cardigliano rte_memzone_free(lif->info_z); 43*669c8de6SAlfredo Cardigliano lif->info = NULL; 44*669c8de6SAlfredo Cardigliano } 45*669c8de6SAlfredo Cardigliano } 46*669c8de6SAlfredo Cardigliano 47*669c8de6SAlfredo Cardigliano int 48*669c8de6SAlfredo Cardigliano ionic_lif_init(struct ionic_lif *lif) 49*669c8de6SAlfredo Cardigliano { 50*669c8de6SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev; 51*669c8de6SAlfredo Cardigliano struct ionic_q_init_comp comp; 52*669c8de6SAlfredo Cardigliano int err; 53*669c8de6SAlfredo Cardigliano 54*669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa); 55*669c8de6SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 56*669c8de6SAlfredo Cardigliano ionic_dev_cmd_comp(idev, &comp); 57*669c8de6SAlfredo Cardigliano if (err) 58*669c8de6SAlfredo Cardigliano return err; 59*669c8de6SAlfredo Cardigliano 60*669c8de6SAlfredo Cardigliano lif->hw_index = comp.hw_index; 61*669c8de6SAlfredo Cardigliano 62*669c8de6SAlfredo Cardigliano lif->state |= IONIC_LIF_F_INITED; 63*669c8de6SAlfredo Cardigliano 64*669c8de6SAlfredo Cardigliano return 0; 65*669c8de6SAlfredo Cardigliano } 66*669c8de6SAlfredo Cardigliano 67*669c8de6SAlfredo Cardigliano void 68*669c8de6SAlfredo Cardigliano ionic_lif_deinit(struct ionic_lif *lif) 69*669c8de6SAlfredo Cardigliano { 70*669c8de6SAlfredo Cardigliano if (!(lif->state & IONIC_LIF_F_INITED)) 71*669c8de6SAlfredo Cardigliano return; 72*669c8de6SAlfredo Cardigliano 73*669c8de6SAlfredo Cardigliano lif->state &= ~IONIC_LIF_F_INITED; 74*669c8de6SAlfredo Cardigliano } 75*669c8de6SAlfredo Cardigliano 76*669c8de6SAlfredo Cardigliano int 77*669c8de6SAlfredo Cardigliano ionic_lif_identify(struct ionic_adapter *adapter) 78*669c8de6SAlfredo Cardigliano { 79*669c8de6SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev; 80*669c8de6SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 81*669c8de6SAlfredo Cardigliano int err; 82*669c8de6SAlfredo Cardigliano unsigned int i; 83*669c8de6SAlfredo Cardigliano unsigned int lif_words = sizeof(ident->lif.words) / 84*669c8de6SAlfredo Cardigliano sizeof(ident->lif.words[0]); 85*669c8de6SAlfredo Cardigliano unsigned int cmd_words = sizeof(idev->dev_cmd->data) / 86*669c8de6SAlfredo Cardigliano sizeof(idev->dev_cmd->data[0]); 87*669c8de6SAlfredo Cardigliano unsigned int nwords; 88*669c8de6SAlfredo Cardigliano 89*669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC, 90*669c8de6SAlfredo Cardigliano IONIC_IDENTITY_VERSION_1); 91*669c8de6SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT); 92*669c8de6SAlfredo Cardigliano if (err) 93*669c8de6SAlfredo Cardigliano return (err); 94*669c8de6SAlfredo Cardigliano 95*669c8de6SAlfredo Cardigliano nwords = RTE_MIN(lif_words, cmd_words); 96*669c8de6SAlfredo Cardigliano for (i = 0; i < nwords; i++) 97*669c8de6SAlfredo Cardigliano ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]); 98*669c8de6SAlfredo Cardigliano 99*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "capabilities 0x%" PRIx64 " ", 100*669c8de6SAlfredo Cardigliano ident->lif.capabilities); 101*669c8de6SAlfredo Cardigliano 102*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.max_ucast_filters 0x%" PRIx32 " ", 103*669c8de6SAlfredo Cardigliano ident->lif.eth.max_ucast_filters); 104*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.max_mcast_filters 0x%" PRIx32 " ", 105*669c8de6SAlfredo Cardigliano ident->lif.eth.max_mcast_filters); 106*669c8de6SAlfredo Cardigliano 107*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.features 0x%" PRIx64 " ", 108*669c8de6SAlfredo Cardigliano ident->lif.eth.config.features); 109*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%" PRIx32 " ", 110*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_ADMINQ]); 111*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%" PRIx32 " ", 112*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_NOTIFYQ]); 113*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%" PRIx32 " ", 114*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]); 115*669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%" PRIx32 " ", 116*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]); 117*669c8de6SAlfredo Cardigliano 118*669c8de6SAlfredo Cardigliano return 0; 119*669c8de6SAlfredo Cardigliano } 120*669c8de6SAlfredo Cardigliano 121*669c8de6SAlfredo Cardigliano int 122*669c8de6SAlfredo Cardigliano ionic_lifs_size(struct ionic_adapter *adapter) 123*669c8de6SAlfredo Cardigliano { 124*669c8de6SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident; 125*669c8de6SAlfredo Cardigliano uint32_t nlifs = ident->dev.nlifs; 126*669c8de6SAlfredo Cardigliano uint32_t nintrs, dev_nintrs = ident->dev.nintrs; 127*669c8de6SAlfredo Cardigliano 128*669c8de6SAlfredo Cardigliano adapter->max_ntxqs_per_lif = 129*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]; 130*669c8de6SAlfredo Cardigliano adapter->max_nrxqs_per_lif = 131*669c8de6SAlfredo Cardigliano ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]; 132*669c8de6SAlfredo Cardigliano 133*669c8de6SAlfredo Cardigliano nintrs = nlifs * 1 /* notifyq */; 134*669c8de6SAlfredo Cardigliano 135*669c8de6SAlfredo Cardigliano if (nintrs > dev_nintrs) { 136*669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "At most %d intr queues supported, minimum required is %u", 137*669c8de6SAlfredo Cardigliano dev_nintrs, nintrs); 138*669c8de6SAlfredo Cardigliano return -ENOSPC; 139*669c8de6SAlfredo Cardigliano } 140*669c8de6SAlfredo Cardigliano 141*669c8de6SAlfredo Cardigliano adapter->nintrs = nintrs; 142*669c8de6SAlfredo Cardigliano 143*669c8de6SAlfredo Cardigliano return 0; 144*669c8de6SAlfredo Cardigliano } 145