diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index e619563d6701..eaf30dd54777 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -594,7 +594,8 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib, "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)) nbytes += scnprintf( dbg_buff + nbytes, IPA_MAX_MSG_LEN - nbytes, @@ -603,7 +604,8 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib, 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)) nbytes += scnprintf( dbg_buff + nbytes, IPA_MAX_MSG_LEN - nbytes, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c index c9a037fa60af..5486266ee8f9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c @@ -13,6 +13,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 @@ -847,6 +852,112 @@ static void ipa_fltrt_generate_mac_addr_hw_rule(u8 **extra, u8 **rest, *rest = ipa_write_8(mac_addr[i], *rest); } +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) +{ + 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_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_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; + } + + 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; + } + + 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_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; + } +} + +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; + + 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_fltrt_generate_mac_addr_hw_rule(extra, rest, offset, + mac_addr_mask, + mac_addr); + + (*ofst_meq128)++; + } + + return 0; +} + static inline int ipa_fltrt_generate_vlan_hw_rule_bdy(u16 *en_rule, const struct ipa_rule_attrib *attrib, u8 *ofst_meq32, u8 **extra, u8 **rest) @@ -909,80 +1020,10 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule, extra = ipa_write_8(attrib->u.v4.protocol, extra); } - 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_TOS_MASKED) { @@ -1359,80 +1400,10 @@ 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) { @@ -2079,6 +2050,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 inline int ipa_flt_generat_vlan_eq( const struct ipa_rule_attrib *attrib, u16 *en_rule, u8 *ofst_meq32, struct ipa_ipfltri_rule_eq *eq_atrb) @@ -2147,68 +2177,10 @@ 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"); + 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("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"); - 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) { @@ -2625,68 +2597,10 @@ 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) { diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 161b8fa45e68..ea2f3eca14bc 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -211,6 +211,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