aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_offload.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_offload.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_offload.c
index 6e814ad72e..5f9e6a6b07 100644
--- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_offload.c
+++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mtk_offload.c
@@ -119,11 +119,11 @@ mtk_foe_set_mac(struct mtk_foe_entry *entry, u8 *smac, u8 *dmac)
}
static int
-mtk_check_hashcollision(struct mtk_eth *eth, u32 hash)
+mtk_check_entry_available(struct mtk_eth *eth, u32 hash)
{
struct mtk_foe_entry entry = ((struct mtk_foe_entry *)eth->foe_table)[hash];
- return (entry.bfib1.state != BIND)? 0:1;
+ return (entry.bfib1.state == BIND)? 0:1;
}
static void
@@ -156,6 +156,12 @@ int mtk_flow_offload(struct mtk_eth *eth,
if (otuple->l4proto != IPPROTO_TCP && otuple->l4proto != IPPROTO_UDP)
return -EINVAL;
+
+ if (type == FLOW_OFFLOAD_DEL) {
+ flow = NULL;
+ synchronize_rcu();
+ return 0;
+ }
switch (otuple->l3proto) {
case AF_INET:
@@ -174,30 +180,25 @@ int mtk_flow_offload(struct mtk_eth *eth,
return -EINVAL;
}
- if (type == FLOW_OFFLOAD_DEL) {
- orig.bfib1.state = INVALID;
- reply.bfib1.state = INVALID;
- flow = NULL;
- goto write;
+ /* Two-way hash: when hash collision occurs, the hash value will be shifted to the next position. */
+ if (!mtk_check_entry_available(eth, ohash)){
+ if (!mtk_check_entry_available(eth, ohash + 1))
+ return -EINVAL;
+ ohash += 1;
+ }
+ if (!mtk_check_entry_available(eth, rhash)){
+ if (!mtk_check_entry_available(eth, rhash + 1))
+ return -EINVAL;
+ rhash += 1;
}
- /* Two-way hash: when hash collision occurs, the hash value will be shifted to the next position. */
- if(mtk_check_hashcollision(eth, ohash))
- ohash += 1;
- if(mtk_check_hashcollision(eth, rhash))
- rhash += 1;
mtk_foe_set_mac(&orig, dest->eth_src, dest->eth_dest);
mtk_foe_set_mac(&reply, src->eth_src, src->eth_dest);
-
-write:
mtk_foe_write(eth, ohash, &orig);
mtk_foe_write(eth, rhash, &reply);
rcu_assign_pointer(eth->foe_flow_table[ohash], flow);
rcu_assign_pointer(eth->foe_flow_table[rhash], flow);
- if (type == FLOW_OFFLOAD_DEL)
- synchronize_rcu();
-
return 0;
}