Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright (c) 2024 Corigine, Inc. 3 : : * All rights reserved. 4 : : */ 5 : : 6 : : #include "nfp_flower_service.h" 7 : : 8 : : #include <rte_spinlock.h> 9 : : 10 : : #include "nfp_flower_ctrl.h" 11 : : #include "../nfpcore/nfp_cpp.h" 12 : : #include "../nfpcore/nfp_sync.h" 13 : : #include "../nfp_logs.h" 14 : : #include "../nfp_service.h" 15 : : 16 : : /* Driver limitation, PMD can enlarge it if need. */ 17 : : #define MAX_FLOWER_SERVICE_SLOT 8 18 : : 19 : : struct nfp_flower_service { 20 : : /** Flower service is enabled */ 21 : : bool enabled; 22 : : /** Flower service info */ 23 : : struct nfp_service_info info; 24 : : /** Store flower cards' information */ 25 : : struct nfp_app_fw_flower *slots[MAX_FLOWER_SERVICE_SLOT]; 26 : : /** Spinlock for sync slots when add/remove card */ 27 : : rte_spinlock_t spinlock; 28 : : }; 29 : : 30 : : static struct nfp_flower_service * 31 : : nfp_flower_service_handle_get(struct nfp_app_fw_flower *app) 32 : : { 33 : 0 : return app->pf_hw->pf_dev->process_share.fl_service; 34 : : } 35 : : 36 : : static int 37 : 0 : nfp_flower_service_loop(void *arg) 38 : : { 39 : : uint16_t slot; 40 : : struct nfp_app_fw_flower *app; 41 : : struct nfp_flower_service *service_handle; 42 : : 43 : : service_handle = arg; 44 : : /* Waiting for enabling service */ 45 [ # # ]: 0 : while (!service_handle->enabled) 46 : : rte_delay_ms(1); 47 : : 48 [ # # ]: 0 : while (rte_service_runstate_get(service_handle->info.id) != 0) { 49 : 0 : rte_spinlock_lock(&service_handle->spinlock); 50 [ # # ]: 0 : for (slot = 0; slot < MAX_FLOWER_SERVICE_SLOT; slot++) { 51 : 0 : app = service_handle->slots[slot]; 52 [ # # ]: 0 : if (app == NULL) 53 : 0 : continue; 54 : : 55 : 0 : nfp_flower_ctrl_vnic_process(app); 56 : : } 57 : : rte_spinlock_unlock(&service_handle->spinlock); 58 : : } 59 : : 60 : 0 : return 0; 61 : : } 62 : : 63 : : static int 64 : 0 : nfp_flower_service_enable(struct nfp_flower_service *service_handle) 65 : : { 66 : : int ret; 67 : : 68 : 0 : const struct rte_service_spec flower_service = { 69 : : .name = "flower_ctrl_vnic_service", 70 : : .callback = nfp_flower_service_loop, 71 : : .callback_userdata = (void *)service_handle, 72 : : }; 73 : : 74 : 0 : ret = nfp_service_enable(&flower_service, &service_handle->info); 75 [ # # ]: 0 : if (ret != 0) 76 : : return ret; 77 : : 78 : : rte_spinlock_init(&service_handle->spinlock); 79 : 0 : service_handle->enabled = true; 80 : : 81 : 0 : return 0; 82 : : } 83 : : 84 : : static uint16_t 85 : 0 : nfp_flower_service_insert(struct nfp_app_fw_flower *app, 86 : : struct nfp_flower_service *service_handle) 87 : : { 88 : : uint16_t slot; 89 : : 90 : 0 : rte_spinlock_lock(&service_handle->spinlock); 91 [ # # ]: 0 : for (slot = 0; slot < MAX_FLOWER_SERVICE_SLOT; slot++) { 92 [ # # ]: 0 : if (service_handle->slots[slot] == NULL) { 93 : 0 : service_handle->slots[slot] = app; 94 : 0 : break; 95 : : } 96 : : } 97 : : rte_spinlock_unlock(&service_handle->spinlock); 98 : : 99 : 0 : return slot; 100 : : } 101 : : 102 : : int 103 : 0 : nfp_flower_service_start(void *app_fw_flower) 104 : : { 105 : : int ret; 106 : : struct nfp_flower_service *service_handle; 107 : : struct nfp_app_fw_flower *app = app_fw_flower; 108 : : 109 : : service_handle = nfp_flower_service_handle_get(app); 110 [ # # ]: 0 : if (service_handle == NULL) { 111 : 0 : PMD_DRV_LOG(ERR, "Can not get service handle"); 112 : 0 : return -EINVAL; 113 : : } 114 : : 115 : : /* Enable flower service when driver initializes the first NIC */ 116 [ # # ]: 0 : if (!service_handle->enabled) { 117 : 0 : ret = nfp_flower_service_enable(service_handle); 118 [ # # ]: 0 : if (ret != 0) { 119 : 0 : PMD_DRV_LOG(ERR, "Could not enable flower service"); 120 : 0 : return -ESRCH; 121 : : } 122 : : } 123 : : 124 : : /* Insert the NIC to flower service slot */ 125 : 0 : ret = nfp_flower_service_insert(app, service_handle); 126 [ # # ]: 0 : if (ret == MAX_FLOWER_SERVICE_SLOT) { 127 : 0 : PMD_DRV_LOG(ERR, "Flower ctrl vnic service slot over %u", 128 : : MAX_FLOWER_SERVICE_SLOT); 129 : 0 : return -ENOSPC; 130 : : } 131 : : 132 : : return 0; 133 : : } 134 : : 135 : : void 136 : 0 : nfp_flower_service_stop(void *app_fw_flower) 137 : : { 138 : : uint16_t slot; 139 : : uint16_t count; 140 : : struct nfp_flower_service *service_handle; 141 : : struct nfp_app_fw_flower *app = app_fw_flower; 142 : : 143 : : service_handle = nfp_flower_service_handle_get(app); 144 [ # # ]: 0 : if (service_handle == NULL) { 145 : 0 : PMD_DRV_LOG(ERR, "Can not get service handle"); 146 : 0 : return; 147 : : } 148 : : 149 : 0 : rte_spinlock_lock(&service_handle->spinlock); 150 [ # # ]: 0 : for (slot = 0; slot < MAX_FLOWER_SERVICE_SLOT; slot++) { 151 : : /* The app only in one slot */ 152 [ # # ]: 0 : if (service_handle->slots[slot] != app) 153 : 0 : continue; 154 : : 155 : 0 : service_handle->slots[slot] = NULL; 156 : : } 157 : : rte_spinlock_unlock(&service_handle->spinlock); 158 : : 159 : : /* Determine whether to disable service */ 160 : 0 : count = nfp_sync_handle_count_get(app->pf_hw->pf_dev->sync, NULL, 161 : : service_handle); 162 [ # # ]: 0 : if (count > 1) 163 : : return; 164 : : 165 [ # # ]: 0 : if (nfp_service_disable(&service_handle->info) != 0) 166 : 0 : PMD_DRV_LOG(ERR, "Could not disable service"); 167 : : } 168 : : 169 : : int 170 : 0 : nfp_flower_service_sync_alloc(void *app_fw_flower) 171 : : { 172 : : struct nfp_flower_service *service_handle; 173 : : struct nfp_app_fw_flower *app = app_fw_flower; 174 : 0 : struct nfp_pf_dev *pf_dev = app->pf_hw->pf_dev; 175 : : 176 : 0 : service_handle = nfp_sync_handle_alloc(pf_dev->sync, NULL, 177 : : NFP_SYNC_MAGIC_FL_SERVICE, 178 : : sizeof(struct nfp_flower_service)); 179 [ # # ]: 0 : if (service_handle == NULL) 180 : : return -ENOMEM; 181 : : 182 : 0 : pf_dev->process_share.fl_service = service_handle; 183 : : 184 : 0 : return 0; 185 : : } 186 : : 187 : : void 188 : 0 : nfp_flower_service_sync_free(void *app_fw_flower) 189 : : { 190 : : struct nfp_app_fw_flower *app = app_fw_flower; 191 : 0 : struct nfp_pf_dev *pf_dev = app->pf_hw->pf_dev; 192 : : 193 : 0 : nfp_sync_handle_free(pf_dev->sync, NULL, pf_dev->process_share.fl_service); 194 : : 195 : 0 : pf_dev->process_share.fl_service = NULL; 196 : 0 : }