d12206e005
Working with the PF requires access to the NFP for basic configuration. NSP is the NFP Service Processor helping with hardware and firmware configuration. NSPU is the NSP user space interface for working with the NSP. Configuration through NSPU allows to create PCI BAR windows for accessing different NFP hardware units, including the BAR window for the NSPU interface access itself. NFP expansion bar registers are used for creating those PCI BAR windows. NSPU uses a specific expansion bar which is reprogrammed for accessing/doing different things. Other expansion bars will be configured later for configuring the PF vNIC bars, a subset of PF PCI BARs. Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
104 lines
2.1 KiB
C
104 lines
2.1 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/file.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <rte_pci.h>
|
|
#include <rte_malloc.h>
|
|
|
|
#include "nfp_nfpu.h"
|
|
|
|
/* PF BAR and expansion BAR for the NSP interface */
|
|
#define NFP_CFG_PCIE_BAR 0
|
|
#define NFP_CFG_EXP_BAR 7
|
|
|
|
#define NFP_CFG_EXP_BAR_CFG_BASE 0x30000
|
|
|
|
/* There could be other NFP userspace tools using the NSP interface.
|
|
* Make sure there is no other process using it and locking the access for
|
|
* avoiding problems.
|
|
*/
|
|
static int
|
|
nspv_aquire_process_lock(nfpu_desc_t *desc)
|
|
{
|
|
int rc;
|
|
struct flock lock;
|
|
char lockname[30];
|
|
|
|
memset(&lock, 0, sizeof(lock));
|
|
|
|
snprintf(lockname, sizeof(lockname), "/var/lock/nfp%d", desc->nfp);
|
|
|
|
/* Using S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH */
|
|
desc->lock = open(lockname, O_RDWR | O_CREAT, 0666);
|
|
|
|
if (desc->lock < 0)
|
|
return desc->lock;
|
|
|
|
lock.l_type = F_WRLCK;
|
|
lock.l_whence = SEEK_SET;
|
|
rc = -1;
|
|
while (rc != 0) {
|
|
rc = fcntl(desc->lock, F_SETLK, &lock);
|
|
if (rc < 0) {
|
|
if ((errno != EAGAIN) && (errno != EACCES)) {
|
|
close(desc->lock);
|
|
return rc;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
nfpu_open(struct rte_pci_device *pci_dev, nfpu_desc_t *desc, int nfp)
|
|
{
|
|
void *cfg_base, *mem_base;
|
|
size_t barsz;
|
|
int ret = 0;
|
|
int i = 0;
|
|
|
|
desc->nfp = nfp;
|
|
|
|
ret = nspv_aquire_process_lock(desc);
|
|
if (ret)
|
|
return -1;
|
|
|
|
barsz = pci_dev->mem_resource[0].len;
|
|
|
|
/* barsz in log2 */
|
|
while (barsz >>= 1)
|
|
i++;
|
|
barsz = i;
|
|
|
|
/* Getting address for NFP expansion BAR registers */
|
|
cfg_base = pci_dev->mem_resource[0].addr;
|
|
cfg_base = (uint8_t *)cfg_base + NFP_CFG_EXP_BAR_CFG_BASE;
|
|
|
|
/* Getting address for NFP NSP interface registers */
|
|
mem_base = pci_dev->mem_resource[0].addr;
|
|
mem_base = (uint8_t *)mem_base + (NFP_CFG_EXP_BAR << (barsz - 3));
|
|
|
|
|
|
desc->nspu = rte_malloc("nfp nspu", sizeof(nspu_desc_t), 0);
|
|
nfp_nspu_init(desc->nspu, desc->nfp, NFP_CFG_PCIE_BAR, barsz,
|
|
NFP_CFG_EXP_BAR, cfg_base, mem_base);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
nfpu_close(nfpu_desc_t *desc)
|
|
{
|
|
rte_free(desc->nspu);
|
|
close(desc->lock);
|
|
unlink("/var/lock/nfp0");
|
|
return 0;
|
|
}
|