Merge tag 'kvmarm-fixes-6.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmar...
[platform/kernel/linux-starfive.git] / net / wireless / mesh.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Portions
4  * Copyright (C) 2022 Intel Corporation
5  */
6 #include <linux/ieee80211.h>
7 #include <linux/export.h>
8 #include <net/cfg80211.h>
9 #include "nl80211.h"
10 #include "core.h"
11 #include "rdev-ops.h"
12
13 /* Default values, timeouts in ms */
14 #define MESH_TTL                31
15 #define MESH_DEFAULT_ELEMENT_TTL 31
16 #define MESH_MAX_RETR           3
17 #define MESH_RET_T              100
18 #define MESH_CONF_T             100
19 #define MESH_HOLD_T             100
20
21 #define MESH_PATH_TIMEOUT       5000
22 #define MESH_RANN_INTERVAL      5000
23 #define MESH_PATH_TO_ROOT_TIMEOUT      6000
24 #define MESH_ROOT_INTERVAL     5000
25 #define MESH_ROOT_CONFIRMATION_INTERVAL 2000
26 #define MESH_DEFAULT_PLINK_TIMEOUT      1800 /* timeout in seconds */
27
28 /*
29  * Minimum interval between two consecutive PREQs originated by the same
30  * interface
31  */
32 #define MESH_PREQ_MIN_INT       10
33 #define MESH_PERR_MIN_INT       100
34 #define MESH_DIAM_TRAVERSAL_TIME 50
35
36 #define MESH_RSSI_THRESHOLD     0
37
38 /*
39  * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds
40  * before timing out.  This way it will remain ACTIVE and no data frames
41  * will be unnecessarily held in the pending queue.
42  */
43 #define MESH_PATH_REFRESH_TIME                  1000
44 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
45
46 /* Default maximum number of established plinks per interface */
47 #define MESH_MAX_ESTAB_PLINKS   32
48
49 #define MESH_MAX_PREQ_RETRIES   4
50
51 #define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50
52
53 #define MESH_DEFAULT_BEACON_INTERVAL    1000    /* in 1024 us units (=TUs) */
54 #define MESH_DEFAULT_DTIM_PERIOD        2
55 #define MESH_DEFAULT_AWAKE_WINDOW       10      /* in 1024 us units (=TUs) */
56
57 const struct mesh_config default_mesh_config = {
58         .dot11MeshRetryTimeout = MESH_RET_T,
59         .dot11MeshConfirmTimeout = MESH_CONF_T,
60         .dot11MeshHoldingTimeout = MESH_HOLD_T,
61         .dot11MeshMaxRetries = MESH_MAX_RETR,
62         .dot11MeshTTL = MESH_TTL,
63         .element_ttl = MESH_DEFAULT_ELEMENT_TTL,
64         .auto_open_plinks = true,
65         .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
66         .dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX,
67         .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
68         .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
69         .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT,
70         .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME,
71         .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
72         .path_refresh_time = MESH_PATH_REFRESH_TIME,
73         .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
74         .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
75         .dot11MeshGateAnnouncementProtocol = false,
76         .dot11MeshForwarding = true,
77         .rssi_threshold = MESH_RSSI_THRESHOLD,
78         .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
79         .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
80         .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
81         .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
82         .power_mode = NL80211_MESH_POWER_ACTIVE,
83         .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
84         .plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT,
85         .dot11MeshNolearn = false,
86 };
87
88 const struct mesh_setup default_mesh_setup = {
89         /* cfg80211_join_mesh() will pick a channel if needed */
90         .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
91         .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
92         .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
93         .auth_id = 0, /* open */
94         .ie = NULL,
95         .ie_len = 0,
96         .is_secure = false,
97         .user_mpm = false,
98         .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL,
99         .dtim_period = MESH_DEFAULT_DTIM_PERIOD,
100 };
101
102 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
103                          struct net_device *dev,
104                          struct mesh_setup *setup,
105                          const struct mesh_config *conf)
106 {
107         struct wireless_dev *wdev = dev->ieee80211_ptr;
108         int err;
109
110         BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
111
112         ASSERT_WDEV_LOCK(wdev);
113
114         if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
115                 return -EOPNOTSUPP;
116
117         if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
118               setup->is_secure)
119                 return -EOPNOTSUPP;
120
121         if (wdev->u.mesh.id_len)
122                 return -EALREADY;
123
124         if (!setup->mesh_id_len)
125                 return -EINVAL;
126
127         if (!rdev->ops->join_mesh)
128                 return -EOPNOTSUPP;
129
130         if (!setup->chandef.chan) {
131                 /* if no channel explicitly given, use preset channel */
132                 setup->chandef = wdev->u.mesh.preset_chandef;
133         }
134
135         if (!setup->chandef.chan) {
136                 /* if we don't have that either, use the first usable channel */
137                 enum nl80211_band band;
138
139                 for (band = 0; band < NUM_NL80211_BANDS; band++) {
140                         struct ieee80211_supported_band *sband;
141                         struct ieee80211_channel *chan;
142                         int i;
143
144                         sband = rdev->wiphy.bands[band];
145                         if (!sband)
146                                 continue;
147
148                         for (i = 0; i < sband->n_channels; i++) {
149                                 chan = &sband->channels[i];
150                                 if (chan->flags & (IEEE80211_CHAN_NO_IR |
151                                                    IEEE80211_CHAN_DISABLED |
152                                                    IEEE80211_CHAN_RADAR))
153                                         continue;
154                                 setup->chandef.chan = chan;
155                                 break;
156                         }
157
158                         if (setup->chandef.chan)
159                                 break;
160                 }
161
162                 /* no usable channel ... */
163                 if (!setup->chandef.chan)
164                         return -EINVAL;
165
166                 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
167                 setup->chandef.center_freq1 = setup->chandef.chan->center_freq;
168         }
169
170         /*
171          * check if basic rates are available otherwise use mandatory rates as
172          * basic rates
173          */
174         if (!setup->basic_rates) {
175                 enum nl80211_bss_scan_width scan_width;
176                 struct ieee80211_supported_band *sband =
177                                 rdev->wiphy.bands[setup->chandef.chan->band];
178
179                 if (setup->chandef.chan->band == NL80211_BAND_2GHZ) {
180                         int i;
181
182                         /*
183                          * Older versions selected the mandatory rates for
184                          * 2.4 GHz as well, but were broken in that only
185                          * 1 Mbps was regarded as a mandatory rate. Keep
186                          * using just 1 Mbps as the default basic rate for
187                          * mesh to be interoperable with older versions.
188                          */
189                         for (i = 0; i < sband->n_bitrates; i++) {
190                                 if (sband->bitrates[i].bitrate == 10) {
191                                         setup->basic_rates = BIT(i);
192                                         break;
193                                 }
194                         }
195                 } else {
196                         scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
197                         setup->basic_rates = ieee80211_mandatory_rates(sband,
198                                                                        scan_width);
199                 }
200         }
201
202         err = cfg80211_chandef_dfs_required(&rdev->wiphy,
203                                             &setup->chandef,
204                                             NL80211_IFTYPE_MESH_POINT);
205         if (err < 0)
206                 return err;
207         if (err > 0 && !setup->userspace_handles_dfs)
208                 return -EINVAL;
209
210         if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef,
211                                      NL80211_IFTYPE_MESH_POINT))
212                 return -EINVAL;
213
214         err = rdev_join_mesh(rdev, dev, conf, setup);
215         if (!err) {
216                 memcpy(wdev->u.mesh.id, setup->mesh_id, setup->mesh_id_len);
217                 wdev->u.mesh.id_len = setup->mesh_id_len;
218                 wdev->u.mesh.chandef = setup->chandef;
219                 wdev->u.mesh.beacon_interval = setup->beacon_interval;
220         }
221
222         return err;
223 }
224
225 int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
226                               struct wireless_dev *wdev,
227                               struct cfg80211_chan_def *chandef)
228 {
229         int err;
230
231         /*
232          * Workaround for libertas (only!), it puts the interface
233          * into mesh mode but doesn't implement join_mesh. Instead,
234          * it is configured via sysfs and then joins the mesh when
235          * you set the channel. Note that the libertas mesh isn't
236          * compatible with 802.11 mesh.
237          */
238         if (rdev->ops->libertas_set_mesh_channel) {
239                 if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
240                         return -EINVAL;
241
242                 if (!netif_running(wdev->netdev))
243                         return -ENETDOWN;
244
245                 err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
246                                                      chandef->chan);
247                 if (!err)
248                         wdev->u.mesh.chandef = *chandef;
249
250                 return err;
251         }
252
253         if (wdev->u.mesh.id_len)
254                 return -EBUSY;
255
256         wdev->u.mesh.preset_chandef = *chandef;
257         return 0;
258 }
259
260 int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
261                           struct net_device *dev)
262 {
263         struct wireless_dev *wdev = dev->ieee80211_ptr;
264         int err;
265
266         ASSERT_WDEV_LOCK(wdev);
267
268         if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
269                 return -EOPNOTSUPP;
270
271         if (!rdev->ops->leave_mesh)
272                 return -EOPNOTSUPP;
273
274         if (!wdev->u.mesh.id_len)
275                 return -ENOTCONN;
276
277         err = rdev_leave_mesh(rdev, dev);
278         if (!err) {
279                 wdev->conn_owner_nlportid = 0;
280                 wdev->u.mesh.id_len = 0;
281                 wdev->u.mesh.beacon_interval = 0;
282                 memset(&wdev->u.mesh.chandef, 0,
283                        sizeof(wdev->u.mesh.chandef));
284                 rdev_set_qos_map(rdev, dev, NULL);
285                 cfg80211_sched_dfs_chan_update(rdev);
286         }
287
288         return err;
289 }
290
291 int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
292                         struct net_device *dev)
293 {
294         struct wireless_dev *wdev = dev->ieee80211_ptr;
295         int err;
296
297         wdev_lock(wdev);
298         err = __cfg80211_leave_mesh(rdev, dev);
299         wdev_unlock(wdev);
300
301         return err;
302 }