Add the FE/PPE/QDMA register definitions and shared driver state needed by the Secure Offload Engine. Add a small SOE-facing header with stubs so later Ethernet and PPE changes remain buildable until the provider is enabled. Signed-off-by: Jihong Min --- drivers/net/ethernet/airoha/airoha_eth.h | 40 +++++++ drivers/net/ethernet/airoha/airoha_regs.h | 16 +++ drivers/net/ethernet/airoha/airoha_soe.h | 126 ++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 drivers/net/ethernet/airoha/airoha_soe.h diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h index 46b1c31939de..c5f09aedd7e7 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h @@ -16,6 +16,8 @@ #include #include +struct airoha_soe; + #define AIROHA_MAX_NUM_GDM_PORTS 4 #define AIROHA_MAX_NUM_GDM_DEVS 2 #define AIROHA_MAX_NUM_QDMA 2 @@ -189,18 +191,31 @@ struct airoha_queue { spinlock_t lock; struct airoha_queue_entry *entry; struct airoha_qdma_desc *desc; + /* Preserved for RX ring reprogramming; dmam_alloc_coherent() owns it. */ + dma_addr_t desc_dma; u16 head; u16 tail; int queued; int ndesc; + /* SOE RX rings may use coherent slots instead of page_pool fragments. */ + int rx_alloc_ndesc; int free_thr; int buf_size; bool txq_stopped; + bool rx_coherent; + bool rx_drop_chain; + void *rx_coherent_buf; + dma_addr_t rx_coherent_dma; + size_t rx_coherent_buf_size; struct napi_struct napi; struct page_pool *page_pool; struct sk_buff *skb; + /* First SOE descriptor metadata is kept while a scattered frame is built. */ + int rx_frame_descs; + u32 soe_rx_msg0; + u32 soe_rx_msg2; struct list_head tx_list; }; @@ -434,6 +449,16 @@ struct airoha_foe_stats64 { u64 packets; }; +struct airoha_ppe_soe_meta { + unsigned long expires; + u32 key_hash; + u16 foe_hash; + u8 valid; + u8 sa_index; + u8 hop; + u8 seen; +}; + struct airoha_flow_data { struct ethhdr eth; @@ -552,6 +577,11 @@ struct airoha_gdm_dev { u32 flags; int nbq; + /* Prevent toggling NETIF_F_HW_ESP while programmed SAs still exist. */ + atomic_t soe_xfrm_state_count; + /* Private SOE submit path into this GDM's active QDMA instance. */ + int (*soe_xmit_skb)(struct airoha_gdm_dev *dev, struct sk_buff *skb, + u32 msg0, u32 msg1, u32 msg2); struct airoha_hw_stats stats; }; @@ -581,6 +611,7 @@ struct airoha_ppe { struct hlist_head *foe_flow; u16 *foe_check_time; + struct airoha_ppe_soe_meta *soe_meta; struct airoha_foe_stats *foe_stats; dma_addr_t foe_stats_dma; @@ -621,6 +652,7 @@ struct airoha_eth { struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; + struct airoha_soe *soe; }; u32 airoha_rr(void __iomem *base, u32 offset); @@ -676,6 +708,14 @@ static inline bool airoha_is_7583(struct airoha_eth *eth) int airoha_get_fe_port(struct airoha_gdm_dev *dev); bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, struct airoha_gdm_dev *dev); +int airoha_qdma_xmit_skb(struct airoha_gdm_dev *dev, struct sk_buff *skb, + u32 msg0, u32 msg1, u32 msg2); +void airoha_ppe_soe_mark_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, + u16 hash, u8 sa_index, u8 hop); +bool airoha_ppe_soe_skb_marked(struct sk_buff *skb); +void airoha_ppe_soe_xmit_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, + struct net_device *netdev); +void airoha_ppe_soe_flush_sa(struct airoha_ppe *ppe, u8 sa_index); void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport); bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h index 436f3c8779c1..27e158d0fa4b 100644 --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h @@ -82,6 +82,10 @@ #define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) #define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) +/* TDMA/SOE port 7 needs shared-buffer flow control enabled in the PSE. */ +#define REG_PSE_FC_CFG 0x0098 +#define PSE_TDMA_SHARE_BUF_DIS_MASK BIT(23) + #define REG_GDM_MISC_CFG 0x0148 #define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) #define GDM2_CHN_VLD_MODE_MASK BIT(5) @@ -252,6 +256,8 @@ #define PPE_GLO_CFG_EN_MASK BIT(0) #define REG_PPE_PPE_FLOW_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x204) +#define PPE_FLOW_CFG_IP6_IPSEC_MASK BIT(28) +#define PPE_FLOW_CFG_IP4_IPSEC_MASK BIT(27) #define PPE_FLOW_CFG_IP6_HASH_GRE_KEY_MASK BIT(20) #define PPE_FLOW_CFG_IP4_HASH_GRE_KEY_MASK BIT(19) #define PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL_MASK BIT(18) @@ -851,6 +857,8 @@ #define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) /* TX MSG0 */ #define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) +/* SOE submit metadata: msg0 carries SA index, msg1 selects port 7 OQ8/OQ9. */ +#define QDMA_ETH_TXMSG_SOE_SA_MASK GENMASK(29, 24) #define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) #define QDMA_ETH_TXMSG_ICO_MASK BIT(13) #define QDMA_ETH_TXMSG_UCO_MASK BIT(12) @@ -873,6 +881,11 @@ /* RX MSG0 */ #define QDMA_ETH_RXMSG_SPTAG GENMASK(21, 14) +/* SOE completion metadata can use the full 16-bit SP tag word. */ +#define QDMA_ETH_RXMSG_SPTAG_FULL GENMASK(29, 14) +/* SOE completion metadata returned by the QDMA RX descriptor. */ +#define QDMA_ETH_RXMSG_SOE_MASK BIT(10) +#define QDMA_ETH_RXMSG_HOP_FLAGS_MASK GENMASK(2, 0) /* RX MSG1 */ #define QDMA_ETH_RXMSG_DEI_MASK BIT(31) #define QDMA_ETH_RXMSG_IP6_MASK BIT(30) @@ -883,6 +896,9 @@ #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) +/* RX MSG2 */ +/* SW_UDF carries the SA index for SOE completion frames. */ +#define QDMA_ETH_RXMSG_SW_UDF_MASK GENMASK(31, 24) struct airoha_qdma_desc { __le32 rsv; diff --git a/drivers/net/ethernet/airoha/airoha_soe.h b/drivers/net/ethernet/airoha/airoha_soe.h new file mode 100644 index 000000000000..0bde2e9c6b5b --- /dev/null +++ b/drivers/net/ethernet/airoha/airoha_soe.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Ethernet-facing declarations for the Airoha Secure Offload Engine (SOE) + * packet offload provider. + * + * airoha_eth owns SOE lifetime and calls these helpers to expose xfrm + * ESP/NAT-T offload on its netdevs. When CONFIG_NET_AIROHA_SOE is disabled, + * the stubs keep the Ethernet driver buildable without SOE support. + */ + +#ifndef AIROHA_SOE_H +#define AIROHA_SOE_H + +#include +#include +#include +#include +#include + +struct airoha_soe; +struct airoha_soe_sa; +struct airoha_eth; +struct airoha_gdm_dev; +struct device; +struct dst_entry; +struct net_device; +struct netlink_ext_ack; +struct sk_buff; +struct xfrm_state; + +#define AIROHA_SOE_FEATURE_ESP BIT(0) + +typedef int (*airoha_soe_xmit_skb_t)(struct airoha_gdm_dev *dev, + struct sk_buff *skb, u32 msg0, u32 msg1, + u32 msg2); + +#if IS_ENABLED(CONFIG_NET_AIROHA_SOE) +int airoha_soe_init(struct airoha_eth *eth); +void airoha_soe_deinit(struct airoha_eth *eth); +bool airoha_soe_available(struct airoha_soe *soe); +u32 airoha_soe_features(struct airoha_soe *soe); +void airoha_soe_build_netdev(struct net_device *dev, + airoha_soe_xmit_skb_t xmit_skb); +void airoha_soe_teardown_netdev(struct net_device *dev); +int airoha_soe_set_features(struct net_device *dev, + netdev_features_t features); +bool airoha_soe_rx_skb(struct airoha_soe *soe, struct sk_buff *skb, + unsigned int sa_index, u32 hop_flags); +bool airoha_soe_rx_plain_skb(struct airoha_gdm_dev *dev, + struct sk_buff *skb, struct net_device *rx_dev, + u16 foe_hash, u32 foe_reason, bool foe_valid); +bool airoha_soe_has_pending_rx(struct airoha_soe *soe); +int airoha_soe_xfrm_ppe_info(const struct dst_entry *dst, u8 *sa_index, + u8 *hop); +int airoha_soe_xmit(struct airoha_soe_sa *sa, struct airoha_gdm_dev *dev, + struct sk_buff *skb, struct xfrm_state *x); +#else +static inline int airoha_soe_init(struct airoha_eth *eth) +{ + return 0; +} + +static inline void airoha_soe_deinit(struct airoha_eth *eth) +{ +} + +static inline bool airoha_soe_available(struct airoha_soe *soe) +{ + return false; +} + +static inline u32 airoha_soe_features(struct airoha_soe *soe) +{ + return 0; +} + +static inline void airoha_soe_build_netdev(struct net_device *dev, + airoha_soe_xmit_skb_t xmit_skb) +{ +} + +static inline void airoha_soe_teardown_netdev(struct net_device *dev) +{ +} + +static inline int airoha_soe_set_features(struct net_device *dev, + netdev_features_t features) +{ + return 0; +} + +static inline bool airoha_soe_rx_skb(struct airoha_soe *soe, + struct sk_buff *skb, + unsigned int sa_index, u32 hop_flags) +{ + return false; +} + +static inline bool airoha_soe_rx_plain_skb(struct airoha_gdm_dev *dev, + struct sk_buff *skb, + struct net_device *rx_dev, + u16 foe_hash, u32 foe_reason, + bool foe_valid) +{ + return false; +} + +static inline bool airoha_soe_has_pending_rx(struct airoha_soe *soe) +{ + return false; +} + +static inline int airoha_soe_xfrm_ppe_info(const struct dst_entry *dst, + u8 *sa_index, u8 *hop) +{ + return -EOPNOTSUPP; +} + +static inline int airoha_soe_xmit(struct airoha_soe_sa *sa, + struct airoha_gdm_dev *dev, + struct sk_buff *skb, struct xfrm_state *x) +{ + return -EOPNOTSUPP; +} +#endif + +#endif /* AIROHA_SOE_H */ -- 2.53.0