blob: 542cc47bed09f3fc2f0165cede1b635aad1e1445 [file] [log] [blame]
/*
**************************************************************************
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
/*
* nss_ppe.h
* NSS PPE header file
*/
#include <net/sock.h>
#include "nss_tx_rx_common.h"
#define PPE_BASE_ADDR 0x3a000000
#define PPE_REG_SIZE 0x1000000
#define PPE_L3_DBG_WR_OFFSET 0x200c04
#define PPE_L3_DBG_RD_OFFSET 0x200c0c
#define PPE_L3_DBG0_OFFSET 0x10001
#define PPE_L3_DBG1_OFFSET 0x10002
#define PPE_L3_DBG2_OFFSET 0x10003
#define PPE_L3_DBG3_OFFSET 0x10004
#define PPE_L3_DBG4_OFFSET 0x10005
#define PPE_L3_DBG_PORT_OFFSET 0x11e80
#define PPE_PKT_CODE_WR_OFFSET 0x100080
#define PPE_PKT_CODE_RD_OFFSET 0x100084
#define PPE_PKT_CODE_DROP0_OFFSET 0xf000000
#define PPE_PKT_CODE_DROP1_OFFSET 0x10000000
#define PPE_PKT_CODE_CPU_OFFSET 0x40000000
#define PPE_PKT_CODE_DROP0_GET(x) (((x) & 0xe0000000) >> 29)
#define PPE_PKT_CODE_DROP1_GET(x) (((x) & 0x7) << 3)
#define PPE_PKT_CODE_DROP_GET(d0, d1) (PPE_PKT_CODE_DROP0_GET(d0) | PPE_PKT_CODE_DROP1_GET(d1))
#define PPE_PKT_CODE_CPU_GET(x) (((x) >> 3) & 0xff)
#define PPE_IPE_PC_REG 0x100000
/*
* NSS_SYS_REG_DROP_CPU_CNT_TBL
* Address map and access APIs for DROP_CPU_CNT table.
*/
#define PPE_DROP_CPU_CNT_TBL_OFFSET 0x60000
#define PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE 0x10
#define PPE_DROP_CPU_CNT_TBL_BASE_OFFSET (PPE_IPE_PC_REG + PPE_DROP_CPU_CNT_TBL_OFFSET)
#define PPE_CPU_CODE_MAX_NUM 256
/*
* CPU code offset
*/
#define PPE_CPU_CODE_OFFSET(n) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((n) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE))
/*
* DROP code offset
*/
#define PPE_DROP_CODE_IDX(code, src_port) (PPE_CPU_CODE_MAX_NUM + (8 * (code)) + (src_port))
#define PPE_DROP_CODE_OFFSET(code, src_port) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((PPE_DROP_CODE_IDX(code, src_port)) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE))
#define NSS_PPE_TX_TIMEOUT 1000 /* 1 Second */
/*
* Maximum number of VSI
*/
#define NSS_PPE_VSI_NUM_MAX 32
/*
* ppe nss debug stats lock
*/
extern spinlock_t nss_ppe_stats_lock;
/*
* Private data structure
*/
struct nss_ppe_pvt {
void * __iomem ppe_base;
struct semaphore sem;
struct completion complete;
int response;
void *cb;
void *app_data;
};
/*
* Data structure to store to PPE private context
*/
extern struct nss_ppe_pvt ppe_pvt;
/**
* nss_ppe_message_types
* Message types for Packet Processing Engine (PPE) requests and responses.
*
* Note: PPE messages are added as short term approach, expect all
* messages below to be deprecated for more integrated approach.
*/
enum nss_ppe_message_types {
NSS_PPE_MSG_SYNC_STATS,
NSS_PPE_MSG_IPSEC_PORT_CONFIG,
NSS_PPE_MSG_IPSEC_PORT_MTU_CHANGE,
NSS_PPE_MSG_IPSEC_ADD_INTF,
NSS_PPE_MSG_IPSEC_DEL_INTF,
NSS_PPE_MSG_MAX,
};
/**
* nss_ppe_msg_error_type
* PPE error types.
*/
enum nss_ppe_msg_error_type {
PPE_MSG_ERROR_OK,
PPE_MSG_ERROR_UNKNOWN_TYPE,
PPE_MSG_ERROR_PORT_CREATION_FAIL,
PPE_MSG_ERROR_INVALID_PORT_VSI,
PPE_MSG_ERROR_INVALID_L3_IF,
PPE_MSG_ERROR_IPSEC_PORT_CONFIG,
PPE_MSG_ERROR_IPSEC_INTF_TABLE_FULL,
PPE_MSG_ERROR_IPSEC_INTF_ATTACHED,
PPE_MSG_ERROR_IPSEC_INTF_UNATTACHED,
PPE_ERROR_MAX
};
/**
* nss_ppe_sc_type
* PPE service code types
*/
enum nss_ppe_sc_type {
NSS_PPE_SC_NONE, /* Normal PPE processing */
NSS_PPE_SC_BYPASS_ALL, /* Bypasses all stages in PPE */
NSS_PPE_SC_ADV_QOS_BRIDGED, /* Adv QoS redirection for bridged flow */
NSS_PPE_SC_BR_QOS, /* Bridge QoS redirection */
NSS_PPE_SC_BNC_0, /* QoS bounce */
NSS_PPE_SC_BNC_CMPL_0, /* QoS bounce complete */
NSS_PPE_SC_ADV_QOS_ROUTED, /* Adv QoS redirection for routed flow */
NSS_PPE_SC_IPSEC_PPE2EIP, /* Inline IPsec redirection from PPE TO EIP */
NSS_PPE_SC_IPSEC_EIP2PPE, /* Inline IPsec redirection from EIP to PPE */
NSS_PPE_SC_VLAN_FILTER_BYPASS, /* VLAN filter bypass for bridge flows between 2 different VSIs */
NSS_PPE_SC_MAX, /* Max service code */
};
/**
* nss_ppe_stats_sc
* Message structure for per service code stats.
*/
struct nss_ppe_stats_sc {
uint32_t nss_ppe_sc_cb_unregister; /* Per service-code counter for callback not registered */
uint32_t nss_ppe_sc_cb_success; /* Per service-code coutner for successful callback */
uint32_t nss_ppe_sc_cb_failure; /* Per service-code counter for failure callback */
};
/**
* nss_ppe_stats
* Message structure for ppe general stats
*/
struct nss_ppe_stats {
uint32_t nss_ppe_v4_l3_flows; /**< Number of IPv4 routed flows. */
uint32_t nss_ppe_v4_l2_flows; /**< Number of IPv4 bridge flows. */
uint32_t nss_ppe_v4_create_req; /**< Number of IPv4 create requests. */
uint32_t nss_ppe_v4_create_fail; /**< Number of IPv4 create failures. */
uint32_t nss_ppe_v4_destroy_req; /**< Number of IPv4 delete requests. */
uint32_t nss_ppe_v4_destroy_fail; /**< Number of IPv4 delete failures. */
uint32_t nss_ppe_v4_mc_create_req; /**< Number of IPv4 MC create requests. */
uint32_t nss_ppe_v4_mc_create_fail; /**< Number of IPv4 MC create failure. */
uint32_t nss_ppe_v4_mc_update_req; /**< Number of IPv4 MC update requests. */
uint32_t nss_ppe_v4_mc_update_fail; /**< Number of IPv4 MC update failure. */
uint32_t nss_ppe_v4_mc_destroy_req; /**< Number of IPv4 MC delete requests. */
uint32_t nss_ppe_v4_mc_destroy_fail; /**< Number of IPv4 MC delete failure. */
uint32_t nss_ppe_v6_l3_flows; /**< Number of IPv6 routed flows. */
uint32_t nss_ppe_v6_l2_flows; /**< Number of IPv6 bridge flows. */
uint32_t nss_ppe_v6_create_req; /**< Number of IPv6 create requests. */
uint32_t nss_ppe_v6_create_fail; /**< Number of IPv6 create failures. */
uint32_t nss_ppe_v6_destroy_req; /**< Number of IPv6 delete requests. */
uint32_t nss_ppe_v6_destroy_fail; /**< Number of IPv6 delete failures. */
uint32_t nss_ppe_v6_mc_create_req; /**< Number of IPv6 MC create requests. */
uint32_t nss_ppe_v6_mc_create_fail; /**< Number of IPv6 MC create failure. */
uint32_t nss_ppe_v6_mc_update_req; /**< Number of IPv6 MC update requests. */
uint32_t nss_ppe_v6_mc_update_fail; /**< Number of IPv6 MC update failure. */
uint32_t nss_ppe_v6_mc_destroy_req; /**< Number of IPv6 MC delete requests. */
uint32_t nss_ppe_v6_mc_destroy_fail; /**< Number of IPv6 MC delete failure. */
uint32_t nss_ppe_fail_vp_full;
/**< Request failed because the virtual port table is full */
uint32_t nss_ppe_fail_nh_full;
/**< Request failed because the next hop table is full. */
uint32_t nss_ppe_fail_flow_full;
/**< Request failed because the flow table is full. */
uint32_t nss_ppe_fail_host_full;
/**< Request failed because the host table is full. */
uint32_t nss_ppe_fail_pubip_full;
/**< Request failed because the public IP table is full. */
uint32_t nss_ppe_fail_port_setup;
/**< Request failed because the PPE port is not setup. */
uint32_t nss_ppe_fail_rw_fifo_full;
/**< Request failed because the read/write FIFO is full. */
uint32_t nss_ppe_fail_flow_command;
/**< Request failed because the PPE flow command failed. */
uint32_t nss_ppe_fail_unknown_proto;
/**< Request failed because of an unknown protocol. */
uint32_t nss_ppe_fail_ppe_unresponsive;
/**< Request failed because the PPE is not responding. */
uint32_t nss_ppe_ce_opaque_invalid;
/**< Request failed because of invalid opaque in connection entry. */
uint32_t nss_ppe_fail_fqg_full;
/**< Request failed because the flow QoS group is full. */
};
/**
* nss_ppe_sync_stats_msg
* Message information for PPE synchronization statistics.
*/
struct nss_ppe_sync_stats_msg {
struct nss_ppe_stats stats; /**< General stats */
struct nss_ppe_stats_sc sc_stats[NSS_PPE_SC_MAX];
/**< Per service-code stats */
};
/**
* nss_ppe_ipsec_port_config_msg
* Message structure for inline IPsec port configuration.
*/
struct nss_ppe_ipsec_port_config_msg {
uint32_t nss_ifnum; /**< NSS interface number corresponding to inline IPsec port. */
uint16_t mtu; /**< MTU value for inline IPsec port. */
uint8_t vsi_num; /**< Default port VSI for inline IPsec port. */
};
/**
* nss_ppe_ipsec_port_mtu_msg
* Message structure for inline IPsec port MTU change.
*/
struct nss_ppe_ipsec_port_mtu_msg {
uint32_t nss_ifnum; /**< NSS interface number corresponding to inline IPsec port. */
uint16_t mtu; /**< MTU value for inline IPsec port. */
};
/**
* nss_ppe_ipsec_add_intf_msg
* Message structure for adding dynamic IPsec/DTLS interface to inline IPsec port.
*/
struct nss_ppe_ipsec_add_intf_msg {
uint32_t nss_ifnum; /**< Dynamic IPsec/DTLS interface number. */
};
/**
* nss_ppe_ipsec_del_intf_msg
* Message structure for deleting dynamic IPsec/DTLS interface to inline IPsec port.
*/
struct nss_ppe_ipsec_del_intf_msg {
uint32_t nss_ifnum; /**< Dynamic IPsec/DTLS interface number. */
};
/**
* nss_ppe_msg
* Data for sending and receiving PPE host-to-NSS messages.
*/
struct nss_ppe_msg {
struct nss_cmn_msg cm; /**< Common message header. */
/**
* Payload of a PPE host-to-NSS message.
*/
union {
struct nss_ppe_sync_stats_msg stats;
/**< Synchronization statistics. */
struct nss_ppe_ipsec_port_config_msg ipsec_config;
/**< PPE inline IPsec port configuration message. */
struct nss_ppe_ipsec_port_mtu_msg ipsec_mtu;
/**< Inline IPsec port MTU change message. */
struct nss_ppe_ipsec_add_intf_msg ipsec_addif;
/**< Inline IPsec NSS interface attach message. */
struct nss_ppe_ipsec_del_intf_msg ipsec_delif;
/**< Inline IPsec NSS interface detach message. */
} msg; /**< Message payload. */
};
/**
* Callback function for receiving PPE messages.
*
* @datatypes
* nss_ppe_msg
*
* @param[in] app_data Pointer to the application context of the message.
* @param[in] msg Pointer to the message data.
*/
typedef void (*nss_ppe_msg_callback_t)(void *app_data, struct nss_ppe_msg *msg);
/**
* nss_ppe_tx_msg
* Sends PPE messages to the NSS.
*
* @datatypes
* nss_ctx_instance \n
* nss_ppe_msg
*
* @param[in] nss_ctx Pointer to the NSS context.
* @param[in] msg Pointer to the message data.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
/**
* nss_ppe_tx_msg_sync
* Sends PPE messages synchronously to the NSS.
*
* @datatypes
* nss_ctx_instance \n
* nss_ppe_msg
*
* @param[in] nss_ctx Pointer to the NSS context.
* @param[in,out] msg Pointer to the message data.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg);
/**
* nss_ppe_msg_init
* Initializes a PPE message.
*
* @datatypes
* nss_ppe_msg
*
* @param[in,out] ncm Pointer to the message.
* @param[in] if_num Interface number
* @param[in] type Type of message.
* @param[in] len Size of the payload.
* @param[in] cb Callback function for the message.
* @param[in] app_data Pointer to the application context of the message.
*
* @return
* None.
*/
void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data);
/**
* nss_ppe_get_context
* Gets the PPE context used in nss_ppe_tx.
*
* @return
* Pointer to the NSS core context.
*/
struct nss_ctx_instance *nss_ppe_get_context(void);
/**
* nss_ppe_tx_ipsec_config_msg
* Sends the PPE a message to configure inline IPsec port.
*
* @param[in] if_num Static IPsec interface number.
* @param[in] vsi_num Default VSI number associated with inline IPsec port.
* @param[in] mtu Default MTU of static inline IPsec port.
* @param[in] mru Default MRU of static inline IPsec port.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_ipsec_config_msg(uint32_t nss_ifnum, uint32_t vsi_num, uint16_t mtu, uint16_t mru);
/**
* nss_ppe_tx_ipsec_mtu_msg
* Sends the PPE a message to configure MTU value on IPsec port.
*
* @param[in] nss_ifnum Static IPsec interface number.
* @param[in] mtu MTU of static IPsec interface.
* @param[in] mru MRU of static IPsec interface.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_ipsec_mtu_msg(uint32_t nss_ifnum, uint16_t mtu, uint16_t mru);
/**
* nss_ppe_tx_ipsec_add_intf_msg
* Sends the PPE a message to attach a dynamic interface number to IPsec port.
*
* @param[in] if_num Dynamic IPsec/DTLS interface number.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_ipsec_add_intf_msg(uint32_t nss_ifnum);
/**
* nss_ppe_tx_ipsec_del_intf_msg
* Sends the PPE a message to detach a dynamic interface number to IPsec port.
*
* @param[in] if_num Dynamic IPsec/DTLS interface number.
*
* @return
* Status of the Tx operation.
*/
nss_tx_status_t nss_ppe_tx_ipsec_del_intf_msg(uint32_t nss_ifnum);
/*
* nss_ppe_reg_read()
*/
static inline void nss_ppe_reg_read(u32 reg, u32 *val)
{
*val = readl((ppe_pvt.ppe_base + reg));
}
/*
* nss_ppe_reg_write()
*/
static inline void nss_ppe_reg_write(u32 reg, u32 val)
{
writel(val, (ppe_pvt.ppe_base + reg));
}
/*
* nss_ppe_log.h
* NSS PPE Log Header File
*/
/*
* nss_ppe_log_tx_msg
* Logs a ppe message that is sent to the NSS firmware.
*/
void nss_ppe_log_tx_msg(struct nss_ppe_msg *npm);
/*
* nss_ppe_log_rx_msg
* Logs a ppe message that is received from the NSS firmware.
*/
void nss_ppe_log_rx_msg(struct nss_ppe_msg *npm);