mac80211: update brcmfmac including missing boardrev workaround
[openwrt.git] / package / kernel / mac80211 / patches / 328-mac80211-let-unused-MPP-table-entries-timeout.patch
1 From: Henning Rogge <hrogge@gmail.com>
2 Date: Wed, 3 Feb 2016 13:58:37 +0100
3 Subject: [PATCH] mac80211: let unused MPP table entries timeout
4
5 Remember the last time when a mpp table entry is used for
6 rx or tx and remove them after MESH_PATH_EXPIRE time.
7
8 Acked-by: Bob Copeland <me@bobcopeland.com>
9 Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de>
10 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
11 ---
12
13 --- a/net/mac80211/mesh_pathtbl.c
14 +++ b/net/mac80211/mesh_pathtbl.c
15 @@ -942,6 +942,46 @@ enddel:
16  }
17  
18  /**
19 + * mpp_path_del - delete a mesh proxy path from the table
20 + *
21 + * @addr: addr address (ETH_ALEN length)
22 + * @sdata: local subif
23 + *
24 + * Returns: 0 if successful
25 + */
26 +static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
27 +{
28 +       struct mesh_table *tbl;
29 +       struct mesh_path *mpath;
30 +       struct mpath_node *node;
31 +       struct hlist_head *bucket;
32 +       int hash_idx;
33 +       int err = 0;
34 +
35 +       read_lock_bh(&pathtbl_resize_lock);
36 +       tbl = resize_dereference_mpp_paths();
37 +       hash_idx = mesh_table_hash(addr, sdata, tbl);
38 +       bucket = &tbl->hash_buckets[hash_idx];
39 +
40 +       spin_lock(&tbl->hashwlock[hash_idx]);
41 +       hlist_for_each_entry(node, bucket, list) {
42 +               mpath = node->mpath;
43 +               if (mpath->sdata == sdata &&
44 +                   ether_addr_equal(addr, mpath->dst)) {
45 +                       __mesh_path_del(tbl, node);
46 +                       goto enddel;
47 +               }
48 +       }
49 +
50 +       err = -ENXIO;
51 +enddel:
52 +       mesh_paths_generation++;
53 +       spin_unlock(&tbl->hashwlock[hash_idx]);
54 +       read_unlock_bh(&pathtbl_resize_lock);
55 +       return err;
56 +}
57 +
58 +/**
59   * mesh_path_tx_pending - sends pending frames in a mesh path queue
60   *
61   * @mpath: mesh path to activate
62 @@ -1157,6 +1197,17 @@ void mesh_path_expire(struct ieee80211_s
63                      time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
64                         mesh_path_del(mpath->sdata, mpath->dst);
65         }
66 +
67 +       tbl = rcu_dereference(mpp_paths);
68 +       for_each_mesh_entry(tbl, node, i) {
69 +               if (node->mpath->sdata != sdata)
70 +                       continue;
71 +               mpath = node->mpath;
72 +               if ((!(mpath->flags & MESH_PATH_FIXED)) &&
73 +                   time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
74 +                       mpp_path_del(mpath->sdata, mpath->dst);
75 +       }
76 +
77         rcu_read_unlock();
78  }
79  
80 --- a/net/mac80211/rx.c
81 +++ b/net/mac80211/rx.c
82 @@ -2291,6 +2291,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
83                         spin_lock_bh(&mppath->state_lock);
84                         if (!ether_addr_equal(mppath->mpp, mpp_addr))
85                                 memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
86 +                       mppath->exp_time = jiffies;
87                         spin_unlock_bh(&mppath->state_lock);
88                 }
89                 rcu_read_unlock();
90 --- a/net/mac80211/tx.c
91 +++ b/net/mac80211/tx.c
92 @@ -2171,8 +2171,11 @@ static struct sk_buff *ieee80211_build_h
93                                         mpp_lookup = true;
94                         }
95  
96 -                       if (mpp_lookup)
97 +                       if (mpp_lookup) {
98                                 mppath = mpp_path_lookup(sdata, skb->data);
99 +                               if (mppath)
100 +                                       mppath->exp_time = jiffies;
101 +                       }
102  
103                         if (mppath && mpath)
104                                 mesh_path_del(mpath->sdata, mpath->dst);