diff --git a/drivers/net/ipq9574/ipq9574_edma.c b/drivers/net/ipq9574/ipq9574_edma.c index fe75be55fb..c3109438e6 100644 --- a/drivers/net/ipq9574/ipq9574_edma.c +++ b/drivers/net/ipq9574/ipq9574_edma.c @@ -59,6 +59,8 @@ extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id); extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id); extern int ipq_board_fw_download(unsigned int phy_addr); +static int tftp_acl_our_port; + /* * EDMA hardware instance */ @@ -408,6 +410,11 @@ static int ipq9574_eth_snd(struct eth_device *dev, void *packet, int length) txdesc_ring = ehw->txdesc_ring; + if (tftp_acl_our_port != tftp_our_port) { + /* Allowing tftp packets */ + ipq9574_ppe_acl_set(3, 0x4, 0x1, tftp_our_port, 0xffff, 0, 0); + tftp_acl_our_port = tftp_our_port; + } /* * Read TXDESC ring producer index */ diff --git a/drivers/net/ipq9574/ipq9574_ppe.c b/drivers/net/ipq9574/ipq9574_ppe.c index 767d889d9d..5b7be0e14c 100644 --- a/drivers/net/ipq9574/ipq9574_ppe.c +++ b/drivers/net/ipq9574/ipq9574_ppe.c @@ -51,6 +51,74 @@ static inline void ipq9574_ppe_reg_write(u32 reg, u32 val) writel(val, (void *)(IPQ9574_PPE_BASE_ADDR + reg)); } +void ppe_ipo_rule_reg_set(union ipo_rule_reg_u *hw_reg, int rule_id) +{ + int i; + + for (i = 0; i < 3; i++) { + ipq9574_ppe_reg_write(IPO_CSR_BASE_ADDR + IPO_RULE_REG_ADDRESS + + (rule_id * IPO_RULE_REG_INC) + (i * 4), hw_reg->val[i]); + } +} + +void ppe_ipo_mask_reg_set(union ipo_mask_reg_u *hw_mask, int rule_id) +{ + int i; + + for (i = 0; i < 2; i++) { + ipq9574_ppe_reg_write((IPO_CSR_BASE_ADDR + IPO_MASK_REG_ADDRESS + + (rule_id * IPO_MASK_REG_INC) + (i * 4)), hw_mask->val[i]); + } +} + +void ppe_ipo_action_set(union ipo_action_u *hw_act, int rule_id) +{ + int i; + + for (i = 0; i < 5; i++) { + ipq9574_ppe_reg_write((IPE_L2_BASE_ADDR + IPO_ACTION_ADDRESS + + (rule_id * IPO_ACTION_INC) + (i * 4)), hw_act->val[i]); + } +} + +void ipq9574_ppe_acl_set(int rule_id, int rule_type, int pkt_type, int l4_port_no, int l4_port_mask, int permit, int deny) +{ + union ipo_rule_reg_u hw_reg = {0}; + union ipo_mask_reg_u hw_mask = {0}; + union ipo_action_u hw_act = {0}; + + memset(&hw_reg, 0, sizeof(hw_reg)); + memset(&hw_mask, 0, sizeof(hw_mask)); + memset(&hw_act, 0, sizeof(hw_act)); + + if (rule_id < MAX_RULE) { + if (rule_type == ADPT_ACL_HPPE_IPV4_DIP_RULE) { + hw_reg.bf.rule_type = ADPT_ACL_HPPE_IPV4_DIP_RULE; + hw_reg.bf.rule_field_0 = l4_port_no; + hw_reg.bf.rule_field_1 = pkt_type<<17; + hw_mask.bf.maskfield_0 = l4_port_mask; + hw_mask.bf.maskfield_1 = 7<<17; + if (permit == 0x0) { + hw_act.bf.dest_info_change_en = 1; + hw_act.bf.fwd_cmd = 0;/*forward*/ + hw_reg.bf.pri = 0x1; + } + + if (deny == 0x1) { + hw_act.bf.dest_info_change_en = 1; + hw_act.bf.fwd_cmd = 1;/*drop*/ + hw_reg.bf.pri = 0x0; + + } + hw_reg.bf.src_0 = 0x0; + hw_reg.bf.src_1 = 0x3f; + ppe_ipo_rule_reg_set(&hw_reg, rule_id); + ppe_ipo_mask_reg_set(&hw_mask, rule_id); + ppe_ipo_action_set(&hw_act, rule_id); + } + } +} + /* * ipq9574_ppe_vp_port_tbl_set() */ @@ -900,4 +968,10 @@ void ipq9574_ppe_provision_init(void) ipq9574_gmac_port_enable(i); ppe_port_bridge_txmac_set(i + 1, 1); } + + /* Allowing DHCP packets */ + ipq9574_ppe_acl_set(0, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 67, 0xffff, 0, 0); + ipq9574_ppe_acl_set(1, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 68, 0xffff, 0, 0); + /* Dropping all the UDP packets */ + ipq9574_ppe_acl_set(2, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 0, 0, 0, 1); } diff --git a/drivers/net/ipq9574/ipq9574_ppe.h b/drivers/net/ipq9574/ipq9574_ppe.h index a13850475a..9e0a8d953e 100644 --- a/drivers/net/ipq9574/ipq9574_ppe.h +++ b/drivers/net/ipq9574/ipq9574_ppe.h @@ -63,6 +63,61 @@ union port_mux_ctrl_u { struct port_mux_ctrl bf; }; +enum { + TCP_PKT, + UDP_PKT, +}; + +#define ADPT_ACL_HPPE_IPV4_DIP_RULE 4 +#define MAX_RULE 512 + +struct ipo_rule_reg { + uint32_t rule_field_0:32; + uint32_t rule_field_1:20; + uint32_t fake_mac_header:1; + uint32_t range_en:1; + uint32_t inverse_en:1; + uint32_t rule_type:5; + uint32_t src_type:3; + uint32_t src_0:1; + uint32_t src_1:7; + uint32_t pri:9; + uint32_t res_chain:1; + uint32_t post_routing_en:1; + uint32_t _reserved0:14; +}; + +union ipo_rule_reg_u { + uint32_t val[3]; + struct ipo_rule_reg bf; +}; + +struct ipo_mask_reg { + uint32_t maskfield_0:32; + uint32_t maskfield_1:21; + uint32_t _reserved0:11; +}; + +union ipo_mask_reg_u { + uint32_t val[2]; + struct ipo_mask_reg bf; +}; + +struct ipo_action { + uint32_t dest_info_change_en:1; + uint32_t fwd_cmd:2; + uint32_t _reserved0:29; + uint32_t _reserved1:32; + uint32_t _reserved2:32; + uint32_t _reserved3:32; + uint32_t _reserved4:32; +}; + +union ipo_action_u { + uint32_t val[5]; + struct ipo_action bf; +}; + #define IPQ9574_PORT_MUX_CTRL 0x10 #define IPQ9574_PORT_MUX_CTRL_NUM 1 #define IPQ9574_PORT_MUX_CTRL_INC 0x4 @@ -91,6 +146,12 @@ union port_mux_ctrl_u { #define IPQ9574_PPE_MAC_MIB_CTL 0x001034 #define IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR 0x400000 +#define IPQ9574_PPE_TM_SHP_CFG_L0_OFFSET 0x00000030 +#define IPQ9574_PPE_TM_SHP_CFG_L1_OFFSET 0x00000034 +#define IPQ9574_PPE_TM_SHP_CFG_L0 IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\ + IPQ9574_PPE_TM_SHP_CFG_L0_OFFSET +#define IPQ9574_PPE_TM_SHP_CFG_L1 IPQ9574_PPE_TRAFFIC_MANAGER_BASE_ADDR +\ + IPQ9574_PPE_TM_SHP_CFG_L1_OFFSET #define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_ADDR 0x10000 #define IPQ9574_PPE_L0_FLOW_PORT_MAP_TBL_INC 0x10 diff --git a/include/configs/ipq9574.h b/include/configs/ipq9574.h index 63f25a3fe3..4a832186f4 100644 --- a/include/configs/ipq9574.h +++ b/include/configs/ipq9574.h @@ -304,7 +304,7 @@ extern loff_t board_env_size; #define CONFIG_IPQ9574_BRIDGED_MODE 1 #define CONFIG_NET_RETRY_COUNT 5 #define CONFIG_SYS_RX_ETH_BUFFER 128 -#define CONFIG_TFTP_BLOCKSIZE 1024 +#define CONFIG_TFTP_BLOCKSIZE 1280 #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_MII