/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Netronome Systems, Inc.
* All rights reserved.
*/
#ifndef NSP_NSP_H
#define NSP_NSP_H 1
#include "nfp_cpp.h"
#include "nfp_nsp.h"
#define GENMASK_ULL(h, l) \
(((~0ULL) - (1ULL << (l)) + 1) & \
(~0ULL >> (64 - 1 - (h))))
#define __bf_shf(x) (__builtin_ffsll(x) - 1)
#define FIELD_GET(_mask, _reg) \
(__extension__ ({ \
typeof(_mask) _x = (_mask); \
(typeof(_x))(((_reg) & (_x)) >> __bf_shf(_x)); \
}))
#define FIELD_FIT(_mask, _val) \
(__extension__ ({ \
typeof(_mask) _x = (_mask); \
!((((typeof(_x))_val) << __bf_shf(_x)) & ~(_x)); \
}))
#define FIELD_PREP(_mask, _val) \
(__extension__ ({ \
typeof(_mask) _x = (_mask); \
((typeof(_x))(_val) << __bf_shf(_x)) & (_x); \
}))
/* Offsets relative to the CSR base */
#define NSP_STATUS 0x00
#define NSP_STATUS_MAGIC GENMASK_ULL(63, 48)
#define NSP_STATUS_MAJOR GENMASK_ULL(47, 44)
#define NSP_STATUS_MINOR GENMASK_ULL(43, 32)
#define NSP_STATUS_CODE GENMASK_ULL(31, 16)
#define NSP_STATUS_RESULT GENMASK_ULL(15, 8)
#define NSP_STATUS_BUSY BIT_ULL(0)
#define NSP_COMMAND 0x08
#define NSP_COMMAND_OPTION GENMASK_ULL(63, 32)
#define NSP_COMMAND_CODE GENMASK_ULL(31, 16)
#define NSP_COMMAND_START BIT_ULL(0)
/* CPP address to retrieve the data from */
#define NSP_BUFFER 0x10
#define NSP_BUFFER_CPP GENMASK_ULL(63, 40)
#define NSP_BUFFER_PCIE GENMASK_ULL(39, 38)
#define NSP_BUFFER_ADDRESS GENMASK_ULL(37, 0)
#define NSP_DFLT_BUFFER 0x18
#define NSP_DFLT_BUFFER_CONFIG 0x20
#define NSP_DFLT_BUFFER_SIZE_MB GENMASK_ULL(7, 0)
#define NSP_MAGIC 0xab10
#define NSP_MAJOR 0
#define NSP_MINOR 8
#define NSP_CODE_MAJOR GENMASK(15, 12)
#define NSP_CODE_MINOR GENMASK(11, 0)
enum nfp_nsp_cmd {
SPCODE_NOOP = 0, /* No operation */
SPCODE_SOFT_RESET = 1, /* Soft reset the NFP */
SPCODE_FW_DEFAULT = 2, /* Load default (UNDI) FW */
SPCODE_PHY_INIT = 3, /* Initialize the PHY */
SPCODE_MAC_INIT = 4, /* Initialize the MAC */
SPCODE_PHY_RXADAPT = 5, /* Re-run PHY RX Adaptation */
SPCODE_FW_LOAD = 6, /* Load fw from buffer, len in option */
SPCODE_ETH_RESCAN = 7, /* Rescan ETHs, write ETH_TABLE to buf */
SPCODE_ETH_CONTROL = 8, /* Update media config from buffer */
SPCODE_NSP_SENSORS = 12, /* Read NSP sensor(s) */
SPCODE_NSP_IDENTIFY = 13, /* Read NSP version */
};
static const struct {
int code;
const char *msg;
} nsp_errors[] = {
{ 6010, "could not map to phy for port" },
{ 6011, "not an allowed rate/lanes for port" },
{ 6012, "not an allowed rate/lanes for port" },
{ 6013, "high/low error, change other port first" },
{ 6014, "config not found in flash" },
};
struct nfp_nsp {
struct nfp_cpp *cpp;
struct nfp_resource *res;
struct {
uint16_t major;
uint16_t minor;
} ver;
/* Eth table config state */
int modified;
unsigned int idx;
void *entries;
};
struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp);
void nfp_nsp_close(struct nfp_nsp *state);
uint16_t nfp_nsp_get_abi_ver_major(struct nfp_nsp *state);
uint16_t nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state);
int nfp_nsp_wait(struct nfp_nsp *state);
int nfp_nsp_device_soft_reset(struct nfp_nsp *state);
int nfp_nsp_load_fw(struct nfp_nsp *state, void *buf, unsigned int size);
int nfp_nsp_mac_reinit(struct nfp_nsp *state);
int nfp_nsp_read_identify(struct nfp_nsp *state, void *buf, unsigned int size);
int nfp_nsp_read_sensors(struct nfp_nsp *state, unsigned int sensor_mask,
void *buf, unsigned int size);
static inline int nfp_nsp_has_mac_reinit(struct nfp_nsp *state)
{
return nfp_nsp_get_abi_ver_minor(state) > 20;
}
enum nfp_eth_interface {
NFP_INTERFACE_NONE = 0,
NFP_INTERFACE_SFP = 1,
NFP_INTERFACE_SFPP = 10,
NFP_INTERFACE_SFP28 = 28,
NFP_INTERFACE_QSFP = 40,
NFP_INTERFACE_CXP = 100,
NFP_INTERFACE_QSFP28 = 112,
};
enum nfp_eth_media {
NFP_MEDIA_DAC_PASSIVE = 0,
NFP_MEDIA_DAC_ACTIVE,
NFP_MEDIA_FIBRE,
};
enum nfp_eth_aneg {
NFP_ANEG_AUTO = 0,
NFP_ANEG_SEARCH,
NFP_ANEG_25G_CONSORTIUM,
NFP_ANEG_25G_IEEE,
NFP_ANEG_DISABLED,
};
enum nfp_eth_fec {
NFP_FEC_AUTO_BIT = 0,
NFP_FEC_BASER_BIT,
NFP_FEC_REED_SOLOMON_BIT,
NFP_FEC_DISABLED_BIT,
};
#define NFP_FEC_AUTO BIT(NFP_FEC_AUTO_BIT)
#define NFP_FEC_BASER BIT(NFP_FEC_BASER_BIT)
#define NFP_FEC_REED_SOLOMON BIT(NFP_FEC_REED_SOLOMON_BIT)
#define NFP_FEC_DISABLED BIT(NFP_FEC_DISABLED_BIT)
#define ETH_ALEN 6
/**
* struct nfp_eth_table - ETH table information
* @count: number of table entries
* @max_index: max of @index fields of all @ports
* @ports: table of ports
*
* @eth_index: port index according to legacy ethX numbering
* @index: chip-wide first channel index
* @nbi: NBI index
* @base: first channel index (within NBI)
* @lanes: number of channels
* @speed: interface speed (in Mbps)
* @interface: interface (module) plugged in
* @media: media type of the @interface
* @fec: forward error correction mode
* @aneg: auto negotiation mode
* @mac_addr: interface MAC address
* @label_port: port id
* @label_subport: id of interface within port (for split ports)
* @enabled: is enabled?
* @tx_enabled: is TX enabled?
* @rx_enabled: is RX enabled?
* @override_changed: is media reconfig pending?
*
* @port_type: one of %PORT_* defines for ethtool
* @port_lanes: total number of lanes on the port (sum of lanes of all subports)
* @is_split: is interface part of a split port
* @fec_modes_supported: bitmap of FEC modes supported
*/
struct nfp_eth_table {
unsigned int count;
unsigned int max_index;
struct nfp_eth_table_port {
unsigned int eth_index;
unsigned int index;
unsigned int nbi;
unsigned int base;
unsigned int lanes;
unsigned int speed;
unsigned int interface;
enum nfp_eth_media media;
enum nfp_eth_fec fec;
enum nfp_eth_aneg aneg;
uint8_t mac_addr[ETH_ALEN];
uint8_t label_port;
uint8_t label_subport;
int enabled;
int tx_enabled;
int rx_enabled;
int override_changed;
/* Computed fields */
uint8_t port_type;
unsigned int port_lanes;
int is_split;
unsigned int fec_modes_supported;
} ports[0];
};
struct nfp_eth_table *nfp_eth_read_ports(struct nfp_cpp *cpp);
int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, int enable);
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx,
int configed);
int
nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode);
int nfp_nsp_read_eth_table(struct nfp_nsp *state, void *buf, unsigned int size);
int nfp_nsp_write_eth_table(struct nfp_nsp *state, const void *buf,
unsigned int size);
void nfp_nsp_config_set_state(struct nfp_nsp *state, void *entries,
unsigned int idx);
void nfp_nsp_config_clear_state(struct nfp_nsp *state);
void nfp_nsp_config_set_modified(struct nfp_nsp *state, int modified);
void *nfp_nsp_config_entries(struct nfp_nsp *state);
int nfp_nsp_config_modified(struct nfp_nsp *state);
unsigned int nfp_nsp_config_idx(struct nfp_nsp *state);
static inline int nfp_eth_can_support_fec(struct nfp_eth_table_port *eth_port)
{
return !!eth_port->fec_modes_supported;
}
static inline unsigned int
nfp_eth_supported_fec_modes(struct nfp_eth_table_port *eth_port)
{
return eth_port->fec_modes_supported;
}
struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx);
int nfp_eth_config_commit_end(struct nfp_nsp *nsp);
void nfp_eth_config_cleanup_end(struct nfp_nsp *nsp);
int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode);
int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int speed);
int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes);
/**
* struct nfp_nsp_identify - NSP static information
* @version: opaque version string
* @flags: version flags
* @br_primary: branch id of primary bootloader
* @br_secondary: branch id of secondary bootloader
* @br_nsp: branch id of NSP
* @primary: version of primarary bootloader
* @secondary: version id of secondary bootloader
* @nsp: version id of NSP
* @sensor_mask: mask of present sensors available on NIC
*/
struct nfp_nsp_identify {
char version[40];
uint8_t flags;
uint8_t br_primary;
uint8_t br_secondary;
uint8_t br_nsp;
uint16_t primary;
uint16_t secondary;
uint16_t nsp;
uint64_t sensor_mask;
};
struct nfp_nsp_identify *__nfp_nsp_identify(struct nfp_nsp *nsp);
enum nfp_nsp_sensor_id {
NFP_SENSOR_CHIP_TEMPERATURE,
NFP_SENSOR_ASSEMBLY_POWER,
NFP_SENSOR_ASSEMBLY_12V_POWER,
NFP_SENSOR_ASSEMBLY_3V3_POWER,
};
int nfp_hwmon_read_sensor(struct nfp_cpp *cpp, enum nfp_nsp_sensor_id id,
long *val);
#endif