wifi: mac80211: fix waiting for beacons logic
[platform/kernel/linux-starfive.git] / net / mac80211 / ocb.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * OCB mode implementation
4  *
5  * Copyright: (c) 2014 Czech Technical University in Prague
6  *            (c) 2014 Volkswagen Group Research
7  * Copyright (C) 2022 - 2023 Intel Corporation
8  * Author:    Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
9  * Funded by: Volkswagen Group Research
10  */
11
12 #include <linux/delay.h>
13 #include <linux/if_ether.h>
14 #include <linux/skbuff.h>
15 #include <linux/if_arp.h>
16 #include <linux/etherdevice.h>
17 #include <linux/rtnetlink.h>
18 #include <net/mac80211.h>
19 #include <asm/unaligned.h>
20
21 #include "ieee80211_i.h"
22 #include "driver-ops.h"
23 #include "rate.h"
24
25 #define IEEE80211_OCB_HOUSEKEEPING_INTERVAL             (60 * HZ)
26 #define IEEE80211_OCB_PEER_INACTIVITY_LIMIT             (240 * HZ)
27 #define IEEE80211_OCB_MAX_STA_ENTRIES                   128
28
29 /**
30  * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks
31  * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks
32  *
33  * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb
34  */
35 enum ocb_deferred_task_flags {
36         OCB_WORK_HOUSEKEEPING,
37 };
38
39 void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
40                              const u8 *bssid, const u8 *addr,
41                              u32 supp_rates)
42 {
43         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
44         struct ieee80211_local *local = sdata->local;
45         struct ieee80211_chanctx_conf *chanctx_conf;
46         struct ieee80211_supported_band *sband;
47         enum nl80211_bss_scan_width scan_width;
48         struct sta_info *sta;
49         int band;
50
51         /* XXX: Consider removing the least recently used entry and
52          *      allow new one to be added.
53          */
54         if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) {
55                 net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n",
56                                      sdata->name, addr);
57                 return;
58         }
59
60         ocb_dbg(sdata, "Adding new OCB station %pM\n", addr);
61
62         rcu_read_lock();
63         chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
64         if (WARN_ON_ONCE(!chanctx_conf)) {
65                 rcu_read_unlock();
66                 return;
67         }
68         band = chanctx_conf->def.chan->band;
69         scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
70         rcu_read_unlock();
71
72         sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
73         if (!sta)
74                 return;
75
76         /* Add only mandatory rates for now */
77         sband = local->hw.wiphy->bands[band];
78         sta->sta.deflink.supp_rates[band] =
79                 ieee80211_mandatory_rates(sband, scan_width);
80
81         spin_lock(&ifocb->incomplete_lock);
82         list_add(&sta->list, &ifocb->incomplete_stations);
83         spin_unlock(&ifocb->incomplete_lock);
84         wiphy_work_queue(local->hw.wiphy, &sdata->work);
85 }
86
87 static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
88         __acquires(RCU)
89 {
90         struct ieee80211_sub_if_data *sdata = sta->sdata;
91         u8 addr[ETH_ALEN];
92
93         memcpy(addr, sta->sta.addr, ETH_ALEN);
94
95         ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n",
96                 addr, sdata->name);
97
98         sta_info_move_state(sta, IEEE80211_STA_AUTH);
99         sta_info_move_state(sta, IEEE80211_STA_ASSOC);
100         sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
101
102         rate_control_rate_init(sta);
103
104         /* If it fails, maybe we raced another insertion? */
105         if (sta_info_insert_rcu(sta))
106                 return sta_info_get(sdata, addr);
107         return sta;
108 }
109
110 static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata)
111 {
112         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
113
114         ocb_dbg(sdata, "Running ocb housekeeping\n");
115
116         ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT);
117
118         mod_timer(&ifocb->housekeeping_timer,
119                   round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL));
120 }
121
122 void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata)
123 {
124         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
125         struct sta_info *sta;
126
127         if (ifocb->joined != true)
128                 return;
129
130         sdata_lock(sdata);
131
132         spin_lock_bh(&ifocb->incomplete_lock);
133         while (!list_empty(&ifocb->incomplete_stations)) {
134                 sta = list_first_entry(&ifocb->incomplete_stations,
135                                        struct sta_info, list);
136                 list_del(&sta->list);
137                 spin_unlock_bh(&ifocb->incomplete_lock);
138
139                 ieee80211_ocb_finish_sta(sta);
140                 rcu_read_unlock();
141                 spin_lock_bh(&ifocb->incomplete_lock);
142         }
143         spin_unlock_bh(&ifocb->incomplete_lock);
144
145         if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags))
146                 ieee80211_ocb_housekeeping(sdata);
147
148         sdata_unlock(sdata);
149 }
150
151 static void ieee80211_ocb_housekeeping_timer(struct timer_list *t)
152 {
153         struct ieee80211_sub_if_data *sdata =
154                 from_timer(sdata, t, u.ocb.housekeeping_timer);
155         struct ieee80211_local *local = sdata->local;
156         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
157
158         set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
159
160         wiphy_work_queue(local->hw.wiphy, &sdata->work);
161 }
162
163 void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata)
164 {
165         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
166
167         timer_setup(&ifocb->housekeeping_timer,
168                     ieee80211_ocb_housekeeping_timer, 0);
169         INIT_LIST_HEAD(&ifocb->incomplete_stations);
170         spin_lock_init(&ifocb->incomplete_lock);
171 }
172
173 int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata,
174                        struct ocb_setup *setup)
175 {
176         struct ieee80211_local *local = sdata->local;
177         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
178         u64 changed = BSS_CHANGED_OCB | BSS_CHANGED_BSSID;
179         int err;
180
181         if (ifocb->joined == true)
182                 return -EINVAL;
183
184         sdata->deflink.operating_11g_mode = true;
185         sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
186         sdata->deflink.needed_rx_chains = sdata->local->rx_chains;
187
188         mutex_lock(&sdata->local->mtx);
189         err = ieee80211_link_use_channel(&sdata->deflink, &setup->chandef,
190                                          IEEE80211_CHANCTX_SHARED);
191         mutex_unlock(&sdata->local->mtx);
192         if (err)
193                 return err;
194
195         ieee80211_bss_info_change_notify(sdata, changed);
196
197         ifocb->joined = true;
198
199         set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags);
200         wiphy_work_queue(local->hw.wiphy, &sdata->work);
201
202         netif_carrier_on(sdata->dev);
203         return 0;
204 }
205
206 int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata)
207 {
208         struct ieee80211_if_ocb *ifocb = &sdata->u.ocb;
209         struct ieee80211_local *local = sdata->local;
210         struct sta_info *sta;
211
212         ifocb->joined = false;
213         sta_info_flush(sdata);
214
215         spin_lock_bh(&ifocb->incomplete_lock);
216         while (!list_empty(&ifocb->incomplete_stations)) {
217                 sta = list_first_entry(&ifocb->incomplete_stations,
218                                        struct sta_info, list);
219                 list_del(&sta->list);
220                 spin_unlock_bh(&ifocb->incomplete_lock);
221
222                 sta_info_free(local, sta);
223                 spin_lock_bh(&ifocb->incomplete_lock);
224         }
225         spin_unlock_bh(&ifocb->incomplete_lock);
226
227         netif_carrier_off(sdata->dev);
228         clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
229         ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB);
230
231         mutex_lock(&sdata->local->mtx);
232         ieee80211_link_release_channel(&sdata->deflink);
233         mutex_unlock(&sdata->local->mtx);
234
235         skb_queue_purge(&sdata->skb_queue);
236
237         del_timer_sync(&sdata->u.ocb.housekeeping_timer);
238         /* If the timer fired while we waited for it, it will have
239          * requeued the work. Now the work will be running again
240          * but will not rearm the timer again because it checks
241          * whether we are connected to the network or not -- at this
242          * point we shouldn't be anymore.
243          */
244
245         return 0;
246 }