1f48298d3SIoana Ciornei /* SPDX-License-Identifier: GPL-2.0 */ 2f48298d3SIoana Ciornei /* 3f48298d3SIoana Ciornei * DPAA2 Ethernet Switch declarations 4f48298d3SIoana Ciornei * 5f48298d3SIoana Ciornei * Copyright 2014-2016 Freescale Semiconductor Inc. 6f48298d3SIoana Ciornei * Copyright 2017-2021 NXP 7f48298d3SIoana Ciornei * 8f48298d3SIoana Ciornei */ 9f48298d3SIoana Ciornei 10f48298d3SIoana Ciornei #ifndef __ETHSW_H 11f48298d3SIoana Ciornei #define __ETHSW_H 12f48298d3SIoana Ciornei 13f48298d3SIoana Ciornei #include <linux/netdevice.h> 14f48298d3SIoana Ciornei #include <linux/etherdevice.h> 15f48298d3SIoana Ciornei #include <linux/rtnetlink.h> 16f48298d3SIoana Ciornei #include <linux/if_vlan.h> 17f48298d3SIoana Ciornei #include <uapi/linux/if_bridge.h> 18f48298d3SIoana Ciornei #include <net/switchdev.h> 19f48298d3SIoana Ciornei #include <linux/if_bridge.h> 20f48298d3SIoana Ciornei #include <linux/fsl/mc.h> 21f48298d3SIoana Ciornei #include <soc/fsl/dpaa2-io.h> 22f48298d3SIoana Ciornei 23f48298d3SIoana Ciornei #include "dpsw.h" 24f48298d3SIoana Ciornei 25f48298d3SIoana Ciornei /* Number of IRQs supported */ 26f48298d3SIoana Ciornei #define DPSW_IRQ_NUM 2 27f48298d3SIoana Ciornei 28f48298d3SIoana Ciornei /* Port is member of VLAN */ 29f48298d3SIoana Ciornei #define ETHSW_VLAN_MEMBER 1 30f48298d3SIoana Ciornei /* VLAN to be treated as untagged on egress */ 31f48298d3SIoana Ciornei #define ETHSW_VLAN_UNTAGGED 2 32f48298d3SIoana Ciornei /* Untagged frames will be assigned to this VLAN */ 33f48298d3SIoana Ciornei #define ETHSW_VLAN_PVID 4 34f48298d3SIoana Ciornei /* VLAN configured on the switch */ 35f48298d3SIoana Ciornei #define ETHSW_VLAN_GLOBAL 8 36f48298d3SIoana Ciornei 37f48298d3SIoana Ciornei /* Maximum Frame Length supported by HW (currently 10k) */ 38f48298d3SIoana Ciornei #define DPAA2_MFL (10 * 1024) 39f48298d3SIoana Ciornei #define ETHSW_MAX_FRAME_LENGTH (DPAA2_MFL - VLAN_ETH_HLEN - ETH_FCS_LEN) 40f48298d3SIoana Ciornei #define ETHSW_L2_MAX_FRM(mtu) ((mtu) + VLAN_ETH_HLEN + ETH_FCS_LEN) 41f48298d3SIoana Ciornei 42f48298d3SIoana Ciornei #define ETHSW_FEATURE_MAC_ADDR BIT(0) 43f48298d3SIoana Ciornei 44f48298d3SIoana Ciornei /* Number of receive queues (one RX and one TX_CONF) */ 45f48298d3SIoana Ciornei #define DPAA2_SWITCH_RX_NUM_FQS 2 46f48298d3SIoana Ciornei 47f48298d3SIoana Ciornei /* Hardware requires alignment for ingress/egress buffer addresses */ 48f48298d3SIoana Ciornei #define DPAA2_SWITCH_RX_BUF_RAW_SIZE PAGE_SIZE 49f48298d3SIoana Ciornei #define DPAA2_SWITCH_RX_BUF_TAILROOM \ 50f48298d3SIoana Ciornei SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) 51f48298d3SIoana Ciornei #define DPAA2_SWITCH_RX_BUF_SIZE \ 52f48298d3SIoana Ciornei (DPAA2_SWITCH_RX_BUF_RAW_SIZE - DPAA2_SWITCH_RX_BUF_TAILROOM) 53f48298d3SIoana Ciornei 54f48298d3SIoana Ciornei #define DPAA2_SWITCH_STORE_SIZE 16 55f48298d3SIoana Ciornei 56f48298d3SIoana Ciornei /* Buffer management */ 57f48298d3SIoana Ciornei #define BUFS_PER_CMD 7 58f48298d3SIoana Ciornei #define DPAA2_ETHSW_NUM_BUFS (1024 * BUFS_PER_CMD) 59f48298d3SIoana Ciornei #define DPAA2_ETHSW_REFILL_THRESH (DPAA2_ETHSW_NUM_BUFS * 5 / 6) 60f48298d3SIoana Ciornei 61f48298d3SIoana Ciornei /* Number of times to retry DPIO portal operations while waiting 62f48298d3SIoana Ciornei * for portal to finish executing current command and become 63f48298d3SIoana Ciornei * available. We want to avoid being stuck in a while loop in case 64f48298d3SIoana Ciornei * hardware becomes unresponsive, but not give up too easily if 65f48298d3SIoana Ciornei * the portal really is busy for valid reasons 66f48298d3SIoana Ciornei */ 67f48298d3SIoana Ciornei #define DPAA2_SWITCH_SWP_BUSY_RETRIES 1000 68f48298d3SIoana Ciornei 69f48298d3SIoana Ciornei /* Hardware annotation buffer size */ 70f48298d3SIoana Ciornei #define DPAA2_SWITCH_HWA_SIZE 64 71f48298d3SIoana Ciornei /* Software annotation buffer size */ 72f48298d3SIoana Ciornei #define DPAA2_SWITCH_SWA_SIZE 64 73f48298d3SIoana Ciornei 74f48298d3SIoana Ciornei #define DPAA2_SWITCH_TX_BUF_ALIGN 64 75f48298d3SIoana Ciornei 76f48298d3SIoana Ciornei #define DPAA2_SWITCH_TX_DATA_OFFSET \ 77f48298d3SIoana Ciornei (DPAA2_SWITCH_HWA_SIZE + DPAA2_SWITCH_SWA_SIZE) 78f48298d3SIoana Ciornei 79f48298d3SIoana Ciornei #define DPAA2_SWITCH_NEEDED_HEADROOM \ 80f48298d3SIoana Ciornei (DPAA2_SWITCH_TX_DATA_OFFSET + DPAA2_SWITCH_TX_BUF_ALIGN) 81f48298d3SIoana Ciornei 82f48298d3SIoana Ciornei extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops; 83f48298d3SIoana Ciornei 84f48298d3SIoana Ciornei struct ethsw_core; 85f48298d3SIoana Ciornei 86f48298d3SIoana Ciornei struct dpaa2_switch_fq { 87f48298d3SIoana Ciornei struct ethsw_core *ethsw; 88f48298d3SIoana Ciornei enum dpsw_queue_type type; 89f48298d3SIoana Ciornei struct dpaa2_io_store *store; 90f48298d3SIoana Ciornei struct dpaa2_io_notification_ctx nctx; 91f48298d3SIoana Ciornei struct napi_struct napi; 92f48298d3SIoana Ciornei u32 fqid; 93f48298d3SIoana Ciornei }; 94f48298d3SIoana Ciornei 95f48298d3SIoana Ciornei struct dpaa2_switch_fdb { 96f48298d3SIoana Ciornei struct net_device *bridge_dev; 97f48298d3SIoana Ciornei u16 fdb_id; 98f48298d3SIoana Ciornei bool in_use; 99f48298d3SIoana Ciornei }; 100f48298d3SIoana Ciornei 101f48298d3SIoana Ciornei /* Per port private data */ 102f48298d3SIoana Ciornei struct ethsw_port_priv { 103f48298d3SIoana Ciornei struct net_device *netdev; 104f48298d3SIoana Ciornei u16 idx; 105f48298d3SIoana Ciornei struct ethsw_core *ethsw_data; 106f48298d3SIoana Ciornei u8 link_state; 107f48298d3SIoana Ciornei u8 stp_state; 108f48298d3SIoana Ciornei 109f48298d3SIoana Ciornei u8 vlans[VLAN_VID_MASK + 1]; 110f48298d3SIoana Ciornei u16 pvid; 111f48298d3SIoana Ciornei u16 tx_qdid; 112f48298d3SIoana Ciornei 113f48298d3SIoana Ciornei struct dpaa2_switch_fdb *fdb; 114b54eb093SIoana Ciornei bool bcast_flood; 115*6253d5e3SIoana Ciornei bool ucast_flood; 116f48298d3SIoana Ciornei }; 117f48298d3SIoana Ciornei 118f48298d3SIoana Ciornei /* Switch data */ 119f48298d3SIoana Ciornei struct ethsw_core { 120f48298d3SIoana Ciornei struct device *dev; 121f48298d3SIoana Ciornei struct fsl_mc_io *mc_io; 122f48298d3SIoana Ciornei u16 dpsw_handle; 123f48298d3SIoana Ciornei struct dpsw_attr sw_attr; 124f48298d3SIoana Ciornei u16 major, minor; 125f48298d3SIoana Ciornei unsigned long features; 126f48298d3SIoana Ciornei int dev_id; 127f48298d3SIoana Ciornei struct ethsw_port_priv **ports; 128f48298d3SIoana Ciornei struct iommu_domain *iommu_domain; 129f48298d3SIoana Ciornei 130f48298d3SIoana Ciornei u8 vlans[VLAN_VID_MASK + 1]; 131f48298d3SIoana Ciornei 132f48298d3SIoana Ciornei struct workqueue_struct *workqueue; 133f48298d3SIoana Ciornei 134f48298d3SIoana Ciornei struct dpaa2_switch_fq fq[DPAA2_SWITCH_RX_NUM_FQS]; 135f48298d3SIoana Ciornei struct fsl_mc_device *dpbp_dev; 136f48298d3SIoana Ciornei int buf_count; 137f48298d3SIoana Ciornei u16 bpid; 138f48298d3SIoana Ciornei int napi_users; 139f48298d3SIoana Ciornei 140f48298d3SIoana Ciornei struct dpaa2_switch_fdb *fdbs; 141f48298d3SIoana Ciornei }; 142f48298d3SIoana Ciornei 143f48298d3SIoana Ciornei static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw) 144f48298d3SIoana Ciornei { 145f48298d3SIoana Ciornei if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) { 146f48298d3SIoana Ciornei dev_err(ethsw->dev, "Control Interface is disabled, cannot probe\n"); 147f48298d3SIoana Ciornei return false; 148f48298d3SIoana Ciornei } 149f48298d3SIoana Ciornei 150f48298d3SIoana Ciornei if (ethsw->sw_attr.flooding_cfg != DPSW_FLOODING_PER_FDB) { 151f48298d3SIoana Ciornei dev_err(ethsw->dev, "Flooding domain is not per FDB, cannot probe\n"); 152f48298d3SIoana Ciornei return false; 153f48298d3SIoana Ciornei } 154f48298d3SIoana Ciornei 155f48298d3SIoana Ciornei if (ethsw->sw_attr.broadcast_cfg != DPSW_BROADCAST_PER_FDB) { 156f48298d3SIoana Ciornei dev_err(ethsw->dev, "Broadcast domain is not per FDB, cannot probe\n"); 157f48298d3SIoana Ciornei return false; 158f48298d3SIoana Ciornei } 159f48298d3SIoana Ciornei 160f48298d3SIoana Ciornei if (ethsw->sw_attr.max_fdbs < ethsw->sw_attr.num_ifs) { 161f48298d3SIoana Ciornei dev_err(ethsw->dev, "The number of FDBs is lower than the number of ports, cannot probe\n"); 162f48298d3SIoana Ciornei return false; 163f48298d3SIoana Ciornei } 164f48298d3SIoana Ciornei 165f48298d3SIoana Ciornei return true; 166f48298d3SIoana Ciornei } 167f48298d3SIoana Ciornei 168f48298d3SIoana Ciornei bool dpaa2_switch_port_dev_check(const struct net_device *netdev); 169f48298d3SIoana Ciornei 170f48298d3SIoana Ciornei int dpaa2_switch_port_vlans_add(struct net_device *netdev, 171f48298d3SIoana Ciornei const struct switchdev_obj_port_vlan *vlan); 172f48298d3SIoana Ciornei 173f48298d3SIoana Ciornei int dpaa2_switch_port_vlans_del(struct net_device *netdev, 174f48298d3SIoana Ciornei const struct switchdev_obj_port_vlan *vlan); 175f48298d3SIoana Ciornei 176f48298d3SIoana Ciornei typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv, 177f48298d3SIoana Ciornei struct fdb_dump_entry *fdb_entry, 178f48298d3SIoana Ciornei void *data); 179f48298d3SIoana Ciornei #endif /* __ETHSW_H */ 180