• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #ifndef __RTW_MESH_PATHTBL_H_
16 #define __RTW_MESH_PATHTBL_H_
17 
18 #ifndef DBG_RTW_MPATH
19 #define DBG_RTW_MPATH 1
20 #endif
21 #if DBG_RTW_MPATH
22 #define RTW_MPATH_DBG(fmt, arg...) RTW_PRINT(fmt, ##arg)
23 #else
24 #define RTW_MPATH_DBG(fmt, arg...) do {} while (0)
25 #endif
26 
27 /**
28  * enum rtw_mesh_path_flags - mesh path flags
29  *
30  * @RTW_MESH_PATH_ACTIVE: the mesh path can be used for forwarding
31  * @RTW_MESH_PATH_RESOLVING: the discovery process is running for this mesh path
32  * @RTW_MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
33  *	number
34  * @RTW_MESH_PATH_FIXED: the mesh path has been manually set and should not be
35  *	modified
36  * @RTW_MESH_PATH_RESOLVED: the mesh path can has been resolved
37  * @RTW_MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
38  *	already queued up, waiting for the discovery process to start.
39  * @RTW_MESH_PATH_DELETED: the mesh path has been deleted and should no longer
40  *	be used
41  * @RTW_MESH_PATH_ROOT_ADD_CHK: root additional check in root mode.
42  *	With this flag, It will try the last used rann_snd_addr
43  * @RTW_MESH_PATH_PEER_AKA: only used toward a peer, only used in active keep
44  *	alive mechanism. PREQ's da = path dst
45  * @RTW_MESH_PATH_BCAST_PREQ: for re-checking next hop resolve toward root.
46  *	Use it to force path_discover sending broadcast PREQ for root.
47  *
48  * RTW_MESH_PATH_RESOLVED is used by the mesh path timer to
49  * decide when to stop or cancel the mesh path discovery.
50  */
51 enum rtw_mesh_path_flags {
52 	RTW_MESH_PATH_ACTIVE =		BIT(0),
53 	RTW_MESH_PATH_RESOLVING =	BIT(1),
54 	RTW_MESH_PATH_SN_VALID =	BIT(2),
55 	RTW_MESH_PATH_FIXED	=	BIT(3),
56 	RTW_MESH_PATH_RESOLVED =	BIT(4),
57 	RTW_MESH_PATH_REQ_QUEUED =	BIT(5),
58 	RTW_MESH_PATH_DELETED =		BIT(6),
59 	RTW_MESH_PATH_ROOT_ADD_CHK =	BIT(7),
60 	RTW_MESH_PATH_PEER_AKA =	BIT(8),
61 	RTW_MESH_PATH_BCAST_PREQ =	BIT(9),
62 };
63 
64 /**
65  * struct rtw_mesh_path - mesh path structure
66  *
67  * @dst: mesh path destination mac address
68  * @mpp: mesh proxy mac address
69  * @rhash: rhashtable list pointer
70  * @gate_list: list pointer for known gates list
71  * @sdata: mesh subif
72  * @next_hop: mesh neighbor to which frames for this destination will be
73  *	forwarded
74  * @timer: mesh path discovery timer
75  * @frame_queue: pending queue for frames sent to this destination while the
76  *	path is unresolved
77  * @rcu: rcu head for freeing mesh path
78  * @sn: target sequence number
79  * @metric: current metric to this destination
80  * @hop_count: hops to destination
81  * @exp_time: in jiffies, when the path will expire or when it expired
82  * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
83  *	retry
84  * @discovery_retries: number of discovery retries
85  * @flags: mesh path flags, as specified on &enum rtw_mesh_path_flags
86  * @state_lock: mesh path state lock used to protect changes to the
87  * mpath itself.  No need to take this lock when adding or removing
88  * an mpath to a hash bucket on a path table.
89  * @rann_snd_addr: the RANN sender address
90  * @rann_metric: the aggregated path metric towards the root node
91  * @last_preq_to_root: Timestamp of last PREQ sent to root
92  * @is_root: the destination station of this path is a root node
93  * @is_gate: the destination station of this path is a mesh gate
94  *
95  *
96  * The dst address is unique in the mesh path table. Since the mesh_path is
97  * protected by RCU, deleting the next_hop STA must remove / substitute the
98  * mesh_path structure and wait until that is no longer reachable before
99  * destroying the STA completely.
100  */
101 struct rtw_mesh_path {
102 	u8 dst[ETH_ALEN];
103 	u8 mpp[ETH_ALEN];	/* used for MPP or MAP */
104 	rtw_rhash_head rhash;
105 	rtw_hlist_node gate_list;
106 	_adapter *adapter;
107 	struct sta_info __rcu *next_hop;
108 	_timer timer;
109 	_queue frame_queue;
110 	u32 frame_queue_len;
111 	rtw_rcu_head rcu;
112 	u32 sn;
113 	u32 metric;
114 	u8 hop_count;
115 	systime exp_time;
116 	systime discovery_timeout;
117 	systime gate_timeout;
118 	u32 gate_ann_int;    /* gate announce interval */
119 	u8 discovery_retries;
120 	enum rtw_mesh_path_flags flags;
121 	_lock state_lock;
122 	u8 rann_snd_addr[ETH_ALEN];
123 #ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
124 	u8 add_chk_rann_snd_addr[ETH_ALEN];
125 #endif
126 	u32 rann_metric;
127 	unsigned long last_preq_to_root;
128 	bool is_root;
129 	bool is_gate;
130 	bool gate_asked;
131 };
132 
133 /**
134  * struct rtw_mesh_table
135  *
136  * @known_gates: list of known mesh gates and their mpaths by the station. The
137  * gate's mpath may or may not be resolved and active.
138  * @gates_lock: protects updates to known_gates
139  * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
140  * @entries: number of entries in the table
141  */
142 struct rtw_mesh_table {
143 	rtw_hlist_head known_gates;
144 	_lock gates_lock;
145 	rtw_rhashtable rhead;
146 	ATOMIC_T entries;
147 };
148 
149 #define RTW_MESH_PATH_EXPIRE (600 * HZ)
150 
151 /* Maximum number of paths per interface */
152 #define RTW_MESH_MAX_MPATHS		1024
153 
154 /* Number of frames buffered per destination for unresolved destinations */
155 #define RTW_MESH_FRAME_QUEUE_LEN	10
156 
157 int rtw_mesh_nexthop_lookup(_adapter *adapter,
158 	const u8 *mda, const u8 *msa, u8 *ra);
159 int rtw_mesh_nexthop_resolve(_adapter *adapter,
160 			 struct xmit_frame *xframe);
161 
162 struct rtw_mesh_path *rtw_mesh_path_lookup(_adapter *adapter,
163 				   const u8 *dst);
164 struct rtw_mesh_path *rtw_mpp_path_lookup(_adapter *adapter,
165 				  const u8 *dst);
166 int rtw_mpp_path_add(_adapter *adapter,
167 		 const u8 *dst, const u8 *mpp);
168 void dump_mpp(void *sel, _adapter *adapter);
169 
170 struct rtw_mesh_path *
171 rtw_mesh_path_lookup_by_idx(_adapter *adapter, int idx);
172 void dump_mpath(void *sel, _adapter *adapter);
173 
174 struct rtw_mesh_path *
175 rtw_mpp_path_lookup_by_idx(_adapter *adapter, int idx);
176 void rtw_mesh_path_fix_nexthop(struct rtw_mesh_path *mpath, struct sta_info *next_hop);
177 void rtw_mesh_path_expire(_adapter *adapter);
178 
179 struct rtw_mesh_path *
180 rtw_mesh_path_add(_adapter *adapter, const u8 *dst);
181 
182 int rtw_mesh_path_add_gate(struct rtw_mesh_path *mpath);
183 void rtw_mesh_gate_del(struct rtw_mesh_table *tbl, struct rtw_mesh_path *mpath);
184 bool rtw_mesh_gate_search(struct rtw_mesh_table *tbl, const u8 *addr);
185 int rtw_mesh_path_send_to_gates(struct rtw_mesh_path *mpath);
186 int rtw_mesh_gate_num(_adapter *adapter);
187 bool rtw_mesh_is_primary_gate(_adapter *adapter);
188 void dump_known_gates(void *sel, _adapter *adapter);
189 
190 void rtw_mesh_plink_broken(struct sta_info *sta);
191 
192 void rtw_mesh_path_assign_nexthop(struct rtw_mesh_path *mpath, struct sta_info *sta);
193 void rtw_mesh_path_flush_pending(struct rtw_mesh_path *mpath);
194 void rtw_mesh_path_tx_pending(struct rtw_mesh_path *mpath);
195 int rtw_mesh_pathtbl_init(_adapter *adapter);
196 void rtw_mesh_pathtbl_unregister(_adapter *adapter);
197 int rtw_mesh_path_del(_adapter *adapter, const u8 *addr);
198 
199 void rtw_mesh_path_flush_by_nexthop(struct sta_info *sta);
200 void rtw_mesh_path_discard_frame(_adapter *adapter,
201 			     struct xmit_frame *xframe);
202 
rtw_mesh_path_activate(struct rtw_mesh_path * mpath)203 static inline void rtw_mesh_path_activate(struct rtw_mesh_path *mpath)
204 {
205 	mpath->flags |= RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVED;
206 }
207 
208 void rtw_mesh_path_flush_by_iface(_adapter *adapter);
209 
210 #endif /* __RTW_MESH_PATHTBL_H_ */
211 
212