1c7e9729dSAlejandro Lucero /* SPDX-License-Identifier: BSD-3-Clause 2c7e9729dSAlejandro Lucero * Copyright(c) 2018 Netronome Systems, Inc. 3c7e9729dSAlejandro Lucero * All rights reserved. 4c7e9729dSAlejandro Lucero */ 5c7e9729dSAlejandro Lucero 6c7e9729dSAlejandro Lucero /* 7c7e9729dSAlejandro Lucero * nfp_rtsym.c 8c7e9729dSAlejandro Lucero * Interface for accessing run-time symbol table 9c7e9729dSAlejandro Lucero */ 10c7e9729dSAlejandro Lucero 119641a2d3SChaoyong He #include "nfp_rtsym.h" 129641a2d3SChaoyong He 13c7e9729dSAlejandro Lucero #include <rte_byteorder.h> 149641a2d3SChaoyong He 1552d810dcSJames Hershaw #include "nfp_logs.h" 16c7e9729dSAlejandro Lucero #include "nfp_mip.h" 17055ccb33SChaoyong He #include "nfp_target.h" 18c7e9729dSAlejandro Lucero #include "nfp6000/nfp6000.h" 19c7e9729dSAlejandro Lucero 209641a2d3SChaoyong He enum nfp_rtsym_type { 219641a2d3SChaoyong He NFP_RTSYM_TYPE_NONE, 229641a2d3SChaoyong He NFP_RTSYM_TYPE_OBJECT, 239641a2d3SChaoyong He NFP_RTSYM_TYPE_FUNCTION, 249641a2d3SChaoyong He NFP_RTSYM_TYPE_ABS, 259641a2d3SChaoyong He }; 269641a2d3SChaoyong He 279641a2d3SChaoyong He #define NFP_RTSYM_TARGET_NONE 0 289641a2d3SChaoyong He #define NFP_RTSYM_TARGET_LMEM -1 299641a2d3SChaoyong He #define NFP_RTSYM_TARGET_EMU_CACHE -7 309641a2d3SChaoyong He 31c7e9729dSAlejandro Lucero /* These need to match the linker */ 32c7e9729dSAlejandro Lucero #define SYM_TGT_LMEM 0 33c7e9729dSAlejandro Lucero #define SYM_TGT_EMU_CACHE 0x17 34c7e9729dSAlejandro Lucero 35c7e9729dSAlejandro Lucero struct nfp_rtsym_entry { 36c7e9729dSAlejandro Lucero uint8_t type; 37c7e9729dSAlejandro Lucero uint8_t target; 38c7e9729dSAlejandro Lucero uint8_t island; 39c7e9729dSAlejandro Lucero uint8_t addr_hi; 40c7e9729dSAlejandro Lucero uint32_t addr_lo; 41c7e9729dSAlejandro Lucero uint16_t name; 42c7e9729dSAlejandro Lucero uint8_t menum; 43c7e9729dSAlejandro Lucero uint8_t size_hi; 44c7e9729dSAlejandro Lucero uint32_t size_lo; 45c7e9729dSAlejandro Lucero }; 46c7e9729dSAlejandro Lucero 479641a2d3SChaoyong He /* 489641a2d3SChaoyong He * Structure describing a run-time NFP symbol. 499641a2d3SChaoyong He * 509641a2d3SChaoyong He * The memory target of the symbol is generally the CPP target number and can be 519641a2d3SChaoyong He * used directly by the nfp_cpp API calls. However, in some cases (i.e., for 529641a2d3SChaoyong He * local memory or control store) the target is encoded using a negative number. 539641a2d3SChaoyong He * 549641a2d3SChaoyong He * When the target type can not be used to fully describe the location of a 559641a2d3SChaoyong He * symbol the domain field is used to further specify the location (i.e., the 569641a2d3SChaoyong He * specific ME or island number). 579641a2d3SChaoyong He * 589641a2d3SChaoyong He * For ME target resources, 'domain' is an MEID. 599641a2d3SChaoyong He * For Island target resources, 'domain' is an island ID, with the one exception 609641a2d3SChaoyong He * of "sram" symbols for backward compatibility, which are viewed as global. 619641a2d3SChaoyong He */ 629641a2d3SChaoyong He struct nfp_rtsym { 639641a2d3SChaoyong He const char *name; /**< Symbol name */ 649641a2d3SChaoyong He uint64_t addr; /**< Address in the domain/target's address space */ 659641a2d3SChaoyong He uint64_t size; /**< Size (in bytes) of the symbol */ 669641a2d3SChaoyong He enum nfp_rtsym_type type; /**< NFP_RTSYM_TYPE_* of the symbol */ 679641a2d3SChaoyong He int target; /**< CPP target identifier, or NFP_RTSYM_TARGET_* */ 689641a2d3SChaoyong He int domain; /**< CPP target domain */ 699641a2d3SChaoyong He }; 709641a2d3SChaoyong He 71c7e9729dSAlejandro Lucero struct nfp_rtsym_table { 72c7e9729dSAlejandro Lucero struct nfp_cpp *cpp; 73c7e9729dSAlejandro Lucero int num; 74c7e9729dSAlejandro Lucero char *strtab; 75c7e9729dSAlejandro Lucero struct nfp_rtsym symtab[]; 76c7e9729dSAlejandro Lucero }; 77c7e9729dSAlejandro Lucero 78c7e9729dSAlejandro Lucero static int 79d108b9e9SChaoyong He nfp_meid(uint8_t island_id, 80d108b9e9SChaoyong He uint8_t menum) 81c7e9729dSAlejandro Lucero { 82c7e9729dSAlejandro Lucero return (island_id & 0x3F) == island_id && menum < 12 ? 83c7e9729dSAlejandro Lucero (island_id << 4) | (menum + 4) : -1; 84c7e9729dSAlejandro Lucero } 85c7e9729dSAlejandro Lucero 86c7e9729dSAlejandro Lucero static void 87d108b9e9SChaoyong He nfp_rtsym_sw_entry_init(struct nfp_rtsym_table *cache, 88d108b9e9SChaoyong He uint32_t strtab_size, 89d108b9e9SChaoyong He struct nfp_rtsym *sw, 90d108b9e9SChaoyong He struct nfp_rtsym_entry *fw) 91c7e9729dSAlejandro Lucero { 92c7e9729dSAlejandro Lucero sw->type = fw->type; 93c7e9729dSAlejandro Lucero sw->name = cache->strtab + rte_le_to_cpu_16(fw->name) % strtab_size; 94c7e9729dSAlejandro Lucero sw->addr = ((uint64_t)fw->addr_hi << 32) | 95c7e9729dSAlejandro Lucero rte_le_to_cpu_32(fw->addr_lo); 96c7e9729dSAlejandro Lucero sw->size = ((uint64_t)fw->size_hi << 32) | 97c7e9729dSAlejandro Lucero rte_le_to_cpu_32(fw->size_lo); 98c7e9729dSAlejandro Lucero 99c7e9729dSAlejandro Lucero switch (fw->target) { 100c7e9729dSAlejandro Lucero case SYM_TGT_LMEM: 101c7e9729dSAlejandro Lucero sw->target = NFP_RTSYM_TARGET_LMEM; 102c7e9729dSAlejandro Lucero break; 103c7e9729dSAlejandro Lucero case SYM_TGT_EMU_CACHE: 104c7e9729dSAlejandro Lucero sw->target = NFP_RTSYM_TARGET_EMU_CACHE; 105c7e9729dSAlejandro Lucero break; 106c7e9729dSAlejandro Lucero default: 107c7e9729dSAlejandro Lucero sw->target = fw->target; 108c7e9729dSAlejandro Lucero break; 109c7e9729dSAlejandro Lucero } 110c7e9729dSAlejandro Lucero 111c7e9729dSAlejandro Lucero if (fw->menum != 0xff) 112c7e9729dSAlejandro Lucero sw->domain = nfp_meid(fw->island, fw->menum); 113c7e9729dSAlejandro Lucero else if (fw->island != 0xff) 114c7e9729dSAlejandro Lucero sw->domain = fw->island; 115c7e9729dSAlejandro Lucero else 116c7e9729dSAlejandro Lucero sw->domain = -1; 117c7e9729dSAlejandro Lucero } 118c7e9729dSAlejandro Lucero 1199641a2d3SChaoyong He static struct nfp_rtsym_table * 1209641a2d3SChaoyong He nfp_rtsym_table_read_real(struct nfp_cpp *cpp, 121d108b9e9SChaoyong He const struct nfp_mip *mip) 122c7e9729dSAlejandro Lucero { 123610bf14bSChaoyong He int n; 124610bf14bSChaoyong He int err; 125610bf14bSChaoyong He uint32_t size; 126610bf14bSChaoyong He uint32_t strtab_addr; 127610bf14bSChaoyong He uint32_t symtab_addr; 128610bf14bSChaoyong He uint32_t strtab_size; 129610bf14bSChaoyong He uint32_t symtab_size; 130c7e9729dSAlejandro Lucero struct nfp_rtsym_table *cache; 131610bf14bSChaoyong He struct nfp_rtsym_entry *rtsymtab; 132c7e9729dSAlejandro Lucero const uint32_t dram = 133c7e9729dSAlejandro Lucero NFP_CPP_ID(NFP_CPP_TARGET_MU, NFP_CPP_ACTION_RW, 0) | 134c7e9729dSAlejandro Lucero NFP_ISL_EMEM0; 135c7e9729dSAlejandro Lucero 136cbcbfd73SJames Hershaw if (mip == NULL) 137c7e9729dSAlejandro Lucero return NULL; 138c7e9729dSAlejandro Lucero 139c7e9729dSAlejandro Lucero nfp_mip_strtab(mip, &strtab_addr, &strtab_size); 140c7e9729dSAlejandro Lucero nfp_mip_symtab(mip, &symtab_addr, &symtab_size); 141c7e9729dSAlejandro Lucero 142cbcbfd73SJames Hershaw if (symtab_size == 0 || strtab_size == 0 || symtab_size % sizeof(*rtsymtab) != 0) 143c7e9729dSAlejandro Lucero return NULL; 144c7e9729dSAlejandro Lucero 145c7e9729dSAlejandro Lucero /* Align to 64 bits */ 1465481d3a8SChaoyong He symtab_size = RTE_ALIGN_CEIL(symtab_size, 8); 1475481d3a8SChaoyong He strtab_size = RTE_ALIGN_CEIL(strtab_size, 8); 148c7e9729dSAlejandro Lucero 149c7e9729dSAlejandro Lucero rtsymtab = malloc(symtab_size); 150cbcbfd73SJames Hershaw if (rtsymtab == NULL) 151c7e9729dSAlejandro Lucero return NULL; 152c7e9729dSAlejandro Lucero 153c7e9729dSAlejandro Lucero size = sizeof(*cache); 154c7e9729dSAlejandro Lucero size += symtab_size / sizeof(*rtsymtab) * sizeof(struct nfp_rtsym); 155c7e9729dSAlejandro Lucero size += strtab_size + 1; 156c7e9729dSAlejandro Lucero cache = malloc(size); 157cbcbfd73SJames Hershaw if (cache == NULL) 158c7e9729dSAlejandro Lucero goto exit_free_rtsym_raw; 159c7e9729dSAlejandro Lucero 160c7e9729dSAlejandro Lucero cache->cpp = cpp; 161c7e9729dSAlejandro Lucero cache->num = symtab_size / sizeof(*rtsymtab); 162c7e9729dSAlejandro Lucero cache->strtab = (void *)&cache->symtab[cache->num]; 163c7e9729dSAlejandro Lucero 164c7e9729dSAlejandro Lucero err = nfp_cpp_read(cpp, dram, symtab_addr, rtsymtab, symtab_size); 165c7e9729dSAlejandro Lucero if (err != (int)symtab_size) 166c7e9729dSAlejandro Lucero goto exit_free_cache; 167c7e9729dSAlejandro Lucero 168c7e9729dSAlejandro Lucero err = nfp_cpp_read(cpp, dram, strtab_addr, cache->strtab, strtab_size); 169c7e9729dSAlejandro Lucero if (err != (int)strtab_size) 170c7e9729dSAlejandro Lucero goto exit_free_cache; 171c7e9729dSAlejandro Lucero cache->strtab[strtab_size] = '\0'; 172c7e9729dSAlejandro Lucero 173c7e9729dSAlejandro Lucero for (n = 0; n < cache->num; n++) 174c7e9729dSAlejandro Lucero nfp_rtsym_sw_entry_init(cache, strtab_size, 175c7e9729dSAlejandro Lucero &cache->symtab[n], &rtsymtab[n]); 176c7e9729dSAlejandro Lucero 177c7e9729dSAlejandro Lucero free(rtsymtab); 178c7e9729dSAlejandro Lucero 179c7e9729dSAlejandro Lucero return cache; 180c7e9729dSAlejandro Lucero 181c7e9729dSAlejandro Lucero exit_free_cache: 182c7e9729dSAlejandro Lucero free(cache); 183c7e9729dSAlejandro Lucero exit_free_rtsym_raw: 184c7e9729dSAlejandro Lucero free(rtsymtab); 185c7e9729dSAlejandro Lucero return NULL; 186c7e9729dSAlejandro Lucero } 187c7e9729dSAlejandro Lucero 1889641a2d3SChaoyong He struct nfp_rtsym_table * 1899641a2d3SChaoyong He nfp_rtsym_table_read(struct nfp_cpp *cpp) 1909641a2d3SChaoyong He { 1919641a2d3SChaoyong He struct nfp_mip *mip; 1929641a2d3SChaoyong He struct nfp_rtsym_table *rtbl; 1939641a2d3SChaoyong He 1949641a2d3SChaoyong He mip = nfp_mip_open(cpp); 1959641a2d3SChaoyong He rtbl = nfp_rtsym_table_read_real(cpp, mip); 1969641a2d3SChaoyong He nfp_mip_close(mip); 1979641a2d3SChaoyong He 1989641a2d3SChaoyong He return rtbl; 1999641a2d3SChaoyong He } 2009641a2d3SChaoyong He 2016d03aa61SChaoyong He /** 2026d03aa61SChaoyong He * Get the number of RTSYM descriptors 203c7e9729dSAlejandro Lucero * 2046d03aa61SChaoyong He * @param rtbl 2056d03aa61SChaoyong He * NFP RTSYM table 2066d03aa61SChaoyong He * 2076d03aa61SChaoyong He * @return 2086d03aa61SChaoyong He * Number of RTSYM descriptors 209c7e9729dSAlejandro Lucero */ 210c7e9729dSAlejandro Lucero int 211c7e9729dSAlejandro Lucero nfp_rtsym_count(struct nfp_rtsym_table *rtbl) 212c7e9729dSAlejandro Lucero { 213cbcbfd73SJames Hershaw if (rtbl == NULL) 214c7e9729dSAlejandro Lucero return -EINVAL; 215c7e9729dSAlejandro Lucero 216c7e9729dSAlejandro Lucero return rtbl->num; 217c7e9729dSAlejandro Lucero } 218c7e9729dSAlejandro Lucero 2196d03aa61SChaoyong He /** 2206d03aa61SChaoyong He * Get the Nth RTSYM descriptor 221c7e9729dSAlejandro Lucero * 2226d03aa61SChaoyong He * @param rtbl 2236d03aa61SChaoyong He * NFP RTSYM table 2246d03aa61SChaoyong He * @param idx 2256d03aa61SChaoyong He * Index (0-based) of the RTSYM descriptor 2266d03aa61SChaoyong He * 2276d03aa61SChaoyong He * @return 2286d03aa61SChaoyong He * Const pointer to a struct nfp_rtsym descriptor, or NULL 229c7e9729dSAlejandro Lucero */ 230c7e9729dSAlejandro Lucero const struct nfp_rtsym * 231d108b9e9SChaoyong He nfp_rtsym_get(struct nfp_rtsym_table *rtbl, 232d108b9e9SChaoyong He int idx) 233c7e9729dSAlejandro Lucero { 234cbcbfd73SJames Hershaw if (rtbl == NULL) 235c7e9729dSAlejandro Lucero return NULL; 236c7e9729dSAlejandro Lucero 237c7e9729dSAlejandro Lucero if (idx >= rtbl->num) 238c7e9729dSAlejandro Lucero return NULL; 239c7e9729dSAlejandro Lucero 240c7e9729dSAlejandro Lucero return &rtbl->symtab[idx]; 241c7e9729dSAlejandro Lucero } 242c7e9729dSAlejandro Lucero 2436d03aa61SChaoyong He /** 2446d03aa61SChaoyong He * Return the RTSYM descriptor for a symbol name 245c7e9729dSAlejandro Lucero * 2466d03aa61SChaoyong He * @param rtbl 2476d03aa61SChaoyong He * NFP RTSYM table 2486d03aa61SChaoyong He * @param name 2496d03aa61SChaoyong He * Symbol name 2506d03aa61SChaoyong He * 2516d03aa61SChaoyong He * @return 2526d03aa61SChaoyong He * Const pointer to a struct nfp_rtsym descriptor, or NULL 253c7e9729dSAlejandro Lucero */ 254c7e9729dSAlejandro Lucero const struct nfp_rtsym * 255d108b9e9SChaoyong He nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, 256d108b9e9SChaoyong He const char *name) 257c7e9729dSAlejandro Lucero { 258c7e9729dSAlejandro Lucero int n; 259c7e9729dSAlejandro Lucero 260cbcbfd73SJames Hershaw if (rtbl == NULL) 261c7e9729dSAlejandro Lucero return NULL; 262c7e9729dSAlejandro Lucero 263c7e9729dSAlejandro Lucero for (n = 0; n < rtbl->num; n++) 264c7e9729dSAlejandro Lucero if (strcmp(name, rtbl->symtab[n].name) == 0) 265c7e9729dSAlejandro Lucero return &rtbl->symtab[n]; 266c7e9729dSAlejandro Lucero 267c7e9729dSAlejandro Lucero return NULL; 268c7e9729dSAlejandro Lucero } 269c7e9729dSAlejandro Lucero 270925c27ecSChaoyong He static uint64_t 271925c27ecSChaoyong He nfp_rtsym_size(const struct nfp_rtsym *sym) 272925c27ecSChaoyong He { 273925c27ecSChaoyong He switch (sym->type) { 274925c27ecSChaoyong He case NFP_RTSYM_TYPE_NONE: 275*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "The type of rtsym '%s' is NONE.", sym->name); 276925c27ecSChaoyong He return 0; 2776d03aa61SChaoyong He case NFP_RTSYM_TYPE_OBJECT: 2786d03aa61SChaoyong He /* FALLTHROUGH */ 279925c27ecSChaoyong He case NFP_RTSYM_TYPE_FUNCTION: 280925c27ecSChaoyong He return sym->size; 281925c27ecSChaoyong He case NFP_RTSYM_TYPE_ABS: 282925c27ecSChaoyong He return sizeof(uint64_t); 283925c27ecSChaoyong He default: 284*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Unknown RTSYM type %u.", sym->type); 285925c27ecSChaoyong He return 0; 286925c27ecSChaoyong He } 287925c27ecSChaoyong He } 288925c27ecSChaoyong He 289925c27ecSChaoyong He static int 290925c27ecSChaoyong He nfp_rtsym_to_dest(struct nfp_cpp *cpp, 291925c27ecSChaoyong He const struct nfp_rtsym *sym, 292925c27ecSChaoyong He uint8_t action, 293925c27ecSChaoyong He uint8_t token, 294925c27ecSChaoyong He uint64_t offset, 295925c27ecSChaoyong He uint32_t *cpp_id, 296925c27ecSChaoyong He uint64_t *addr) 297925c27ecSChaoyong He { 298925c27ecSChaoyong He if (sym->type != NFP_RTSYM_TYPE_OBJECT) { 299*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s': direct access to non-object rtsym.", 300925c27ecSChaoyong He sym->name); 301925c27ecSChaoyong He return -EINVAL; 302925c27ecSChaoyong He } 303925c27ecSChaoyong He 304925c27ecSChaoyong He *addr = sym->addr + offset; 305925c27ecSChaoyong He 306925c27ecSChaoyong He if (sym->target >= 0) { 307925c27ecSChaoyong He *cpp_id = NFP_CPP_ISLAND_ID(sym->target, action, token, sym->domain); 308925c27ecSChaoyong He } else if (sym->target == NFP_RTSYM_TARGET_EMU_CACHE) { 309925c27ecSChaoyong He int locality_off = nfp_cpp_mu_locality_lsb(cpp); 310925c27ecSChaoyong He 311925c27ecSChaoyong He *addr &= ~(NFP_MU_ADDR_ACCESS_TYPE_MASK << locality_off); 312925c27ecSChaoyong He *addr |= NFP_MU_ADDR_ACCESS_TYPE_DIRECT << locality_off; 313925c27ecSChaoyong He 314925c27ecSChaoyong He *cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU, action, token, 315925c27ecSChaoyong He sym->domain); 316925c27ecSChaoyong He } else { 317*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s': unhandled target encoding: %d.", 318925c27ecSChaoyong He sym->name, sym->target); 319925c27ecSChaoyong He return -EINVAL; 320925c27ecSChaoyong He } 321925c27ecSChaoyong He 322925c27ecSChaoyong He return 0; 323925c27ecSChaoyong He } 324925c27ecSChaoyong He 325925c27ecSChaoyong He static int 3269641a2d3SChaoyong He nfp_rtsym_read_real(struct nfp_cpp *cpp, 3279641a2d3SChaoyong He const struct nfp_rtsym *sym, 3289641a2d3SChaoyong He uint8_t action, 3299641a2d3SChaoyong He uint8_t token, 3309641a2d3SChaoyong He uint64_t offset, 3319641a2d3SChaoyong He void *buf, 3329641a2d3SChaoyong He size_t len) 3339641a2d3SChaoyong He { 3349641a2d3SChaoyong He int err; 3359641a2d3SChaoyong He uint64_t addr; 3369641a2d3SChaoyong He uint32_t cpp_id; 3379641a2d3SChaoyong He size_t length = len; 3389641a2d3SChaoyong He uint64_t sym_size = nfp_rtsym_size(sym); 3399641a2d3SChaoyong He 340322cb472SLong Wu if (offset >= sym_size) { 341*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' read out of bounds.", sym->name); 3429641a2d3SChaoyong He return -ENXIO; 3439641a2d3SChaoyong He } 3449641a2d3SChaoyong He 3459641a2d3SChaoyong He if (length > sym_size - offset) 3469641a2d3SChaoyong He length = sym_size - offset; 3479641a2d3SChaoyong He 3489641a2d3SChaoyong He if (sym->type == NFP_RTSYM_TYPE_ABS) { 3499641a2d3SChaoyong He union { 3509641a2d3SChaoyong He uint64_t value_64; 3519641a2d3SChaoyong He uint8_t value_8[8]; 3529641a2d3SChaoyong He } tmp; 3539641a2d3SChaoyong He 3549641a2d3SChaoyong He tmp.value_64 = sym->addr; 3559641a2d3SChaoyong He memcpy(buf, &tmp.value_8[offset], length); 3569641a2d3SChaoyong He 3579641a2d3SChaoyong He return length; 3589641a2d3SChaoyong He } 3599641a2d3SChaoyong He 3609641a2d3SChaoyong He err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 3619641a2d3SChaoyong He if (err != 0) 3629641a2d3SChaoyong He return err; 3639641a2d3SChaoyong He 3649641a2d3SChaoyong He return nfp_cpp_read(cpp, cpp_id, addr, buf, length); 3659641a2d3SChaoyong He } 3669641a2d3SChaoyong He 3679641a2d3SChaoyong He int 3689641a2d3SChaoyong He nfp_rtsym_read(struct nfp_cpp *cpp, 3699641a2d3SChaoyong He const struct nfp_rtsym *sym, 3709641a2d3SChaoyong He uint64_t offset, 3719641a2d3SChaoyong He void *buf, 3729641a2d3SChaoyong He size_t len) 3739641a2d3SChaoyong He { 3749641a2d3SChaoyong He return nfp_rtsym_read_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, buf, len); 3759641a2d3SChaoyong He } 3769641a2d3SChaoyong He 3779641a2d3SChaoyong He static int 3789641a2d3SChaoyong He nfp_rtsym_readl_real(struct nfp_cpp *cpp, 379925c27ecSChaoyong He const struct nfp_rtsym *sym, 380925c27ecSChaoyong He uint8_t action, 381925c27ecSChaoyong He uint8_t token, 382925c27ecSChaoyong He uint64_t offset, 383925c27ecSChaoyong He uint32_t *value) 384925c27ecSChaoyong He { 385925c27ecSChaoyong He int ret; 386925c27ecSChaoyong He uint64_t addr; 387925c27ecSChaoyong He uint32_t cpp_id; 388925c27ecSChaoyong He 389925c27ecSChaoyong He if (offset + 4 > nfp_rtsym_size(sym)) { 390*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s': readl out of bounds.", sym->name); 391925c27ecSChaoyong He return -ENXIO; 392925c27ecSChaoyong He } 393925c27ecSChaoyong He 394925c27ecSChaoyong He ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 395925c27ecSChaoyong He if (ret != 0) 396925c27ecSChaoyong He return ret; 397925c27ecSChaoyong He 398925c27ecSChaoyong He return nfp_cpp_readl(cpp, cpp_id, addr, value); 399925c27ecSChaoyong He } 400925c27ecSChaoyong He 4019641a2d3SChaoyong He int 4029641a2d3SChaoyong He nfp_rtsym_readl(struct nfp_cpp *cpp, 4039641a2d3SChaoyong He const struct nfp_rtsym *sym, 4049641a2d3SChaoyong He uint64_t offset, 4059641a2d3SChaoyong He uint32_t *value) 4069641a2d3SChaoyong He { 4079641a2d3SChaoyong He return nfp_rtsym_readl_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value); 4089641a2d3SChaoyong He } 4099641a2d3SChaoyong He 410925c27ecSChaoyong He static int 4119641a2d3SChaoyong He nfp_rtsym_readq_real(struct nfp_cpp *cpp, 412925c27ecSChaoyong He const struct nfp_rtsym *sym, 413925c27ecSChaoyong He uint8_t action, 414925c27ecSChaoyong He uint8_t token, 415925c27ecSChaoyong He uint64_t offset, 416925c27ecSChaoyong He uint64_t *value) 417925c27ecSChaoyong He { 418925c27ecSChaoyong He int ret; 419925c27ecSChaoyong He uint64_t addr; 420925c27ecSChaoyong He uint32_t cpp_id; 421925c27ecSChaoyong He 422925c27ecSChaoyong He if (offset + 8 > nfp_rtsym_size(sym)) { 423*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s': readq out of bounds.", sym->name); 424925c27ecSChaoyong He return -ENXIO; 425925c27ecSChaoyong He } 426925c27ecSChaoyong He 427925c27ecSChaoyong He if (sym->type == NFP_RTSYM_TYPE_ABS) { 428925c27ecSChaoyong He *value = sym->addr; 429925c27ecSChaoyong He return 0; 430925c27ecSChaoyong He } 431925c27ecSChaoyong He 432925c27ecSChaoyong He ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 433925c27ecSChaoyong He if (ret != 0) 434925c27ecSChaoyong He return ret; 435925c27ecSChaoyong He 436925c27ecSChaoyong He return nfp_cpp_readq(cpp, cpp_id, addr, value); 437925c27ecSChaoyong He } 438925c27ecSChaoyong He 4399641a2d3SChaoyong He int 4409641a2d3SChaoyong He nfp_rtsym_readq(struct nfp_cpp *cpp, 4419641a2d3SChaoyong He const struct nfp_rtsym *sym, 4429641a2d3SChaoyong He uint64_t offset, 4439641a2d3SChaoyong He uint64_t *value) 4449641a2d3SChaoyong He { 4459641a2d3SChaoyong He return nfp_rtsym_readq_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value); 4469641a2d3SChaoyong He } 4479641a2d3SChaoyong He 4489641a2d3SChaoyong He static int 4499641a2d3SChaoyong He nfp_rtsym_write_real(struct nfp_cpp *cpp, 4509641a2d3SChaoyong He const struct nfp_rtsym *sym, 4519641a2d3SChaoyong He uint8_t action, 4529641a2d3SChaoyong He uint8_t token, 4539641a2d3SChaoyong He uint64_t offset, 4549641a2d3SChaoyong He void *buf, 4559641a2d3SChaoyong He size_t len) 4569641a2d3SChaoyong He { 4579641a2d3SChaoyong He int err; 4589641a2d3SChaoyong He uint64_t addr; 4599641a2d3SChaoyong He uint32_t cpp_id; 4609641a2d3SChaoyong He size_t length = len; 4619641a2d3SChaoyong He uint64_t sym_size = nfp_rtsym_size(sym); 4629641a2d3SChaoyong He 4639641a2d3SChaoyong He if (offset > sym_size) { 464*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' write out of bounds.", sym->name); 4659641a2d3SChaoyong He return -ENXIO; 4669641a2d3SChaoyong He } 4679641a2d3SChaoyong He 4689641a2d3SChaoyong He if (length > sym_size - offset) 4699641a2d3SChaoyong He length = sym_size - offset; 4709641a2d3SChaoyong He 4719641a2d3SChaoyong He err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 4729641a2d3SChaoyong He if (err != 0) 4739641a2d3SChaoyong He return err; 4749641a2d3SChaoyong He 4759641a2d3SChaoyong He return nfp_cpp_write(cpp, cpp_id, addr, buf, length); 4769641a2d3SChaoyong He } 4779641a2d3SChaoyong He 4789641a2d3SChaoyong He int 4799641a2d3SChaoyong He nfp_rtsym_write(struct nfp_cpp *cpp, 4809641a2d3SChaoyong He const struct nfp_rtsym *sym, 4819641a2d3SChaoyong He uint64_t offset, 4829641a2d3SChaoyong He void *buf, 4839641a2d3SChaoyong He size_t len) 4849641a2d3SChaoyong He { 4859641a2d3SChaoyong He return nfp_rtsym_write_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, buf, len); 4869641a2d3SChaoyong He } 4879641a2d3SChaoyong He 4889641a2d3SChaoyong He static int 4899641a2d3SChaoyong He nfp_rtsym_writel_real(struct nfp_cpp *cpp, 4909641a2d3SChaoyong He const struct nfp_rtsym *sym, 4919641a2d3SChaoyong He uint8_t action, 4929641a2d3SChaoyong He uint8_t token, 4939641a2d3SChaoyong He uint64_t offset, 4949641a2d3SChaoyong He uint32_t value) 4959641a2d3SChaoyong He { 4969641a2d3SChaoyong He int err; 4979641a2d3SChaoyong He uint64_t addr; 4989641a2d3SChaoyong He uint32_t cpp_id; 4999641a2d3SChaoyong He 5009641a2d3SChaoyong He if (offset + 4 > nfp_rtsym_size(sym)) { 501*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' write out of bounds.", sym->name); 5029641a2d3SChaoyong He return -ENXIO; 5039641a2d3SChaoyong He } 5049641a2d3SChaoyong He 5059641a2d3SChaoyong He err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 5069641a2d3SChaoyong He if (err != 0) 5079641a2d3SChaoyong He return err; 5089641a2d3SChaoyong He 5099641a2d3SChaoyong He return nfp_cpp_writel(cpp, cpp_id, addr, value); 5109641a2d3SChaoyong He } 5119641a2d3SChaoyong He 5129641a2d3SChaoyong He int 5139641a2d3SChaoyong He nfp_rtsym_writel(struct nfp_cpp *cpp, 5149641a2d3SChaoyong He const struct nfp_rtsym *sym, 5159641a2d3SChaoyong He uint64_t offset, 5169641a2d3SChaoyong He uint32_t value) 5179641a2d3SChaoyong He { 5189641a2d3SChaoyong He return nfp_rtsym_writel_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value); 5199641a2d3SChaoyong He } 5209641a2d3SChaoyong He 5219641a2d3SChaoyong He static int 5229641a2d3SChaoyong He nfp_rtsym_writeq_real(struct nfp_cpp *cpp, 5239641a2d3SChaoyong He const struct nfp_rtsym *sym, 5249641a2d3SChaoyong He uint8_t action, 5259641a2d3SChaoyong He uint8_t token, 5269641a2d3SChaoyong He uint64_t offset, 5279641a2d3SChaoyong He uint64_t value) 5289641a2d3SChaoyong He { 5299641a2d3SChaoyong He int err; 5309641a2d3SChaoyong He uint64_t addr; 5319641a2d3SChaoyong He uint32_t cpp_id; 5329641a2d3SChaoyong He 5339641a2d3SChaoyong He if (offset + 8 > nfp_rtsym_size(sym)) { 534*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' write out of bounds.", sym->name); 5359641a2d3SChaoyong He return -ENXIO; 5369641a2d3SChaoyong He } 5379641a2d3SChaoyong He 5389641a2d3SChaoyong He err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr); 5399641a2d3SChaoyong He if (err != 0) 5409641a2d3SChaoyong He return err; 5419641a2d3SChaoyong He 5429641a2d3SChaoyong He return nfp_cpp_writeq(cpp, cpp_id, addr, value); 5439641a2d3SChaoyong He } 5449641a2d3SChaoyong He 5459641a2d3SChaoyong He int 5469641a2d3SChaoyong He nfp_rtsym_writeq(struct nfp_cpp *cpp, 5479641a2d3SChaoyong He const struct nfp_rtsym *sym, 5489641a2d3SChaoyong He uint64_t offset, 5499641a2d3SChaoyong He uint64_t value) 5509641a2d3SChaoyong He { 5519641a2d3SChaoyong He return nfp_rtsym_writeq_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value); 5529641a2d3SChaoyong He } 5539641a2d3SChaoyong He 5546d03aa61SChaoyong He /** 5556d03aa61SChaoyong He * Read a simple unsigned scalar value from symbol 556c7e9729dSAlejandro Lucero * 557c7e9729dSAlejandro Lucero * Lookup a symbol, map, read it and return it's value. Value of the symbol 558c7e9729dSAlejandro Lucero * will be interpreted as a simple little-endian unsigned value. Symbol can 559c7e9729dSAlejandro Lucero * be 4 or 8 bytes in size. 560c7e9729dSAlejandro Lucero * 5616d03aa61SChaoyong He * @param rtbl 5626d03aa61SChaoyong He * NFP RTSYM table 5636d03aa61SChaoyong He * @param name 5646d03aa61SChaoyong He * Symbol name 5656d03aa61SChaoyong He * @param error 5666d03aa61SChaoyong He * Pointer to error code (optional) 5676d03aa61SChaoyong He * 5686d03aa61SChaoyong He * @return 5696d03aa61SChaoyong He * Value read, on error sets the error and returns ~0ULL. 570c7e9729dSAlejandro Lucero */ 571c7e9729dSAlejandro Lucero uint64_t 572d108b9e9SChaoyong He nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, 573d108b9e9SChaoyong He const char *name, 574d108b9e9SChaoyong He int *error) 575c7e9729dSAlejandro Lucero { 576c7e9729dSAlejandro Lucero int err; 577610bf14bSChaoyong He uint64_t val; 578610bf14bSChaoyong He uint32_t val32; 579610bf14bSChaoyong He const struct nfp_rtsym *sym; 580c7e9729dSAlejandro Lucero 581c7e9729dSAlejandro Lucero sym = nfp_rtsym_lookup(rtbl, name); 582cbcbfd73SJames Hershaw if (sym == NULL) { 583c7e9729dSAlejandro Lucero err = -ENOENT; 584c7e9729dSAlejandro Lucero goto exit; 585c7e9729dSAlejandro Lucero } 586c7e9729dSAlejandro Lucero 587c7e9729dSAlejandro Lucero switch (sym->size) { 588c7e9729dSAlejandro Lucero case 4: 5899641a2d3SChaoyong He err = nfp_rtsym_readl(rtbl->cpp, sym, 0, &val32); 590c7e9729dSAlejandro Lucero val = val32; 591c7e9729dSAlejandro Lucero break; 592c7e9729dSAlejandro Lucero case 8: 5939641a2d3SChaoyong He err = nfp_rtsym_readq(rtbl->cpp, sym, 0, &val); 594c7e9729dSAlejandro Lucero break; 595c7e9729dSAlejandro Lucero default: 596*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' unsupported size: %#lx.", 597c7e9729dSAlejandro Lucero name, sym->size); 598c7e9729dSAlejandro Lucero err = -EINVAL; 599c7e9729dSAlejandro Lucero break; 600c7e9729dSAlejandro Lucero } 601c7e9729dSAlejandro Lucero 602c7e9729dSAlejandro Lucero exit: 6034aa75cadSChaoyong He if (error != NULL) 604c7e9729dSAlejandro Lucero *error = err; 605c7e9729dSAlejandro Lucero 6064aa75cadSChaoyong He if (err != 0) 607c7e9729dSAlejandro Lucero return ~0ULL; 608c7e9729dSAlejandro Lucero 609c7e9729dSAlejandro Lucero return val; 610c7e9729dSAlejandro Lucero } 611c7e9729dSAlejandro Lucero 6129641a2d3SChaoyong He /** 6139641a2d3SChaoyong He * Write an unsigned scalar value to a symbol 6149641a2d3SChaoyong He * 6159641a2d3SChaoyong He * Lookup a symbol and write a value to it. Symbol can be 4 or 8 bytes in size. 6169641a2d3SChaoyong He * If 4 bytes then the lower 32-bits of 'value' are used. Value will be 6179641a2d3SChaoyong He * written as simple little-endian unsigned value. 6189641a2d3SChaoyong He * 6199641a2d3SChaoyong He * @param rtbl 6209641a2d3SChaoyong He * NFP RTSYM table 6219641a2d3SChaoyong He * @param name 6229641a2d3SChaoyong He * Symbol name 6239641a2d3SChaoyong He * @param value 6249641a2d3SChaoyong He * Value to write 6259641a2d3SChaoyong He * 6269641a2d3SChaoyong He * @return 6279641a2d3SChaoyong He * 0 on success or error code. 6289641a2d3SChaoyong He */ 6299641a2d3SChaoyong He int 6309641a2d3SChaoyong He nfp_rtsym_write_le(struct nfp_rtsym_table *rtbl, 6319641a2d3SChaoyong He const char *name, 6329641a2d3SChaoyong He uint64_t value) 6339641a2d3SChaoyong He { 6349641a2d3SChaoyong He int err; 6359641a2d3SChaoyong He uint64_t sym_size; 6369641a2d3SChaoyong He const struct nfp_rtsym *sym; 6379641a2d3SChaoyong He 6389641a2d3SChaoyong He sym = nfp_rtsym_lookup(rtbl, name); 6399641a2d3SChaoyong He if (sym == NULL) 6409641a2d3SChaoyong He return -ENOENT; 6419641a2d3SChaoyong He 6429641a2d3SChaoyong He sym_size = nfp_rtsym_size(sym); 6439641a2d3SChaoyong He switch (sym_size) { 6449641a2d3SChaoyong He case 4: 6459641a2d3SChaoyong He err = nfp_rtsym_writel(rtbl->cpp, sym, 0, value); 6469641a2d3SChaoyong He break; 6479641a2d3SChaoyong He case 8: 6489641a2d3SChaoyong He err = nfp_rtsym_writeq(rtbl->cpp, sym, 0, value); 6499641a2d3SChaoyong He break; 6509641a2d3SChaoyong He default: 651*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s' unsupported size: %#lx.", 6529641a2d3SChaoyong He name, sym_size); 6539641a2d3SChaoyong He err = -EINVAL; 6549641a2d3SChaoyong He break; 6559641a2d3SChaoyong He } 6569641a2d3SChaoyong He 6579641a2d3SChaoyong He return err; 6589641a2d3SChaoyong He } 6599641a2d3SChaoyong He 660c7e9729dSAlejandro Lucero uint8_t * 661f5df3ef4SPeng Zhang nfp_rtsym_map_offset(struct nfp_rtsym_table *rtbl, 662d108b9e9SChaoyong He const char *name, 663f5df3ef4SPeng Zhang uint32_t offset, 664c69debceSChaoyong He uint32_t min_size, 665d108b9e9SChaoyong He struct nfp_cpp_area **area) 666c7e9729dSAlejandro Lucero { 667925c27ecSChaoyong He int ret; 668c7e9729dSAlejandro Lucero uint8_t *mem; 669925c27ecSChaoyong He uint64_t addr; 670925c27ecSChaoyong He uint32_t cpp_id; 671925c27ecSChaoyong He const struct nfp_rtsym *sym; 672c7e9729dSAlejandro Lucero 673c7e9729dSAlejandro Lucero sym = nfp_rtsym_lookup(rtbl, name); 674cbcbfd73SJames Hershaw if (sym == NULL) { 675*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Symbol lookup fails for %s.", name); 676c7e9729dSAlejandro Lucero return NULL; 677c7e9729dSAlejandro Lucero } 678c7e9729dSAlejandro Lucero 679925c27ecSChaoyong He ret = nfp_rtsym_to_dest(rtbl->cpp, sym, NFP_CPP_ACTION_RW, 0, 0, 680925c27ecSChaoyong He &cpp_id, &addr); 681925c27ecSChaoyong He if (ret != 0) { 682*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "RTSYM '%s': mapping failed.", name); 683925c27ecSChaoyong He return NULL; 684925c27ecSChaoyong He } 685925c27ecSChaoyong He 686c7e9729dSAlejandro Lucero if (sym->size < min_size) { 687*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Symbol %s too small (%" PRIu64 " < %u).", name, 688c7e9729dSAlejandro Lucero sym->size, min_size); 689c7e9729dSAlejandro Lucero return NULL; 690c7e9729dSAlejandro Lucero } 691c7e9729dSAlejandro Lucero 692f5df3ef4SPeng Zhang mem = nfp_cpp_map_area(rtbl->cpp, cpp_id, addr + offset, sym->size, area); 693cbcbfd73SJames Hershaw if (mem == NULL) { 694*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Failed to map symbol %s.", name); 695c7e9729dSAlejandro Lucero return NULL; 696c7e9729dSAlejandro Lucero } 697c7e9729dSAlejandro Lucero 698c7e9729dSAlejandro Lucero return mem; 699c7e9729dSAlejandro Lucero } 700f5df3ef4SPeng Zhang 701f5df3ef4SPeng Zhang uint8_t * 702f5df3ef4SPeng Zhang nfp_rtsym_map(struct nfp_rtsym_table *rtbl, 703f5df3ef4SPeng Zhang const char *name, 704f5df3ef4SPeng Zhang uint32_t min_size, 705f5df3ef4SPeng Zhang struct nfp_cpp_area **area) 706f5df3ef4SPeng Zhang { 707f5df3ef4SPeng Zhang return nfp_rtsym_map_offset(rtbl, name, 0, min_size, area); 708f5df3ef4SPeng Zhang } 709987d6a8cSPeng Zhang 710987d6a8cSPeng Zhang /** 711987d6a8cSPeng Zhang * Pop a simple unsigned scalar value from ring 712987d6a8cSPeng Zhang * 713987d6a8cSPeng Zhang * Lookup the symbol table for ring base and address, then pop value base on 714987d6a8cSPeng Zhang * the ring with cpp read and write operation. 715987d6a8cSPeng Zhang * 716987d6a8cSPeng Zhang * @param rtbl 717987d6a8cSPeng Zhang * NFP run-time symbol table 718987d6a8cSPeng Zhang * @param aux_name 719987d6a8cSPeng Zhang * The auxiliary rtsym table name which can ensure ring base and address 720987d6a8cSPeng Zhang * @param name 721987d6a8cSPeng Zhang * The rtsym table name which can handle the ring 722987d6a8cSPeng Zhang * @param value 723987d6a8cSPeng Zhang * Pop this value from ring 724987d6a8cSPeng Zhang * 725987d6a8cSPeng Zhang * @return 726987d6a8cSPeng Zhang * 0 on success, negative errno otherwise. 727987d6a8cSPeng Zhang */ 728987d6a8cSPeng Zhang int 729987d6a8cSPeng Zhang nfp_rtsym_readl_indirect(struct nfp_rtsym_table *rtbl, 730987d6a8cSPeng Zhang const char *aux_name, 731987d6a8cSPeng Zhang const char *name, 732987d6a8cSPeng Zhang uint32_t *value) 733987d6a8cSPeng Zhang { 734987d6a8cSPeng Zhang int ret; 735987d6a8cSPeng Zhang uint32_t cpp_id; 736987d6a8cSPeng Zhang const struct nfp_rtsym *sym; 737987d6a8cSPeng Zhang const struct nfp_rtsym *aux_sym; 738987d6a8cSPeng Zhang 739987d6a8cSPeng Zhang if (value == NULL) 740987d6a8cSPeng Zhang return -EINVAL; 741987d6a8cSPeng Zhang 742987d6a8cSPeng Zhang aux_sym = nfp_rtsym_lookup(rtbl, aux_name); 743987d6a8cSPeng Zhang if (aux_sym == NULL) { 744*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Failed to find symbol %s.", aux_name); 745987d6a8cSPeng Zhang return -ENOENT; 746987d6a8cSPeng Zhang } 747987d6a8cSPeng Zhang 748987d6a8cSPeng Zhang sym = nfp_rtsym_lookup(rtbl, name); 749987d6a8cSPeng Zhang if (sym == NULL) { 750*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Failed to find symbol %s.", name); 751987d6a8cSPeng Zhang return -ENOENT; 752987d6a8cSPeng Zhang } 753987d6a8cSPeng Zhang 754987d6a8cSPeng Zhang /* Ring Pop */ 755987d6a8cSPeng Zhang cpp_id = NFP_CPP_ISLAND_ID(aux_sym->target, 22, 0, aux_sym->domain); 756987d6a8cSPeng Zhang ret = nfp_cpp_readl(rtbl->cpp, cpp_id, sym->addr, value); 757987d6a8cSPeng Zhang if (ret != 0) 758987d6a8cSPeng Zhang return -EIO; 759987d6a8cSPeng Zhang 760987d6a8cSPeng Zhang return 0; 761987d6a8cSPeng Zhang } 762987d6a8cSPeng Zhang 763987d6a8cSPeng Zhang /** 764987d6a8cSPeng Zhang * Push a simple unsigned scalar value to ring 765987d6a8cSPeng Zhang * 766987d6a8cSPeng Zhang * Lookup the symbol table for ring base and address, then Push value base on 767987d6a8cSPeng Zhang * the ring with cpp read and write operation. 768987d6a8cSPeng Zhang * 769987d6a8cSPeng Zhang * @param rtbl 770987d6a8cSPeng Zhang * NFP run-time symbol table 771987d6a8cSPeng Zhang * @param aux_name 772987d6a8cSPeng Zhang * The auxiliary rtsym table name which can ensure ring base and address 773987d6a8cSPeng Zhang * @param name 774987d6a8cSPeng Zhang * The rtsym table name which can handle the ring 775987d6a8cSPeng Zhang * @param value 776987d6a8cSPeng Zhang * Push this value to ring 777987d6a8cSPeng Zhang * 778987d6a8cSPeng Zhang * @return 779987d6a8cSPeng Zhang * 0 on success, negative errno otherwise. 780987d6a8cSPeng Zhang */ 781987d6a8cSPeng Zhang int 782987d6a8cSPeng Zhang nfp_rtsym_writel_indirect(struct nfp_rtsym_table *rtbl, 783987d6a8cSPeng Zhang const char *aux_name, 784987d6a8cSPeng Zhang const char *name, 785987d6a8cSPeng Zhang uint32_t value) 786987d6a8cSPeng Zhang { 787987d6a8cSPeng Zhang int ret; 788987d6a8cSPeng Zhang uint32_t cpp_id; 789987d6a8cSPeng Zhang const struct nfp_rtsym *sym; 790987d6a8cSPeng Zhang const struct nfp_rtsym *aux_sym; 791987d6a8cSPeng Zhang 792987d6a8cSPeng Zhang aux_sym = nfp_rtsym_lookup(rtbl, aux_name); 793987d6a8cSPeng Zhang if (aux_sym == NULL) { 794*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Failed to find symbol %s.", aux_name); 795987d6a8cSPeng Zhang return -ENOENT; 796987d6a8cSPeng Zhang } 797987d6a8cSPeng Zhang 798987d6a8cSPeng Zhang sym = nfp_rtsym_lookup(rtbl, name); 799987d6a8cSPeng Zhang if (sym == NULL) { 800*b6de4353SZerun Fu PMD_DRV_LOG(ERR, "Failed to find symbol %s.", name); 801987d6a8cSPeng Zhang return -ENOENT; 802987d6a8cSPeng Zhang } 803987d6a8cSPeng Zhang 804987d6a8cSPeng Zhang /* Ring Put */ 805987d6a8cSPeng Zhang cpp_id = NFP_CPP_ISLAND_ID(aux_sym->target, 20, 0, aux_sym->domain); 806987d6a8cSPeng Zhang ret = nfp_cpp_writel(rtbl->cpp, cpp_id, sym->addr, value); 807987d6a8cSPeng Zhang if (ret != 0) 808987d6a8cSPeng Zhang return -EIO; 809987d6a8cSPeng Zhang 810987d6a8cSPeng Zhang return 0; 811987d6a8cSPeng Zhang } 812