ipq807x: Add ACL support for edma

Change-Id: I9102709f2a744e8434cc8d96d8a396766c4fc6c0
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
Sham Muthayyan 2018-03-29 18:00:19 +05:30 committed by Gerrit - the friendly Code Review server
parent 750b3ca7ac
commit 039b3c19d5
5 changed files with 147 additions and 3 deletions

View file

@ -59,6 +59,7 @@ extern void qca8075_phy_interface_set_mode(uint32_t phy_id,
uint32_t mode);
extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id);
static int tftp_acl_our_port;
/*
* EDMA hardware instance
@ -469,6 +470,11 @@ static int ipq807x_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 */
ipq807x_ppe_acl_set(3, 0x4, 0x1, tftp_our_port, 0xffff, 0, 0);
tftp_acl_our_port = tftp_our_port;
}
/*
* Read TXDESC ring producer index
*/

View file

@ -25,7 +25,6 @@
DECLARE_GLOBAL_DATA_PTR;
#define pr_info(fmt, args...) printf(fmt, ##args);
/*
* ipq807x_ppe_gpio_reg_write()
*/
@ -50,6 +49,74 @@ static inline void ipq807x_ppe_reg_write(u32 reg, u32 val)
writel(val, (void *)(IPQ807X_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++) {
ipq807x_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++) {
ipq807x_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++) {
ipq807x_ppe_reg_write((IPE_L2_BASE_ADDR + IPO_ACTION_ADDRESS +
(rule_id * IPO_ACTION_INC) + (i * 4)), hw_act->val[i]);
}
}
void ipq807x_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 = 0x6;
hw_reg.bf.src_1 = 0x7;
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);
}
}
}
/*
* ipq807x_ppe_vp_port_tbl_set()
*/
@ -1193,4 +1260,10 @@ void ipq807x_ppe_provision_init(void)
/* Port 0-5 enable */
for (i = 0; i < 6; i++)
ipq807x_gmac_port_enable(i);
/* Allowing DHCP packets */
ipq807x_ppe_acl_set(0, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 67, 0xffff, 0, 0);
ipq807x_ppe_acl_set(1, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 68, 0xffff, 0, 0);
/* Dropping all the UDP packets */
ipq807x_ppe_acl_set(2, ADPT_ACL_HPPE_IPV4_DIP_RULE, UDP_PKT, 0, 0, 0, 1);
}

View file

@ -49,6 +49,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:4;
uint32_t src_type:2;
uint32_t src_0:3;
uint32_t src_1:5;
uint32_t pri:9;
uint32_t res_chain:1;
uint32_t post_routing_en:1;
uint32_t _reserved0:16;
};
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 IPQ807X_PORT_MUX_CTRL 0x10
#define PORT4_PCS_SEL_GMII_FROM_PCS0 1
#define PORT4_PCS_SEL_RGMII 0
@ -180,3 +235,13 @@ union port_mux_ctrl_u {
#define PORT_BRIDGE_CTRL_INC 0x4
#define TX_MAC_EN (1 << 16)
#define IPO_CSR_BASE_ADDR 0x0b0000
#define IPO_RULE_REG_ADDRESS 0x0
#define IPO_RULE_REG_INC 0x10
#define IPO_MASK_REG_ADDRESS 0x2000
#define IPO_MASK_REG_INC 0x10
#define IPO_ACTION_ADDRESS 0x8000
#define IPO_ACTION_INC 0x20

View file

@ -510,7 +510,7 @@ extern ushort net_our_vlan; /* Our VLAN */
extern ushort net_native_vlan; /* Our Native VLAN */
extern int net_restart_wrap; /* Tried all network devices */
extern int tftp_our_port;
enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
TFTPSRV, TFTPPUT, LINKLOCAL

View file

@ -70,7 +70,7 @@ static struct in_addr tftp_remote_ip;
/* The UDP port at their end */
static int tftp_remote_port;
/* The UDP port at our end */
static int tftp_our_port;
int tftp_our_port;
static int timeout_count;
/* packet sequence number */
static ulong tftp_cur_block;