Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: BSD-3-Clause-Clear */
2/*
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4 */
5
6#ifndef __MT76_UTIL_H
7#define __MT76_UTIL_H
8
9#include <linux/skbuff.h>
10#include <linux/bitops.h>
11#include <linux/bitfield.h>
12#include <net/mac80211.h>
13
14struct mt76_worker
15{
16 struct task_struct *task;
17 void (*fn)(struct mt76_worker *);
18 unsigned long state;
19};
20
21enum {
22 MT76_WORKER_SCHEDULED,
23 MT76_WORKER_RUNNING,
24};
25
26#define MT76_INCR(_var, _size) \
27 (_var = (((_var) + 1) % (_size)))
28
29int mt76_wcid_alloc(u32 *mask, int size);
30
31static inline void
32mt76_wcid_mask_set(u32 *mask, int idx)
33{
34 mask[idx / 32] |= BIT(idx % 32);
35}
36
37static inline void
38mt76_wcid_mask_clear(u32 *mask, int idx)
39{
40 mask[idx / 32] &= ~BIT(idx % 32);
41}
42
43static inline void
44mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
45{
46 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
47
48 if (enable)
49 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
50 else
51 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
52}
53
54int __mt76_worker_fn(void *ptr);
55
56static inline int
57mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w,
58 void (*fn)(struct mt76_worker *),
59 const char *name)
60{
61 const char *dev_name = wiphy_name(hw->wiphy);
62 int ret;
63
64 if (fn)
65 w->fn = fn;
66 w->task = kthread_run(__mt76_worker_fn, w,
67 "mt76-%s %s", name, dev_name);
68
69 if (IS_ERR(w->task)) {
70 ret = PTR_ERR(w->task);
71 w->task = NULL;
72 return ret;
73 }
74
75 return 0;
76}
77
78static inline void mt76_worker_schedule(struct mt76_worker *w)
79{
80 if (!w->task)
81 return;
82
83 if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) &&
84 !test_bit(MT76_WORKER_RUNNING, &w->state))
85 wake_up_process(w->task);
86}
87
88static inline void mt76_worker_disable(struct mt76_worker *w)
89{
90 if (!w->task)
91 return;
92
93 kthread_park(w->task);
94 WRITE_ONCE(w->state, 0);
95}
96
97static inline void mt76_worker_enable(struct mt76_worker *w)
98{
99 if (!w->task)
100 return;
101
102 kthread_unpark(w->task);
103 mt76_worker_schedule(w);
104}
105
106static inline void mt76_worker_teardown(struct mt76_worker *w)
107{
108 if (!w->task)
109 return;
110
111 kthread_stop(w->task);
112 w->task = NULL;
113}
114
115#endif