hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/net/wireless/mediatek/mt76/util.h
....@@ -1,15 +1,7 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
34 * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2
7
- * as published by the Free Software Foundation
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
135 */
146
157 #ifndef __MT76_UTIL_H
....@@ -18,22 +10,47 @@
1810 #include <linux/skbuff.h>
1911 #include <linux/bitops.h>
2012 #include <linux/bitfield.h>
13
+#include <net/mac80211.h>
14
+
15
+struct mt76_worker
16
+{
17
+ struct task_struct *task;
18
+ void (*fn)(struct mt76_worker *);
19
+ unsigned long state;
20
+};
21
+
22
+enum {
23
+ MT76_WORKER_SCHEDULED,
24
+ MT76_WORKER_RUNNING,
25
+};
2126
2227 #define MT76_INCR(_var, _size) \
23
- _var = (((_var) + 1) % _size)
28
+ (_var = (((_var) + 1) % (_size)))
2429
25
-int mt76_wcid_alloc(unsigned long *mask, int size);
30
+int mt76_wcid_alloc(u32 *mask, int size);
31
+
32
+static inline bool
33
+mt76_wcid_mask_test(u32 *mask, int idx)
34
+{
35
+ return mask[idx / 32] & BIT(idx % 32);
36
+}
2637
2738 static inline void
28
-mt76_wcid_free(unsigned long *mask, int idx)
39
+mt76_wcid_mask_set(u32 *mask, int idx)
2940 {
30
- mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG);
41
+ mask[idx / 32] |= BIT(idx % 32);
42
+}
43
+
44
+static inline void
45
+mt76_wcid_mask_clear(u32 *mask, int idx)
46
+{
47
+ mask[idx / 32] &= ~BIT(idx % 32);
3148 }
3249
3350 static inline void
3451 mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
3552 {
36
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
53
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
3754
3855 if (enable)
3956 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
....@@ -41,4 +58,67 @@
4158 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
4259 }
4360
61
+int __mt76_worker_fn(void *ptr);
62
+
63
+static inline int
64
+mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w,
65
+ void (*fn)(struct mt76_worker *),
66
+ const char *name)
67
+{
68
+ const char *dev_name = wiphy_name(hw->wiphy);
69
+ int ret;
70
+
71
+ if (fn)
72
+ w->fn = fn;
73
+ w->task = kthread_create(__mt76_worker_fn, w, "mt76-%s %s",
74
+ name, dev_name);
75
+
76
+ ret = PTR_ERR_OR_ZERO(w->task);
77
+ if (ret) {
78
+ w->task = NULL;
79
+ return ret;
80
+ }
81
+
82
+ wake_up_process(w->task);
83
+
84
+ return 0;
85
+}
86
+
87
+static inline void mt76_worker_schedule(struct mt76_worker *w)
88
+{
89
+ if (!w->task)
90
+ return;
91
+
92
+ if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) &&
93
+ !test_bit(MT76_WORKER_RUNNING, &w->state))
94
+ wake_up_process(w->task);
95
+}
96
+
97
+static inline void mt76_worker_disable(struct mt76_worker *w)
98
+{
99
+ if (!w->task)
100
+ return;
101
+
102
+ kthread_park(w->task);
103
+ WRITE_ONCE(w->state, 0);
104
+}
105
+
106
+static inline void mt76_worker_enable(struct mt76_worker *w)
107
+{
108
+ if (!w->task)
109
+ return;
110
+
111
+ kthread_unpark(w->task);
112
+ mt76_worker_schedule(w);
113
+}
114
+
115
+static inline void mt76_worker_teardown(struct mt76_worker *w)
116
+{
117
+ if (!w->task)
118
+ return;
119
+
120
+ kthread_stop(w->task);
121
+ w->task = NULL;
122
+}
123
+
44124 #endif