Loading drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +4 −2 Original line number Diff line number Diff line Loading @@ -517,13 +517,15 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib, pr_err("frg "); if ((attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) || (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3)) { (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) || (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_1Q)) { pr_err("src_mac_addr:%pM ", attrib->src_mac_addr); } if ((attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP)) { (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q)) { pr_err("dst_mac_addr:%pM ", attrib->dst_mac_addr); } Loading drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +182 −268 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include "ipahal_i.h" #include "../../ipa_common_i.h" #define IPA_MAC_FLT_BITS (IPA_FLT_MAC_DST_ADDR_ETHER_II | \ IPA_FLT_MAC_SRC_ADDR_ETHER_II | IPA_FLT_MAC_DST_ADDR_802_3 | \ IPA_FLT_MAC_SRC_ADDR_802_3 | IPA_FLT_MAC_DST_ADDR_802_1Q | \ IPA_FLT_MAC_SRC_ADDR_802_1Q) /* * struct ipahal_fltrt_obj - Flt/Rt H/W information for specific IPA version * @support_hash: Is hashable tables supported Loading Loading @@ -597,102 +602,138 @@ static void ipa_fltrt_generate_mac_addr_hw_rule(u8 **extra, u8 **rest, *rest = ipa_write_8(mac_addr[i], *rest); } static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 **extra_wrds, u8 **rest_wrds) static inline void ipa_fltrt_get_mac_data(const struct ipa_rule_attrib *attrib, uint32_t attrib_mask, u8 *offset, const uint8_t **mac_addr, const uint8_t **mac_addr_mask) { u8 *extra = *extra_wrds; u8 *rest = *rest_wrds; u8 ofst_meq32 = 0; u8 ihl_ofst_rng16 = 0; u8 ihl_ofst_meq32 = 0; u8 ofst_meq128 = 0; int rc = 0; if (attrib->attrib_mask & IPA_FLT_TOS) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_TOS_EQ); extra = ipa_write_8(attrib->u.v4.tos, extra); if (attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { *offset = -14; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_PROTOCOL) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_PROTOCOL_EQ); extra = ipa_write_8(attrib->u.v4.protocol, extra); if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { *offset = -8; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; if (attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { *offset = -22; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { *offset = -16; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } ofst_meq128++; if (attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q) { *offset = -18; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_1Q) { *offset = -10; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr); static int ipa_fltrt_generate_mac_hw_rule_bdy(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 *ofst_meq128, u8 **extra, u8 **rest) { u8 offset = 0; const uint8_t *mac_addr = NULL; const uint8_t *mac_addr_mask = NULL; int i; uint32_t attrib_mask; ofst_meq128++; for (i = 0; i < hweight_long(IPA_MAC_FLT_BITS); i++) { switch (i) { case 0: attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II; break; case 1: attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II; break; case 2: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_3; break; case 3: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_3; break; case 4: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_1Q; break; case 5: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_1Q; break; default: return -EPERM; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { attrib_mask &= attrib->attrib_mask; if (!attrib_mask) continue; if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, *ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); ipa3_0_ofst_meq128[*ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ipa_fltrt_get_mac_data(attrib, attrib_mask, &offset, &mac_addr, &mac_addr_mask); ofst_meq128++; ipa_fltrt_generate_mac_addr_hw_rule(extra, rest, offset, mac_addr_mask, mac_addr); (*ofst_meq128)++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; return 0; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr); static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 **extra_wrds, u8 **rest_wrds) { u8 *extra = *extra_wrds; u8 *rest = *rest_wrds; u8 ofst_meq32 = 0; u8 ihl_ofst_rng16 = 0; u8 ihl_ofst_meq32 = 0; u8 ofst_meq128 = 0; int rc = 0; ofst_meq128++; if (attrib->attrib_mask & IPA_FLT_TOS) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_TOS_EQ); extra = ipa_write_8(attrib->u.v4.tos, extra); } if (attrib->attrib_mask & IPA_FLT_PROTOCOL) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_PROTOCOL_EQ); extra = ipa_write_8(attrib->u.v4.protocol, extra); } if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_fltrt_generate_mac_hw_rule_bdy(en_rule, attrib, &ofst_meq128, &extra, &rest)) goto err; } if (attrib->attrib_mask & IPA_FLT_TOS_MASKED) { Loading Loading @@ -1032,81 +1073,11 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule, ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_fltrt_generate_mac_hw_rule_bdy(en_rule, attrib, &ofst_meq128, &extra, &rest)) goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) { Loading Loading @@ -1747,6 +1718,65 @@ static void ipa_flt_generate_mac_addr_eq(struct ipa_ipfltri_rule_eq *eq_atrb, mac_addr[i]; } static int ipa_flt_generate_mac_eq( const struct ipa_rule_attrib *attrib, u16 *en_rule, u8 *ofst_meq128, struct ipa_ipfltri_rule_eq *eq_atrb) { u8 offset = 0; const uint8_t *mac_addr = NULL; const uint8_t *mac_addr_mask = NULL; int i; uint32_t attrib_mask; for (i = 0; i < hweight_long(IPA_MAC_FLT_BITS); i++) { switch (i) { case 0: attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II; break; case 1: attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II; break; case 2: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_3; break; case 3: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_3; break; case 4: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_1Q; break; case 5: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_1Q; break; default: return -EPERM; } attrib_mask &= attrib->attrib_mask; if (!attrib_mask) continue; if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, *ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[*ofst_meq128]); ipa_fltrt_get_mac_data(attrib, attrib_mask, &offset, &mac_addr, &mac_addr_mask); ipa_flt_generate_mac_addr_eq(eq_atrb, offset, mac_addr_mask, mac_addr, *ofst_meq128); (*ofst_meq128)++; } return 0; } static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip, const struct ipa_rule_attrib *attrib, struct ipa_ipfltri_rule_eq *eq_atrb) Loading @@ -1770,69 +1800,11 @@ static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip, eq_atrb->protocol_eq = attrib->u.v4.protocol; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_flt_generate_mac_eq(attrib, en_rule, &ofst_meq128, eq_atrb)) return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32, Loading Loading @@ -2200,69 +2172,11 @@ static int ipa_flt_generate_eq_ip6(enum ipa_ip_type ip, ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_flt_generate_mac_eq(attrib, en_rule, &ofst_meq128, eq_atrb)) return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32, Loading include/uapi/linux/msm_ipa.h +2 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,8 @@ #define IPA_FLT_L2TP_INNER_IPV4_DST_ADDR (1ul << 26) #define IPA_FLT_IS_PURE_ACK (1ul << 27) #define IPA_FLT_VLAN_ID (1ul << 28) #define IPA_FLT_MAC_SRC_ADDR_802_1Q (1ul << 29) #define IPA_FLT_MAC_DST_ADDR_802_1Q (1ul << 30) /** * maximal number of NAT PDNs in the PDN config table Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +4 −2 Original line number Diff line number Diff line Loading @@ -517,13 +517,15 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib, pr_err("frg "); if ((attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) || (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3)) { (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) || (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_1Q)) { pr_err("src_mac_addr:%pM ", attrib->src_mac_addr); } if ((attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP)) { (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) || (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q)) { pr_err("dst_mac_addr:%pM ", attrib->dst_mac_addr); } Loading
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +182 −268 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include "ipahal_i.h" #include "../../ipa_common_i.h" #define IPA_MAC_FLT_BITS (IPA_FLT_MAC_DST_ADDR_ETHER_II | \ IPA_FLT_MAC_SRC_ADDR_ETHER_II | IPA_FLT_MAC_DST_ADDR_802_3 | \ IPA_FLT_MAC_SRC_ADDR_802_3 | IPA_FLT_MAC_DST_ADDR_802_1Q | \ IPA_FLT_MAC_SRC_ADDR_802_1Q) /* * struct ipahal_fltrt_obj - Flt/Rt H/W information for specific IPA version * @support_hash: Is hashable tables supported Loading Loading @@ -597,102 +602,138 @@ static void ipa_fltrt_generate_mac_addr_hw_rule(u8 **extra, u8 **rest, *rest = ipa_write_8(mac_addr[i], *rest); } static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 **extra_wrds, u8 **rest_wrds) static inline void ipa_fltrt_get_mac_data(const struct ipa_rule_attrib *attrib, uint32_t attrib_mask, u8 *offset, const uint8_t **mac_addr, const uint8_t **mac_addr_mask) { u8 *extra = *extra_wrds; u8 *rest = *rest_wrds; u8 ofst_meq32 = 0; u8 ihl_ofst_rng16 = 0; u8 ihl_ofst_meq32 = 0; u8 ofst_meq128 = 0; int rc = 0; if (attrib->attrib_mask & IPA_FLT_TOS) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_TOS_EQ); extra = ipa_write_8(attrib->u.v4.tos, extra); if (attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { *offset = -14; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_PROTOCOL) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_PROTOCOL_EQ); extra = ipa_write_8(attrib->u.v4.protocol, extra); if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { *offset = -8; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; if (attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { *offset = -22; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { *offset = -16; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } ofst_meq128++; if (attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q) { *offset = -18; *mac_addr = attrib->dst_mac_addr; *mac_addr_mask = attrib->dst_mac_addr_mask; return; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; if (attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_1Q) { *offset = -10; *mac_addr = attrib->src_mac_addr; *mac_addr_mask = attrib->src_mac_addr_mask; return; } } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr); static int ipa_fltrt_generate_mac_hw_rule_bdy(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 *ofst_meq128, u8 **extra, u8 **rest) { u8 offset = 0; const uint8_t *mac_addr = NULL; const uint8_t *mac_addr_mask = NULL; int i; uint32_t attrib_mask; ofst_meq128++; for (i = 0; i < hweight_long(IPA_MAC_FLT_BITS); i++) { switch (i) { case 0: attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II; break; case 1: attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II; break; case 2: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_3; break; case 3: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_3; break; case 4: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_1Q; break; case 5: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_1Q; break; default: return -EPERM; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { attrib_mask &= attrib->attrib_mask; if (!attrib_mask) continue; if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, *ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); ipa3_0_ofst_meq128[*ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ipa_fltrt_get_mac_data(attrib, attrib_mask, &offset, &mac_addr, &mac_addr_mask); ofst_meq128++; ipa_fltrt_generate_mac_addr_hw_rule(extra, rest, offset, mac_addr_mask, mac_addr); (*ofst_meq128)++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; return 0; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr); static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 **extra_wrds, u8 **rest_wrds) { u8 *extra = *extra_wrds; u8 *rest = *rest_wrds; u8 ofst_meq32 = 0; u8 ihl_ofst_rng16 = 0; u8 ihl_ofst_meq32 = 0; u8 ofst_meq128 = 0; int rc = 0; ofst_meq128++; if (attrib->attrib_mask & IPA_FLT_TOS) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_TOS_EQ); extra = ipa_write_8(attrib->u.v4.tos, extra); } if (attrib->attrib_mask & IPA_FLT_PROTOCOL) { *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_PROTOCOL_EQ); extra = ipa_write_8(attrib->u.v4.protocol, extra); } if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_fltrt_generate_mac_hw_rule_bdy(en_rule, attrib, &ofst_meq128, &extra, &rest)) goto err; } if (attrib->attrib_mask & IPA_FLT_TOS_MASKED) { Loading Loading @@ -1032,81 +1073,11 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule, ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_fltrt_generate_mac_hw_rule_bdy(en_rule, attrib, &ofst_meq128, &extra, &rest)) goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); goto err; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_fltrt_generate_mac_addr_hw_rule( &extra, &rest, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) { Loading Loading @@ -1747,6 +1718,65 @@ static void ipa_flt_generate_mac_addr_eq(struct ipa_ipfltri_rule_eq *eq_atrb, mac_addr[i]; } static int ipa_flt_generate_mac_eq( const struct ipa_rule_attrib *attrib, u16 *en_rule, u8 *ofst_meq128, struct ipa_ipfltri_rule_eq *eq_atrb) { u8 offset = 0; const uint8_t *mac_addr = NULL; const uint8_t *mac_addr_mask = NULL; int i; uint32_t attrib_mask; for (i = 0; i < hweight_long(IPA_MAC_FLT_BITS); i++) { switch (i) { case 0: attrib_mask = IPA_FLT_MAC_DST_ADDR_ETHER_II; break; case 1: attrib_mask = IPA_FLT_MAC_SRC_ADDR_ETHER_II; break; case 2: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_3; break; case 3: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_3; break; case 4: attrib_mask = IPA_FLT_MAC_DST_ADDR_802_1Q; break; case 5: attrib_mask = IPA_FLT_MAC_SRC_ADDR_802_1Q; break; default: return -EPERM; } attrib_mask &= attrib->attrib_mask; if (!attrib_mask) continue; if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, *ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[*ofst_meq128]); ipa_fltrt_get_mac_data(attrib, attrib_mask, &offset, &mac_addr, &mac_addr_mask); ipa_flt_generate_mac_addr_eq(eq_atrb, offset, mac_addr_mask, mac_addr, *ofst_meq128); (*ofst_meq128)++; } return 0; } static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip, const struct ipa_rule_attrib *attrib, struct ipa_ipfltri_rule_eq *eq_atrb) Loading @@ -1770,69 +1800,11 @@ static int ipa_flt_generate_eq_ip4(enum ipa_ip_type ip, eq_atrb->protocol_eq = attrib->u.v4.protocol; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_flt_generate_mac_eq(attrib, en_rule, &ofst_meq128, eq_atrb)) return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32, Loading Loading @@ -2200,69 +2172,11 @@ static int ipa_flt_generate_eq_ip6(enum ipa_ip_type ip, ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); if (attrib->attrib_mask & IPA_MAC_FLT_BITS) { if (ipa_flt_generate_mac_eq(attrib, en_rule, &ofst_meq128, eq_atrb)) return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -14 => offset of dst mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -14, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_ETHER_II) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -8 => offset of src mac addr in Ethernet II hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -8, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -22 => offset of dst mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -22, attrib->dst_mac_addr_mask, attrib->dst_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_SRC_ADDR_802_3) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq128, ofst_meq128)) { IPAHAL_ERR_RL("ran out of meq128 eq\n"); return -EPERM; } *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN( ipa3_0_ofst_meq128[ofst_meq128]); /* -16 => offset of src mac addr in 802.3 hdr */ ipa_flt_generate_mac_addr_eq(eq_atrb, -16, attrib->src_mac_addr_mask, attrib->src_mac_addr, ofst_meq128); ofst_meq128++; } if (attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) { if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32, Loading
include/uapi/linux/msm_ipa.h +2 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,8 @@ #define IPA_FLT_L2TP_INNER_IPV4_DST_ADDR (1ul << 26) #define IPA_FLT_IS_PURE_ACK (1ul << 27) #define IPA_FLT_VLAN_ID (1ul << 28) #define IPA_FLT_MAC_SRC_ADDR_802_1Q (1ul << 29) #define IPA_FLT_MAC_DST_ADDR_802_1Q (1ul << 30) /** * maximal number of NAT PDNs in the PDN config table Loading