@@ -18,6 +18,7 @@
#include "ppe_ops.h"
#define PPE_SCHEDULER_PORT_NUM 8
+#define MPPE_SCHEDULER_PORT_NUM 3
#define PPE_SCHEDULER_L0_NUM 300
#define PPE_SCHEDULER_L1_NUM 64
#define PPE_SP_PRIORITY_NUM 8
@@ -1118,6 +1119,59 @@ static int ppe_servcode_init(struct ppe_device *ppe_dev)
return ppe_servcode_config_set(ppe_dev, 1, servcode_cfg);
}
+static int ppe_port_ctrl_init(struct ppe_device *ppe_dev)
+{
+ union ppe_mru_mtu_ctrl_cfg_u mru_mtu_cfg;
+ int ret, port_num = PPE_SCHEDULER_PORT_NUM;
+ u32 reg_val;
+
+ if (ppe_type_get(ppe_dev) == PPE_TYPE_MPPE) {
+ for (ret = 0; ret < MPPE_SCHEDULER_PORT_NUM; ret++) {
+ reg_val = FIELD_PREP(PPE_TX_BUFF_THRSH_XOFF, 3) |
+ FIELD_PREP(PPE_TX_BUFF_THRSH_XON, 3);
+ ppe_write(ppe_dev, PPE_TX_BUFF_THRSH + PPE_TX_BUFF_THRSH_INC * ret,
+ reg_val);
+
+ /* Fix 147B line rate on physical port */
+ if (ret != 0)
+ ppe_mask(ppe_dev, PPE_RX_FIFO_CFG + PPE_RX_FIFO_CFG_INC * ret,
+ PPE_RX_FIFO_CFG_THRSH,
+ FIELD_PREP(PPE_RX_FIFO_CFG_THRSH, 7));
+ }
+
+ port_num = MPPE_SCHEDULER_PORT_NUM;
+ }
+
+ for (ret = 0; ret < port_num; ret++) {
+ if (ret != 0) {
+ memset(&mru_mtu_cfg, 0, sizeof(mru_mtu_cfg));
+ ppe_read_tbl(ppe_dev,
+ PPE_MRU_MTU_CTRL_TBL + PPE_MRU_MTU_CTRL_TBL_INC * ret,
+ mru_mtu_cfg.val, sizeof(mru_mtu_cfg.val));
+
+ /* Drop the packet when the packet size is more than
+ * the MTU of the physical interface.
+ */
+ mru_mtu_cfg.bf.mru_cmd = PPE_ACTION_DROP;
+ mru_mtu_cfg.bf.mtu_cmd = PPE_ACTION_DROP;
+
+ ppe_write_tbl(ppe_dev,
+ PPE_MRU_MTU_CTRL_TBL + PPE_MRU_MTU_CTRL_TBL_INC * ret,
+ mru_mtu_cfg.val, sizeof(mru_mtu_cfg.val));
+
+ ppe_mask(ppe_dev,
+ PPE_MC_MTU_CTRL_TBL + PPE_MC_MTU_CTRL_TBL_INC * ret,
+ PPE_MC_MTU_CTRL_TBL_MTU_CMD,
+ FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU_CMD, PPE_ACTION_DROP));
+ }
+
+ /* Enable PPE port counter */
+ ppe_counter_set(ppe_dev, ret, true);
+ }
+
+ return 0;
+}
+
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
{
int ret;
@@ -1126,7 +1180,11 @@ static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
if (ret)
return ret;
- return ppe_servcode_init(ppe_dev);
+ ret = ppe_servcode_init(ppe_dev);
+ if (ret)
+ return ret;
+
+ return ppe_port_ctrl_init(ppe_dev);
}
static int qcom_ppe_probe(struct platform_device *pdev)
@@ -132,6 +132,16 @@ enum {
PPE_TYPE_MAX = 0xff,
};
+/* The action of packet received by PPE can be forwarded, dropped, copied
+ * to CPU(enter multicast queue), redirected to CPU(enter unicast queue).
+ */
+enum {
+ PPE_ACTION_FORWARD = 0,
+ PPE_ACTION_DROP,
+ PPE_ACTION_COPY_TO_CPU,
+ PPE_ACTION_REDIRECTED_TO_CPU
+};
+
/* PPE private data of different PPE type device */
struct ppe_data {
int ppe_type;
@@ -311,6 +311,28 @@ int ppe_servcode_config_set(struct ppe_device *ppe_dev,
return ppe_write(ppe_dev, PPE_TL_SERVICE_TBL + PPE_TL_SERVICE_TBL_INC * servcode, val);
}
+int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable)
+{
+ union ppe_mru_mtu_ctrl_cfg_u mru_mtu_cfg;
+
+ memset(&mru_mtu_cfg, 0, sizeof(mru_mtu_cfg));
+
+ ppe_read_tbl(ppe_dev, PPE_MRU_MTU_CTRL_TBL + PPE_MRU_MTU_CTRL_TBL_INC * port,
+ mru_mtu_cfg.val, sizeof(mru_mtu_cfg.val));
+ mru_mtu_cfg.bf.rx_cnt_en = enable;
+ mru_mtu_cfg.bf.tx_cnt_en = enable;
+ ppe_write_tbl(ppe_dev, PPE_MRU_MTU_CTRL_TBL + PPE_MRU_MTU_CTRL_TBL_INC * port,
+ mru_mtu_cfg.val, sizeof(mru_mtu_cfg.val));
+
+ ppe_mask(ppe_dev, PPE_MC_MTU_CTRL_TBL + PPE_MC_MTU_CTRL_TBL_INC * port,
+ PPE_MC_MTU_CTRL_TBL_TX_CNT_EN,
+ FIELD_PREP(PPE_MC_MTU_CTRL_TBL_TX_CNT_EN, enable));
+
+ return ppe_mask(ppe_dev, PPE_PORT_EG_VLAN + PPE_PORT_EG_VLAN_INC * port,
+ PPE_PORT_EG_VLAN_TX_COUNTING_EN,
+ FIELD_PREP(PPE_PORT_EG_VLAN_TX_COUNTING_EN, enable));
+}
+
static const struct ppe_queue_ops qcom_ppe_queue_config_ops = {
.queue_scheduler_set = ppe_queue_scheduler_set,
.queue_scheduler_get = ppe_queue_scheduler_get,
@@ -183,4 +183,5 @@ const struct ppe_queue_ops *ppe_queue_config_ops_get(void);
int ppe_servcode_config_set(struct ppe_device *ppe_dev,
int servcode,
struct ppe_servcode_cfg cfg);
+int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable);
#endif
@@ -14,6 +14,11 @@
#define PPE_BM_TDM_CTRL_TDM_OFFSET GENMASK(14, 8)
#define PPE_BM_TDM_CTRL_TDM_EN BIT(31)
+#define PPE_RX_FIFO_CFG 0xb004
+#define PPE_RX_FIFO_CFG_NUM 8
+#define PPE_RX_FIFO_CFG_INC 4
+#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)
+
#define PPE_BM_TDM_CFG_TBL 0xc000
#define PPE_BM_TDM_CFG_TBL_NUM 128
#define PPE_BM_TDM_CFG_TBL_INC 0x10
@@ -43,6 +48,17 @@ union ppe_service_cfg_u {
struct ppe_service_cfg bf;
};
+#define PPE_PORT_EG_VLAN 0x20020
+#define PPE_PORT_EG_VLAN_NUM 8
+#define PPE_PORT_EG_VLAN_INC 4
+#define PPE_PORT_EG_VLAN_PORT_VLAN_TYPE BIT(0)
+#define PPE_PORT_EG_VLAN_PORT_EG_VLAN_CTAG_MODE GENMASK(2, 1)
+#define PPE_PORT_EG_VLAN_PORT_EG_VLAN_STAG_MODE GENMASK(4, 3)
+#define PPE_PORT_EG_VLAN_VSI_TAG_MODE_EN BIT(5)
+#define PPE_PORT_EG_VLAN_PORT_EG_PCP_PROP_CMD BIT(6)
+#define PPE_PORT_EG_VLAN_PORT_EG_DEI_PROP_CMD BIT(7)
+#define PPE_PORT_EG_VLAN_TX_COUNTING_EN BIT(8)
+
#define PPE_EG_BRIDGE_CONFIG 0x20044
#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
@@ -73,6 +89,59 @@ union ppe_eg_service_cfg_u {
struct ppe_eg_service_cfg bf;
};
+#define PPE_TX_BUFF_THRSH 0x26100
+#define PPE_TX_BUFF_THRSH_NUM 8
+#define PPE_TX_BUFF_THRSH_INC 4
+#define PPE_TX_BUFF_THRSH_XOFF GENMASK(7, 0)
+#define PPE_TX_BUFF_THRSH_XON GENMASK(15, 8)
+
+#define PPE_MC_MTU_CTRL_TBL 0x60a00
+#define PPE_MC_MTU_CTRL_TBL_NUM 8
+#define PPE_MC_MTU_CTRL_TBL_INC 4
+#define PPE_MC_MTU_CTRL_TBL_MTU GENMASK(13, 0)
+#define PPE_MC_MTU_CTRL_TBL_MTU_CMD GENMASK(15, 14)
+#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN BIT(16)
+
+#define PPE_MRU_MTU_CTRL_TBL 0x65000
+#define PPE_MRU_MTU_CTRL_TBL_NUM 256
+#define PPE_MRU_MTU_CTRL_TBL_INC 0x10
+
+/* PPE port control configuration, the MTU and QoS are configured by
+ * this table.
+ */
+struct ppe_mru_mtu_ctrl_cfg {
+ u32 mru:14,
+ mru_cmd:2,
+ mtu:14,
+ mtu_cmd:2;
+
+ u32 rx_cnt_en:1,
+ tx_cnt_en:1,
+ src_profile:2,
+ pcp_qos_group_id:1,
+ dscp_qos_group_id:1,
+ pcp_res_prec_force:1,
+ dscp_res_prec_force:1,
+ preheader_res_prec:3,
+ pcp_res_prec:3,
+ dscp_res_prec:3,
+ flow_res_prec:3,
+ pre_acl_res_prec:3,
+ post_acl_res_prec:3,
+ source_filtering_bypass:1,
+ source_filtering_mode:1,
+ pre_ipo_outer_res_prec:3,
+ pre_ipo_inner_res_prec_0:1;
+
+ u32 pre_ipo_inner_res_prec_1:2,
+ res0:30;
+};
+
+union ppe_mru_mtu_ctrl_cfg_u {
+ u32 val[3];
+ struct ppe_mru_mtu_ctrl_cfg bf;
+};
+
#define PPE_IN_L2_SERVICE_TBL 0x66000
#define PPE_IN_L2_SERVICE_TBL_NUM 256
#define PPE_IN_L2_SERVICE_TBL_INC 0x10