/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* Copyright (C) 2015-2018 Netronome Systems, Inc. */
/*
* nfp_cpp . h
* Interface for low - level NFP CPP access .
* Authors : Jason McMullan < jason . mcmullan @ netronome . com >
* Rolf Neugebauer < rolf . neugebauer @ netronome . com >
*/
#ifndef __NFP_CPP_H__
#define __NFP_CPP_H__
#include <linux/ctype.h>
#include <linux/types.h>
#include <linux/sizes.h>
#ifndef NFP_SUBSYS
#define NFP_SUBSYS "nfp"
#endif
#define nfp_err(cpp, fmt, args...) \
dev_err(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args)
#define nfp_warn(cpp, fmt, args...) \
dev_warn(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args)
#define nfp_info(cpp, fmt, args...) \
dev_info(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args)
#define nfp_dbg(cpp, fmt, args...) \
dev_dbg(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args)
#define nfp_printk(level, cpp, fmt, args...) \
dev_printk(level, nfp_cpp_device(cpp)->parent, \
NFP_SUBSYS ": " fmt, ## args)
#define PCI_64BIT_BAR_COUNT 3
#define NFP_CPP_NUM_TARGETS 16
/* Max size of area it should be safe to request */
#define NFP_CPP_SAFE_AREA_SIZE SZ_2M
/* NFP_MUTEX_WAIT_* are timeouts in seconds when waiting for a mutex */
#define NFP_MUTEX_WAIT_FIRST_WARN 15
#define NFP_MUTEX_WAIT_NEXT_WARN 5
#define NFP_MUTEX_WAIT_ERROR 60
struct device;
struct nfp_cpp_area;
struct nfp_cpp;
struct resource;
/* Wildcard indicating a CPP read or write action
*
* The action used will be either read or write depending on whether a
* read or write instruction / call is performed on the NFP_CPP_ID . It
* is recomended that the RW action is used even if all actions to be
* performed on a NFP_CPP_ID are known to be only reads or writes .
* Doing so will in many cases save NFP CPP internal software
* resources .
*/
#define NFP_CPP_ACTION_RW 32
#define NFP_CPP_TARGET_ID_MASK 0 x1f
#define NFP_CPP_ATOMIC_RD(target, island) \
NFP_CPP_ISLAND_ID((target), 3 , 0 , (island))
#define NFP_CPP_ATOMIC_WR(target, island) \
NFP_CPP_ISLAND_ID((target), 4 , 0 , (island))
/**
* NFP_CPP_ID ( ) - pack target , token , and action into a CPP ID .
* @ target : NFP CPP target id
* @ action : NFP CPP action id
* @ token : NFP CPP token id
*
* Create a 32 - bit CPP identifier representing the access to be made .
* These identifiers are used as parameters to other NFP CPP
* functions . Some CPP devices may allow wildcard identifiers to be
* specified .
*
* Return : NFP CPP ID
*/
#define NFP_CPP_ID(target, action, token) \
((((target) & 0 x7f) << 24 ) | (((token) & 0 xff) << 16 ) | \
(((action) & 0 xff) << 8 ))
/**
* NFP_CPP_ISLAND_ID ( ) - pack target , token , action , and island into a CPP ID .
* @ target : NFP CPP target id
* @ action : NFP CPP action id
* @ token : NFP CPP token id
* @ island : NFP CPP island id
*
* Create a 32 - bit CPP identifier representing the access to be made .
* These identifiers are used as parameters to other NFP CPP
* functions . Some CPP devices may allow wildcard identifiers to be
* specified .
*
* Return : NFP CPP ID
*/
#define NFP_CPP_ISLAND_ID(target, action, token, island) \
((((target) & 0 x7f) << 24 ) | (((token) & 0 xff) << 16 ) | \
(((action) & 0 xff) << 8 ) | (((island) & 0 xff) << 0 ))
/**
* NFP_CPP_ID_TARGET_of ( ) - Return the NFP CPP target of a NFP CPP ID
* @ id : NFP CPP ID
*
* Return : NFP CPP target
*/
static inline u8 NFP_CPP_ID_TARGET_of(u32 id)
{
return (id >> 24 ) & NFP_CPP_TARGET_ID_MASK;
}
/**
* NFP_CPP_ID_TOKEN_of ( ) - Return the NFP CPP token of a NFP CPP ID
* @ id : NFP CPP ID
* Return : NFP CPP token
*/
static inline u8 NFP_CPP_ID_TOKEN_of(u32 id)
{
return (id >> 16 ) & 0 xff;
}
/**
* NFP_CPP_ID_ACTION_of ( ) - Return the NFP CPP action of a NFP CPP ID
* @ id : NFP CPP ID
*
* Return : NFP CPP action
*/
static inline u8 NFP_CPP_ID_ACTION_of(u32 id)
{
return (id >> 8 ) & 0 xff;
}
/**
* NFP_CPP_ID_ISLAND_of ( ) - Return the NFP CPP island of a NFP CPP ID
* @ id : NFP CPP ID
*
* Return : NFP CPP island
*/
static inline u8 NFP_CPP_ID_ISLAND_of(u32 id)
{
return (id >> 0 ) & 0 xff;
}
/* NFP Interface types - logical interface for this CPP connection
* 4 bits are reserved for interface type .
*/
#define NFP_CPP_INTERFACE_TYPE_INVALID 0 x0
#define NFP_CPP_INTERFACE_TYPE_PCI 0 x1
#define NFP_CPP_INTERFACE_TYPE_ARM 0 x2
#define NFP_CPP_INTERFACE_TYPE_RPC 0 x3
#define NFP_CPP_INTERFACE_TYPE_ILA 0 x4
/**
* NFP_CPP_INTERFACE ( ) - Construct a 16 - bit NFP Interface ID
* @ type : NFP Interface Type
* @ unit : Unit identifier for the interface type
* @ channel : Channel identifier for the interface unit
*
* Interface IDs consists of 4 bits of interface type ,
* 4 bits of unit identifier , and 8 bits of channel identifier .
*
* The NFP Interface ID is used in the implementation of
* NFP CPP API mutexes , which use the MU Atomic CompareAndWrite
* operation - hence the limit to 16 bits to be able to
* use the NFP Interface ID as a lock owner .
*
* Return : Interface ID
*/
#define NFP_CPP_INTERFACE(type, unit, channel) \
((((type) & 0 xf) << 12 ) | \
(((unit) & 0 xf) << 8 ) | \
(((channel) & 0 xff) << 0 ))
/**
* NFP_CPP_INTERFACE_TYPE_of ( ) - Get the interface type
* @ interface : NFP Interface ID
* Return : NFP Interface ID ' s type
*/
#define NFP_CPP_INTERFACE_TYPE_of(interface) (((interface) >> 12 ) & 0 xf)
/**
* NFP_CPP_INTERFACE_UNIT_of ( ) - Get the interface unit
* @ interface : NFP Interface ID
* Return : NFP Interface ID ' s unit
*/
#define NFP_CPP_INTERFACE_UNIT_of(interface) (((interface) >> 8 ) & 0 xf)
/**
* NFP_CPP_INTERFACE_CHANNEL_of ( ) - Get the interface channel
* @ interface : NFP Interface ID
* Return : NFP Interface ID ' s channel
*/
#define NFP_CPP_INTERFACE_CHANNEL_of(interface) (((interface) >> 0 ) & 0 xff)
/* Implemented in nfp_cppcore.c */
void nfp_cpp_free(struct nfp_cpp *cpp);
u32 nfp_cpp_model(struct nfp_cpp *cpp);
u16 nfp_cpp_interface(struct nfp_cpp *cpp);
int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial);
unsigned int nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp);
struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp,
u32 cpp_id,
const char *name,
unsigned long long address,
unsigned long size);
struct nfp_cpp_area *nfp_cpp_area_alloc(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address,
unsigned long size);
struct nfp_cpp_area *
nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, const char *name, u32 cpp_id,
unsigned long long address, unsigned long size);
void nfp_cpp_area_free(struct nfp_cpp_area *area);
int nfp_cpp_area_acquire(struct nfp_cpp_area *area);
int nfp_cpp_area_acquire_nonblocking(struct nfp_cpp_area *area);
void nfp_cpp_area_release(struct nfp_cpp_area *area);
void nfp_cpp_area_release_free(struct nfp_cpp_area *area);
int nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset,
void *buffer, size_t length);
int nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset,
const void *buffer, size_t length);
size_t nfp_cpp_area_size(struct nfp_cpp_area *area);
const char *nfp_cpp_area_name(struct nfp_cpp_area *cpp_area);
void *nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area);
struct nfp_cpp *nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area);
struct resource *nfp_cpp_area_resource(struct nfp_cpp_area *area);
phys_addr_t nfp_cpp_area_phys(struct nfp_cpp_area *area);
void __iomem *nfp_cpp_area_iomem(struct nfp_cpp_area *area);
int nfp_cpp_area_readl(struct nfp_cpp_area *area, unsigned long offset,
u32 *value);
int nfp_cpp_area_writel(struct nfp_cpp_area *area, unsigned long offset,
u32 value);
int nfp_cpp_area_readq(struct nfp_cpp_area *area, unsigned long offset,
u64 *value);
int nfp_cpp_area_writeq(struct nfp_cpp_area *area, unsigned long offset,
u64 value);
int nfp_cpp_area_fill(struct nfp_cpp_area *area, unsigned long offset,
u32 value, size_t length);
int nfp_xpb_readl(struct nfp_cpp *cpp, u32 xpb_tgt, u32 *value);
int nfp_xpb_writel(struct nfp_cpp *cpp, u32 xpb_tgt, u32 value);
int nfp_xpb_writelm(struct nfp_cpp *cpp, u32 xpb_tgt, u32 mask, u32 value);
/* Implemented in nfp_cpplib.c */
int nfp_cpp_read(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, void *kernel_vaddr, size_t length);
int nfp_cpp_write(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, const void *kernel_vaddr,
size_t length);
int nfp_cpp_readl(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, u32 *value);
int nfp_cpp_writel(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, u32 value);
int nfp_cpp_readq(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, u64 *value);
int nfp_cpp_writeq(struct nfp_cpp *cpp, u32 cpp_id,
unsigned long long address, u64 value);
u8 __iomem *
nfp_cpp_map_area(struct nfp_cpp *cpp, const char *name, u32 cpp_id, u64 addr,
unsigned long size, struct nfp_cpp_area **area);
struct nfp_cpp_mutex;
int nfp_cpp_mutex_init(struct nfp_cpp *cpp, int target,
unsigned long long address, u32 key_id);
struct nfp_cpp_mutex *nfp_cpp_mutex_alloc(struct nfp_cpp *cpp, int target,
unsigned long long address,
u32 key_id);
void nfp_cpp_mutex_free(struct nfp_cpp_mutex *mutex);
int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex);
int nfp_cpp_mutex_unlock(struct nfp_cpp_mutex *mutex);
int nfp_cpp_mutex_trylock(struct nfp_cpp_mutex *mutex);
int nfp_cpp_mutex_reclaim(struct nfp_cpp *cpp, int target,
unsigned long long address);
/**
* nfp_cppcore_pcie_unit ( ) - Get PCI Unit of a CPP handle
* @ cpp : CPP handle
*
* Return : PCI unit for the NFP CPP handle
*/
static inline u8 nfp_cppcore_pcie_unit(struct nfp_cpp *cpp)
{
return NFP_CPP_INTERFACE_UNIT_of(nfp_cpp_interface(cpp));
}
struct nfp_cpp_explicit;
struct nfp_cpp_explicit_command {
u32 cpp_id;
u16 data_ref;
u8 data_master;
u8 len;
u8 byte_mask;
u8 signal_master;
u8 signal_ref;
u8 posted;
u8 siga;
u8 sigb;
s8 siga_mode;
s8 sigb_mode;
};
#define NFP_SERIAL_LEN 6
/**
* struct nfp_cpp_operations - NFP CPP operations structure
* @ area_priv_size : Size of the nfp_cpp_area private data
* @ owner : Owner module
* @ init : Initialize the NFP CPP bus
* @ free : Free the bus
* @ read_serial : Read serial number to memory provided
* @ get_interface : Return CPP interface
* @ area_init : Initialize a new NFP CPP area ( not serialized )
* @ area_cleanup : Clean up a NFP CPP area ( not serialized )
* @ area_acquire : Acquire the NFP CPP area ( serialized )
* @ area_release : Release area ( serialized )
* @ area_resource : Get resource range of area ( not serialized )
* @ area_phys : Get physical address of area ( not serialized )
* @ area_iomem : Get iomem of area ( not serialized )
* @ area_read : Perform a read from a NFP CPP area ( serialized )
* @ area_write : Perform a write to a NFP CPP area ( serialized )
* @ explicit_priv_size : Size of an explicit ' s private area
* @ explicit_acquire : Acquire an explicit area
* @ explicit_release : Release an explicit area
* @ explicit_put : Write data to send
* @ explicit_get : Read data received
* @ explicit_do : Perform the transaction
*/
struct nfp_cpp_operations {
size_t area_priv_size;
struct module *owner;
int (*init)(struct nfp_cpp *cpp);
void (*free)(struct nfp_cpp *cpp);
int (*read_serial)(struct device *dev, u8 *serial);
int (*get_interface)(struct device *dev);
int (*area_init)(struct nfp_cpp_area *area,
u32 dest, unsigned long long address,
unsigned long size);
void (*area_cleanup)(struct nfp_cpp_area *area);
int (*area_acquire)(struct nfp_cpp_area *area);
void (*area_release)(struct nfp_cpp_area *area);
struct resource *(*area_resource)(struct nfp_cpp_area *area);
phys_addr_t (*area_phys)(struct nfp_cpp_area *area);
void __iomem *(*area_iomem)(struct nfp_cpp_area *area);
int (*area_read)(struct nfp_cpp_area *area, void *kernel_vaddr,
unsigned long offset, unsigned int length);
int (*area_write)(struct nfp_cpp_area *area, const void *kernel_vaddr,
unsigned long offset, unsigned int length);
size_t explicit_priv_size;
int (*explicit_acquire)(struct nfp_cpp_explicit *expl);
void (*explicit_release)(struct nfp_cpp_explicit *expl);
int (*explicit_put)(struct nfp_cpp_explicit *expl,
const void *buff, size_t len);
int (*explicit_get)(struct nfp_cpp_explicit *expl,
void *buff, size_t len);
int (*explicit_do)(struct nfp_cpp_explicit *expl,
const struct nfp_cpp_explicit_command *cmd,
u64 address);
};
struct nfp_cpp *
nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
struct device *parent, void *priv);
void *nfp_cpp_priv(struct nfp_cpp *priv);
int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size);
/* The following section contains extensions to the
* NFP CPP API , to be used in a Linux kernel - space context .
*/
/* Use this channel ID for multiple virtual channel interfaces
* ( ie ARM and PCIe ) when setting up the interface field .
*/
#define NFP_CPP_INTERFACE_CHANNEL_PEROPENER 255
struct device *nfp_cpp_device(struct nfp_cpp *cpp);
/* Return code masks for nfp_cpp_explicit_do()
*/
#define NFP_SIGNAL_MASK_A BIT(0 ) /* Signal A fired */
#define NFP_SIGNAL_MASK_B BIT(1 ) /* Signal B fired */
enum nfp_cpp_explicit_signal_mode {
NFP_SIGNAL_NONE = 0 ,
NFP_SIGNAL_PUSH = 1 ,
NFP_SIGNAL_PUSH_OPTIONAL = -1 ,
NFP_SIGNAL_PULL = 2 ,
NFP_SIGNAL_PULL_OPTIONAL = -2 ,
};
struct nfp_cpp_explicit *nfp_cpp_explicit_acquire(struct nfp_cpp *cpp);
int nfp_cpp_explicit_set_target(struct nfp_cpp_explicit *expl, u32 cpp_id,
u8 len, u8 mask);
int nfp_cpp_explicit_set_data(struct nfp_cpp_explicit *expl,
u8 data_master, u16 data_ref);
int nfp_cpp_explicit_set_signal(struct nfp_cpp_explicit *expl,
u8 signal_master, u8 signal_ref);
int nfp_cpp_explicit_set_posted(struct nfp_cpp_explicit *expl, int posted,
u8 siga,
enum nfp_cpp_explicit_signal_mode siga_mode,
u8 sigb,
enum nfp_cpp_explicit_signal_mode sigb_mode);
int nfp_cpp_explicit_put(struct nfp_cpp_explicit *expl,
const void *buff, size_t len);
int nfp_cpp_explicit_do(struct nfp_cpp_explicit *expl, u64 address);
int nfp_cpp_explicit_get(struct nfp_cpp_explicit *expl, void *buff, size_t len);
void nfp_cpp_explicit_release(struct nfp_cpp_explicit *expl);
struct nfp_cpp *nfp_cpp_explicit_cpp(struct nfp_cpp_explicit *expl);
void *nfp_cpp_explicit_priv(struct nfp_cpp_explicit *cpp_explicit);
/* Implemented in nfp_cpplib.c */
int nfp_cpp_model_autodetect(struct nfp_cpp *cpp, u32 *model);
int nfp_cpp_explicit_read(struct nfp_cpp *cpp, u32 cpp_id,
u64 addr, void *buff, size_t len,
int width_read);
int nfp_cpp_explicit_write(struct nfp_cpp *cpp, u32 cpp_id,
u64 addr, const void *buff, size_t len,
int width_write);
#endif /* !__NFP_CPP_H__ */
Messung V0.5 in Prozent C=94 H=100 G=96
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-11)
¤
*© Formatika GbR, Deutschland